Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

36
deps/v8/.bazelrc vendored Normal file
View File

@ -0,0 +1,36 @@
# 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.
# Enable Bzlmod for every Bazel command
common --enable_bzlmod
# Pass CC, CXX and PATH from the environment
build --action_env=CC
build --action_env=CXX
build --action_env=PATH
build --copt=-std=c++20
# Use Clang compiler
build:clang --action_env=BAZEL_COMPILER=clang
build:clang --action_env=CC=clang
build:clang --action_env=CXX=clang++
# V8 debug config
build:debug --compilation_mode=dbg
build:debug --config=v8_enable_debugging_features
build:debug --//:v8_enable_fast_mksnapshot
build:debug --//:v8_enable_backtrace
build:debug --//:v8_enable_local_handle_zapping
build:debug --//:v8_enable_global_handle_zapping
# v8_enable_debugging_features flags
build:v8_enable_debugging_features --//:v8_enable_verify_heap
build:v8_enable_debugging_features --//:v8_enable_object_print
build:v8_enable_debugging_features --//:v8_enable_disassembler
build:v8_enable_debugging_features --//:v8_enable_trace_maps
build:v8_enable_debugging_features --//:v8_enable_test_features
build:v8_enable_debugging_features --//:v8_enable_v8_checks
build:v8_enable_debugging_features --//:v8_code_comments
build:v8_enable_debugging_features --//:v8_enable_debug_code
build:v8_enable_debugging_features --//:v8_enable_snapshot_native_code_counters

15
deps/v8/.clang-format vendored Normal file
View File

@ -0,0 +1,15 @@
# Defines the Google C++ style for automatic reformatting.
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Google
DerivePointerAlignment: false
MaxEmptyLinesToKeep: 1
IfMacros:
- IF
- IF_NOT
Macros:
# Make clang-format think TurboShaft `ELSE` expands to just `else`, so that
# it formats well alongside `if`
- ELSE=else
StatementMacros:
- DECL_CAST
- DECL_VERIFIER

26
deps/v8/.clang-tidy vendored Normal file
View File

@ -0,0 +1,26 @@
---
---
Checks: '-*,
bugprone-unique-ptr-array-mismatch,
# google-build-explicit-make-pair,
google-default-arguments,
google-explicit-constructor,
google-readability-casting,
modernize-redundant-void-arg,
modernize-replace-random-shuffle,
modernize-shrink-to-fit,
modernize-type-traits,
# modernize-use-auto,
modernize-use-constraints,
modernize-use-bool-literals,
modernize-use-equals-default,
# modernize-use-equals-delete,
modernize-use-nullptr,
modernize-use-override,
performance-inefficient-vector-operation,
performance-trivially-destructible,
performance-unnecessary-copy-initialization'
WarningsAsErrors: ''
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
...

9
deps/v8/.editorconfig vendored Normal file
View File

@ -0,0 +1,9 @@
# editorconfig.org
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

10
deps/v8/.flake8 vendored Normal file
View File

@ -0,0 +1,10 @@
[flake8]
ignore = E111,E114,E310 # We use 2-space indentation
exclude =
./third_party/, # third-party code
./build/, # third-party code
./buildtools/, # third-party code
./test/wasm-js/, # third-party code
./test/wasm-js/data/, # third-party code
./test/test262/data/, # third-party code
./test/test262/harness/, # third-party code

123
deps/v8/.git-blame-ignore-revs vendored Normal file
View File

@ -0,0 +1,123 @@
# git hyper-blame master ignore list.
#
# This file contains a list of git hashes of revisions to be ignored by git
# hyper-blame (in depot_tools). These revisions are considered "unimportant" in
# that they are unlikely to be what you are interested in when blaming.
#
# Instructions:
# - Only large (generally automated) reformatting or renaming CLs should be
# added to this list. Do not put things here just because you feel they are
# trivial or unimportant. If in doubt, do not put it on this list.
# - Precede each revision with a comment containing the first line of its log.
# For bulk work over many commits, place all commits in a block with a single
# comment at the top describing the work done in those commits.
# - Only put full 40-character hashes on this list (not short hashes or any
# other revision reference).
# - Append to the bottom of the file (revisions should be in chronological order
# from oldest to newest).
# - Because you must use a hash, you need to append to this list in a follow-up
# CL to the actual reformatting CL that you are trying to ignore.
# objects.h splitting
0604031eb1d01c52b6c1c9ae3012d80b23d74a68
09e405453359000d66cc0faaa102854e626bebeb
766ef168fbcac6bd0728cc2c9bb3ae7cbd74278a
b5a2839b927be04bdb50a236071c11764e4d6400
c911f91b5b6219e038c0117b05a8375bdf3db0b0
1bb48bf91ba8c887884a0fbd674c91f64964d8a5
19da9f24df7b59fec72b9dd8a979ad0ce5639c87
b090d7e7468236ffce0afdb55bb496bf0073f2ee
f40638d148b7a435522d5b714993908061e3b10d
e8a1c25f6afae9b77921abb70fad49da252eb6f0
6fa8283d0e031c9585d190f751907ed45bf85de0
9aa861c4bcfed612039259f93c2cd2b01337e99e
8175648018bd9f70af866f9fa433f1d79644d86b
c7b1ceb801ec7f639a093468d8e6424212cc197c
e39d2cbe1b1baa6513ddce2d73c981e335cc34fb
eda00a5c499b7a83479115eb275a816b8a2ed104
68deca9b418976ca8b3375e81058a9e0a815357f
0525e17847f39f80e3fd163021a58f68d8fcaf06
81a3c699d6eef936452ac3d10c7c59a2c1e38c0c
01452bedfca2b5447a7f62bda87edbbb76259a6e
1baf1050113a5418696839c273e05ea5ad1b5c4d
4b39fe3d608916b1cfea015de287511a1623fc7f
c6effdbba9b301244475553538f6eb1b3d9670b9
71e4c573199466ea4541e3d6b307c9b33d7bb785
efc92f0d4aa77bb90f5b56606b6f0d0819fba4af
a9db2c74b5bae2345ac52be404748954a3b5050d
0a01b6202226bbe99c0b83acf6c5a80344f5fb6a
a6c44361c8f2dc07b935e3f2bb3e0d3ad4f4a383
10d8aab1de430695a69e9d75af6ea42c2cdc9d6d
dd3c4fca2f0a2761b8b95cd47fcd62836d714890
e9c932233980866074025e65051003d1f298516c
2b1f79881c3f0b69bfb9274bda57ea50f7304982
7f031160d71a3d836667dc98288eaff4c94e6f56
490fabb4578f8a3c4096fdccff688c17ed5ed00d
d953b2ab726acca0b3abe90ce090a16d7ccc2ae3
bb514c426b9438cfb1149d219ac4ec2d8d1c8458
dfb453d713d8a05e76f720a6aae2871eec210276
b490fd66b873c89fca37b21eab58502b6367a864
9a71683d9c8ff9470eda6be5b2b11babac7b9863
37945f731c4d800ef788e3c32f8663773a93450e
b90c98fc29a8d896354de4a22c055f6d98376171
35f3e9d0e654e84646a0b98f29e4a2786cdca4b1
260eb5bb9b62ea3d5fa6ad0b0e8c2de75d48bad4
cc2c11441ce352360acce8638a19f58edf361f7d
7be0159e4b1e0b064e215ae4ced34d649cb2552e
95a7cfe0eaabbcff0f730ed60e1805779f6cfe41
8f54d18ba4ad10770e9537a2803459feccfe79a3
f44759d9ff52a3e5563e5f2bb23ee2c08222fcfd
09050c8a967f5f2956305e5d016b304d7bf5e669
c769745d5856a7eb3a0dbe6af5376c7638944364
a1547aa914aeedd7862f74124c18d2bbaf432c36
5f950698c0dc7c36b855961feb929022f74102fb
4aedeb1bd50c12ebcd6cf954c4cbef1205fff5ac
7366d8954cb1bd277d3283241da2fae62b886c48
bc35251f5e55a65c3a4acf7cba52cee505c86a46
4fb60b215801db70c694a799e735b64bfead59bb
03762b8488de0e393077e3f40fe7b63e675b3af3
a8a45d875f0a98b192cf0063ceda12aaf75ddfaf
a48e5ab8804e9e97b5ea577d6f2667bacee92eb2
# Update of quotations in DEPS file.
e50b49a0e38b34e2b28e026f4d1c7e0da0c7bb1a
# Rewrite code base to use "." instead of "->" to access Object members.
878ccb33bd3cf0e6dc018ff8d15843f585ac07be
# Splitting src/ into subfolders
632239011db501e76475d82ff6492f37fa8c1edc
f455f86d899716df3b9550950ce172f5b867619a
24a51e1eee4e286165dd0bba6afb4c35e8177a25
f9a88acbc928f0fc5e9a3acbcd3b4ece52355f3d
dec3298d9cfbe95759774a0e00302a08836b5f3d
a0c3797461810e3159662851e64946e17654236e
b72941e8b0d2843adf768442024d8950da798db1
4c986c625f19e35c95f3492c662822f4695218b4
0fa243af7096ee5b748b194476be2e4efecaec59
786ce26341b7ab11b4d42f1c77202530d5138ad2
a6eeea35cb7ff0c29b6cfdd1c786f382110241ce
be014256adea1552d4a044ef80616cdab6a7d549
93d3b7173fec7d010539057cdbd78d497f09fa9b
5bfe84a0dab60289b3470c080908ce83ac2212d4
a7695520556665ba73ab02c497ab73b162a5fb13
61523c45a335fe3be76498e0b16bf8e7aec0d058
bf372a73d8a5f4029fc9f4f69b675ef0cad80ada
8ad6b335376c6275ffb3361c662a1a45c853f4fc
06bf8261cf2c94fc071652652600b5790f719c05
81a0102fe8586071cc68e9595b26c5c1207ee5b3
5f28539599f6a6a265e18b8c897cc96ccbeec9c4
3253767622a784866dc34aeb7b5d0f02ebdff61e
9ac8b20086f95f1158a1901eefe12e25fd0333e4
3cb560adfe26edb586a0e6e655e5a7c4755cad1a
7bbd0bfe5161d57bcf268716ce4d1ce14d6786e6
c39cabbcbea26891558b81fd2236c38a7aeada08
a3187716d31a0ab9d7051adde6be9bd2b2c6fec1
# Move test/mjsunit/regress-*.js => test/mjsunit/regress/
cb67be1a3842fcf6a0da18aee444e3b7ea789e04
# [include] Split out v8.h
d1b27019d3bf86360ea838c317f8505fac6d3a7e
44fe02ced6e4c6b49d627807e3b3fd0edbbeb36e
ec06bb6ce5641cf65e400ec55b7421f87d04b999

7
deps/v8/.gitattributes vendored Normal file
View File

@ -0,0 +1,7 @@
# Automatically normalize line endings (to LF) for all text-based files.
* text=auto eol=lf
# Do not modify line endings for binary files (which are sometimes auto
# detected as text files by git).
*.png binary
# Don't include minified JS in git grep/diff output
test/mjsunit/asm/sqlite3/*.js -diff

View File

@ -0,0 +1,13 @@
# `true` will close all PRs.
filters:
- true
# The message to post to the closed PR.
commentBody: |
Thanks for your contribution! Unfortunately, we don't use GitHub pull
requests to manage code contributions to this repository. Instead, please
see https://v8.dev/docs/contribute which provides full instructions on
how to get involved.
# Whether to add a label to the closed PR.
addLabel: false

156
deps/v8/.gitignore vendored Normal file
View File

@ -0,0 +1,156 @@
#*#
*.Makefile
*.a
*.exe
*.idb
*.lib
*.log
*.map
*.mk
*.ncb
*.pdb
*.pyc
*.scons*
*.sdf
*.sln
*.so
*.suo
*.user
*.vcproj
*.vcxproj
*.vcxproj.filters
*.xcodeproj
*~
.#*
.*.sw?
.cache
.ccls-cache
.clangd
.cpplint-cache
.cproject
.DS_Store
.gclient_entries
.gdb_history
.idea
.jslint-cache
.landmines
.project
.pydevproject
.settings
.torquelint-cache
.vscode
/_*
/base
/build
/buildtools
/check-header-includes
/Default/
/out
/out.gn
/perf.data
/perf.data.old
/src/inspector/build/closure-compiler
/src/inspector/build/closure-compiler.tar.gz
/test/benchmarks/data
/test/fuzzer/wasm_corpus/
/test/fuzzer/wasm_corpus.tar.gz
!/test/mjsunit/tools/*.log
/test/mozilla/data
/test/test262/data
/test/wasm-js/data
/test/wasm-js/tests
/test/wasm-js/tests.tar.gz
/test/wasm-spec-tests/tests
/test/wasm-spec-tests/tests.tar.gz
/third_party/*
!/third_party/antlr4
!/third_party/colorama
/third_party/colorama/src
!/third_party/cpu_features
/third_party/cpu_features/src
!/third_party/fast_float
/third_party/fast_float/src/*
!/third_party/fast_float/src/include
!/third_party/glibc
!/third_party/googletest
/third_party/googletest/src/*
!/third_party/googletest/src/googletest
/third_party/googletest/src/googletest/*
!/third_party/googletest/src/googletest/include
/third_party/googletest/src/googletest/include/*
!/third_party/googletest/src/googletest/include/gtest
/third_party/googletest/src/googletest/include/gtest/*
!/third_party/googletest/src/googletest/include/gtest/gtest_prod.h
!/third_party/highway
/third_party/highway/src/*
!/third_party/highway/src/hwy
!/third_party/inspector_protocol
!/third_party/jsoncpp
/third_party/jsoncpp/source
!/third_party/llvm-libc
/third_party/llvm-libc/src
!/third_party/rapidhash-v8
!/third_party/re2
/third_party/re2/src
!/third_party/siphash
!/third_party/utf8-decoder
!/third_party/v8
!/third_party/valgrind
!/third_party/vtune
!/third_party/wasm-api
/tools/builtins-pgo/profiles/*
!/tools/builtins-pgo/profiles/.*
/tools/clang
/tools/gcmole/bootstrap
/tools/gcmole/gcmole-tools
/tools/gcmole/gcmole-tools.tar.gz
/tools/jsfunfuzz/jsfunfuzz
/tools/jsfunfuzz/jsfunfuzz.tar.gz
/tools/luci-go
/tools/oom_dump/oom_dump
/tools/oom_dump/oom_dump.o
/tools/protoc_wrapper
/tools/rust
/tools/turbolizer/build
/tools/turbolizer/.rpt2_cache
/tools/turbolizer/deploy
/tools/v8heapconst.py
/tools/visual_studio/Debug
/tools/visual_studio/Release
/v8.log.ll
/xcodebuild
GPATH
GRTAGS
GSYMS
GTAGS
TAGS
bsuite
compile_commands.json
gccauses
gcsuspects
gtags.files
jit-*.dump
node_modules
tags
turbo*.cfg
turbo*.dot
turbo*.json
v8.ignition_dispatches_table.json
bazel-bin
bazel-out
bazel-testlogs
bazel-v8
!/third_party/jinja2
!/third_party/markupsafe
!/third_party/zlib
/third_party/zlib/contrib/bench
/third_party/zlib/contrib/tests
/third_party/zlib/google/test
!/third_party/ittapi
!/third_party/abseil-cpp
/third_party/abseil-cpp/.github
/third_party/abseil-cpp/ci
!/third_party/fp16
/third_party/fp16/src/*
!/third_party/fp16/src/include
!/third_party/simdutf

39
deps/v8/.gn vendored Normal file
View File

@ -0,0 +1,39 @@
# This file is used by the GN meta build system to find the root of the source
# tree and to set startup options. For documentation on the values set in this
# file, run "gn help dotfile" at the command line.
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"
# 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
# their includes checked for proper dependencies when you run either
# "gn check" or "gn gen --check".
no_check_targets = [
"//:cppgc_base",
"//:v8_internal_headers",
"//src/inspector:inspector",
"//test/cctest:cctest_sources", # 15 errors
"//test/unittests:inspector_unittests_sources", # 2 errors
"//third_party/icu:*",
]
default_args = {
# Disable js dependencies like the closure compiler.
enable_js_protobuf = false
# Disable rust dependencies.
enable_rust = true
}
# These are the list of GN files that run exec_script. This whitelist exists
# to force additional review for new uses of exec_script, which is strongly
# discouraged except for gypi_to_gn calls.
exec_script_whitelist = build_dotfile_settings.exec_script_whitelist +
[ "//build_overrides/build.gni" ]

16
deps/v8/.mailmap vendored Normal file
View File

@ -0,0 +1,16 @@
# 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.
# People change their names or email addresses for many reasons. This
# list makes sure people’s preferences are respected when using Git
# commands such as `git log` or `git blame`.
#
# See https://git-scm.com/docs/gitmailmap for more information.
#
# Please keep the list sorted.
Clemens Backes <clemensb@chromium.org> Clemens Hammacher <clemensh@chromium.org>
Jakob Linke <jgruber@chromium.org>
Jakob Linke <jgruber@chromium.org> <jgruber@google.com>
Timothy Gu <timothygu@chromium.org> <timothygu99@gmail.com>

2
deps/v8/.style.yapf vendored Normal file
View File

@ -0,0 +1,2 @@
[style]
based_on_style = yapf

102
deps/v8/.vpython3 vendored Normal file
View File

@ -0,0 +1,102 @@
# 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.8"
# 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:5.5.chromium.3"
>
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/mock-py2_py3"
version: "version:2.0.0"
>
wheel: <
name: "infra/python/wheels/numpy/${vpython_platform}"
version: "version:1.2x.supported.1"
>
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-py2_py3"
version: "version:3.7.2"
>

189
deps/v8/.ycm_extra_conf.py vendored Normal file
View File

@ -0,0 +1,189 @@
# 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.
# Autocompletion config for YouCompleteMe in V8.
#
# USAGE:
#
# 1. Install YCM [https://github.com/Valloric/YouCompleteMe]
# (Googlers should check out [go/ycm])
#
# 2. Profit
#
#
# Usage notes:
#
# * You must use ninja & clang to build V8.
#
# * You must have run gyp_v8 and built V8 recently.
#
#
# Hacking notes:
#
# * The purpose of this script is to construct an accurate enough command line
# for YCM to pass to clang so it can build and extract the symbols.
#
# * Right now, we only pull the -I and -D flags. That seems to be sufficient
# for everything I've used it for.
#
# * That whole ninja & clang thing? We could support other configs if someone
# were willing to write the correct commands and a parser.
#
# * This has only been tested on gTrusty.
import os
import os.path
import subprocess
import sys
# Flags from YCM's default config.
flags = [
'-DUSE_CLANG_COMPLETER',
'-x',
'c++',
]
def PathExists(*args):
return os.path.exists(os.path.join(*args))
def FindV8SrcFromFilename(filename):
"""Searches for the root of the V8 checkout.
Simply checks parent directories until it finds .gclient and v8/.
Args:
filename: (String) Path to source file being edited.
Returns:
(String) Path of 'v8/', or None if unable to find.
"""
curdir = os.path.normpath(os.path.dirname(filename))
while not (PathExists(curdir, 'v8') and PathExists(curdir, 'v8', 'DEPS')
and (PathExists(curdir, '.gclient')
or PathExists(curdir, 'v8', '.git'))):
nextdir = os.path.normpath(os.path.join(curdir, '..'))
if nextdir == curdir:
return None
curdir = nextdir
return os.path.join(curdir, 'v8')
def GetClangCommandFromNinjaForFilename(v8_root, filename):
"""Returns the command line to build |filename|.
Asks ninja how it would build the source file. If the specified file is a
header, tries to find its companion source file first.
Args:
v8_root: (String) Path to v8/.
filename: (String) Path to source file being edited.
Returns:
(List of Strings) Command line arguments for clang.
"""
if not v8_root:
return []
# Generally, everyone benefits from including V8's root, because all of
# V8's includes are relative to that.
v8_flags = ['-I' + os.path.join(v8_root)]
# Version of Clang used to compile V8 can be newer then version of
# libclang that YCM uses for completion. So it's possible that YCM's libclang
# doesn't know about some used warning options, which causes compilation
# warnings (and errors, because of '-Werror');
v8_flags.append('-Wno-unknown-warning-option')
# Header files can't be built. Instead, try to match a header file to its
# corresponding source file.
if filename.endswith('.h'):
base = filename[:-6] if filename.endswith('-inl.h') else filename[:-2]
for alternate in [base + e for e in ['.cc', '.cpp']]:
if os.path.exists(alternate):
filename = alternate
break
else:
# If this is a standalone .h file with no source, we ask ninja for the
# compile flags of some generic cc file ('src/utils/utils.cc'). This
# should contain most/all of the interesting flags for other targets too.
filename = os.path.join(v8_root, 'src', 'utils', 'utils.cc')
sys.path.append(os.path.join(v8_root, 'tools', 'vim'))
from ninja_output import GetNinjaOutputDirectory
out_dir = os.path.realpath(GetNinjaOutputDirectory(v8_root))
# Ninja needs the path to the source file relative to the output build
# directory.
rel_filename = os.path.relpath(os.path.realpath(filename), out_dir)
# Ask ninja how it would build our source file.
p = subprocess.Popen(['ninja', '-v', '-C', out_dir, '-t',
'commands', rel_filename + '^'],
stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode:
return v8_flags
# Ninja might execute several commands to build something. We want the last
# clang command.
clang_line = None
for line in reversed(stdout.decode('utf-8').splitlines()):
if 'clang' in line:
clang_line = line
break
else:
return v8_flags
# Parse flags that are important for YCM's purposes.
for flag in clang_line.split(' '):
if flag.startswith('-I'):
v8_flags.append(MakeIncludePathAbsolute(flag, "-I", out_dir))
elif flag.startswith('-isystem'):
v8_flags.append(MakeIncludePathAbsolute(flag, "-isystem", out_dir))
elif flag.startswith('-std') or flag.startswith(
'-pthread') or flag.startswith('-no'):
v8_flags.append(flag)
elif flag.startswith('-') and flag[1] in 'DWFfmgOX':
v8_flags.append(flag)
return v8_flags
def MakeIncludePathAbsolute(flag, prefix, out_dir):
# Relative paths need to be resolved, because they're relative to the
# output dir, not the source.
if flag[len(prefix)] == '/':
return flag
else:
abs_path = os.path.normpath(os.path.join(out_dir, flag[len(prefix):]))
return prefix + abs_path
def FlagsForFile(filename):
"""This is the main entry point for YCM. Its interface is fixed.
Args:
filename: (String) Path to source file being edited.
Returns:
(Dictionary)
'flags': (List of Strings) Command line flags.
'do_cache': (Boolean) True if the result should be cached.
"""
v8_root = FindV8SrcFromFilename(filename)
v8_flags = GetClangCommandFromNinjaForFilename(v8_root, filename)
final_flags = flags + v8_flags
return {
'flags': final_flags,
'do_cache': True
}
def Settings(**kwargs):
if kwargs['language'] == 'cfamily':
return FlagsForFile(kwargs['filename'])
return {}

336
deps/v8/AUTHORS vendored Normal file
View File

@ -0,0 +1,336 @@
# Below is a list of people and organizations that have contributed
# to the V8 project. Names should be added to the list like so:
#
# Name/Organization <email address>
Google Inc. <*@google.com>
The Chromium Authors <*@chromium.org>
Sigma Designs Inc. <*@sdesigns.com>
ARM Ltd. <*@arm.com>
Hewlett-Packard Development Company, LP <*@palm.com>
Igalia, S.L. <*@igalia.com>
Joyent, Inc. <*@joyent.com>
Bloomberg Finance L.P. <*@bloomberg.net>
NVIDIA Corporation <*@nvidia.com>
BlackBerry Limited <*@blackberry.com>
Opera Software ASA <*@opera.com>
Intel Corporation <*@intel.com>
LG Electronics, Inc. <*@lge.com>
Microsoft <*@microsoft.com>
MIPS Technologies, Inc. <*@mips.com>
Imagination Technologies, LLC <*@imgtec.com>
Wave Computing, Inc. <*@wavecomp.com>
Loongson Technology Corporation Limited <*@loongson.cn>
Code Aurora Forum <*@codeaurora.org>
Home Jinni Inc. <*@homejinni.com>
IBM Inc. <*@*.ibm.com>
IBM Inc. <*@ibm.com>
Raptor Computing Systems, LLC <*@raptorcs.com>
Red Hat Inc. <*@redhat.com>
Samsung <*@*.samsung.com>
Samsung <*@samsung.com>
RT-RK Computer Based System <*@rt-rk.com>
Amazon, Inc <*@amazon.com>
ST Microelectronics <*@st.com>
Yandex LLC <*@yandex-team.ru>
StrongLoop, Inc. <*@strongloop.com>
Facebook, Inc. <*@fb.com>
Facebook, Inc. <*@oculus.com>
Vewd Software AS <*@vewd.com>
Groupon <*@groupon.com>
Meteor Development Group <*@meteor.com>
Cloudflare, Inc. <*@cloudflare.com>
Julia Computing, Inc. <*@juliacomputing.com>
CodeWeavers, Inc. <*@codeweavers.com>
Alibaba, Inc. <*@alibaba-inc.com>
SiFive, Inc. <*@sifive.com>
Aapo Alasuutari <aapo.alasuutari@gmail.com>
Aaron Bieber <deftly@gmail.com>
Aaron O'Mullan <aaron.omullan@gmail.com>
Abdulla Kamar <abdulla.kamar@gmail.com>
Adam Kallai <kadam@inf.u-szeged.hu>
Akinori MUSHA <knu@FreeBSD.org>
Alessandro Pignotti <alessandro@leaningtech.com>
Alex Kodat <akodat@rocketsoftware.com>
Alexander Botero-Lowry <alexbl@FreeBSD.org>
Alexander Karpinsky <homm86@gmail.com>
Alexander Neville <dark@volatile.bz>
Alexandre Vassalotti <avassalotti@gmail.com>
Alexey Pavlyutkin <alexey.pavlyutkin@syntacore.com>
Alexis Campailla <alexis@janeasystems.com>
Aliya Minimullina <a.minimullina@syntacore.com>
Allan Sandfeld Jensen <allan.jensen@qt.io>
Amos Lim <eui-sang.lim@samsung.com>
Andreas Anyuru <andreas.anyuru@gmail.com>
Andrei Kashcha <anvaka@gmail.com>
Andreu Botella <andreu@andreubotella.com>
Andrew Paprocki <andrew@ishiboo.com>
Anna Henningsen <anna@addaleax.net>
Antoine du Hamel <duhamelantoine1995@gmail.com>
Anton Bershanskiy <8knots@protonmail.com>
Anton Bikineev <ant.bikineev@gmail.com>
Ao Wang <wangao.james@bytedance.com>
Archil Sharashenidze <achosharashenidze@gmail.com>
Artem Kobzar <artem.kobzar@jetbrains.com>
Arthur Islamov <arthur@islamov.ai>
Asuka Shikina <shikina.asuka@gmail.com>
Aurèle Barrière <aurele.barriere@gmail.com>
Bala Avulapati <bavulapati@gmail.com>
Bangfu Tao <bangfu.tao@samsung.com>
Ben Coe <bencoe@gmail.com>
Ben Newman <ben@meteor.com>
Ben Noordhuis <info@bnoordhuis.nl>
Benjamin Tan <demoneaux@gmail.com>
Bert Belder <bertbelder@gmail.com>
Brendon Tiszka <btiszka@gmail.com>
Brice Dobry <brice.dobry@futurewei.com>
Bruno Pitrus <brunopitrus@hotmail.com>
Burcu Dogan <burcujdogan@gmail.com>
Caitlin Potter <caitpotter88@gmail.com>
Chao Wang <chao.w@rioslab.org>
Charles Kerr <charles@charleskerr.com>
Cheng Zhao <zcbenz@gmail.com>
Chengzhong Wu <legendecas@gmail.com>
Choongwoo Han <cwhan.tunz@gmail.com>
Chris Nardi <hichris123@gmail.com>
Christopher A. Taylor <chris@gameclosure.com>
Christopher Nady <nady.christopher@gmail.com>
Colin Ihrig <cjihrig@gmail.com>
Cong Zuo <zckevinzc@gmail.com>
Craig Schlenter <craig.schlenter@gmail.com>
Daniel Andersson <kodandersson@gmail.com>
Daniel Bevenius <daniel.bevenius@gmail.com>
Daniel Dromboski <dandromb@gmail.com>
Daniel James <dnljms@gmail.com>
Daniel Shelton <d1.shelton@samsung.com>
Daniil Bakin <bd.bakin@gmail.com>
Danylo Boiko <danielboyko02@gmail.com>
Darshan Sen <raisinten@gmail.com>
David Carlier <devnexen@gmail.com>
David Manouchehri <david@davidmanouchehri.com>
David Sanders <dsanders11@ucsbalum.com>
Debadree Chatterjee <debadree333@gmail.com>
Deepak Mohan <hop2deep@gmail.com>
Deon Dior <diaoyuanjie@gmail.com>
Derek Tu <derek.t@rioslab.org>
Divy Srivastava <dj.srivastava23@gmail.com>
Dmitry Bezhetskov <dima00782@gmail.com>
Dominic Chen <d.c.ddcc@gmail.com>
Dominic Farolini <domfarolino@gmail.com>
Douglas Crosher <dtc-v8@scieneer.com>
Dusan Milosavljevic <dusan.m.milosavljevic@gmail.com>
Eden Wang <nedenwang@tencent.com>
Edoardo Marangoni <edoardo@wasmer.io>
Elisha Hollander <just4now666666@gmail.com>
Eric Rannaud <eric.rannaud@gmail.com>
Erich Ocean <erich.ocean@me.com>
Evan Lucas <evan.lucas@help.com>
Fedor Indutny <fedor@indutny.com>
Felix Geisendörfer <haimuiba@gmail.com>
Feng Yu <f3n67u@gmail.com>
Filipe David Manana <fdmanana@gmail.com>
Frank Lemanschik <frank@dspeed.eu>
Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Gao Sheng <gaosheng08@meituan.com>
Geoffrey Garside <ggarside@gmail.com>
Gergely Nagy <ngg@ngg.hu>
Gilang Mentari Hamidy <gilang@hamidy.net>
Giovanny Gutierrez <giovannygutierrez@gmail.com>
Gus Caplan <me@gus.host>
Gwang Yoon Hwang <ryumiel@company100.net>
Haichuan Wang <hc.opensource@gmail.com>
Hannu Trey <hannu.trey@gmail.com>
Harshal Nandigramwar <pro.bbcom18@gmail.com>
Harshil Jain <twitharshil@gmail.com>
Henrique Ferreiro <henrique.ferreiro@gmail.com>
Helmut Januschka <helmut@januschka.com>
Hirofumi Mako <mkhrfm@gmail.com>
Hisham Muhammad <hisham@gobolinux.org>
Honggyu Kim <honggyu.kp@gmail.com>
Huáng Jùnliàng <jlhwung@gmail.com>
HyeockJin Kim <kherootz@gmail.com>
Iain Ireland <iireland@mozilla.com>
Ilya Gavrilin <ilya.gavrilin@syntacore.com>
Ingvar Stepanyan <me@rreverser.com>
Ioseb Dzmanashvili <ioseb.dzmanashvili@gmail.com>
Isiah Meadows <impinball@gmail.com>
Jaime Bernardo <jaime@janeasystems.com>
Jake Hughes <jh@jakehughes.uk>
James M Snell <jasnell@gmail.com>
James Pike <g00gle@chilon.net>
Jan Krems <jan.krems@gmail.com>
Jan de Mooij <jandemooij@gmail.com>
Janusz Majnert <jmajnert@gmail.com>
Javad Amiri <javad.amiri@anu.edu.au>
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>
Ji Qiu <qiuji@iscas.ac.cn>
Jiawen Geng <technicalcute@gmail.com>
Jiaxun Yang <jiaxun.yang@flygoat.com>
Joel Stanley <joel@jms.id.au>
Johan Bergström <johan@bergstroem.nu>
Johan Levin <johan13@gmail.com>
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Jojo R <rjiejie@gmail.com>
Jonathan Liu <net147@gmail.com>
Juan Arboleda <soyjuanarbol@gmail.com>
Julien Brianceau <jbriance@cisco.com>
JunHo Seo <sejunho@gmail.com>
Junha Park <jpark3@scu.edu>
Junming Huang <kiminghjm@gmail.com>
Kang-Hao (Kenny) Lu <kennyluck@csail.mit.edu>
Karl Skomski <karl@skomski.com>
Keith Smiley <keithbsmiley@gmail.com>
Kevin Gibbons <bakkot@gmail.com>
Keyhan Vakil <kvakil@googlecontrib.kvakil.me>
Kris Selden <kris.selden@gmail.com>
Kyounga Ra <kyounga@alticast.com>
Levi Zim <rsworktech@outlook.com>
Loo Rong Jie <loorongjie@gmail.com>
Lu Yahan <yahan@iscas.ac.cn>
Ludovic Mermod <ludovic.mermod@gmail.com>
Luis Reis <luis.m.reis@gmail.com>
Luke Albao <lukealbao@gmail.com>
Luke Zarko <lukezarko@gmail.com>
Ma Aiguo <maaiguo@uniontech.com>
Maciej Małecki <me@mmalecki.com>
Marcel Laverdet <marcel@laverdet.com>
Marcin Cieślak <saper@marcincieslak.com>
Marcin Wiącek <marcin@mwiacek.com>
Marisa Kirisame <u1319884@utah.edu>
Martin Bidlingmaier <martin.bidlingmaier@gmail.com>
Mateusz Czeladka <mateusz.szczap@gmail.com>
Matheus Marchini <mat@mmarchini.me>
Matheus Marchini <mmarchini@netflix.com>
Mathias Bynens <mathias@qiwi.be>
Matt Hanselman <mjhanselman@gmail.com>
Matthew Sporleder <msporleder@gmail.com>
Maxim Mazurok <maxim@mazurok.com>
Maxim Mossienko <maxim.mossienko@gmail.com>
Md Hasibul Hasan <hasibulhasan873@gmail.com>
Meir Shpilraien <meir@redis.com>
Meng Tan <tannal2409@gmail.com>
Michael Lutz <michi@icosahedron.de>
Michael Mclaughlin <m8ch88l@gmail.com>
Michael Smith <mike@w3.org>
Michaël Zasso <mic.besace@gmail.com>
Mihir Shah <mihirshah.11204@gmail.com>
Mika Fischer <mika.fischer@zoopnet.de>
Mike Gilbert <floppymaster@gmail.com>
Mike Pennisi <mike@mikepennisi.com>
Mikhail Gusarov <dottedmag@dottedmag.net>
Milton Chiang <milton.chiang@mediatek.com>
Mu Tao <pamilty@gmail.com>
Myeong-bo Shim <m0609.shim@samsung.com>
Nicolas Antonius Ernst Leopold Maria Kaiser <nikai@nikai.net>
Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
Niek van der Maas <mail@niekvandermaas.nl>
Niklas Hambüchen <mail@nh2.me>
Noj Vek <nojvek@gmail.com>
Oleksandr Chekhovskyi <oleksandr.chekhovskyi@gmail.com>
Oliver Dunk <oliver@oliverdunk.com>
Paolo Giarrusso <p.giarrusso@gmail.com>
Patrick Gansterer <paroga@paroga.com>
Paul Lind <plind44@gmail.com>
Pavel Medvedev <pmedvedev@gmail.com>
Pedro Falcato <pedro.falcato@gmail.com>
Peng Fei <pfgenyun@gmail.com>
Peng Wu <peng.w@rioslab.org>
Peng-Yu Chen <pengyu@libstarrify.so>
Peter Rybin <peter.rybin@gmail.com>
Peter Varga <pvarga@inf.u-szeged.hu>
Peter Wong <peter.wm.wong@gmail.com>
PhistucK <phistuck@gmail.com>
Pierrick Bouvier <pierrick.bouvier@linaro.org>
Punith B Nayak <npunith125@gmail.com>
Rafal Krypa <rafal@krypa.net>
Raul Tambre <raul@tambre.ee>
Ray Glover <ray@rayglover.net>
Ray Wang <ray@isrc.iscas.ac.cn>
Refael Ackermann <refack@gmail.com>
Rene Rebe <rene@exactcode.de>
Reza Yazdani <ryazdani@futurewei.com>
Rick Waldron <waldron.rick@gmail.com>
Rob Wu <rob@robwu.nl>
Robert Meijer <robert.s.meijer@gmail.com>
Robert Mustacchi <rm@fingolfin.org>
Robert Nagy <robert.nagy@gmail.com>
Robert O'Callahan <rocallahan@gmail.com>
Rong Wang <wangrong089@gmail.com>
Ross Kirsling <rkirsling@gmail.com>
Ruben Bridgewater <ruben@bridgewater.de>
Ryan Dahl <ry@tinyclouds.org>
Sakthipriyan Vairamani (thefourtheye) <thechargingvolcano@gmail.com>
Sander Mathijs van Veen <sander@leaningtech.com>
Sandro Santilli <strk@keybit.net>
Sanjoy Das <sanjoy@playingwithpointers.com>
Sam James <sam@gentoo.org>
Sébastien Doeraene <sjrdoeraene@gmail.com>
Seo Sanghyeon <sanxiyn@gmail.com>
Shawn Anastasio <shawnanastasio@gmail.com>
Shawn Presser <shawnpresser@gmail.com>
Sho Miyamoto <me@shqld.dev>
Stefan Penner <stefan.penner@gmail.com>
Stefan Stojanovic <stefko.stojanovic@gmail.com>
Stephan Hartmann <stha09@googlemail.com>
Stephen Belanger <stephen.belanger@datadoghq.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>
Thomas Young <wenzhang5800@gmail.com>
Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Tianping Yang <yangtianping@oppo.com>
Timo Teräs <timo.teras@iki.fi>
Tobias Burnus <burnus@net-b.de>
Tobias Nießen <tniessen@tnie.de>
Ujjwal Sharma <usharma1998@gmail.com>
Vadim Gorbachev <bmsdave@gmail.com>
Varun Varada <varuncvarada@gmail.com>
Victor Costan <costan@gmail.com>
Victor Polevoy <fx@thefx.co>
Vlad Burlik <vladbph@gmail.com>
Vladimir Kempik <vladimir.kempik@syntacore.com>
Vladimir Krivosheev <develar@gmail.com>
Vladimir Shutoff <vovan@shutoff.ru>
Wael Almattar <waelsy123@gmail.com>
Wang Chen <wangchen20@iscas.ac.cn>
WANG Xuerui <git@xen0n.name>
Wei Wu <lazyparser@gmail.com>
Wenlu Wang <kingwenlu@gmail.com>
Wenming Yang <yangwenming@bytedance.com>
Wenyu Zhao <wenyu.zhao@anu.edu.au>
Wiktor Garbacz <wiktor.garbacz@gmail.com>
Wouter Vermeiren <wouter.vermeiren@essensium.com>
Xiaofang Zou <zouxiaofang@iscas.ac.cn>
Xiaoyin Liu <xiaoyin.l@outlook.com>
Yagiz Nizipli <yagiz@nizipli.com>
Yanbo Li <lybvinci@gmail.com>
Yannic Bonenberger <contact@yannic-bonenberger.com>
Yi Wang <wangyi8848@gmail.com>
Yong Wang <ccyongwang@tencent.com>
Youfeng Hao <ajihyf@gmail.com>
Yu Yin <xwafish@gmail.com>
Yujie Wang <hex6770@gmail.com>
Yuri Iozzelli <yuri@leaningtech.com>
Yuri Gaevsky <yuri.gaevsky@syntacore.com>
Yusif Khudhur <yusif.khudhur@gmail.com>
Yuxiang Cao <caoyxsh@outlook.com>
Zac Hansen <xaxxon@gmail.com>
Zeynep Cankara <zeynepcankara402@gmail.com>
Zhao Jiazhong <kyslie3100@gmail.com>
Zhao Qin <qzmiss@gmail.com>
Zhaojun Meng <zhaojun.meng@gmail.com>
Zheng Liu <i6122f@gmail.com>
Zhongping Wang <kewpie.w.zp@gmail.com>
柳荣一 <admin@web-tinker.com>
Yang Xiang <xiangyangemail@gmail.com>
Kotaro Ohsugi <dec4m4rk@gmail.com>
Jing Peiyang <jingpeiyang@eswincomputing.com>
magic-akari <akari.ccino@gmail.com>
Ryuhei Shima <shimaryuhei@gmail.com>

4642
deps/v8/BUILD.bazel vendored Normal file

File diff suppressed because it is too large Load Diff

8152
deps/v8/BUILD.gn vendored Normal file

File diff suppressed because it is too large Load Diff

8
deps/v8/CODE_OF_CONDUCT.md vendored Normal file
View File

@ -0,0 +1,8 @@
# V8 Code of Conduct
As part of the Chromium team, the V8 team is committed to preserving and
fostering a diverse, welcoming community. To this end, the [Chromium Code of
Conduct](https://chromium.googlesource.com/chromium/src/+/master/CODE_OF_CONDUCT.md)
applies to our repos and organizations, mailing lists, blog content, and any
other Chromium-supported communication group, as well as any private
communication initiated in the context of these spaces.

39
deps/v8/COMMON_OWNERS vendored Normal file
View File

@ -0,0 +1,39 @@
adamk@chromium.org
ahaas@chromium.org
alexschulze@chromium.org
bikineev@chromium.org
bmeurer@chromium.org
cbruni@chromium.org
clemensb@chromium.org
dinfuehr@chromium.org
dlehmann@chromium.org
dmercadier@chromium.org
ecmziegler@chromium.org
evih@chromium.org
fgm@chromium.org
gdeepti@chromium.org
hpayer@chromium.org
ishell@chromium.org
jgruber@chromium.org
jkummerow@chromium.org
leszeks@chromium.org
liviurau@chromium.org
machenbach@chromium.org
manoskouk@chromium.org
marja@chromium.org
mliedtke@chromium.org
mlippautz@chromium.org
nicohartmann@chromium.org
nikolaos@chromium.org
olivf@chromium.org
omerkatz@chromium.org
pthier@chromium.org
rezvan@chromium.org
sroettger@google.com
syg@chromium.org
szuend@chromium.org
thibaudm@chromium.org
vahl@chromium.org
verwaest@chromium.org
victorgomes@chromium.org
yangguo@chromium.org

833
deps/v8/DEPS vendored Normal file
View File

@ -0,0 +1,833 @@
# Note: The buildbots evaluate this file with CWD set to the parent
# directory and assume that the root of the checkout is in ./v8/, so
# all paths in here must match this assumption.
use_relative_paths = True
gclient_gn_args_file = 'build/config/gclient_args.gni'
gclient_gn_args = [
]
vars = {
# Fetches only the SDK boot images which match at least one of the whitelist
# entries in a comma-separated list.
#
# Available images:
# Emulation:
# - terminal.qemu-x64
# - terminal.qemu-arm64
# - workstation.qemu-x64-release
# Hardware:
# - minimal.x64
# - core.x64-dfv2
#
# Since the images are hundreds of MB, default to only downloading the image
# most commonly useful for developers. Bots and developers that need to use
# other images (e.g., qemu.arm64) can override this with additional images.
'checkout_fuchsia_boot_images': "terminal.x64",
'checkout_fuchsia_product_bundles': '"{checkout_fuchsia_boot_images}" != ""',
'checkout_instrumented_libraries': False,
'checkout_ittapi': False,
# Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to
# process the raw profiles produced by instrumented targets (built with
# the gn arg 'use_clang_coverage').
'checkout_clang_coverage_tools': False,
# Fetch clang-tidy into the same bin/ directory as our clang binary.
'checkout_clang_tidy': False,
# Fetch clangd into the same bin/ directory as our clang binary.
'checkout_clangd': False,
# Fetch and build V8 builtins with PGO profiles
'checkout_v8_builtins_pgo_profiles': False,
'android_url': 'https://android.googlesource.com',
'chromium_url': 'https://chromium.googlesource.com',
'download_gcmole': False,
'download_jsfunfuzz': False,
'download_prebuilt_bazel': False,
'check_v8_header_includes': False,
# By default, download the fuchsia sdk from the public sdk directory.
'fuchsia_sdk_cipd_prefix': 'fuchsia/sdk/core/',
# Used for downloading the Fuchsia SDK without running hooks.
'checkout_fuchsia_no_hooks': False,
# reclient CIPD package version
'reclient_version': 're_client_version:0.177.1.e58c0145-gomaip',
# Fetch configuration files required for the 'use_remoteexec' gn arg
'download_remoteexec_cfg': False,
# RBE instance to use for running remote builds
'rbe_instance': Str('projects/rbe-chrome-untrusted/instances/default_instance'),
# RBE project to download rewrapper config files for. Only needed if
# different from the project used in 'rbe_instance'
'rewrapper_cfg_project': Str(''),
# This variable is overrided in Chromium's DEPS file.
'build_with_chromium': False,
# GN CIPD package version.
'gn_version': 'git_revision:6e8e0d6d4a151ab2ed9b4a35366e630c55888444',
# 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:68bdc49e4e23aef066fc652cbdb1b4973aab1a31',
# 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:27.20250326.5.1',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling partition_alloc_version
# and whatever else without interference from each other.
'partition_alloc_version': 'ab56923a27b2793f21994589b0c39bc3324ff49f',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_build-tools_version
# and whatever else without interference from each other.
'android_sdk_build-tools_version': 'y3EsZLg4bxPmpW0oYsAHylywNyMnIwPS3kh1VbQLAFAC',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_emulator_version
# and whatever else without interference from each other.
'android_sdk_emulator_version': '9lGp8nTUCRRWGMnI_96HcKfzjnxEJKUcfvfwmA3wXNkC',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_extras_version
# and whatever else without interference from each other.
'android_sdk_extras_version': 'bY55nDqO6FAm6FkGIj09sh2KW9oqAkCGKjYok5nUvBMC',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_patcher_version
# and whatever else without interference from each other.
'android_sdk_patcher_version': 'I6FNMhrXlpB-E1lOhMlvld7xt9lBVNOO83KIluXDyA0C',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_platform-tools_version
# and whatever else without interference from each other.
'android_sdk_platform-tools_version': 'mjFmRj7k_XR9yj60pYbr9mG38FyEbU5oWdU56bZQ5cwC',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_platforms_version
# and whatever else without interference from each other.
'android_sdk_platforms_version': '_YHemUrK49JrE7Mctdf5DDNOHu1VKBx_PTcWnZ-cbOAC',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_sources_version
# and whatever else without interference from each other.
'android_sdk_sources_version': 'qfTSF99e29-w3eIVPpfcif0Em5etyvxuicTDTntWHQMC',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_tools-lint_version
# and whatever else without interference from each other.
'android_sdk_cmdline-tools_version': 'gekOVsZjseS1w9BXAT3FsoW__ByGDJYS9DgqesiwKYoC',
}
deps = {
'build':
Var('chromium_url') + '/chromium/src/build.git' + '@' + '451ef881d77fff0b7a8bbfa61934f5e4a35b4c96',
'buildtools':
Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '6f359296daa889aa726f3d05046b9f37be241169',
'buildtools/linux64': {
'packages': [
{
'package': 'gn/gn/linux-${{arch}}',
'version': Var('gn_version'),
}
],
'dep_type': 'cipd',
'condition': 'host_os == "linux" and host_cpu != "s390" and host_os != "zos" and host_cpu != "ppc"',
},
'buildtools/mac': {
'packages': [
{
'package': 'gn/gn/mac-${{arch}}',
'version': Var('gn_version'),
}
],
'dep_type': 'cipd',
'condition': 'host_os == "mac"',
},
'buildtools/win': {
'packages': [
{
'package': 'gn/gn/windows-amd64',
'version': Var('gn_version'),
}
],
'dep_type': 'cipd',
'condition': 'host_os == "win"',
},
'buildtools/reclient': {
'packages': [
{
'package': 'infra/rbe/client/${{platform}}',
'version': Var('reclient_version'),
}
],
'dep_type': 'cipd',
'condition': '(host_os == "linux" or host_os == "mac" or host_os == "win") and host_cpu != "s390" and host_os != "zos" and host_cpu != "ppc" and (host_cpu != "arm64" or host_os == "mac")',
},
'test/benchmarks/data':
Var('chromium_url') + '/v8/deps/third_party/benchmarks.git' + '@' + '05d7188267b4560491ff9155c5ee13e207ecd65f',
'test/mozilla/data':
Var('chromium_url') + '/v8/deps/third_party/mozilla-tests.git' + '@' + 'f6c578a10ea707b1a8ab0b88943fe5115ce2b9be',
'test/test262/data':
Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + 'ce7e72d2107f99d165f4259571f10aa75753d997',
'third_party/android_platform': {
'url': Var('chromium_url') + '/chromium/src/third_party/android_platform.git' + '@' + '98aee46efb1cc4e09fa0e3ecaa6b19dc258645fa',
'condition': 'checkout_android',
},
'third_party/android_sdk/public': {
'packages': [
{
'package': 'chromium/third_party/android_sdk/public/build-tools/36.0.0',
'version': Var('android_sdk_build-tools_version'),
},
{
'package': 'chromium/third_party/android_sdk/public/emulator',
'version': Var('android_sdk_emulator_version'),
},
{
'package': 'chromium/third_party/android_sdk/public/extras',
'version': Var('android_sdk_extras_version'),
},
{
'package': 'chromium/third_party/android_sdk/public/patcher',
'version': Var('android_sdk_patcher_version'),
},
{
'package': 'chromium/third_party/android_sdk/public/platform-tools',
'version': Var('android_sdk_platform-tools_version'),
},
{
'package': 'chromium/third_party/android_sdk/public/platforms/android-36',
'version': Var('android_sdk_platforms_version'),
},
{
'package': 'chromium/third_party/android_sdk/public/sources/android-30',
'version': Var('android_sdk_sources_version'),
},
{
'package': 'chromium/third_party/android_sdk/public/cmdline-tools',
'version': Var('android_sdk_cmdline-tools_version'),
},
],
'condition': 'checkout_android',
'dep_type': 'cipd',
},
'third_party/android_toolchain/ndk': {
'packages': [
{
'package': 'chromium/third_party/android_toolchain/android_toolchain',
'version': 'Idl-vYnWGnM8K3XJhM3h6zjYVDXlnljVz3FE00V9IM8C',
},
],
'condition': 'checkout_android',
'dep_type': 'cipd',
},
'third_party/catapult': {
'url': Var('chromium_url') + '/catapult.git' + '@' + '5bda0fdab9d93ec9963e2cd858c7b49ad7fec7d4',
'condition': 'checkout_android',
},
'third_party/clang-format/script':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/clang/tools/clang-format.git' + '@' + '37f6e68a107df43b7d7e044fd36a13cbae3413f2',
'third_party/colorama/src': {
'url': Var('chromium_url') + '/external/colorama.git' + '@' + '3de9f013df4b470069d03d250224062e8cf15c49',
'condition': 'checkout_android',
},
'third_party/cpu_features/src': {
'url': Var('chromium_url') + '/external/github.com/google/cpu_features.git' + '@' + '936b9ab5515dead115606559502e3864958f7f6e',
'condition': 'checkout_android',
},
'third_party/depot_tools':
Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'f40ddcd8d51626fb7be3ab3c418b3f3be801623f',
'third_party/fp16/src':
Var('chromium_url') + '/external/github.com/Maratyszcza/FP16.git' + '@' + '0a92994d729ff76a58f692d3028ca1b64b145d91',
'third_party/fast_float/src':
Var('chromium_url') + '/external/github.com/fastfloat/fast_float.git' + '@' + 'cb1d42aaa1e14b09e1452cfdef373d051b8c02a4',
'third_party/fuchsia-gn-sdk': {
'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + '3845a68eb4421e64fbdf9f4805b5ac6d73742e08',
'condition': 'checkout_fuchsia',
},
'third_party/simdutf':
Var('chromium_url') + '/chromium/src/third_party/simdutf' + '@' + '40d1fa26cd5ca221605c974e22c001ca2fb12fde',
# Exists for rolling the Fuchsia SDK. Check out of the SDK should always
# rely on the hook running |update_sdk.py| script below.
'third_party/fuchsia-sdk/sdk': {
'packages': [
{
'package': Var('fuchsia_sdk_cipd_prefix') + '${{platform}}',
'version': Var('fuchsia_version'),
},
],
'condition': 'checkout_fuchsia_no_hooks',
'dep_type': 'cipd',
},
'third_party/google_benchmark_chrome': {
'url': Var('chromium_url') + '/chromium/src/third_party/google_benchmark.git' + '@' + '917e1208b42fdce63511e401067677ffee3a5c7d',
},
'third_party/google_benchmark_chrome/src': {
'url': Var('chromium_url') + '/external/github.com/google/benchmark.git' + '@' + '761305ec3b33abf30e08d50eb829e19a802581cc',
},
'third_party/fuzztest':
Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + 'df29ed1355d06c486e17fc421767ff01af050ca4',
'third_party/fuzztest/src':
Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + '3c7bc855a4938c5d0d1d07303aa0697c88d33e6c',
'third_party/googletest/src':
Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '52204f78f94d7512df1f0f3bea1d47437a2c3a58',
'third_party/highway/src':
Var('chromium_url') + '/external/github.com/google/highway.git' + '@' + '00fe003dac355b979f36157f9407c7c46448958e',
'third_party/icu':
Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'c9fb4b3a6fb54aa8c20a03bbcaa0a4a985ffd34b',
'third_party/instrumented_libs': {
'url': Var('chromium_url') + '/chromium/third_party/instrumented_libraries.git' + '@' + '69015643b3f68dbd438c010439c59adc52cac808',
'condition': 'checkout_instrumented_libraries',
},
'third_party/ittapi': {
# Force checkout ittapi libraries to pass v8 header includes check on
# bots that has check_v8_header_includes enabled.
'url': Var('chromium_url') + '/external/github.com/intel/ittapi' + '@' + 'a3911fff01a775023a06af8754f9ec1e5977dd97',
'condition': "checkout_ittapi or check_v8_header_includes",
},
'third_party/jinja2':
Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + '5e1ee241ab04b38889f8d517f2da8b3df7cfbd9a',
'third_party/jsoncpp/source':
Var('chromium_url') + '/external/github.com/open-source-parsers/jsoncpp.git'+ '@' + '42e892d96e47b1f6e29844cc705e148ec4856448',
'third_party/libc++/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + '449310fe2e37834a7e62972d2a690cade2ef596b',
'third_party/libc++abi/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + '94c5d7a8edc09f0680aee57548c0b5d400c2840d',
'third_party/libunwind/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + 'e2e6f2a67e9420e770b014ce9bba476fa2ab9874',
'third_party/llvm-libc/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libc.git' + '@' + '188329a7f2118a957efbb3e6219c255e7dba997c',
'third_party/llvm-build/Release+Asserts': {
'dep_type': 'gcs',
'bucket': 'chromium-browser-clang',
'objects': [
{
'object_name': 'Linux_x64/clang-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '790fcc5b04e96882e8227ba7994161ab945c0e096057fc165a0f71e32a7cb061',
'size_bytes': 54517328,
'generation': 1742541959624765,
'condition': 'host_os == "linux"',
},
{
'object_name': 'Linux_x64/clang-tidy-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '6e325d9f62e831bfbae23413a75535a851fd2cdf2f7cf06a5b724e86f72b2df0',
'size_bytes': 13206280,
'generation': 1742541959572183,
'condition': 'host_os == "linux" and checkout_clang_tidy',
},
{
'object_name': 'Linux_x64/clangd-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '95d4146cb0b892db68c55bbb523b30301e538d0f4dc71517612fdee62664b81a',
'size_bytes': 13566616,
'generation': 1742541959718102,
'condition': 'host_os == "linux" and checkout_clangd',
},
{
'object_name': 'Linux_x64/llvm-code-coverage-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': 'a10c2831ad30275a72f2955e65e62f6af78542f380661443dab4d20c65f203a4',
'size_bytes': 2299292,
'generation': 1742541960157221,
'condition': 'host_os == "linux" and checkout_clang_coverage_tools',
},
{
'object_name': 'Linux_x64/llvmobjdump-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '56a5bb654a4550d332f86a23e38a0495c6187092868af817ecb999bd9de9c8a0',
'size_bytes': 5429676,
'generation': 1742541959869492,
'condition': '(checkout_linux or checkout_mac or checkout_android and host_os != "mac")',
},
{
'object_name': 'Mac/clang-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '330f8c4cdde3095ac54aff772dbf9bbd96a753df58525546931cbd9bb615f793',
'size_bytes': 51652432,
'generation': 1742541961981004,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
'object_name': 'Mac/clang-mac-runtime-library-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '013f468c65fae6f736cd380791fef892a0fc9fc107516fcae34d1f998eeb081f',
'size_bytes': 978248,
'generation': 1742541983231339,
'condition': 'checkout_mac and not host_os == "mac"',
},
{
'object_name': 'Mac/clang-tidy-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': 'f29391d18e9fa40774e0386224235890933a8b9eddb9b7eb93d2a4a0867241a1',
'size_bytes': 13468608,
'generation': 1742541962672221,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_tidy',
},
{
'object_name': 'Mac/clangd-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '06c48661d55a7b465d8fb02be56f8550c34d3962a9d0f8ce19b17bdd37127691',
'size_bytes': 15012228,
'generation': 1742541962463652,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clangd',
},
{
'object_name': 'Mac/llvm-code-coverage-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '12f3accae43fa9591bbf28a8e0785b99ff75ed2c84f89518bd5ef5119a2525f0',
'size_bytes': 2255296,
'generation': 1742541963013464,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_coverage_tools',
},
{
'object_name': 'Mac_arm64/clang-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '49967dab3fa4c5f1ff1fe235059be71727c190ff4ccc80f08d39e1bba4dfed58',
'size_bytes': 43810156,
'generation': 1742541984650930,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
'object_name': 'Mac_arm64/clang-tidy-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '4f5326253ed3736ec262e8e69d93befadf9473419865240673a2ec883c3614b6',
'size_bytes': 11607236,
'generation': 1742541984970894,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_tidy',
},
{
'object_name': 'Mac_arm64/clangd-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': 'b3da417d27ba5afe6c9f612d5808c416a17ed1b28f2acd745e0cd2962a5eeac1',
'size_bytes': 12000852,
'generation': 1742541985144552,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clangd',
},
{
'object_name': 'Mac_arm64/llvm-code-coverage-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '78139b473cdf4d43da880b573661a5d28d94a8bcb4dea41607d324301745f28c',
'size_bytes': 1976480,
'generation': 1742541985608174,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_coverage_tools',
},
{
'object_name': 'Win/clang-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': 'b46fb4a5cbf9c52d0b345fc2d77ad4ac15dfbb45aa494fb49261786c679af44a',
'size_bytes': 46813332,
'generation': 1742542010902044,
'condition': 'host_os == "win"',
},
{
'object_name': 'Win/clang-tidy-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '50d527e811ae8543effa2bb5734a1d424d9c497fbf1d96c76d44b6b5ee7f240b',
'size_bytes': 13233236,
'generation': 1742542011983982,
'condition': 'host_os == "win" and checkout_clang_tidy',
},
{
'object_name': 'Win/clang-win-runtime-library-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': 'bd2ad1930c0ba7d00364dd344886fd57e16aa070ff1b6a1aade72b58d28e8275',
'size_bytes': 2474048,
'generation': 1742542035740788,
'condition': 'checkout_win and not host_os == "win"',
},
{
'object_name': 'Win/clangd-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '06563cfcb24d7196717551dfcda13ed0b97fb9e795dba06007c55ae563e824b0',
'size_bytes': 13759668,
'generation': 1742542011820938,
'condition': 'host_os == "win" and checkout_clangd',
},
{
'object_name': 'Win/llvm-code-coverage-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': '7c2fe8784910dc05445cd7f16742e0b2a09a45fb2ba96ddd5f1d8c895ac65d44',
'size_bytes': 2365956,
'generation': 1742542013491786,
'condition': 'host_os == "win" and checkout_clang_coverage_tools',
},
{
'object_name': 'Win/llvmobjdump-llvmorg-21-init-5118-g52cd27e6-5.tar.xz',
'sha256sum': 'a07be25cb4d565422b10001ca3595111d40bd42c47b37b41e2fff5708fe82302',
'size_bytes': 5527784,
'generation': 1742542012678160,
'condition': 'checkout_linux or checkout_mac or checkout_android and host_os == "win"',
},
],
},
'third_party/logdog/logdog':
Var('chromium_url') + '/infra/luci/luci-py/client/libs/logdog' + '@' + '0b2078a90f7a638d576b3a7c407d136f2fb62399',
'third_party/markupsafe':
Var('chromium_url') + '/chromium/src/third_party/markupsafe.git' + '@' + '9f8efc8637f847ab1ba984212598e6fb9cf1b3d4',
'third_party/ninja': {
'packages': [
{
'package': 'infra/3pp/tools/ninja/${{platform}}',
'version': Var('ninja_version'),
}
],
'dep_type': 'cipd',
'condition': 'host_cpu != "s390" and host_os != "zos" and host_cpu != "ppc"'
},
'third_party/partition_alloc': {
'url': Var('chromium_url') + '/chromium/src/base/allocator/partition_allocator.git@' + Var('partition_alloc_version'),
'condition': 'not build_with_chromium',
},
'third_party/perfetto':
Var('android_url') + '/platform/external/perfetto.git' + '@' + '40b529923598b739b2892a536a7692eedbed5685',
'third_party/protobuf':
Var('chromium_url') + '/chromium/src/third_party/protobuf.git' + '@' + 'b714f7890b8b6ad3ff3471d3148b28c2c7bbff90',
'third_party/re2/src':
Var('chromium_url') + '/external/github.com/google/re2.git' + '@' + 'c84a140c93352cdabbfb547c531be34515b12228',
'third_party/requests': {
'url': Var('chromium_url') + '/external/github.com/kennethreitz/requests.git' + '@' + 'c7e0fc087ceeadb8b4c84a0953a422c474093d6d',
'condition': 'checkout_android',
},
'tools/rust':
Var('chromium_url') + '/chromium/src/tools/rust' + '@' + '7cdd3d9540f3ab428dbcc9ab83c2896c100bcdc5',
'third_party/rust':
Var('chromium_url') + '/chromium/src/third_party/rust' + '@' + 'ed577320339cd175171e9c96d3d73452ddbcbd98',
'third_party/rust-toolchain': {
'dep_type': 'gcs',
'bucket': 'chromium-browser-clang',
'objects': [
{
'object_name': 'Linux_x64/rust-toolchain-f7b43542838f0a4a6cfdb17fbeadf45002042a77-1-llvmorg-21-init-5118-g52cd27e6.tar.xz',
'sha256sum': '213ffcc751ba5f5a4e15fc0dbcbdb94aa7dbc4b6cddd3605121cd26ff8a8b359',
'size_bytes': 118223072,
'generation': 1741985831167267,
'condition': 'host_os == "linux"',
},
{
'object_name': 'Mac/rust-toolchain-f7b43542838f0a4a6cfdb17fbeadf45002042a77-1-llvmorg-21-init-5118-g52cd27e6.tar.xz',
'sha256sum': 'f5ad2fe26336a87713ffcad9e06ae4c1ecb4773ae496a33450a7091c5eec560c',
'size_bytes': 111168208,
'generation': 1741985832885972,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
'object_name': 'Mac_arm64/rust-toolchain-f7b43542838f0a4a6cfdb17fbeadf45002042a77-1-llvmorg-21-init-5118-g52cd27e6.tar.xz',
'sha256sum': 'fac3586c08239bbb8fd192a7ba5deaa9ae62f6fde2c1d665953f87176467a156',
'size_bytes': 100534232,
'generation': 1741985834191792,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
'object_name': 'Win/rust-toolchain-f7b43542838f0a4a6cfdb17fbeadf45002042a77-1-llvmorg-21-init-5118-g52cd27e6.tar.xz',
'sha256sum': '7b41e74c9b45ca97ca65279c605e6af878de5682fe574d1f1860d9da9b3a5909',
'size_bytes': 180896336,
'generation': 1741985835535129,
'condition': 'host_os == "win"',
},
],
},
'third_party/siso': {
'packages': [
{
'package': 'infra/build/siso/${{platform}}',
'version': Var('siso_version'),
}
],
'dep_type': 'cipd',
'condition': 'not build_with_chromium and host_cpu != "s390" and host_os != "zos" and host_cpu != "ppc"',
},
'third_party/zlib':
Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '788cb3c270e8700b425c7bdca1f9ce6b0c1400a9',
'tools/clang':
Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '0078c27c43cae91e96bb28d8a4407045966e0542',
'tools/protoc_wrapper':
Var('chromium_url') + '/chromium/src/tools/protoc_wrapper.git' + '@' + 'dbcbea90c20ae1ece442d8ef64e61c7b10e2b013',
'third_party/abseil-cpp': {
'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + '3fbb10e80d80e3430224b75add53c47c7a711612',
'condition': 'not build_with_chromium',
},
'third_party/zoslib': {
'url': Var('chromium_url') + '/external/github.com/ibmruntimes/zoslib.git' + '@' + '1e68de6e37efced3738a88536fccb6bbfe2d70b2',
'condition': 'host_os == "zos"',
}
}
include_rules = [
# Everybody can use some things.
'+include',
'+unicode',
'+third_party/fast_float/src/include',
'+third_party/fdlibm',
'+third_party/fp16/src/include',
'+third_party/fuzztest',
'+third_party/ittapi/include',
'+third_party/simdutf',
'+third_party/v8/codegen',
'+third_party/vtune',
'+hwy/highway.h',
# Abseil features are allow-listed. Please use your best judgement when adding
# to this set -- if in doubt, email v8-dev@. For general guidance, refer to
# the Chromium guidelines (though note that some requirements in V8 may be
# different to Chromium's):
# https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++11.md
'+absl/container/flat_hash_map.h',
'+absl/container/flat_hash_set.h',
'+absl/container/btree_map.h',
'+absl/status',
'+absl/synchronization/mutex.h',
'+absl/time/time.h',
# Some abseil features are explicitly banned.
'-absl/types/any.h', # Requires RTTI.
'-absl/types/flags', # Requires RTTI.
]
# checkdeps.py shouldn't check for includes in these directories:
skip_child_includes = [
'build',
'third_party',
]
hooks = [
{
# Ensure that the DEPS'd "depot_tools" has its self-update capability
# disabled.
'name': 'disable_depot_tools_selfupdate',
'pattern': '.',
'action': [
'python3',
'third_party/depot_tools/update_depot_tools_toggle.py',
'--disable',
],
},
{
# This clobbers when necessary (based on get_landmines.py). It must be the
# first hook so that other things that get/generate into the output
# directory will not subsequently be clobbered.
'name': 'landmines',
'pattern': '.',
'action': [
'python3',
'build/landmines.py',
'--landmine-scripts',
'tools/get_landmines.py',
],
},
{
'name': 'bazel',
'pattern': '.',
'condition': 'download_prebuilt_bazel',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--bucket', 'chromium-v8-prebuilt-bazel/linux',
'--no_resume',
'-s', 'tools/bazel/bazel.sha1',
'--platform=linux*',
],
},
# Pull dsymutil binaries using checked-in hashes.
{
'name': 'dsymutil_mac_arm64',
'pattern': '.',
'condition': 'host_os == "mac" and host_cpu == "arm64"',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-browser-clang',
'-s', 'tools/clang/dsymutil/bin/dsymutil.arm64.sha1',
'-o', 'tools/clang/dsymutil/bin/dsymutil',
],
},
{
'name': 'dsymutil_mac_x64',
'pattern': '.',
'condition': 'host_os == "mac" and host_cpu == "x64"',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-browser-clang',
'-s', 'tools/clang/dsymutil/bin/dsymutil.x64.sha1',
'-o', 'tools/clang/dsymutil/bin/dsymutil',
],
},
{
'name': 'gcmole',
'pattern': '.',
'condition': 'download_gcmole',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--bucket', 'chrome-v8-gcmole',
'-u', '--no_resume',
'-s', 'tools/gcmole/gcmole-tools.tar.gz.sha1',
'--platform=linux*',
],
},
{
'name': 'jsfunfuzz',
'pattern': '.',
'condition': 'download_jsfunfuzz',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--bucket', 'chrome-v8-jsfunfuzz',
'-u', '--no_resume',
'-s', 'tools/jsfunfuzz/jsfunfuzz.tar.gz.sha1',
'--platform=linux*',
],
},
{
'name': 'wasm_spec_tests',
'pattern': '.',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'-u',
'--bucket', 'v8-wasm-spec-tests',
'-s', 'test/wasm-spec-tests/tests.tar.gz.sha1',
],
},
{
'name': 'wasm_js',
'pattern': '.',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'-u',
'--bucket', 'v8-wasm-spec-tests',
'-s', 'test/wasm-js/tests.tar.gz.sha1',
],
},
{
# Case-insensitivity for the Win SDK. Must run before win_toolchain below.
'name': 'ciopfs_linux',
'pattern': '.',
'condition': 'checkout_win and host_os == "linux"',
'action': [ 'python3',
'third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-browser-clang/ciopfs',
'-s', 'build/ciopfs.sha1',
]
},
{
# Update the Windows toolchain if necessary.
'name': 'win_toolchain',
'pattern': '.',
'condition': 'checkout_win',
'action': ['python3', 'build/vs_toolchain.py', 'update', '--force'],
},
{
# Update the Mac toolchain if necessary.
'name': 'mac_toolchain',
'pattern': '.',
'condition': 'checkout_mac',
'action': ['python3', 'build/mac_toolchain.py'],
},
{
# Update LASTCHANGE.
'name': 'lastchange',
'pattern': '.',
'action': ['python3', 'build/util/lastchange.py',
'-o', 'build/util/LASTCHANGE'],
},
{
'name': 'Download Fuchsia SDK from GCS',
'pattern': '.',
'condition': 'checkout_fuchsia',
'action': [
'python3',
'build/fuchsia/update_sdk.py',
'--cipd-prefix={fuchsia_sdk_cipd_prefix}',
'--version={fuchsia_version}',
],
},
{
'name': 'Download Fuchsia system images',
'pattern': '.',
'condition': 'checkout_fuchsia and checkout_fuchsia_product_bundles',
'action': [
'python3',
'build/fuchsia/update_product_bundles.py',
'{checkout_fuchsia_boot_images}',
],
},
{
# Mac does not have llvm-objdump, download it for cross builds in Fuchsia.
'name': 'llvm-objdump',
'pattern': '.',
'condition': 'host_os == "mac" and checkout_fuchsia',
'action': ['python3', 'tools/clang/scripts/update.py',
'--package=objdump'],
},
{
'name': 'vpython3_common',
'pattern': '.',
'action': [ 'vpython3',
'-vpython-spec', '.vpython3',
'-vpython-tool', 'install',
],
},
{
'name': 'check_v8_header_includes',
'pattern': '.',
'condition': 'check_v8_header_includes',
'action': [
'python3',
'tools/generate-header-include-checks.py',
],
},
{
'name': 'checkout_v8_builtins_pgo_profiles',
'pattern': '.',
'condition': 'checkout_v8_builtins_pgo_profiles',
'action': [
'python3',
'tools/builtins-pgo/download_profiles.py',
'download',
'--quiet',
],
},
# Configure remote exec cfg files
{
'name': 'download_and_configure_reclient_cfgs',
'pattern': '.',
'condition': 'download_remoteexec_cfg and not build_with_chromium',
'action': ['python3',
'buildtools/reclient_cfgs/configure_reclient_cfgs.py',
'--rbe_instance',
Var('rbe_instance'),
'--reproxy_cfg_template',
'reproxy.cfg.template',
'--rewrapper_cfg_project',
Var('rewrapper_cfg_project'),
'--quiet',
],
},
{
'name': 'configure_reclient_cfgs',
'pattern': '.',
'condition': 'not download_remoteexec_cfg and not build_with_chromium',
'action': ['python3',
'buildtools/reclient_cfgs/configure_reclient_cfgs.py',
'--rbe_instance',
Var('rbe_instance'),
'--reproxy_cfg_template',
'reproxy.cfg.template',
'--rewrapper_cfg_project',
Var('rewrapper_cfg_project'),
'--skip_remoteexec_cfg_fetch',
],
},
# Configure Siso for developer builds.
{
'name': 'configure_siso',
'pattern': '.',
'condition': 'not build_with_chromium',
'action': ['python3',
'build/config/siso/configure_siso.py',
'--rbe_instance',
Var('rbe_instance'),
],
},
]
recursedeps = [
'build',
'buildtools',
'third_party/instrumented_libs',
]

15
deps/v8/DIR_METADATA vendored Normal file
View File

@ -0,0 +1,15 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Blink>JavaScript"
}
team_email: "v8-dev@googlegroups.com"
buganizer_public: {
component_id: 1456824
}

12
deps/v8/ENG_REVIEW_OWNERS vendored Normal file
View File

@ -0,0 +1,12 @@
# Eng reviewers. This is to define an escalation path for potential
# disagreement among owners. Please consult before adding top-level
# directories.
adamk@chromium.org
gdeepti@chromium.org
hpayer@chromium.org #{LAST_RESORT_SUGGESTION}
leszeks@chromium.org
mlippautz@chromium.org
syg@chromium.org
verwaest@chromium.org
vahl@chromium.org

4
deps/v8/INFRA_OWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
alexschulze@chromium.org
almuthanna@chromium.org
liviurau@chromium.org
machenbach@chromium.org

4
deps/v8/INTL_OWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
cira@chromium.org
mnita@google.com
jshin@chromium.org
ftang@chromium.org

61
deps/v8/LICENSE vendored Normal file
View File

@ -0,0 +1,61 @@
This license applies to all parts of V8 that are not externally
maintained libraries. The externally maintained libraries used by V8
are:
- PCRE test suite, located in
test/mjsunit/third_party/regexp-pcre/regexp-pcre.js. This is based on the
test suite from PCRE-7.3, which is copyrighted by the University
of Cambridge and Google, Inc. The copyright notice and license
are embedded in regexp-pcre.js.
- Layout tests, located in test/mjsunit/third_party/object-keys. These are
based on layout tests from webkit.org which are copyrighted by
Apple Computer, Inc. and released under a 3-clause BSD license.
- Strongtalk assembler, the basis of the files assembler-arm-inl.h,
assembler-arm.cc, assembler-arm.h, assembler-ia32-inl.h,
assembler-ia32.cc, assembler-ia32.h, assembler-x64-inl.h,
assembler-x64.cc, assembler-x64.h, assembler.cc and assembler.h.
This code is copyrighted by Sun Microsystems Inc. and released
under a 3-clause BSD license.
- Valgrind client API header, located at third_party/valgrind/valgrind.h
This is released under the BSD license.
- The Wasm C/C++ API headers, located at third_party/wasm-api/wasm.{h,hh}
This is released under the Apache license. The API's upstream prototype
implementation also formed the basis of V8's implementation in
src/wasm/c-api.cc.
These libraries have their own licenses; we recommend you read them,
as their terms may differ from the terms below.
Further license information can be found in LICENSE files located in
sub-directories.
Copyright 2014, 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.

6
deps/v8/LICENSE.fdlibm vendored Normal file
View File

@ -0,0 +1,6 @@
Copyright (C) 1993-2004 by Sun Microsystems, Inc. All rights reserved.
Developed at SunSoft, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.

29
deps/v8/LICENSE.strongtalk vendored Normal file
View File

@ -0,0 +1,29 @@
Copyright (c) 1994-2006 Sun Microsystems Inc.
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.
- Redistribution 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 Sun Microsystems or the names of 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.

26
deps/v8/LICENSE.v8 vendored Normal file
View File

@ -0,0 +1,26 @@
Copyright 2006-2011, 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.

3
deps/v8/LOONG_OWNERS vendored Normal file
View File

@ -0,0 +1,3 @@
liuyu@loongson.cn
yuyin-hf@loongson.cn
zhaojiazhong-hf@loongson.cn

3
deps/v8/MIPS_OWNERS vendored Normal file
View File

@ -0,0 +1,3 @@
xwafish@gmail.com
zhaojiazhong-hf@loongson.cn
liuyu@loongson.cn

19
deps/v8/MODULE.bazel vendored Normal file
View File

@ -0,0 +1,19 @@
module(
name = "v8",
version = "0.0.0",
)
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "rules_python", version = "1.0.0")
bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "abseil-cpp", version = "20240722.0.bcr.2")
bazel_dep(name = "highway", version = "1.2.0")
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
hub_name = "v8_python_deps",
python_version = "3.11",
requirements_lock = "//:bazel/requirements.txt",
extra_pip_args = ["--require-hashes"],
)
use_repo(pip, "v8_python_deps")

28
deps/v8/OWNERS vendored Normal file
View File

@ -0,0 +1,28 @@
# Eng reviewer. Please reach out before adding new top-level directories.
# Disagreement among owners should be escalated to eng reviewers.
file:ENG_REVIEW_OWNERS
per-file .*=file:INFRA_OWNERS
per-file .bazelrc=file:COMMON_OWNERS
per-file .mailmap=file:COMMON_OWNERS
per-file .ycm_extra_conf.py=file:COMMON_OWNERS
per-file codereview.settings=file:INFRA_OWNERS
per-file AUTHORS=file:COMMON_OWNERS
per-file BUILD.bazel=file:COMMON_OWNERS
per-file BUILD.gn=file:COMMON_OWNERS
per-file DEPS=file:COMMON_OWNERS
per-file INFRA_OWNERS=file:INFRA_OWNERS
per-file MODULE.bazel=file:COMMON_OWNERS
per-file PRESUBMIT.py=file:INFRA_OWNERS
per-file WATCHLISTS=file:COMMON_OWNERS
# Needed by the auto_tag builder
per-file WATCHLISTS=v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com
per-file DEPS=v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com
per-file ...-loong64*=file:LOONG_OWNERS
per-file ...-mips*=file:MIPS_OWNERS
per-file ...-mips64*=file:MIPS_OWNERS
per-file ...-ppc*=file:PPC_OWNERS
per-file ...-riscv*=file:RISCV_OWNERS
per-file ...-s390*=file:S390_OWNERS

4
deps/v8/PPC_OWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
junyan@redhat.com
joransiu@ca.ibm.com
midawson@redhat.com
mfarazma@redhat.com

624
deps/v8/PRESUBMIT.py vendored Normal file
View File

@ -0,0 +1,624 @@
# 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.
"""Top-level presubmit script for V8.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
import ast
import json
import os
import re
import sys
import traceback
# This line is 'magic' in that git-cl looks for it to decide whether to
# use Python3 instead of Python2 when running the code in this file.
USE_PYTHON3 = True
_EXCLUDED_PATHS = (
r"^test[\\\/].*",
r"^testing[\\\/].*",
r"^third_party[\\\/].*",
r"^tools[\\\/].*",
)
_LICENSE_FILE = (
r"LICENSE"
)
# Regular expression that matches code which should not be run through cpplint.
_NO_LINT_PATHS = (
r'src[\\\/]base[\\\/]export-template\.h',
)
# Regular expression that matches code only used for test binaries
# (best effort).
_TEST_CODE_EXCLUDED_PATHS = (
r'.+-unittest\.cc',
# Has a method VisitForTest().
r'src[\\\/]compiler[\\\/]ast-graph-builder\.cc',
# Test extension.
r'src[\\\/]extensions[\\\/]gc-extension\.cc',
# Runtime functions used for testing.
r'src[\\\/]runtime[\\\/]runtime-test\.cc',
# Testing helpers.
r'src[\\\/]heap[\\\/]cppgc[\\\/]testing\.cc',
)
_TEST_ONLY_WARNING = (
'You might be calling functions intended only for testing from\n'
'production code. It is OK to ignore this warning if you know what\n'
'you are doing, as the heuristics used to detect the situation are\n'
'not perfect. The commit queue will not block on this warning.')
def _V8PresubmitChecks(input_api, output_api):
"""Runs the V8 presubmit checks."""
import sys
sys.path.append(input_api.os_path.join(
input_api.PresubmitLocalPath(), 'tools'))
from v8_presubmit import CppLintProcessor
from v8_presubmit import GCMoleProcessor
from v8_presubmit import JSLintProcessor
from v8_presubmit import TorqueLintProcessor
from v8_presubmit import SourceProcessor
from v8_presubmit import StatusFilesProcessor
def FilterFile(affected_file):
return input_api.FilterSourceFile(
affected_file,
files_to_check=None,
files_to_skip=_NO_LINT_PATHS)
def FilterTorqueFile(affected_file):
return input_api.FilterSourceFile(
affected_file,
files_to_check=(r'.+\.tq'))
def FilterJSFile(affected_file):
return input_api.FilterSourceFile(
affected_file,
files_to_check=(r'.+\.m?js'))
results = []
if not CppLintProcessor().RunOnFiles(
input_api.AffectedFiles(file_filter=FilterFile, include_deletes=False)):
results.append(output_api.PresubmitError("C++ lint check failed"))
if not TorqueLintProcessor().RunOnFiles(
input_api.AffectedFiles(file_filter=FilterTorqueFile,
include_deletes=False)):
results.append(output_api.PresubmitError("Torque format check failed"))
if not JSLintProcessor().RunOnFiles(
input_api.AffectedFiles(file_filter=FilterJSFile,
include_deletes=False)):
results.append(output_api.PresubmitError("JS format check failed"))
if not SourceProcessor().RunOnFiles(
input_api.AffectedFiles(include_deletes=False)):
results.append(output_api.PresubmitError(
"Copyright header, trailing whitespaces and two empty lines " \
"between declarations check failed"))
if not StatusFilesProcessor().RunOnFiles(
input_api.AffectedFiles(include_deletes=True)):
results.append(output_api.PresubmitError("Status file check failed"))
if not GCMoleProcessor().RunOnFiles(
input_api.AffectedFiles(include_deletes=False)):
results.append(output_api.PresubmitError("GCMole pattern check failed"))
results.extend(input_api.canned_checks.CheckAuthorizedAuthor(
input_api, output_api, bot_allowlist=[
'v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com',
'v8-ci-test262-import-export@chops-service-accounts.iam.gserviceaccount.com',
]))
return results
def _CheckPythonLiterals(input_api, output_api):
"""Checks that all .pyl files are valid python literals."""
affected_files = [
af for af in input_api.AffectedFiles()
if af.LocalPath().endswith('.pyl')
]
results = []
for af in affected_files:
try:
ast.literal_eval('\n'.join(af.NewContents()))
except SyntaxError as e:
results.append(output_api.PresubmitError(
f'Failed to parse python literal {af.LocalPath()}:\n' +
traceback.format_exc(0)
))
return results
def _CheckUnwantedDependencies(input_api, output_api):
"""Runs checkdeps on #include statements added in this
change. Breaking - rules is an error, breaking ! rules is a
warning.
"""
# We need to wait until we have an input_api object and use this
# roundabout construct to import checkdeps because this file is
# eval-ed and thus doesn't have __file__.
original_sys_path = sys.path
try:
sys.path = sys.path + [input_api.os_path.join(
input_api.PresubmitLocalPath(), 'buildtools', 'checkdeps')]
import checkdeps
from cpp_checker import CppChecker
from rules import Rule
finally:
# Restore sys.path to what it was before.
sys.path = original_sys_path
def _FilesImpactedByDepsChange(files):
all_files = [f.AbsoluteLocalPath() for f in files]
deps_files = [p for p in all_files if IsDepsFile(p)]
impacted_files = union([_CollectImpactedFiles(path) for path in deps_files])
impacted_file_objs = [ImpactedFile(path) for path in impacted_files]
return impacted_file_objs
def IsDepsFile(p):
return os.path.isfile(p) and os.path.basename(p) == 'DEPS'
def union(list_of_lists):
"""Ensure no duplicates"""
return set(sum(list_of_lists, []))
def _CollectImpactedFiles(deps_file):
# TODO(liviurau): Do not walk paths twice. Then we have no duplicates.
# Higher level DEPS changes may dominate lower level DEPS changes.
# TODO(liviurau): Check if DEPS changed in the right way.
# 'include_rules' impact c++ files but 'vars' or 'deps' do not.
# Maybe we just eval both old and new DEPS content and check
# if the list are the same.
result = []
parent_dir = os.path.dirname(deps_file)
for relative_f in input_api.change.AllFiles(parent_dir):
abs_f = os.path.join(parent_dir, relative_f)
if CppChecker.IsCppFile(abs_f):
result.append(abs_f)
return result
class ImpactedFile(object):
"""Duck type version of AffectedFile needed to check files under directories
where a DEPS file changed. Extend the interface along the line of
AffectedFile if you need it for other checks."""
def __init__(self, path):
self._path = path
def LocalPath(self):
path = self._path.replace(os.sep, '/')
return os.path.normpath(path)
def ChangedContents(self):
with open(self._path) as f:
# TODO(liviurau): read only '#include' lines
lines = f.readlines()
return enumerate(lines, start=1)
def _FilterDuplicates(impacted_files, affected_files):
""""We include all impacted files but exclude affected files that are also
impacted. Files impacted by DEPS changes take precedence before files
affected by direct changes."""
result = impacted_files[:]
only_paths = set([imf.LocalPath() for imf in impacted_files])
for af in affected_files:
if not af.LocalPath() in only_paths:
result.append(af)
return result
added_includes = []
affected_files = input_api.AffectedFiles()
impacted_by_deps = _FilesImpactedByDepsChange(affected_files)
for f in _FilterDuplicates(impacted_by_deps, affected_files):
if not CppChecker.IsCppFile(f.LocalPath()):
continue
changed_lines = [line for line_num, line in f.ChangedContents()]
added_includes.append([f.LocalPath(), changed_lines])
deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
error_descriptions = []
warning_descriptions = []
for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
added_includes):
description_with_path = '{}\n {}'.format(path, rule_description)
if rule_type == Rule.DISALLOW:
error_descriptions.append(description_with_path)
else:
warning_descriptions.append(description_with_path)
results = []
if error_descriptions:
results.append(output_api.PresubmitError(
'You added one or more #includes that violate checkdeps rules.',
error_descriptions))
if warning_descriptions:
results.append(output_api.PresubmitPromptOrNotify(
'You added one or more #includes of files that are temporarily\n'
'allowed but being removed. Can you avoid introducing the\n'
'#include? See relevant DEPS file(s) for details and contacts.',
warning_descriptions))
return results
def _CheckHeadersHaveIncludeGuards(input_api, output_api):
"""Ensures that all header files have include guards."""
file_inclusion_pattern = r'src/.+\.h'
def FilterFile(affected_file):
files_to_skip = _EXCLUDED_PATHS + input_api.DEFAULT_FILES_TO_SKIP
return input_api.FilterSourceFile(
affected_file,
files_to_check=(file_inclusion_pattern, ),
files_to_skip=files_to_skip)
leading_src_pattern = input_api.re.compile(r'^src[\\\/]')
dash_dot_slash_pattern = input_api.re.compile(r'[-.\\\/]')
def PathToGuardMacro(path):
"""Guards should be of the form V8_PATH_TO_FILE_WITHOUT_SRC_H_."""
x = input_api.re.sub(leading_src_pattern, 'v8_', path)
x = input_api.re.sub(dash_dot_slash_pattern, '_', x)
x = x.upper() + "_"
return x
problems = []
for f in input_api.AffectedSourceFiles(FilterFile):
local_path = f.LocalPath()
guard_macro = PathToGuardMacro(local_path)
guard_patterns = [
input_api.re.compile(r'^#ifndef ' + guard_macro + '$'),
input_api.re.compile(r'^#define ' + guard_macro + '$'),
input_api.re.compile(r'^#endif // ' + guard_macro + '$')]
skip_check_pattern = input_api.re.compile(
r'^// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD')
found_patterns = [ False, False, False ]
file_omitted = False
for line in f.NewContents():
for i in range(len(guard_patterns)):
if guard_patterns[i].match(line):
found_patterns[i] = True
if skip_check_pattern.match(line):
file_omitted = True
break
if not file_omitted and not all(found_patterns):
problems.append('{}: Missing include guard \'{}\''.format(
local_path, guard_macro))
if problems:
return [output_api.PresubmitError(
'You added one or more header files without an appropriate\n'
'include guard. Add the include guard {#ifndef,#define,#endif}\n'
'triplet or omit the check entirely through the magic comment:\n'
'"// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD".', problems)]
else:
return []
def _CheckNoInlineHeaderIncludesInNormalHeaders(input_api, output_api):
"""Attempts to prevent inclusion of inline headers into normal header
files. This tries to establish a layering where inline headers can be
included by other inline headers or compilation units only."""
file_inclusion_pattern = r'(?!.+-inl\.h).+\.h'
include_directive_pattern = input_api.re.compile(r'#include ".+-inl.h"')
include_error = (
'You are including an inline header (e.g. foo-inl.h) within a normal\n'
'header (e.g. bar.h) file. This violates layering of dependencies.')
def FilterFile(affected_file):
files_to_skip = _EXCLUDED_PATHS + input_api.DEFAULT_FILES_TO_SKIP
return input_api.FilterSourceFile(
affected_file,
files_to_check=(file_inclusion_pattern, ),
files_to_skip=files_to_skip)
problems = []
for f in input_api.AffectedSourceFiles(FilterFile):
local_path = f.LocalPath()
for line_number, line in f.ChangedContents():
if (include_directive_pattern.search(line)):
problems.append('{}:{}\n {}'.format(local_path, line_number,
line.strip()))
if problems:
return [output_api.PresubmitError(include_error, problems)]
else:
return []
def _CheckInlineHeadersIncludeNonInlineHeadersFirst(input_api, output_api):
"""Checks that the first include in each inline header ("*-inl.h") is the
non-inl counterpart of that header, if that file exists."""
file_inclusion_pattern = r'.+-inl\.h'
include_error = (
'The first include of an -inl.h header should be the non-inl counterpart.'
)
def FilterFile(affected_file):
files_to_skip = _EXCLUDED_PATHS + input_api.DEFAULT_FILES_TO_SKIP + (
# Exclude macro-assembler-<ARCH>-inl.h headers because they have special
# include rules (arch-specific macro assembler headers must be included
# via the general macro-assembler.h).
r'src[\\\/]codegen[\\\/].*[\\\/]macro-assembler-.*-inl\.h',)
return input_api.FilterSourceFile(
affected_file,
files_to_check=(file_inclusion_pattern,),
files_to_skip=files_to_skip)
to_non_inl = lambda filename: filename[:-len("-inl.h")] + ".h"
problems = []
for f in input_api.AffectedSourceFiles(FilterFile):
if not os.path.isfile(to_non_inl(f.AbsoluteLocalPath())):
continue
non_inl_header = to_non_inl(f.LocalPath())
first_include = None
for line in f.NewContents():
if line.startswith('#include '):
first_include = line
break
expected_include = f'#include "{non_inl_header}"'
if first_include is None:
problems.append(f'{f.LocalPath()}: should include {non_inl_header}\n'
' found no includes in the file.')
elif not first_include.startswith(expected_include):
problems.append(
f'{f.LocalPath()}: should include {non_inl_header} first\n'
f' found: {first_include}')
if problems:
return [output_api.PresubmitError(include_error, problems)]
else:
return []
def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
"""Attempts to prevent use of functions intended only for testing in
non-testing code. For now this is just a best-effort implementation
that ignores header files and may have some false positives. A
better implementation would probably need a proper C++ parser.
"""
# We only scan .cc files, as the declaration of for-testing functions in
# header files are hard to distinguish from calls to such functions without a
# proper C++ parser.
file_inclusion_pattern = r'.+\.cc'
base_function_pattern = r'[ :]test::[^\s]+|ForTest(ing)?|for_test(ing)?'
inclusion_pattern = input_api.re.compile(
r'({})\s*\('.format(base_function_pattern))
comment_pattern = input_api.re.compile(
r'//.*({})'.format(base_function_pattern))
exclusion_pattern = input_api.re.compile(
r'::[A-Za-z0-9_]+({})|({})[^;]+'.format(base_function_pattern,
base_function_pattern) + '\{')
def FilterFile(affected_file):
files_to_skip = (_EXCLUDED_PATHS +
_TEST_CODE_EXCLUDED_PATHS +
input_api.DEFAULT_FILES_TO_SKIP)
return input_api.FilterSourceFile(
affected_file,
files_to_check=(file_inclusion_pattern, ),
files_to_skip=files_to_skip)
problems = []
for f in input_api.AffectedSourceFiles(FilterFile):
local_path = f.LocalPath()
for line_number, line in f.ChangedContents():
if (inclusion_pattern.search(line) and
not comment_pattern.search(line) and
not exclusion_pattern.search(line)):
problems.append('{}:{}\n {}'.format(local_path, line_number,
line.strip()))
if problems:
return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
else:
return []
def _CheckGenderNeutralInLicenses(input_api, output_api):
# License files are taken as is, even if they include gendered pronouns.
def LicenseFilter(path):
input_api.FilterSourceFile(path, files_to_skip=_LICENSE_FILE)
return input_api.canned_checks.CheckGenderNeutral(
input_api, output_api, source_file_filter=LicenseFilter)
def _RunTestsWithVPythonSpec(input_api, output_api):
return input_api.RunTests(
input_api.canned_checks.CheckVPythonSpec(input_api, output_api))
def _CommonChecks(input_api, output_api):
"""Checks common to both upload and commit."""
# TODO(machenbach): Replace some of those checks, e.g. owners and copyright,
# with the canned PanProjectChecks. Need to make sure that the checks all
# pass on all existing files.
checks = [
input_api.canned_checks.CheckOwnersFormat,
input_api.canned_checks.CheckOwners,
_CheckCommitMessageBugEntry,
input_api.canned_checks.CheckPatchFormatted,
_CheckGenderNeutralInLicenses,
_V8PresubmitChecks,
_CheckUnwantedDependencies,
_CheckNoProductionCodeUsingTestOnlyFunctions,
_CheckHeadersHaveIncludeGuards,
_CheckNoInlineHeaderIncludesInNormalHeaders,
_CheckInlineHeadersIncludeNonInlineHeadersFirst,
_CheckJSONFiles,
_CheckNoexceptAnnotations,
_RunTestsWithVPythonSpec,
_CheckPythonLiterals,
]
return sum([check(input_api, output_api) for check in checks], [])
def _SkipTreeCheck(input_api, output_api):
"""Check the env var whether we want to skip tree check.
Only skip if include/v8-version.h has been updated."""
src_version = 'include/v8-version.h'
if not input_api.AffectedSourceFiles(
lambda file: file.LocalPath() == src_version):
return False
return input_api.environ.get('PRESUBMIT_TREE_CHECK') == 'skip'
def _CheckCommitMessageBugEntry(input_api, output_api):
"""Check that bug entries are well-formed in commit message."""
bogus_bug_msg = (
'Bogus BUG entry: {}. Please specify prefix:number for v8 or chromium '
'(e.g. chromium:12345) or b/number for buganizer.')
results = []
for bug in (input_api.change.BUG or '').split(','):
bug = bug.strip()
if 'none'.startswith(bug.lower()):
continue
if ':' not in bug and not bug.startswith('b/'):
try:
if int(bug) < 10000000:
if int(bug) > 200000:
prefix_guess = 'chromium'
else:
prefix_guess = 'v8'
results.append(
'BUG entry requires issue tracker prefix, e.g. {}:{}'.format(
prefix_guess, bug))
except ValueError:
results.append(bogus_bug_msg.format(bug))
elif not re.match(r'\w+[:\/]\d+', bug):
results.append(bogus_bug_msg.format(bug))
return [output_api.PresubmitError(r) for r in results]
def _CheckJSONFiles(input_api, output_api):
def FilterFile(affected_file):
return input_api.FilterSourceFile(
affected_file,
files_to_check=(r'.+\.json',))
results = []
for f in input_api.AffectedFiles(
file_filter=FilterFile, include_deletes=False):
with open(f.LocalPath()) as j:
try:
json.load(j)
except Exception as e:
results.append('JSON validation failed for {}. Error:\n{}'.format(
f.LocalPath(), e))
return [output_api.PresubmitError(r) for r in results]
def _CheckNoexceptAnnotations(input_api, output_api):
"""
Checks that all user-defined constructors and assignment operators are marked
V8_NOEXCEPT.
This is required for standard containers to pick the right constructors. Our
macros (like MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS) add this automatically.
Omitting it at some places can result in weird compiler errors if this is
mixed with other classes that have the annotation.
TODO(clemensb): This check should eventually be enabled for all files via
tools/presubmit.py (https://crbug.com/v8/8616).
"""
def FilterFile(affected_file):
files_to_skip = _EXCLUDED_PATHS + (
# Skip api.cc since we cannot easily add the 'noexcept' annotation to
# public methods.
r'src[\\\/]api[\\\/]api\.cc',
# Skip src/bigint/ because it's meant to be V8-independent.
r'src[\\\/]bigint[\\\/].*',
)
return input_api.FilterSourceFile(
affected_file,
files_to_check=(r'src[\\\/].*\.cc', r'src[\\\/].*\.h',
r'test[\\\/].*\.cc', r'test[\\\/].*\.h'),
files_to_skip=files_to_skip)
# matches any class name.
class_name = r'\b([A-Z][A-Za-z0-9_:]*)(?:::\1)?'
# initial class name is potentially followed by this to declare an assignment
# operator.
potential_assignment = r'(?:&\s+(?:\1::)?operator=)?\s*'
# matches an argument list that contains only a reference to a class named
# like the first capture group, potentially const.
single_class_ref_arg = r'\(\s*(?:const\s+)?\1(?:::\1)?&&?[^,;)]*\)'
# matches anything but a sequence of whitespaces followed by either
# V8_NOEXCEPT or "= delete".
not_followed_by_noexcept = r'(?!\s+(?:V8_NOEXCEPT|=\s+delete)\b)'
full_pattern = r'^.*?' + class_name + potential_assignment + \
single_class_ref_arg + not_followed_by_noexcept + '.*?$'
regexp = input_api.re.compile(full_pattern, re.MULTILINE)
errors = []
for f in input_api.AffectedFiles(file_filter=FilterFile,
include_deletes=False):
with open(f.LocalPath()) as fh:
for match in re.finditer(regexp, fh.read()):
errors.append(f'in {f.LocalPath()}: {match.group().strip()}')
if errors:
return [output_api.PresubmitPromptOrNotify(
'Copy constructors, move constructors, copy assignment operators and '
'move assignment operators should be marked V8_NOEXCEPT.\n'
'Please report false positives on https://crbug.com/v8/8616.',
errors)]
return []
def CheckChangeOnUpload(input_api, output_api):
results = []
results.extend(_CommonChecks(input_api, output_api))
return results
def CheckChangeOnCommit(input_api, output_api):
results = []
results.extend(_CommonChecks(input_api, output_api))
results.extend(input_api.canned_checks.CheckChangeHasDescription(
input_api, output_api))
if not _SkipTreeCheck(input_api, output_api):
results.extend(input_api.canned_checks.CheckTreeIsOpen(
input_api, output_api,
json_url='http://v8-status.appspot.com/current?format=json'))
return results

40
deps/v8/README.md vendored Normal file
View File

@ -0,0 +1,40 @@
V8 JavaScript Engine
=============
V8 is Google's open source JavaScript engine.
V8 implements ECMAScript as specified in ECMA-262.
V8 is written in C++ and is used in Google Chrome, the open source
browser from Google.
V8 can run standalone, or can be embedded into any C++ application.
V8 Project page: https://v8.dev/docs
Getting the Code
=============
Checkout [depot tools](http://www.chromium.org/developers/how-tos/install-depot-tools), and run
fetch v8
This will checkout V8 into the directory `v8` and fetch all of its dependencies.
To stay up to date, run
git pull origin
gclient sync
For fetching all branches, add the following into your remote
configuration in `.git/config`:
fetch = +refs/branch-heads/*:refs/remotes/branch-heads/*
fetch = +refs/tags/*:refs/tags/*
Contributing
=============
Please follow the instructions mentioned at
[v8.dev/docs/contribute](https://v8.dev/docs/contribute).

4
deps/v8/RISCV_OWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
brice.dobry@futurewei.com
peng.w@rioslab.org
qiuji@iscas.ac.cn
yahan@iscas.ac.cn

4
deps/v8/S390_OWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
junyan@redhat.com
joransiu@ca.ibm.com
midawson@redhat.com
mfarazma@redhat.com

186
deps/v8/WATCHLISTS vendored Normal file
View File

@ -0,0 +1,186 @@
# Copyright 2013 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Watchlist Rules
# Refer: http://dev.chromium.org/developers/contributing-code/watchlists
# IMPORTANT: The regular expression filepath is tested against each path using
# re.search, so it is not usually necessary to add .*.
{
'WATCHLIST_DEFINITIONS': {
'api': {
'filepath': 'include/',
},
'snapshot': {
'filepath': 'src/snapshot/',
},
'devtools': {
'filepath': 'src/debug/' \
'|src/inspector/' \
'|src/profiler/' \
'|src/libsampler/' \
'|src/tracing/' \
'|include/js_protocol.pdl' \
'|include/v8-inspector*\.h',
},
'baseline': {
'filepath': 'src/baseline/',
},
'flags': {
'filepath': 'src/flags/flag-definitions.h',
},
'heap_changes': {
'filepath': 'src/heap/',
},
'arm': {
'filepath': '/arm/',
},
'merges': {
'filepath': '.',
},
'wasm': {
'filepath': 'src/wasm/' \
'|src/compiler/wasm',
},
'value_serializer': {
'filepath': 'src/value-serializer',
},
'maglev': {
'filepath': 'src/maglev/',
},
'compiler': {
'filepath': 'src/compiler',
},
'parser': {
'filepath': 'src/ast/' \
'|src/parsing/',
},
'tracing': {
'filepath': 'src/tracing/',
},
'ieee754': {
'filepath': 'src/base/ieee754\.(cc|h)' \
'|src/base/overflowing-math.h' \
'|LICENSE.fdlibm',
},
'regexp': {
'filepath': 'src/.*regexp',
},
'bazel': {
'filepath': 'BUILD.gn' \
'|BUILD.bazel' \
'|WORKSPACE' \
'|bazel/',
},
'cppgc': {
'filepath': 'src/heap/cppgc/' \
'|src/heap/cppgc-js/' \
'|include/cppgc/' \
'|test/unittests/heap/cppgc/' \
'|test/unittests/heap/cppgc-js/',
},
'trap-handler': {
'filepath': 'src/trap-handler/',
},
},
'WATCHLISTS': {
'maglev': [
'leszeks+watch@chromium.org',
'verwaest+watch@chromium.org',
'victorgomes+watch@chromium.org',
],
'compiler': [
'dmercadier+watch@chromium.org',
],
'snapshot': [
'jgruber+watch@chromium.org',
],
'devtools': [
'devtools-reviews+v8@chromium.org',
],
'baseline': [
'leszeks+watch@chromium.org',
'verwaest+watch@chromium.org',
],
'flags': [
'v8-flag-updates@chromium.org',
],
'heap_changes': [
'hpayer@chromium.org',
'mlippautz+watch@chromium.org',
],
'arm': [
'v8-mips-ports@googlegroups.com',
'v8-ppc-ports@googlegroups.com',
'v8-risc-v-ports@chromium.org',
],
'merges': [
# Only enabled on branches created with tools/release/create_release.py
'v8-merges@googlegroups.com',
],
'wasm': [
'wasm-v8@google.com',
],
'value_serializer': [
'jbroman+watch@chromium.org',
],
'parser': [
'marja+watch@chromium.org',
],
'tracing': [
'alph+watch@chromium.org',
'lpy+v8tracing@chromium.org',
'fmeawad@chromium.org',
'cbruni+watch@chromium.org',
],
'ieee754': [
'rtoy+watch@chromium.org',
'hongchan+watch@chromium.org',
],
'regexp': [
'jgruber+watch@chromium.org',
'pthier+watch@chromium.org',
],
'bazel': [
'victorgomes+watch@chromium.org',
],
'api': [
'cbruni+watch@chromium.org',
],
'cppgc': [
'oilpan-reviews+v8@chromium.org',
],
'trap-handler': [
'ahaas@chromium.org',
'clemensb@chromium.org',
'mark@chromium.org',
'mseaborn@chromium.org',
],
},
}

113
deps/v8/bazel/BUILD.icu vendored Normal file
View File

@ -0,0 +1,113 @@
# 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.
filegroup(
name = "icudata",
srcs = ["common/icudtl.dat"],
visibility = ["//visibility:public"],
)
cc_library(
name = "icuuc",
srcs = glob([
"source/common/**/*.h",
"source/common/**/*.cpp",
]),
copts = select({
"@platforms//os:windows": [
"/wd4005", # Macro redefinition.
"/wd4068", # Unknown pragmas.
"/wd4267", # Conversion from size_t on 64-bits.
"/utf-8", # ICU source files are in UTF-8.
],
"//conditions:default": [
"-Wno-deprecated-declarations",
],
}),
data = [":icudata"],
defines = [
"HAVE_DLOPEN=0",
"UCONFIG_ONLY_HTML_CONVERSION=1",
"U_CHARSET_IS_UTF8=1",
"U_USING_ICU_NAMESPACE=0",
"U_ENABLE_DYLOAD=0",
"USE_CHROMIUM_ICU=1",
"U_ENABLE_TRACING=1",
"U_ENABLE_RESOURCE_TRACING=0",
"UNISTR_FROM_STRING_EXPLICIT=",
"UNISTR_FROM_CHAR_EXPLICIT=",
] + select({
"@platforms//os:windows": [
"U_STATIC_IMPLEMENTATION",
"UNICODE",
"_UNICODE",
],
"//conditions:default": [],
}),
includes = [
"source/common",
"source/i18n",
],
local_defines = [
"U_COMMON_IMPLEMENTATION",
"U_ICUDATAENTRY_IN_COMMON",
],
tags = ["requires-rtti"],
alwayslink = 1,
)
cc_library(
name = "icui18n",
srcs = glob([
"source/i18n/**/*.h",
"source/i18n/**/*.cpp",
]),
copts = select({
"@platforms//os:windows": [
"/wd4005", # Macro redefinition.
"/wd4068", # Unknown pragmas.
"/wd4267", # Conversion from size_t on 64-bits.
"/utf-8", # ICU source files are in UTF-8.
],
"//conditions:default": [
"-Wno-deprecated-declarations",
],
}),
local_defines = [
"U_I18N_IMPLEMENTATION",
],
deps = [":icuuc"],
alwayslink = 1,
)
cc_library(
name = "icu",
srcs = [
"source/stubdata/stubdata.cpp",
"source/stubdata/stubdata.h",
],
hdrs = glob([
"source/common/unicode/*.h",
"source/i18n/unicode/*.h",
]),
copts = select({
"@platforms//os:windows": [
"/wd4005", # Macro redefinition.
"/wd4068", # Unknown pragmas.
"/wd4267", # Conversion from size_t on 64-bits.
"/utf-8", # ICU source files are in UTF-8.
],
"//conditions:default": [],
}),
include_prefix = "third_party/icu",
local_defines = [
"U_COMMON_IMPLEMENTATION",
],
visibility = ["//visibility:public"],
deps = [
":icui18n",
":icuuc",
],
alwayslink = 1,
)

15
deps/v8/bazel/BUILD.ittapi vendored Normal file
View File

@ -0,0 +1,15 @@
cc_library(
name = "lib_ittapi",
srcs = [
"third_party/ittapi/include/ittnotify.h",
"third_party/ittapi/include/jitprofiling.h",
"third_party/ittapi/src/ittnotify/ittnotify_config.h",
"third_party/ittapi/src/ittnotify/jitprofiling.c",
],
hdrs = [
"third_party/ittapi/include/ittnotify.h",
"third_party/ittapi/src/ittnotify/ittnotify_types.h",
],
copts = ["-Iexternal/intel_ittapi/third_party/ittapi/include"],
visibility = ["//visibility:public"],
)

4
deps/v8/bazel/OWNERS vendored Normal file
View File

@ -0,0 +1,4 @@
# Google3 V8 owners
ahaas@chromium.org
cbruni@chromium.org
victorgomes@chromium.org

359
deps/v8/bazel/config/BUILD.bazel vendored Normal file
View File

@ -0,0 +1,359 @@
# 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.
load("@bazel_skylib//lib:selects.bzl", "selects")
load(
":v8-target-cpu.bzl",
"v8_configure_target_cpu",
"v8_target_cpu",
)
package(
default_visibility = [
"//visibility:public",
],
)
config_setting(
name = "is_fastbuild",
values = {
"compilation_mode": "fastbuild",
},
)
config_setting(
name = "is_opt",
values = {
"compilation_mode": "opt",
},
)
config_setting(
name = "is_debug",
values = {
"compilation_mode": "dbg",
},
)
selects.config_setting_group(
name = "is_opt_android",
match_all = [
":is_opt",
":is_android",
],
)
config_setting(
name = "platform_cpu_x64",
constraint_values = ["@platforms//cpu:x86_64"],
)
config_setting(
name = "platform_cpu_ia32",
constraint_values = ["@platforms//cpu:x86_32"],
)
config_setting(
name = "platform_cpu_arm64",
constraint_values = ["@platforms//cpu:aarch64"],
)
config_setting(
name = "platform_cpu_arm",
constraint_values = ["@platforms//cpu:arm"],
)
config_setting(
name = "platform_cpu_s390x",
constraint_values = ["@platforms//cpu:s390x"],
)
config_setting(
name = "platform_cpu_riscv64",
constraint_values = ["@platforms//cpu:riscv64"],
)
config_setting(
name = "platform_cpu_ppc64le",
constraint_values = ["@platforms//cpu:ppc"],
)
v8_target_cpu(
name = "v8_target_cpu",
build_setting_default = "none",
)
config_setting(
name = "v8_host_target_is_none",
flag_values = {
":v8_target_cpu": "none",
},
)
v8_configure_target_cpu(
name = "x64",
matching_configs = [":platform_cpu_x64"],
)
v8_configure_target_cpu(
name = "ia32",
matching_configs = [":platform_cpu_ia32"],
)
v8_configure_target_cpu(
name = "arm64",
matching_configs = [":platform_cpu_arm64"],
)
v8_configure_target_cpu(
name = "arm",
matching_configs = [":platform_cpu_arm"],
)
v8_configure_target_cpu(
name = "s390x",
matching_configs = [":platform_cpu_s390x"],
)
v8_configure_target_cpu(
name = "riscv64",
matching_configs = [":platform_cpu_riscv64"],
)
v8_configure_target_cpu(
name = "ppc64le",
matching_configs = [":platform_cpu_ppc64le"],
)
selects.config_setting_group(
name = "v8_target_is_32_bits",
match_any = [
":v8_target_ia32",
":v8_target_arm",
],
)
# Running arm64 simulator on x64 host.
selects.config_setting_group(
name = "v8_arm64_simulator",
match_all = [
":v8_target_arm64",
":is_x64",
],
)
config_setting(
name = "is_linux",
constraint_values = ["@platforms//os:linux"],
)
config_setting(
name = "is_android",
constraint_values = ["@platforms//os:android"],
)
config_setting(
name = "is_macos",
constraint_values = ["@platforms//os:macos"],
)
config_setting(
name = "is_windows",
constraint_values = ["@platforms//os:windows"],
)
selects.config_setting_group(
name = "is_64bit",
match_any = [
":v8_target_arm64",
":is_x64",
":is_arm64",
":is_s390x",
":is_riscv64",
":is_ppc64le",
],
)
selects.config_setting_group(
name = "is_windows_64bit",
match_all = [
":is_64bit",
":is_windows",
],
)
selects.config_setting_group(
name = "is_posix",
match_any = [
":is_linux",
":is_android",
":is_macos",
],
)
selects.config_setting_group(
name = "is_not_android",
match_any = [
":is_windows",
":is_linux",
":is_macos",
]
)
selects.config_setting_group(
name = "is_posix_x64",
match_all = [
":is_posix",
":is_x64",
],
)
selects.config_setting_group(
name = "is_inline_asm_x64",
match_all = [
":is_posix",
":is_x64",
],
)
selects.config_setting_group(
name = "is_inline_asm_ia32",
match_all = [
":is_posix",
":is_ia32",
],
)
selects.config_setting_group(
name = "is_inline_asm_arm64",
match_all = [
":is_posix",
":is_arm64",
],
)
selects.config_setting_group(
name = "is_inline_asm_arm",
match_all = [
":is_posix",
":is_arm",
],
)
selects.config_setting_group(
name = "is_inline_asm_s390x",
match_all = [
":is_posix",
":is_s390x",
],
)
selects.config_setting_group(
name = "is_inline_asm_riscv64",
match_all = [
":is_posix",
":is_riscv64",
],
)
selects.config_setting_group(
name = "is_inline_asm_ppc64le",
match_all = [
":is_posix",
":is_ppc64le",
],
)
selects.config_setting_group(
name = "is_msvc_asm_x64",
match_all = [
":is_windows",
":is_x64",
],
)
selects.config_setting_group(
name = "is_msvc_asm_ia32",
match_all = [
":is_windows",
":is_ia32",
],
)
selects.config_setting_group(
name = "is_msvc_asm_arm64",
match_all = [
":is_windows",
":is_arm64",
],
)
config_setting(
name = "is_compiler_default",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "compiler",
},
)
selects.config_setting_group(
name = "is_compiler_default_on_linux",
match_all = [
":is_compiler_default",
":is_linux",
],
)
selects.config_setting_group(
name = "is_compiler_default_on_macos",
match_all = [
":is_compiler_default",
":is_macos",
],
)
config_setting(
name = "is_compiler_clang",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "clang",
},
)
selects.config_setting_group(
name = "is_clang",
match_any = [
":is_compiler_default_on_macos",
":is_compiler_clang",
],
)
selects.config_setting_group(
name = "is_clang_s390x",
match_all = [
":is_clang",
":is_s390x",
],
)
config_setting(
name = "is_compiler_gcc",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "gcc",
},
)
selects.config_setting_group(
name = "is_gcc",
match_any = [
":is_compiler_default_on_linux",
":is_compiler_gcc",
],
)
selects.config_setting_group(
name = "is_gcc_fastbuild",
match_all = [
":is_gcc",
":is_fastbuild",
],
)

61
deps/v8/bazel/config/v8-target-cpu.bzl vendored Normal file
View File

@ -0,0 +1,61 @@
# 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.
"""Build rules to choose the v8 target architecture."""
load("@bazel_skylib//lib:selects.bzl", "selects")
V8CpuTypeInfo = provider(
doc = "A singleton provider that specifies the V8 target CPU type",
fields = {
"value": "The V8 Target CPU selected.",
},
)
def _host_target_cpu_impl(ctx):
allowed_values = ["arm", "arm64", "ia32", "ppc64le", "riscv64", "s390x", "x64", "none"]
cpu_type = ctx.build_setting_value
if cpu_type in allowed_values:
return V8CpuTypeInfo(value = cpu_type)
else:
fail("Error setting " + str(ctx.label) + ": invalid v8 target cpu '" +
cpu_type + "'. Allowed values are " + str(allowed_values))
v8_target_cpu = rule(
implementation = _host_target_cpu_impl,
build_setting = config.string(flag = True),
doc = "CPU that V8 will generate code for.",
)
def v8_configure_target_cpu(name, matching_configs):
selects.config_setting_group(
name = "is_" + name,
match_any = matching_configs,
)
# If v8_target_cpu flag is set to 'name'
native.config_setting(
name = "v8_host_target_is_" + name,
flag_values = {
":v8_target_cpu": name,
},
)
# Default target if no v8_host_target flag is set.
selects.config_setting_group(
name = "v8_target_is_" + name,
match_all = [
":v8_host_target_is_none",
":is_" + name,
],
)
# Select either the default target or the flag.
selects.config_setting_group(
name = "v8_target_" + name,
match_any = [
":v8_host_target_is_" + name,
":v8_target_is_" + name,
],
)

617
deps/v8/bazel/defs.bzl vendored Normal file
View File

@ -0,0 +1,617 @@
# 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.
"""
This module contains helper functions to compile V8.
"""
FlagInfo = provider("The value of an option.",
fields = ["value"])
def _options_impl(ctx):
return FlagInfo(value = ctx.build_setting_value)
_create_option_flag = rule(
implementation = _options_impl,
build_setting = config.bool(flag = True),
)
_create_option_string = rule(
implementation = _options_impl,
build_setting = config.string(flag = True),
)
_create_option_int = rule(
implementation = _options_impl,
build_setting = config.int(flag = True),
)
def v8_flag(name, default = False):
_create_option_flag(name = name, build_setting_default = default)
native.config_setting(name = "is_" + name, flag_values = {name: "True"})
native.config_setting(name = "is_not_" + name, flag_values = {name: "False"})
def v8_string(name, default = ""):
_create_option_string(name = name, build_setting_default = default)
def v8_int(name, default = 0):
_create_option_int(name = name, build_setting_default = default)
def _custom_config_impl(ctx):
defs = []
defs.append("V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=" +
str(ctx.attr._v8_typed_array_max_size_in_heap[FlagInfo].value))
context = cc_common.create_compilation_context(defines = depset(defs))
return [CcInfo(compilation_context = context)]
v8_custom_config = rule(
implementation = _custom_config_impl,
attrs = {
"_v8_typed_array_max_size_in_heap": attr.label(default = ":v8_typed_array_max_size_in_heap"),
},
)
def _config_impl(ctx):
hdrs = []
# Add headers
for h in ctx.attr.hdrs:
hdrs += h[DefaultInfo].files.to_list()
defs = []
# Add conditional_defines
for f, d in ctx.attr.conditional_defines.items():
if f[FlagInfo].value:
defs.append(d)
# Add defines
for d in ctx.attr.defines:
defs.append(d)
context = cc_common.create_compilation_context(
defines = depset(
defs,
transitive = [dep[CcInfo].compilation_context.defines for dep in ctx.attr.deps],
),
headers = depset(
hdrs,
transitive = [dep[CcInfo].compilation_context.headers for dep in ctx.attr.deps],
),
)
return [CcInfo(compilation_context = context)]
v8_config = rule(
implementation = _config_impl,
attrs = {
"conditional_defines": attr.label_keyed_string_dict(),
"defines": attr.string_list(),
"deps": attr.label_list(),
"hdrs": attr.label_list(allow_files = True),
},
)
def _default_args():
return struct(
deps = [":define_flags"],
defines = select({
"@v8//bazel/config:is_windows": [
"UNICODE",
"_UNICODE",
"_CRT_RAND_S",
"_WIN32_WINNT=0x0A00", # Override bazel default to Windows 10
],
"//conditions:default": [],
}),
copts = select({
"@v8//bazel/config:is_posix": [
"-fPIC",
"-fno-strict-aliasing",
"-Werror",
"-Wextra",
"-Wno-unneeded-internal-declaration",
"-Wno-unknown-warning-option", # b/330781959
"-Wno-cast-function-type-mismatch", # b/330781959
"-Wno-bitwise-instead-of-logical",
"-Wno-builtin-assume-aligned-alignment",
"-Wno-unused-parameter",
"-Wno-implicit-int-float-conversion",
"-Wno-deprecated-copy",
"-Wno-non-virtual-dtor",
"-isystem .",
],
"//conditions:default": [],
}) + select({
"@v8//bazel/config:is_clang": [
"-Wno-invalid-offsetof",
"-Wno-deprecated-this-capture",
"-Wno-deprecated-declarations",
"-std=c++20",
],
"@v8//bazel/config:is_gcc": [
"-Wno-extra",
"-Wno-array-bounds",
"-Wno-class-memaccess",
"-Wno-comments",
"-Wno-deprecated-declarations",
"-Wno-implicit-fallthrough",
"-Wno-int-in-bool-context",
"-Wno-maybe-uninitialized",
"-Wno-mismatched-new-delete",
"-Wno-redundant-move",
"-Wno-return-type",
"-Wno-stringop-overflow",
"-Wno-deprecated-this-capture",
# Use GNU dialect, because GCC doesn't allow using
# ##__VA_ARGS__ when in standards-conforming mode.
"-std=gnu++2a",
],
"@v8//bazel/config:is_windows": [
"/std:c++20",
],
"//conditions:default": [],
}) + select({
"@v8//bazel/config:is_gcc_fastbuild": [
# Non-debug builds without optimizations fail because
# of recursive inlining of "always_inline" functions.
"-O1",
],
"//conditions:default": [],
}) + select({
"@v8//bazel/config:is_clang_s390x": [
"-fno-integrated-as",
],
"//conditions:default": [],
}) + select({
"@v8//bazel/config:is_opt_android": [
"-fvisibility=hidden",
"-fvisibility-inlines-hidden",
],
"//conditions:default": [
],
}),
includes = ["include"],
linkopts = select({
"@v8//bazel/config:is_windows": [
"Winmm.lib",
"DbgHelp.lib",
"Advapi32.lib",
],
"@v8//bazel/config:is_macos": ["-pthread"],
"//conditions:default": ["-Wl,--no-as-needed -ldl -latomic -pthread"],
}) + select({
":should_add_rdynamic": ["-rdynamic"],
"//conditions:default": [],
}),
)
ENABLE_I18N_SUPPORT_DEFINES = [
"-DV8_INTL_SUPPORT",
"-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC",
# src/regexp/regexp-compiler-tonode.cc uses an unsafe ICU method and
# access a character implicitly.
"-DUNISTR_FROM_CHAR_EXPLICIT=",
]
def _should_emit_noicu_and_icu(noicu_srcs, noicu_deps, noicu_defines, icu_srcs, icu_deps, icu_defines):
return noicu_srcs != [] or noicu_deps != [] or noicu_defines != [] or icu_srcs != [] or icu_deps != [] or icu_defines != []
# buildifier: disable=function-docstring
def v8_binary(
name,
srcs,
deps = [],
defines = [],
includes = [],
copts = [],
linkopts = [],
noicu_srcs = [],
noicu_deps = [],
noicu_defines = [],
icu_srcs = [],
icu_deps = [],
icu_defines = [],
**kwargs):
default = _default_args()
if _should_emit_noicu_and_icu(noicu_srcs, noicu_deps, noicu_defines, icu_srcs, icu_deps, icu_defines):
native.cc_binary(
name = "noicu/" + name,
srcs = srcs + noicu_srcs,
deps = deps + noicu_deps + default.deps,
defines = defines + noicu_defines + default.defines,
includes = includes + ["noicu/"] + default.includes,
copts = copts + default.copts,
linkopts = linkopts + default.linkopts,
**kwargs
)
native.cc_binary(
name = "icu/" + name,
srcs = srcs + icu_srcs,
deps = deps + icu_deps + default.deps,
includes = includes + ["icu/"] + default.includes,
defines = defines + icu_defines + default.defines,
copts = copts + default.copts + ENABLE_I18N_SUPPORT_DEFINES,
linkopts = linkopts + default.linkopts,
**kwargs
)
else:
native.cc_binary(
name = name,
srcs = srcs,
deps = deps + default.deps,
defines = defines + default.defines,
includes = includes + default.includes,
copts = copts + default.copts,
linkopts = linkopts + default.linkopts,
**kwargs
)
# buildifier: disable=function-docstring
def v8_library(
name,
srcs,
deps = [],
includes = [],
copts = [],
linkopts = [],
noicu_srcs = [],
noicu_deps = [],
noicu_defines = [],
icu_srcs = [],
icu_deps = [],
icu_defines = [],
**kwargs):
default = _default_args()
if _should_emit_noicu_and_icu(noicu_srcs, noicu_deps, noicu_defines, icu_srcs, icu_deps, icu_defines):
native.cc_library(
name = name + "_noicu",
srcs = srcs + noicu_srcs,
deps = deps + noicu_deps + default.deps,
includes = includes + ["noicu/"] + default.includes,
copts = copts + default.copts,
linkopts = linkopts + default.linkopts,
alwayslink = 1,
linkstatic = 1,
**kwargs
)
# Alias target used because of cc_library bug in bazel on windows
# https://github.com/bazelbuild/bazel/issues/14237
# TODO(victorgomes): Remove alias once bug is fixed
native.alias(
name = "noicu/" + name,
actual = name + "_noicu",
)
native.cc_library(
name = name + "_icu",
srcs = srcs + icu_srcs,
deps = deps + icu_deps + default.deps,
includes = includes + ["icu/"] + default.includes,
copts = copts + default.copts + ENABLE_I18N_SUPPORT_DEFINES,
linkopts = linkopts + default.linkopts,
alwayslink = 1,
linkstatic = 1,
**kwargs
)
# Alias target used because of cc_library bug in bazel on windows
# https://github.com/bazelbuild/bazel/issues/14237
# TODO(victorgomes): Remove alias once bug is fixed
native.alias(
name = "icu/" + name,
actual = name + "_icu",
)
else:
native.cc_library(
name = name,
srcs = srcs,
deps = deps + default.deps,
includes = includes + default.includes,
copts = copts + default.copts,
linkopts = linkopts + default.linkopts,
alwayslink = 1,
linkstatic = 1,
**kwargs
)
# Use a single generator target for torque definitions and initializers. We can
# split the set of outputs by using OutputGroupInfo, that way we do not need to
# run the torque generator twice.
def _torque_files_impl(ctx):
# Allow building V8 as a dependency: workspace_root points to external/v8
# when building V8 from a different repository and empty otherwise.
v8root = ctx.label.workspace_root
if v8root == "":
v8root = "."
# Arguments
args = []
args += ctx.attr.args
args.append("-o")
args.append(ctx.bin_dir.path + "/" + v8root + "/" + ctx.attr.prefix + "/torque-generated")
args.append("-strip-v8-root")
args.append("-v8-root")
args.append(v8root)
# Sources
args += [f.path for f in ctx.files.srcs]
# Generate/declare output files
defs = []
inits = []
for src in ctx.files.srcs:
root, _period, _ext = src.path.rpartition(".")
# Strip v8root
if root[:len(v8root)] == v8root:
root = root[len(v8root):]
file = ctx.attr.prefix + "/torque-generated/" + root
defs.append(ctx.actions.declare_file(file + "-tq-inl.inc"))
defs.append(ctx.actions.declare_file(file + "-tq.inc"))
defs.append(ctx.actions.declare_file(file + "-tq.cc"))
inits.append(ctx.actions.declare_file(file + "-tq-csa.cc"))
inits.append(ctx.actions.declare_file(file + "-tq-csa.h"))
defs += [ctx.actions.declare_file(ctx.attr.prefix + "/torque-generated/" + f) for f in ctx.attr.definition_extras]
inits += [ctx.actions.declare_file(ctx.attr.prefix + "/torque-generated/" + f) for f in ctx.attr.initializer_extras]
outs = defs + inits
ctx.actions.run(
outputs = outs,
inputs = ctx.files.srcs,
arguments = args,
executable = ctx.executable.tool,
mnemonic = "GenTorqueFiles",
progress_message = "Generating Torque files",
)
return [
DefaultInfo(files = depset(outs)),
OutputGroupInfo(
initializers = depset(inits),
definitions = depset(defs),
),
]
_v8_torque_files = rule(
implementation = _torque_files_impl,
# cfg = v8_target_cpu_transition,
attrs = {
"prefix": attr.string(mandatory = True),
"srcs": attr.label_list(allow_files = True, mandatory = True),
"definition_extras": attr.string_list(),
"initializer_extras": attr.string_list(),
"tool": attr.label(
allow_files = True,
executable = True,
cfg = "exec",
),
"args": attr.string_list(),
},
)
def v8_torque_files(name, noicu_srcs, icu_srcs, args, definition_extras, initializer_extras):
_v8_torque_files(
name = "noicu/" + name,
prefix = "noicu",
srcs = noicu_srcs,
args = args,
definition_extras = definition_extras,
initializer_extras = initializer_extras,
tool = select({
"@v8//bazel/config:v8_target_is_32_bits": ":noicu/torque_non_pointer_compression",
"//conditions:default": ":noicu/torque",
}),
)
_v8_torque_files(
name = "icu/" + name,
prefix = "icu",
srcs = icu_srcs,
args = args,
definition_extras = definition_extras,
initializer_extras = initializer_extras,
tool = select({
"@v8//bazel/config:v8_target_is_32_bits": ":icu/torque_non_pointer_compression",
"//conditions:default": ":icu/torque",
}),
)
def _v8_target_cpu_transition_impl(settings,
attr, # @unused
):
# Check for an existing v8_target_cpu flag.
if "@v8//bazel/config:v8_target_cpu" in settings:
if settings["@v8//bazel/config:v8_target_cpu"] != "none":
return {}
# Auto-detect target architecture based on the --cpu flag.
mapping = {
"haswell": "x64",
"k8": "x64",
"x86_64": "x64",
"darwin": "x64",
"darwin_x86_64": "x64",
"x64_windows": "x64",
"x86": "ia32",
"aarch64": "arm64",
"arm64-v8a": "arm64",
"arm": "arm64",
"darwin_arm64": "arm64",
"armeabi-v7a": "arm32",
"s390x": "s390x",
"riscv64": "riscv64",
"ppc64": "ppc64le",
}
v8_target_cpu = mapping[settings["//command_line_option:cpu"]]
return {"@v8//bazel/config:v8_target_cpu": v8_target_cpu}
# Set the v8_target_cpu to be the correct architecture given the cpu specified
# on the command line.
v8_target_cpu_transition = transition(
implementation = _v8_target_cpu_transition_impl,
inputs = ["@v8//bazel/config:v8_target_cpu", "//command_line_option:cpu"],
outputs = ["@v8//bazel/config:v8_target_cpu"],
)
def _mksnapshot(ctx):
prefix = ctx.attr.prefix
suffix = ctx.attr.suffix
outs = [
ctx.actions.declare_file(prefix + "/snapshot" + suffix + ".cc"),
ctx.actions.declare_file(prefix + "/embedded" + suffix + ".S"),
]
ctx.actions.run(
outputs = outs,
inputs = [],
arguments = [
"--embedded_variant=Default",
"--target_os",
ctx.attr.target_os,
"--startup_src",
outs[0].path,
"--embedded_src",
outs[1].path,
] + ctx.attr.args,
executable = ctx.executable.tool,
progress_message = "Running mksnapshot",
)
return [DefaultInfo(files = depset(outs))]
_v8_mksnapshot = rule(
implementation = _mksnapshot,
attrs = {
"args": attr.string_list(),
"tool": attr.label(
mandatory = True,
allow_files = True,
executable = True,
cfg = "exec",
),
"target_os": attr.string(mandatory = True),
"prefix": attr.string(mandatory = True),
"suffix": attr.string(mandatory = True),
},
cfg = v8_target_cpu_transition,
)
def v8_mksnapshot(name, args, suffix = ""):
_v8_mksnapshot(
name = "noicu/" + name,
args = args,
prefix = "noicu",
tool = ":noicu/mksnapshot" + suffix,
suffix = suffix,
target_os = select({
"@v8//bazel/config:is_macos": "mac",
"@v8//bazel/config:is_windows": "win",
"//conditions:default": "",
}),
)
_v8_mksnapshot(
name = "icu/" + name,
args = args,
prefix = "icu",
tool = ":icu/mksnapshot" + suffix,
suffix = suffix,
target_os = select({
"@v8//bazel/config:is_macos": "mac",
"@v8//bazel/config:is_windows": "win",
"//conditions:default": "",
}),
)
def _quote(val):
if val[0] == '"' and val[-1] == '"':
fail("String", val, "already quoted")
return '"' + val + '"'
def _kv_bool_pair(k, v):
return _quote(k) + ": " + v
def _json(kv_pairs):
content = "{"
for (k, v) in kv_pairs[:-1]:
content += _kv_bool_pair(k, v) + ", "
(k, v) = kv_pairs[-1]
content += _kv_bool_pair(k, v)
content += "}\n"
return content
def build_config_content(cpu, icu):
arch = cpu
if cpu == 'x86':
arch = 'ia32'
return _json([
("arch", arch),
("asan", "false"),
("atomic_object_field_writes", "false"),
("cet_shadow_stack", "false"),
("cfi", "false"),
("clang_coverage", "false"),
("clang", "true"),
("code_comments", "false"),
("component_build", "false"),
("concurrent_marking", "false"),
("conservative_stack_scanning", "false"),
("current_cpu", cpu),
("dcheck_always_on", "false"),
("debug_code", "false"),
("DEBUG_defined", "false"),
("debugging_features", "false"),
("dict_property_const_tracking", "false"),
("direct_handle", "false"),
("disassembler", "false"),
("full_debug", "false"),
("gdbjit", "false"),
("has_jitless", "false"),
("has_maglev", "true"),
("has_turbofan", "true"),
("has_webassembly", "false"),
("has_wasm_interpreter", "false"),
("i18n", icu),
("is_android", "false"),
("is_ios", "false"),
("js_shared_memory", "false"),
("leaptiering", "true"),
("lite_mode", "false"),
("local_off_stack_check", "false"),
("lower_limits_mode", "false"),
("memory_corruption_api", "false"),
("mips_arch_variant", '""'),
("mips_use_msa", "false"),
("msan", "false"),
("official_build", "false"),
("pointer_compression_shared_cage", "false"),
("pointer_compression", "true"),
("runtime_call_stats", "false"),
("sandbox", "false"),
("shared_ro_heap", "false"),
("simd_mips", "false"),
("simulator_run", "false"),
("single_generation", "false"),
("slow_dchecks", "false"),
("target_cpu", cpu),
("tsan", "false"),
("ubsan", "false"),
("use_sanitizer", "false"),
("v8_cfi", "false"),
("v8_current_cpu", cpu),
("v8_target_cpu", cpu),
("verify_csa", "false"),
("verify_heap", "false"),
("verify_predictable", "false"),
("wasm_random_fuzzers", "false"),
("write_barriers", "false"),
])
# TODO(victorgomes): Create a rule (instead of a macro), that can
# dynamically populate the build config.
def v8_build_config(name, arch):
cpu = '"' + arch + '"'
native.genrule(
name = "noicu/" + name,
outs = ["noicu/" + name + ".json"],
cmd = "echo '" + build_config_content(cpu, "false") + "' > \"$@\"",
)
native.genrule(
name = "icu/" + name,
outs = ["icu/" + name + ".json"],
cmd = "echo '" + build_config_content(cpu, "true") + "' > \"$@\"",
)

1
deps/v8/bazel/requirements.in vendored Normal file
View File

@ -0,0 +1 @@
jinja2

81
deps/v8/bazel/requirements.txt vendored Normal file
View File

@ -0,0 +1,81 @@
#
# This file is autogenerated by pip-compile with python 3.9
# To update, run:
#
# pip-compile --generate-hashes requirements.in
#
jinja2==3.0.3 \
--hash=sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8 \
--hash=sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7
# via -r requirements.in
markupsafe==2.0.1 \
--hash=sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298 \
--hash=sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64 \
--hash=sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b \
--hash=sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194 \
--hash=sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567 \
--hash=sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff \
--hash=sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724 \
--hash=sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74 \
--hash=sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646 \
--hash=sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35 \
--hash=sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6 \
--hash=sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a \
--hash=sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6 \
--hash=sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad \
--hash=sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26 \
--hash=sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38 \
--hash=sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac \
--hash=sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7 \
--hash=sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6 \
--hash=sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047 \
--hash=sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75 \
--hash=sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f \
--hash=sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b \
--hash=sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135 \
--hash=sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8 \
--hash=sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a \
--hash=sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a \
--hash=sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1 \
--hash=sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9 \
--hash=sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864 \
--hash=sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914 \
--hash=sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee \
--hash=sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f \
--hash=sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18 \
--hash=sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8 \
--hash=sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2 \
--hash=sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d \
--hash=sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b \
--hash=sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b \
--hash=sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86 \
--hash=sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6 \
--hash=sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f \
--hash=sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb \
--hash=sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833 \
--hash=sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28 \
--hash=sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e \
--hash=sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415 \
--hash=sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902 \
--hash=sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f \
--hash=sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d \
--hash=sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9 \
--hash=sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d \
--hash=sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145 \
--hash=sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066 \
--hash=sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c \
--hash=sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1 \
--hash=sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a \
--hash=sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207 \
--hash=sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f \
--hash=sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53 \
--hash=sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd \
--hash=sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134 \
--hash=sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85 \
--hash=sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9 \
--hash=sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5 \
--hash=sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94 \
--hash=sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509 \
--hash=sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51 \
--hash=sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872
# via jinja2

View File

@ -0,0 +1,53 @@
"""
Exposes the rule v8_binary_non_pointer_compression, which forces a label
to be compiled without pointer compression.
"""
def _v8_disable_pointer_compression(settings, attr):
return {
"//:v8_enable_pointer_compression": "False",
}
v8_disable_pointer_compression = transition(
implementation = _v8_disable_pointer_compression,
inputs = [],
outputs = ["//:v8_enable_pointer_compression"],
)
# The implementation of transition_rule: all this does is copy the
# cc_binary's output to its own output and propagate its runfiles
# and executable to use for "$ bazel run".
#
# This makes transition_rule as close to a pure wrapper of cc_binary
# as possible.
def _v8_binary_non_pointer_compression(ctx):
binary = ctx.attr.binary[0]
outfile = ctx.actions.declare_file(ctx.label.name)
cc_binary_outfile = binary[DefaultInfo].files.to_list()[0]
ctx.actions.run_shell(
inputs = [cc_binary_outfile],
outputs = [outfile],
command = "cp %s %s" % (cc_binary_outfile.path, outfile.path),
)
return [
DefaultInfo(
executable = outfile,
data_runfiles = binary[DefaultInfo].data_runfiles,
),
]
# The purpose of this rule is to transition to a config where v8_target_cpu is
# set to the appropriate architecture, which will remain in place through exec
# transitions, so mksnapshot can for instance build on x64 but for arm64.
v8_binary_non_pointer_compression = rule(
implementation = _v8_binary_non_pointer_compression,
attrs = {
# This is the cc_binary whose deps will select() on that feature.
# Note specificaly how it's configured with v8_target_cpu_transition, which
# ensures that setting propagates down the graph.
"binary": attr.label(cfg = v8_disable_pointer_compression),
},
# Making this executable means it works with "$ bazel run".
executable = True,
)

1
deps/v8/build_overrides/OWNERS vendored Normal file
View File

@ -0,0 +1 @@
file:../INFRA_OWNERS

65
deps/v8/build_overrides/build.gni vendored Normal file
View File

@ -0,0 +1,65 @@
# Copyright 2016 The V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Variable that can be used to support multiple build scenarios, like having
# Chromium specific targets in a client project's GN file etc.
build_with_chromium = false
# Variable that can be used to support multiple build scenarios, like when
# V8 is embedded within a target.
build_with_v8_embedder = false
# Not all of V8's dependencies are available in V8's Node.js build.
build_with_node = false
# Used by perfetto to distinguish from its own standalone build and the
# chromium build.
perfetto_build_with_embedder = true
# We use Perfetto's Trace Processor to convert traces to the legacy JSON
# format.
enable_perfetto_trace_processor = true
# When building with chromium, determines whether we want to also use the
# perfetto library from chromium instead declaring our own.
use_perfetto_client_library = false
# Uncomment these to specify a different NDK location and version in
# non-Chromium builds.
# default_android_ndk_root = "//third_party/android_ndk"
# default_android_ndk_version = "r10e"
# Some non-Chromium builds don't support building java targets.
enable_java_templates = false
# Enables assertions on safety checks in libc++.
enable_safe_libcxx = true
# Enable assertions on safety checks, also in libstdc++
#
# In case the C++ standard library implementation used is libstdc++, then
# enable its own hardening checks.
enable_safe_libstdcxx = true
# Allows different projects to specify their own suppressions files.
asan_suppressions_file = "//build/sanitizers/asan_suppressions.cc"
lsan_suppressions_file = "//build/sanitizers/lsan_suppressions.cc"
tsan_suppressions_file = "//build/sanitizers/tsan_suppressions.cc"
# Skip assertions about 4GiB file size limit.
ignore_elf32_limitations = true
if (host_os == "mac") {
_result = exec_script("//build/mac/should_use_hermetic_xcode.py",
[ target_os ],
"value")
assert(_result != 2,
"Do not allow building targets with the default" +
"hermetic toolchain if the minimum OS version is not met.")
assert(_result != 3,
"iOS does not support building with a hermetic toolchain. " +
"Please install Xcode.")
use_system_xcode = _result == 0
}

15
deps/v8/build_overrides/gtest.gni vendored Normal file
View File

@ -0,0 +1,15 @@
# Copyright 2016 The V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Exclude support for registering main function in multi-process tests.
gtest_include_multiprocess = false
# Exclude support for platform-specific operations across unit tests.
gtest_include_platform_test = false
# Exclude support for testing Objective C code on OS X and iOS.
gtest_include_objc_support = false
# Exclude support for flushing coverage files on iOS.
gtest_include_ios_coverage = false

View File

@ -0,0 +1,47 @@
# 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.
# Import into partition_alloc, some required variable definitions.
import("//build/config/compiler/compiler.gni")
import("//build/config/dcheck_always_on.gni")
import("//build/config/sanitizers/sanitizers.gni")
# partition_alloc is performance critical and it should generally be optimized
# for speed, even in debug mode.
partition_alloc_remove_configs =
[ "//build/config/compiler:default_optimization" ]
partition_alloc_add_configs = [ "//build/config/compiler:optimize_speed" ]
partition_alloc_enable_arc_config = "//build/config/compiler:enable_arc"
# MSVC's cl.exe compiler is not supported.
_supported_compiler = is_clang || !is_win
# Windows: debug CRT is not yet compatible with the allocator shim.
# https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/free-dbg
_supported_build_type = !is_win || (!is_component_build && !is_debug)
_supported_platform =
is_android || is_chromeos || is_fuchsia || is_linux || is_mac || is_win
# Sanitizers are already replacing the allocator with their own. We shouldn't
# enable partition_alloc when this happens
_use_sanitizer = is_asan || is_cfi || is_msan || is_tsan || is_ubsan
_supported = _supported_compiler && _supported_build_type &&
_supported_platform && !_use_sanitizer
use_partition_alloc_as_malloc_default = _supported
use_allocator_shim_default = _supported
enable_backup_ref_ptr_support_default = _supported
put_ref_count_in_previous_slot_default = true
enable_backup_ref_ptr_slow_checks_default = false
enable_dangling_raw_ptr_checks_default = _supported
assert_cpp20_default = true
# V8 doesn't use raw_ptr, so it doesn't really matter. Still, it has to be
# defined, so we take the configuration used by v8.
raw_ptr_zero_on_construct_default = true
raw_ptr_zero_on_move_default = true
raw_ptr_zero_on_destruct_default = false

7
deps/v8/codereview.settings vendored Normal file
View File

@ -0,0 +1,7 @@
PROJECT: v8
GERRIT_HOST: True
CODE_REVIEW_SERVER: https://codereview.chromium.org
CC_LIST: v8-reviews@googlegroups.com
VIEW_VC: https://chromium.googlesource.com/v8/v8/+/
STATUS: http://v8-status.appspot.com/status
RUN_POST_UPLOAD_HOOK: True

4
deps/v8/custom_deps/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*
!.gitignore
!OWNERS
!README.md

1
deps/v8/custom_deps/OWNERS vendored Normal file
View File

@ -0,0 +1 @@
file:../INFRA_OWNERS

2
deps/v8/custom_deps/README.md vendored Normal file
View File

@ -0,0 +1,2 @@
Common directory for custom dependencies pulled in via .gclient custom_deps.
All subdirectories are ignored by git by default.

1
deps/v8/docs/OWNERS vendored Normal file
View File

@ -0,0 +1 @@
hpayer@chromium.org

1
deps/v8/docs/README.md vendored Normal file
View File

@ -0,0 +1 @@
The documentation for V8 can be found at [v8.dev/docs](https://v8.dev/docs).

34
deps/v8/gni/Info.plist vendored Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UISupportedInterfaceOrientation</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

5
deps/v8/gni/OWNERS vendored Normal file
View File

@ -0,0 +1,5 @@
file:../INFRA_OWNERS
per-file v8.cml=victorgomes@chromium.org
per-file release_branch_toggle.gni=v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com
per-file release_branch_toggle.gni=vahl@chromium.org

7
deps/v8/gni/release_branch_toggle.gni vendored Normal file
View File

@ -0,0 +1,7 @@
# 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.
declare_args() {
v8_is_on_release_branch = true
}

124
deps/v8/gni/snapshot_toolchain.gni vendored Normal file
View File

@ -0,0 +1,124 @@
# Copyright 2015 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import("//build/config/v8_target_cpu.gni")
declare_args() {
# The v8 snapshot needs to be built by code that is compiled with a
# toolchain that matches the bit-width of the target CPU, but runs on
# the host.
v8_snapshot_toolchain = ""
}
# Try to infer the appropriate snapshot toolchain for the v8_current_cpu
# where possible.
#
# Assume that v8_target_cpu (and hence v8_current_cpu) has been validated
# as supported on the current host CPU and OS in v8_target_cpu.gni. The
# logic below is complicated enough without also needing to do input
# validation.
#
# There are test cases for this code posted as an attachment to
# https://crbug.com/625353.
if (v8_snapshot_toolchain == "") {
if (current_os == host_os && current_cpu == host_cpu) {
# This is not a cross-compile, so build the snapshot with the current
# toolchain.
v8_snapshot_toolchain = current_toolchain
} else if (current_os == host_os && current_cpu == "x86" &&
host_cpu == "x64") {
# This is an x64 -> x86 cross-compile, but x64 hosts can usually run x86
# binaries built for the same OS, so build the snapshot with the current
# toolchain here, too.
v8_snapshot_toolchain = current_toolchain
} else if (current_os == host_os && host_cpu == "arm64" &&
current_cpu == "arm") {
# Trying to compile 32-bit arm on arm64. Good luck!
v8_snapshot_toolchain = current_toolchain
} else if (host_cpu == "x64" && v8_current_cpu == "mips64") {
# We don't support snapshot generation for big-endian targets,
# therefore snapshots will need to be built using native mksnapshot
# in combination with qemu
v8_snapshot_toolchain = current_toolchain
} else if (host_cpu == current_cpu) {
# Cross-build from same ISA on one OS to another. For example:
# * targeting win/x64 on a linux/x64 host
# * targeting win/arm64 on a mac/arm64 host
v8_snapshot_toolchain = host_toolchain
} else if (host_cpu == "arm64" && current_cpu == "x64") {
# Cross-build from arm64 to intel (likely on an Apple Silicon mac).
v8_snapshot_toolchain =
"//build/toolchain/${host_os}:clang_arm64_v8_$v8_current_cpu"
} else if (host_cpu == "x64") {
# This is a cross-compile from an x64 host to either a non-Intel target
# cpu or to 32-bit x86 on a different target OS.
assert(v8_current_cpu != "x64", "handled by host_cpu == current_cpu branch")
if (v8_current_cpu == "x86") {
_cpus = v8_current_cpu
} else if (v8_current_cpu == "arm64" || v8_current_cpu == "mips64el" ||
v8_current_cpu == "riscv64" || v8_current_cpu == "loong64") {
if (is_win && v8_current_cpu == "arm64") {
# set _cpus to blank for Windows ARM64 so host_toolchain could be
# selected as snapshot toolchain later.
_cpus = ""
} else {
_cpus = "x64_v8_${v8_current_cpu}"
}
} else if (v8_current_cpu == "arm" || v8_current_cpu == "riscv32") {
_cpus = "x86_v8_${v8_current_cpu}"
} else {
# This branch should not be reached; leave _cpus blank so the assert
# below will fail.
_cpus = ""
}
if (_cpus != "") {
v8_snapshot_toolchain = "//build/toolchain/${host_os}:clang_${_cpus}"
} else if (is_win && v8_current_cpu == "arm64") {
# cross compile Windows arm64 with host toolchain.
v8_snapshot_toolchain = host_toolchain
}
} else if (host_cpu == "arm64" && current_cpu == "arm64" &&
host_os == "mac") {
# cross compile iOS arm64 with host_toolchain
v8_snapshot_toolchain = host_toolchain
}
}
assert(v8_snapshot_toolchain != "",
"Do not know how to build a snapshot for $current_toolchain " +
"on $host_os $host_cpu")
# We reuse the snapshot toolchain for building torque and other generators to
# avoid building v8_libbase on the host more than once. On mips with big endian,
# the snapshot toolchain is the target toolchain and, hence, can't be used.
v8_generator_toolchain = v8_snapshot_toolchain
if (host_cpu == "x64" && v8_current_cpu == "mips64") {
v8_generator_toolchain = "//build/toolchain/linux:clang_x64"
}

78
deps/v8/gni/split_static_library.gni vendored Normal file
View File

@ -0,0 +1,78 @@
# Copyright 2019 the V8 project authors. All rights reserved.
# Copyright 2016 The Chromium 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("//build/config/compiler/compiler.gni")
template("split_static_library") {
assert(defined(invoker.split_count),
"Must define split_count for split_static_library")
# In many conditions the number of inputs will be 1 (because the
# count will be conditional on platform or configuration) and for
# some build configurations it's unnecessary to split libraries
# since the tooling will never create files of a problematic size.
if (invoker.split_count == 1 || use_lld) {
static_library(target_name) {
forward_variables_from(invoker, "*")
}
} else {
group_name = target_name
generated_static_libraries = []
current_library_index = 0
foreach(current_sources, split_list(invoker.sources, invoker.split_count)) {
current_name = "${target_name}_$current_library_index"
assert(
current_sources != [],
"Your values for splitting a static library generate one that has no sources.")
generated_static_libraries += [ ":$current_name" ]
static_library(current_name) {
# Generated static library shard gets everything but sources (which
# we're redefining) and visibility (which is set to be the group
# below).
forward_variables_from(invoker,
"*",
[
"check_includes",
"sources",
"visibility",
])
sources = current_sources
visibility = [ ":$group_name" ]
# When splitting a target's sources up into a series of static
# libraries, those targets will naturally include headers from each
# other arbitrarily. We could theoretically generate a web of
# dependencies and allow_circular_includes_from between all pairs of
# targets, but that's very cumbersome. Typical usage in Chrome is that
# only official Windows builds use split static libraries due to the
# Visual Studio size limits, and this means we'll still get header
# checking coverage for the other configurations.
check_includes = false
# Uniquify the output name if one is specified.
if (defined(invoker.output_name)) {
output_name = "${invoker.output_name}_$current_library_index"
}
}
current_library_index = current_library_index + 1
}
group(group_name) {
public_deps = generated_static_libraries
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
}
}
}
set_defaults("split_static_library") {
configs = default_compiler_configs
}

21
deps/v8/gni/v8.cml vendored Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2022 The V8 project authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
{
include: [ "syslog/client.shard.cml" ],
program: {
runner: "elf",
binary: "d8",
},
use: [
{
protocol: [
"fuchsia.kernel.VmexResource",
],
},
{
storage: "tmp",
path: "/tmp",
},
],
}

462
deps/v8/gni/v8.gni vendored Normal file
View File

@ -0,0 +1,462 @@
# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/chrome_build.gni")
import("//build/config/compiler/pgo/pgo.gni")
import("//build/config/gclient_args.gni")
import("//build/config/ios/config.gni")
import("//build/config/ios/ios_sdk_overrides.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/config/v8_target_cpu.gni")
import("//build_overrides/build.gni")
import("release_branch_toggle.gni")
import("split_static_library.gni")
if (is_ios) {
import("//build/config/apple/mobile_config.gni") # For `target_platform`.
}
declare_args() {
# Includes files needed for correctness fuzzing.
v8_correctness_fuzzer = false
# Adds additional compile target for building multiple architectures at once.
v8_multi_arch_build = false
# Indicate if valgrind was fetched as a custom deps to make it available on
# swarming.
v8_has_valgrind = false
# Indicate if gcmole was fetched as a hook to make it available on swarming.
v8_gcmole = false
# Turns on compiler optimizations in V8 in Debug build.
v8_optimized_debug = true
# Support for backtrace_symbols on linux.
v8_enable_backtrace = ""
# Use external files for startup data blobs:
# the JS builtins sources and the start snapshot.
v8_use_external_startup_data = ""
# Includes profiles to optimize builtins.
v8_enable_builtins_optimization = ""
# Turns on all V8 debug features. Enables running V8 in a pseudo debug mode
# within a release Chrome.
v8_enable_debugging_features = is_debug
# Enable ECMAScript Internationalization API. Enabling this feature will
# add a dependency on the ICU library.
v8_enable_i18n_support = true
# Use static libraries instead of source_sets.
v8_static_library = false
# Enable monolithic static library for embedders.
v8_monolithic = false
# Expose public symbols for native modules of Node.js and Electron. Default
# is false.
v8_expose_public_symbols = ""
# Deprecated for v8_expose_public_symbols.
v8_expose_symbols = false
# Implement tracing using Perfetto (https://perfetto.dev).
v8_use_perfetto = false
# Override global symbol level setting for v8.
v8_symbol_level = symbol_level
# Enable WebAssembly debugging via GDB-remote protocol.
v8_enable_wasm_gdb_remote_debugging = false
# Lite mode disables a number of performance optimizations to reduce memory
# at the cost of performance.
# Sets -DV8_LITE_MODE.
v8_enable_lite_mode = false
# We use target_os == "ios" here because it isn't equivalent to is_ios
# (is_ios is based on host_os).
if (target_os == "ios") {
if (target_platform == "iphoneos") {
# iOS executable code pages is in 17.4 SDK.
# TODO(dtapuska): Change this to an assert.
v8_enable_lite_mode = ios_deployment_target != "17.4"
} else if (target_platform == "tvos") {
# tvOS runs in single process mode and is not allowed to use JIT.
# TODO(crbug.com/394710095): Enable the v8 lite mode to run v8 with the
# jitless mode on tvOS.
v8_enable_lite_mode = true
}
}
# Enable the Turbofan compiler.
# Sets -dV8_ENABLE_TURBOFAN.
v8_enable_turbofan = ""
# Enable the Maglev compiler.
# Sets -dV8_ENABLE_MAGLEV
v8_enable_maglev = ""
# Include support for WebAssembly. If disabled, the 'WebAssembly' global
# will not be available, and embedder APIs to generate WebAssembly modules
# will fail. Also, asm.js will not be translated to WebAssembly and will be
# executed as standard JavaScript instead.
# Sets -dV8_ENABLE_WEBASSEMBLY.
v8_enable_webassembly = ""
# Enable 256-bit long vector re-vectorization pass in WASM compilation pipeline.
v8_enable_wasm_simd256_revec = false
# Enable runtime call stats.
v8_enable_runtime_call_stats = !v8_is_on_release_branch
# Add fuzzilli fuzzer support.
v8_fuzzilli = false
# Enable FuzzTest
v8_enable_fuzztest = !build_with_v8_embedder &&
!(defined(build_with_node) && build_with_node) &&
!(is_win && is_component_build) && is_clang
# Scan the call stack conservatively during garbage collection.
v8_enable_conservative_stack_scanning = false
# Use direct pointers in handles (v8::internal::Handle and v8::Local).
v8_enable_direct_handle = ""
# Check for off-stack allocated local handles.
v8_enable_local_off_stack_check = false
v8_enable_google_benchmark = false
cppgc_is_standalone = false
# Enables certain checks on API level functionality.
cppgc_enable_api_checks = is_debug || dcheck_always_on
# Enable slow checks on API level functionality.
cppgc_enable_slow_api_checks = false
# Enable object names in cppgc for profiling purposes.
cppgc_enable_object_names = is_chrome_for_testing
# Enable young generation in cppgc.
cppgc_enable_young_generation = false
# Enables a slim write barrier that only performs a single check in the fast
# path and delegates all further checks to a slow path call. This is fast
# in a setting with few slow-path checks, i.e., with disabled young generation
# GC.
cppgc_enable_slim_write_barrier = true
# Enable pointer compression in cppgc.
cppgc_enable_pointer_compression = false
# Enable support for larger cages, up to 16GB.
# iOS cannot mmap above 8GB, so use the smaller cage.
cppgc_enable_larger_cage = !is_ios
# Enable advanced BigInt algorithms, costing about 10-30 KB binary size
# depending on platform. Disabled on Android to save binary size.
v8_advanced_bigint_algorithms = !is_android
# TODO: macros for determining endian type are clang specific.
v8_use_libm_trig_functions = is_clang
# Location of icu.
v8_icu_path = "//third_party/icu"
# Location of zlib.
v8_zlib_path = "//third_party/zlib"
# Enable pointer compression (sets -dV8_COMPRESS_POINTERS).
v8_enable_pointer_compression = ""
v8_enable_pointer_compression_shared_cage = ""
v8_enable_31bit_smis_on_64bit_arch = false
# Change code emission and runtime features to be CET shadow-stack compliant
# (incomplete and experimental).
v8_enable_cet_shadow_stack = false
# Emit CET IBT landing pad instructions in JIT generated code (experimental).
v8_enable_cet_ibt = false
# Use memory sealing to protect various global memory mappings for CFI
# (experimental).
# TODO(sroettger): enable by default once we have bot support for testing.
v8_enable_memory_sealing = false
# Sets -DV8_ENABLE_ETW_STACK_WALKING. Enables ETW Stack Walking
v8_enable_etw_stack_walking = is_win
}
if (v8_use_external_startup_data == "") {
# If not specified as a gn arg, use external startup data by default if
# we're not on ios.
v8_use_external_startup_data = !is_ios
}
if (v8_enable_backtrace == "") {
v8_enable_backtrace = is_debug && !v8_optimized_debug
}
# Chromium is configured to use the perfetto client library, v8 should also
# use perfetto for tracing.
if (build_with_chromium) {
v8_use_perfetto = true
}
# Includes profiles to optimize builtins if
# * it is a Chromium build, and
# * Chromium builds with optimization.
# If no profiles are downloaded during gclient runhooks, optimization fails
# silently.
if (v8_enable_builtins_optimization == "") {
v8_enable_builtins_optimization = build_with_chromium && chrome_pgo_phase == 2
}
# TODO(jgruber): Move v8_jitless from BUILD.gn here as these
# all depend on each other and really should be derived from
# v8_jitless.
# WebAssembly is enabled by default, except in lite mode.
if (v8_enable_webassembly == "") {
v8_enable_webassembly = !v8_enable_lite_mode
}
assert(!(v8_enable_webassembly && v8_enable_lite_mode),
"Webassembly is not available in lite mode.")
if (v8_enable_pointer_compression == "") {
v8_enable_pointer_compression =
v8_current_cpu == "arm64" || v8_current_cpu == "x64" ||
v8_current_cpu == "loong64"
}
# The Wasm interpreter is currently supported only on arm64 and x64, on
# Windows, Linux and MacOS.
is_drumbrake_supported =
v8_enable_webassembly && v8_enable_pointer_compression &&
(v8_current_cpu == "x64" || v8_current_cpu == "arm64") &&
(target_os == "win" || target_os == "linux" || target_os == "mac")
# Turbofan is enabled by default, except in lite mode.
if (v8_enable_turbofan == "") {
v8_enable_turbofan = !v8_enable_lite_mode
}
assert(v8_enable_turbofan || !v8_enable_webassembly,
"Webassembly is not available when Turbofan is disabled.")
# Direct internal handles and direct locals are enabled by default if
# conservative stack scanning is enabled.
if (v8_enable_direct_handle == "") {
v8_enable_direct_handle = v8_enable_conservative_stack_scanning
}
# Points to // in v8 stand-alone or to //v8/ in chromium. We need absolute
# paths for all configs in templates as they are shared in different
# subdirectories.
v8_path_prefix = get_path_info("../", "abspath")
v8_inspector_js_protocol = v8_path_prefix + "/include/js_protocol.pdl"
###############################################################################
# Templates
#
# Common configs to remove or add in all v8 targets.
v8_remove_configs = []
v8_add_configs = [
v8_path_prefix + ":features",
v8_path_prefix + ":toolchain",
v8_path_prefix + ":strict_warnings",
]
if (is_debug && !v8_optimized_debug) {
v8_remove_configs += [ "//build/config/compiler:default_optimization" ]
v8_add_configs += [ "//build/config/compiler:no_optimize" ]
} else {
v8_remove_configs += [ "//build/config/compiler:default_optimization" ]
# TODO(crbug.com/621335) Rework this so that we don't have the confusion
# between "optimize_speed" and "optimize_max".
if (((is_posix && !is_android) || is_win) && !using_sanitizer) {
v8_add_configs += [ "//build/config/compiler:optimize_speed" ]
} else {
v8_add_configs += [ "//build/config/compiler:optimize_max" ]
}
}
if (!is_debug) {
v8_remove_configs += [
# Too much performance impact, unclear security benefit.
"//build/config/compiler:default_init_stack_vars",
]
}
if (v8_symbol_level != symbol_level) {
v8_remove_configs += [ "//build/config/compiler:default_symbols" ]
if (v8_symbol_level == 0) {
v8_add_configs += [ "//build/config/compiler:no_symbols" ]
} else if (v8_symbol_level == 1) {
v8_add_configs += [ "//build/config/compiler:minimal_symbols" ]
} else if (v8_symbol_level == 2) {
v8_add_configs += [ "//build/config/compiler:symbols" ]
} else {
assert(false)
}
}
if ((is_posix || is_fuchsia) && (v8_enable_backtrace || v8_monolithic)) {
v8_remove_configs += [ "//build/config/gcc:symbol_visibility_hidden" ]
v8_add_configs += [ "//build/config/gcc:symbol_visibility_default" ]
}
# On MIPS gcc_target_rpath and ldso_path might be needed for all builds.
if (target_cpu == "mips64el" || target_cpu == "mips64") {
v8_add_configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
}
if (!build_with_chromium && is_clang) {
v8_remove_configs += [ "//build/config/clang:find_bad_constructs" ]
}
# All templates should be kept in sync.
template("v8_source_set") {
if (defined(invoker.split_count) && invoker.split_count > 1 &&
defined(v8_static_library) && v8_static_library && is_win) {
link_target_type = "split_static_library"
} else if (defined(v8_static_library) && v8_static_library) {
link_target_type = "static_library"
} else {
link_target_type = "source_set"
}
target(link_target_type, target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
configs -= v8_remove_configs
configs += v8_add_configs
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
configs += invoker.configs
}
}
template("v8_header_set") {
source_set(target_name) {
forward_variables_from(invoker, "*", [ "configs" ])
configs -= v8_remove_configs
configs += v8_add_configs
configs += invoker.configs
}
}
template("v8_executable") {
if (is_ios) {
import("//build/config/ios/rules.gni")
ios_app_bundle(target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
configs -= v8_remove_configs
configs += v8_add_configs
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
configs += invoker.configs
deps += [ v8_path_prefix + ":v8_dump_build_config" ]
# Provide sensible defaults in case invoker did not define any of those
# required variables.
if (!defined(info_plist) && !defined(info_plist_target)) {
info_plist = v8_path_prefix + "/gni/Info.plist"
}
bundle_identifier = "$ios_app_bundle_id_prefix.chrome.unittests.dev"
}
} else {
executable(target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
configs -= v8_remove_configs
configs += v8_add_configs
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
configs += invoker.configs
if (is_linux || is_chromeos) {
# For enabling ASLR.
ldflags = [ "-pie" ]
}
deps += [ v8_path_prefix + ":v8_dump_build_config" ]
if (is_win && !v8_enable_cet_shadow_stack) {
configs -= [ "//build/config/compiler:cet_shadow_stack" ]
}
}
}
}
template("v8_component") {
component(target_name) {
output_name = target_name
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
configs -= v8_remove_configs
configs += v8_add_configs
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
configs += invoker.configs
}
}
template("v8_shared_library") {
shared_library(target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
configs -= v8_remove_configs
configs += v8_add_configs
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
if (defined(invoker.configs)) {
configs += invoker.configs
}
}
}
template("v8_static_library") {
static_library(target_name) {
complete_static_lib = true
forward_variables_from(invoker, "*", [ "configs" ])
configs -= v8_remove_configs
configs -= [ "//build/config/compiler:thin_archive" ]
configs += v8_add_configs
configs += invoker.configs
}
}

72
deps/v8/include/APIDesign.md vendored Normal file
View File

@ -0,0 +1,72 @@
# The V8 public C++ API
# Overview
The V8 public C++ API aims to support four use cases:
1. Enable applications that embed V8 (called the embedder) to configure and run
one or more instances of V8.
2. Expose ECMAScript-like capabilities to the embedder.
3. Enable the embedder to interact with ECMAScript by exposing API objects.
4. Provide access to the V8 debugger (inspector).
# Configuring and running an instance of V8
V8 requires access to certain OS-level primitives such as the ability to
schedule work on threads, or allocate memory.
The embedder can define how to access those primitives via the v8::Platform
interface. While V8 bundles a basic implementation, embedders are highly
encouraged to implement v8::Platform themselves.
Currently, the v8::ArrayBuffer::Allocator is passed to the v8::Isolate factory
method, however, conceptually it should also be part of the v8::Platform since
all instances of V8 should share one allocator.
Once the v8::Platform is configured, an v8::Isolate can be created. All
further interactions with V8 should explicitly reference the v8::Isolate they
refer to. All API methods should eventually take an v8::Isolate parameter.
When a given instance of V8 is no longer needed, it can be destroyed by
disposing the respective v8::Isolate. If the embedder wishes to free all memory
associated with the v8::Isolate, it has to first clear all global handles
associated with that v8::Isolate.
# ECMAScript-like capabilities
In general, the C++ API shouldn't enable capabilities that aren't available to
scripts running in V8. Experience has shown that it's not possible to maintain
such API methods in the long term. However, capabilities also available to
scripts, i.e., ones that are defined in the ECMAScript standard are there to
stay, and we can safely expose them to embedders.
The C++ API should also be pleasant to use, and not require learning new
paradigms. Similarly to how the API exposed to scripts aims to provide good
ergonomics, we should aim to provide a reasonable developer experience for this
API surface.
ECMAScript makes heavy use of exceptions, however, V8's C++ code doesn't use
C++ exceptions. Therefore, all API methods that can throw exceptions should
indicate so by returning a v8::Maybe&lt;&gt; or v8::MaybeLocal&lt;&gt; result,
and by taking a v8::Local&lt;v8::Context&gt; parameter that indicates in which
context a possible exception should be thrown.
# API objects
V8 allows embedders to define special objects that expose additional
capabilities and APIs to scripts. The most prominent example is exposing the
HTML DOM in Blink. Other examples are e.g. node.js. It is less clear what kind
of capabilities we want to expose via this API surface. As a rule of thumb, we
want to expose operations as defined in the WebIDL and HTML spec: we
assume that those requirements are somewhat stable, and that they are a
superset of the requirements of other embedders including node.js.
Ideally, the API surfaces defined in those specs hook into the ECMAScript spec
which in turn guarantees long-term stability of the API.
# The V8 inspector
All debugging capabilities of V8 should be exposed via the inspector protocol.
The exception to this are profiling features exposed via v8-profiler.h.
Changes to the inspector protocol need to ensure backwards compatibility and
commitment to maintain.

12
deps/v8/include/DEPS vendored Normal file
View File

@ -0,0 +1,12 @@
include_rules = [
# v8-inspector-protocol.h depends on generated files under include/inspector.
"+inspector",
"+cppgc/common.h",
# Used by v8-cppgc.h to bridge to cppgc.
"+cppgc/custom-space.h",
"+cppgc/heap-statistics.h",
"+cppgc/internal/conditional-stack-allocated.h",
"+cppgc/internal/write-barrier.h",
"+cppgc/visitor.h",
"+perfetto",
]

14
deps/v8/include/DIR_METADATA vendored Normal file
View File

@ -0,0 +1,14 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Blink>JavaScript>API"
}
buganizer_public: {
component_id: 1456124
}

24
deps/v8/include/OWNERS vendored Normal file
View File

@ -0,0 +1,24 @@
adamk@chromium.org
cbruni@chromium.org
leszeks@chromium.org
mlippautz@chromium.org
verwaest@chromium.org
yangguo@chromium.org
per-file *DEPS=file:../COMMON_OWNERS
per-file v8-internal.h=file:../COMMON_OWNERS
per-file v8-debug.h=file:../src/debug/OWNERS
per-file js_protocol.pdl=file:../src/inspector/OWNERS
per-file v8-inspector*=file:../src/inspector/OWNERS
per-file v8-inspector*=file:../src/inspector/OWNERS
per-file v8-profiler.h=file:../src/profiler/OWNERS
# Needed by the auto_tag builder
per-file v8-version.h=v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com
# For branch updates:
per-file v8-version.h=file:../INFRA_OWNERS
per-file v8-version.h=vahl@chromium.org

9
deps/v8/include/cppgc/DEPS vendored Normal file
View File

@ -0,0 +1,9 @@
include_rules = [
"-include",
"+v8config.h",
"+v8-platform.h",
"+v8-source-location.h",
"+cppgc",
"-src",
"+libplatform/libplatform.h",
]

2
deps/v8/include/cppgc/OWNERS vendored Normal file
View File

@ -0,0 +1,2 @@
bikineev@chromium.org
omerkatz@chromium.org

135
deps/v8/include/cppgc/README.md vendored Normal file
View File

@ -0,0 +1,135 @@
# Oilpan: C++ Garbage Collection
Oilpan is an open-source garbage collection library for C++ that can be used stand-alone or in collaboration with V8's JavaScript garbage collector.
Oilpan implements mark-and-sweep garbage collection (GC) with limited compaction (for a subset of objects).
**Key properties**
- Trace-based garbage collection;
- Incremental and concurrent marking;
- Incremental and concurrent sweeping;
- Precise on-heap memory layout;
- Conservative on-stack memory layout;
- Allows for collection with and without considering stack;
- Non-incremental and non-concurrent compaction for selected spaces;
See the [Hello World](https://chromium.googlesource.com/v8/v8/+/main/samples/cppgc/hello-world.cc) example on how to get started using Oilpan to manage C++ code.
Oilpan follows V8's project organization, see e.g. on how we accept [contributions](https://v8.dev/docs/contribute) and [provide a stable API](https://v8.dev/docs/api).
## Threading model
Oilpan features thread-local garbage collection and assumes heaps are not shared among threads.
In other words, objects are accessed and ultimately reclaimed by the garbage collector on the same thread that allocates them.
This allows Oilpan to run garbage collection in parallel with mutators running in other threads.
References to objects belonging to another thread's heap are modeled using cross-thread roots.
This is even true for on-heap to on-heap references.
Oilpan heaps may generally not be accessed from different threads unless otherwise noted.
## Heap partitioning
Oilpan's heaps are partitioned into spaces.
The space for an object is chosen depending on a number of criteria, e.g.:
- Objects over 64KiB are allocated in a large object space
- Objects can be assigned to a dedicated custom space.
Custom spaces can also be marked as compactable.
- Other objects are allocated in one of the normal page spaces bucketed depending on their size.
## Precise and conservative garbage collection
Oilpan supports two kinds of GCs:
1. **Conservative GC.**
A GC is called conservative when it is executed while the regular native stack is not empty.
In this case, the native stack might contain references to objects in Oilpan's heap, which should be kept alive.
The GC scans the native stack and treats the pointers discovered via the native stack as part of the root set.
This kind of GC is considered imprecise because values on stack other than references may accidentally appear as references to on-heap object, which means these objects will be kept alive despite being in practice unreachable from the application as an actual reference.
2. **Precise GC.**
A precise GC is triggered at the end of an event loop, which is controlled by an embedder via a platform.
At this point, it is guaranteed that there are no on-stack references pointing to Oilpan's heap.
This means there is no risk of confusing other value types with references.
Oilpan has precise knowledge of on-heap object layouts, and so it knows exactly where pointers lie in memory.
Oilpan can just start marking from the regular root set and collect all garbage precisely.
## Atomic, incremental and concurrent garbage collection
Oilpan has three modes of operation:
1. **Atomic GC.**
The entire GC cycle, including all its phases (e.g. see [Marking](#Marking-phase) and [Sweeping](#Sweeping-phase)), are executed back to back in a single pause.
This mode of operation is also known as Stop-The-World (STW) garbage collection.
It results in the most jank (due to a single long pause), but is overall the most efficient (e.g. no need for write barriers).
2. **Incremental GC.**
Garbage collection work is split up into multiple steps which are interleaved with the mutator, i.e. user code chunked into tasks.
Each step is a small chunk of work that is executed either as dedicated tasks between mutator tasks or, as needed, during mutator tasks.
Using incremental GC introduces the need for write barriers that record changes to the object graph so that a consistent state is observed and no objects are accidentally considered dead and reclaimed.
The incremental steps are followed by a smaller atomic pause to finalize garbage collection.
The smaller pause times, due to smaller chunks of work, helps with reducing jank.
3. **Concurrent GC.**
This is the most common type of GC.
It builds on top of incremental GC and offloads much of the garbage collection work away from the mutator thread and on to background threads.
Using concurrent GC allows the mutator thread to spend less time on GC and more on the actual mutator.
## Marking phase
The marking phase consists of the following steps:
1. Mark all objects in the root set.
2. Mark all objects transitively reachable from the root set by calling `Trace()` methods defined on each object.
3. Clear out all weak handles to unreachable objects and run weak callbacks.
The marking phase can be executed atomically in a stop-the-world manner, in which all 3 steps are executed one after the other.
Alternatively, it can also be executed incrementally/concurrently.
With incremental/concurrent marking, step 1 is executed in a short pause after which the mutator regains control.
Step 2 is repeatedly executed in an interleaved manner with the mutator.
When the GC is ready to finalize, i.e. step 2 is (almost) finished, another short pause is triggered in which step 2 is finished and step 3 is performed.
To prevent a user-after-free (UAF) issues it is required for Oilpan to know about all edges in the object graph.
This means that all pointers except on-stack pointers must be wrapped with Oilpan's handles (i.e., Persistent<>, Member<>, WeakMember<>).
Raw pointers to on-heap objects create an edge that Oilpan cannot observe and cause UAF issues
Thus, raw pointers shall not be used to reference on-heap objects (except for raw pointers on native stacks).
## Sweeping phase
The sweeping phase consists of the following steps:
1. Invoke pre-finalizers.
At this point, no destructors have been invoked and no memory has been reclaimed.
Pre-finalizers are allowed to access any other on-heap objects, even those that may get destructed.
2. Sweeping invokes destructors of the dead (unreachable) objects and reclaims memory to be reused by future allocations.
Assumptions should not be made about the order and the timing of their execution.
There is no guarantee on the order in which the destructors are invoked.
That's why destructors must not access any other on-heap objects (which might have already been destructed).
If some destructor unavoidably needs to access other on-heap objects, it will have to be converted to a pre-finalizer.
The pre-finalizer is allowed to access other on-heap objects.
The mutator is resumed before all destructors have ran.
For example, imagine a case where X is a client of Y, and Y holds a list of clients.
If the code relies on X's destructor removing X from the list, there is a risk that Y iterates the list and calls some method of X which may touch other on-heap objects.
This causes a use-after-free.
Care must be taken to make sure that X is explicitly removed from the list before the mutator resumes its execution in a way that doesn't rely on X's destructor (e.g. a pre-finalizer).
Similar to marking, sweeping can be executed in either an atomic stop-the-world manner or incrementally/concurrently.
With incremental/concurrent sweeping, step 2 is interleaved with mutator.
Incremental/concurrent sweeping can be atomically finalized in case it is needed to trigger another GC cycle.
Even with concurrent sweeping, destructors are guaranteed to run on the thread the object has been allocated on to preserve C++ semantics.
Notes:
* Weak processing runs only when the holder object of the WeakMember outlives the pointed object.
If the holder object and the pointed object die at the same time, weak processing doesn't run.
It is wrong to write code assuming that the weak processing always runs.
* Pre-finalizers are heavy because the thread needs to scan all pre-finalizers at each sweeping phase to determine which pre-finalizers should be invoked (the thread needs to invoke pre-finalizers of dead objects).
Adding pre-finalizers to frequently created objects should be avoided.

308
deps/v8/include/cppgc/allocation.h vendored Normal file
View File

@ -0,0 +1,308 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_ALLOCATION_H_
#define INCLUDE_CPPGC_ALLOCATION_H_
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <new>
#include <type_traits>
#include <utility>
#include "cppgc/custom-space.h"
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/gc-info.h"
#include "cppgc/type-traits.h"
#include "v8config.h" // NOLINT(build/include_directory)
#if defined(__has_attribute)
#if __has_attribute(assume_aligned)
#define CPPGC_DEFAULT_ALIGNED \
__attribute__((assume_aligned(api_constants::kDefaultAlignment)))
#define CPPGC_DOUBLE_WORD_ALIGNED \
__attribute__((assume_aligned(2 * api_constants::kDefaultAlignment)))
#endif // __has_attribute(assume_aligned)
#endif // defined(__has_attribute)
#if !defined(CPPGC_DEFAULT_ALIGNED)
#define CPPGC_DEFAULT_ALIGNED
#endif
#if !defined(CPPGC_DOUBLE_WORD_ALIGNED)
#define CPPGC_DOUBLE_WORD_ALIGNED
#endif
namespace cppgc {
/**
* AllocationHandle is used to allocate garbage-collected objects.
*/
class AllocationHandle;
namespace internal {
using AlignVal = std::align_val_t;
class MakeGarbageCollectedTraitInternal {
protected:
static inline void MarkObjectAsFullyConstructed(const void* payload) {
// See api_constants for an explanation of the constants.
std::atomic<uint16_t>* atomic_mutable_bitfield =
reinterpret_cast<std::atomic<uint16_t>*>(
const_cast<uint16_t*>(reinterpret_cast<const uint16_t*>(
reinterpret_cast<const uint8_t*>(payload) -
api_constants::kFullyConstructedBitFieldOffsetFromPayload)));
// It's safe to split use load+store here (instead of a read-modify-write
// operation), since it's guaranteed that this 16-bit bitfield is only
// modified by a single thread. This is cheaper in terms of code bloat (on
// ARM) and performance.
uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed);
value |= api_constants::kFullyConstructedBitMask;
atomic_mutable_bitfield->store(value, std::memory_order_release);
}
// Dispatch based on compile-time information.
//
// Default implementation is for a custom space with >`kDefaultAlignment` byte
// alignment.
template <typename GCInfoType, typename CustomSpace, size_t alignment>
struct AllocationDispatcher final {
static void* Invoke(AllocationHandle& handle, size_t size) {
static_assert(std::is_base_of<CustomSpaceBase, CustomSpace>::value,
"Custom space must inherit from CustomSpaceBase.");
static_assert(
!CustomSpace::kSupportsCompaction,
"Custom spaces that support compaction do not support allocating "
"objects with non-default (i.e. word-sized) alignment.");
return MakeGarbageCollectedTraitInternal::Allocate(
handle, size, static_cast<AlignVal>(alignment),
internal::GCInfoTrait<GCInfoType>::Index(), CustomSpace::kSpaceIndex);
}
};
// Fast path for regular allocations for the default space with
// `kDefaultAlignment` byte alignment.
template <typename GCInfoType>
struct AllocationDispatcher<GCInfoType, void,
api_constants::kDefaultAlignment>
final {
static void* Invoke(AllocationHandle& handle, size_t size) {
return MakeGarbageCollectedTraitInternal::Allocate(
handle, size, internal::GCInfoTrait<GCInfoType>::Index());
}
};
// Default space with >`kDefaultAlignment` byte alignment.
template <typename GCInfoType, size_t alignment>
struct AllocationDispatcher<GCInfoType, void, alignment> final {
static void* Invoke(AllocationHandle& handle, size_t size) {
return MakeGarbageCollectedTraitInternal::Allocate(
handle, size, static_cast<AlignVal>(alignment),
internal::GCInfoTrait<GCInfoType>::Index());
}
};
// Custom space with `kDefaultAlignment` byte alignment.
template <typename GCInfoType, typename CustomSpace>
struct AllocationDispatcher<GCInfoType, CustomSpace,
api_constants::kDefaultAlignment>
final {
static void* Invoke(AllocationHandle& handle, size_t size) {
static_assert(std::is_base_of<CustomSpaceBase, CustomSpace>::value,
"Custom space must inherit from CustomSpaceBase.");
return MakeGarbageCollectedTraitInternal::Allocate(
handle, size, internal::GCInfoTrait<GCInfoType>::Index(),
CustomSpace::kSpaceIndex);
}
};
private:
V8_EXPORT static void* CPPGC_DEFAULT_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, GCInfoIndex);
V8_EXPORT static void* CPPGC_DOUBLE_WORD_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, AlignVal, GCInfoIndex);
V8_EXPORT static void* CPPGC_DEFAULT_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, GCInfoIndex, CustomSpaceIndex);
V8_EXPORT static void* CPPGC_DOUBLE_WORD_ALIGNED
Allocate(cppgc::AllocationHandle&, size_t, AlignVal, GCInfoIndex,
CustomSpaceIndex);
friend class HeapObjectHeader;
};
} // namespace internal
/**
* Base trait that provides utilities for advancers users that have custom
* allocation needs (e.g., overriding size). It's expected that users override
* MakeGarbageCollectedTrait (see below) and inherit from
* MakeGarbageCollectedTraitBase and make use of the low-level primitives
* offered to allocate and construct an object.
*/
template <typename T>
class MakeGarbageCollectedTraitBase
: private internal::MakeGarbageCollectedTraitInternal {
private:
static_assert(internal::IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
static_assert(!IsGarbageCollectedWithMixinTypeV<T> ||
sizeof(T) <=
internal::api_constants::kLargeObjectSizeThreshold,
"GarbageCollectedMixin may not be a large object");
protected:
/**
* Allocates memory for an object of type T.
*
* \param handle AllocationHandle identifying the heap to allocate the object
* on.
* \param size The size that should be reserved for the object.
* \returns the memory to construct an object of type T on.
*/
V8_INLINE static void* Allocate(AllocationHandle& handle, size_t size) {
static_assert(
std::is_base_of<typename T::ParentMostGarbageCollectedType, T>::value,
"U of GarbageCollected<U> must be a base of T. Check "
"GarbageCollected<T> base class inheritance.");
static constexpr size_t kWantedAlignment =
alignof(T) < internal::api_constants::kDefaultAlignment
? internal::api_constants::kDefaultAlignment
: alignof(T);
static_assert(
kWantedAlignment <= internal::api_constants::kMaxSupportedAlignment,
"Requested alignment larger than alignof(std::max_align_t) bytes. "
"Please file a bug to possibly get this restriction lifted.");
return AllocationDispatcher<
typename internal::GCInfoFolding<
T, typename T::ParentMostGarbageCollectedType>::ResultType,
typename SpaceTrait<T>::Space, kWantedAlignment>::Invoke(handle, size);
}
/**
* Marks an object as fully constructed, resulting in precise handling by the
* garbage collector.
*
* \param payload The base pointer the object is allocated at.
*/
V8_INLINE static void MarkObjectAsFullyConstructed(const void* payload) {
internal::MakeGarbageCollectedTraitInternal::MarkObjectAsFullyConstructed(
payload);
}
};
/**
* Passed to MakeGarbageCollected to specify how many bytes should be appended
* to the allocated object.
*
* Example:
* \code
* class InlinedArray final : public GarbageCollected<InlinedArray> {
* public:
* explicit InlinedArray(size_t bytes) : size(bytes), byte_array(this + 1) {}
* void Trace(Visitor*) const {}
* size_t size;
* char* byte_array;
* };
*
* auto* inlined_array = MakeGarbageCollected<InlinedArray(
* GetAllocationHandle(), AdditionalBytes(4), 4);
* for (size_t i = 0; i < 4; i++) {
* Process(inlined_array->byte_array[i]);
* }
* \endcode
*/
struct AdditionalBytes {
constexpr explicit AdditionalBytes(size_t bytes) : value(bytes) {}
const size_t value;
};
/**
* Default trait class that specifies how to construct an object of type T.
* Advanced users may override how an object is constructed using the utilities
* that are provided through MakeGarbageCollectedTraitBase.
*
* Any trait overriding construction must
* - allocate through `MakeGarbageCollectedTraitBase<T>::Allocate`;
* - mark the object as fully constructed using
* `MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed`;
*/
template <typename T>
class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase<T> {
public:
template <typename... Args>
static T* Call(AllocationHandle& handle, Args&&... args) {
void* memory =
MakeGarbageCollectedTraitBase<T>::Allocate(handle, sizeof(T));
T* object = ::new (memory) T(std::forward<Args>(args)...);
MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed(object);
return object;
}
template <typename... Args>
static T* Call(AllocationHandle& handle, AdditionalBytes additional_bytes,
Args&&... args) {
void* memory = MakeGarbageCollectedTraitBase<T>::Allocate(
handle, sizeof(T) + additional_bytes.value);
T* object = ::new (memory) T(std::forward<Args>(args)...);
MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed(object);
return object;
}
};
/**
* Allows users to specify a post-construction callback for specific types. The
* callback is invoked on the instance of type T right after it has been
* constructed. This can be useful when the callback requires a
* fully-constructed object to be able to dispatch to virtual methods.
*/
template <typename T, typename = void>
struct PostConstructionCallbackTrait {
static void Call(T*) {}
};
/**
* Constructs a managed object of type T where T transitively inherits from
* GarbageCollected.
*
* \param args List of arguments with which an instance of T will be
* constructed.
* \returns an instance of type T.
*/
template <typename T, typename... Args>
V8_INLINE T* MakeGarbageCollected(AllocationHandle& handle, Args&&... args) {
T* object =
MakeGarbageCollectedTrait<T>::Call(handle, std::forward<Args>(args)...);
PostConstructionCallbackTrait<T>::Call(object);
return object;
}
/**
* Constructs a managed object of type T where T transitively inherits from
* GarbageCollected. Created objects will have additional bytes appended to
* it. Allocated memory would suffice for `sizeof(T) + additional_bytes`.
*
* \param additional_bytes Denotes how many bytes to append to T.
* \param args List of arguments with which an instance of T will be
* constructed.
* \returns an instance of type T.
*/
template <typename T, typename... Args>
V8_INLINE T* MakeGarbageCollected(AllocationHandle& handle,
AdditionalBytes additional_bytes,
Args&&... args) {
T* object = MakeGarbageCollectedTrait<T>::Call(handle, additional_bytes,
std::forward<Args>(args)...);
PostConstructionCallbackTrait<T>::Call(object);
return object;
}
} // namespace cppgc
#undef CPPGC_DEFAULT_ALIGNED
#undef CPPGC_DOUBLE_WORD_ALIGNED
#endif // INCLUDE_CPPGC_ALLOCATION_H_

28
deps/v8/include/cppgc/common.h vendored Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_COMMON_H_
#define INCLUDE_CPPGC_COMMON_H_
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
/**
* Indicator for the stack state of the embedder.
*/
enum class EmbedderStackState {
/**
* Stack may contain interesting heap pointers.
*/
kMayContainHeapPointers,
/**
* Stack does not contain any interesting heap pointers.
*/
kNoHeapPointers,
};
} // namespace cppgc
#endif // INCLUDE_CPPGC_COMMON_H_

View File

@ -0,0 +1,466 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_
#define INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_
#include <atomic>
#include "cppgc/internal/persistent-node.h"
#include "cppgc/internal/pointer-policies.h"
#include "cppgc/persistent.h"
#include "cppgc/visitor.h"
namespace cppgc {
namespace internal {
// Wrapper around PersistentBase that allows accessing poisoned memory when
// using ASAN. This is needed as the GC of the heap that owns the value
// of a CTP, may clear it (heap termination, weakness) while the object
// holding the CTP may be poisoned as itself may be deemed dead.
class CrossThreadPersistentBase : public PersistentBase {
public:
CrossThreadPersistentBase() = default;
explicit CrossThreadPersistentBase(const void* raw) : PersistentBase(raw) {}
V8_CLANG_NO_SANITIZE("address") const void* GetValueFromGC() const {
return raw_;
}
V8_CLANG_NO_SANITIZE("address")
PersistentNode* GetNodeFromGC() const { return node_; }
V8_CLANG_NO_SANITIZE("address")
void ClearFromGC() const {
raw_ = nullptr;
SetNodeSafe(nullptr);
}
// GetNodeSafe() can be used for a thread-safe IsValid() check in a
// double-checked locking pattern. See ~BasicCrossThreadPersistent.
PersistentNode* GetNodeSafe() const {
return reinterpret_cast<std::atomic<PersistentNode*>*>(&node_)->load(
std::memory_order_acquire);
}
// The GC writes using SetNodeSafe() while holding the lock.
V8_CLANG_NO_SANITIZE("address")
void SetNodeSafe(PersistentNode* value) const {
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
#define V8_IS_ASAN 1
#endif
#endif
#ifdef V8_IS_ASAN
__atomic_store(&node_, &value, __ATOMIC_RELEASE);
#else // !V8_IS_ASAN
// Non-ASAN builds can use atomics. This also covers MSVC which does not
// have the __atomic_store intrinsic.
reinterpret_cast<std::atomic<PersistentNode*>*>(&node_)->store(
value, std::memory_order_release);
#endif // !V8_IS_ASAN
#undef V8_IS_ASAN
}
};
template <typename T, typename WeaknessPolicy, typename LocationPolicy,
typename CheckingPolicy>
class BasicCrossThreadPersistent final : public CrossThreadPersistentBase,
public LocationPolicy,
private WeaknessPolicy,
private CheckingPolicy {
public:
using typename WeaknessPolicy::IsStrongPersistent;
using PointeeType = T;
~BasicCrossThreadPersistent() {
// This implements fast path for destroying empty/sentinel.
//
// Simplified version of `AssignUnsafe()` to allow calling without a
// complete type `T`. Uses double-checked locking with a simple thread-safe
// check for a valid handle based on a node.
if (GetNodeSafe()) {
PersistentRegionLock guard;
const void* old_value = GetValue();
// The fast path check (GetNodeSafe()) does not acquire the lock. Recheck
// validity while holding the lock to ensure the reference has not been
// cleared.
if (IsValid(old_value)) {
CrossThreadPersistentRegion& region =
this->GetPersistentRegion(old_value);
region.FreeNode(GetNode());
SetNode(nullptr);
} else {
CPPGC_DCHECK(!GetNode());
}
}
// No need to call SetValue() as the handle is not used anymore. This can
// leave behind stale sentinel values but will always destroy the underlying
// node.
}
BasicCrossThreadPersistent(
const SourceLocation& loc = SourceLocation::Current())
: LocationPolicy(loc) {}
BasicCrossThreadPersistent(
std::nullptr_t, const SourceLocation& loc = SourceLocation::Current())
: LocationPolicy(loc) {}
BasicCrossThreadPersistent(
SentinelPointer s, const SourceLocation& loc = SourceLocation::Current())
: CrossThreadPersistentBase(s), LocationPolicy(loc) {}
BasicCrossThreadPersistent(
T* raw, const SourceLocation& loc = SourceLocation::Current())
: CrossThreadPersistentBase(raw), LocationPolicy(loc) {
if (!IsValid(raw)) return;
PersistentRegionLock guard;
CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
SetNode(region.AllocateNode(this, &TraceAsRoot));
this->CheckPointer(raw);
}
class UnsafeCtorTag {
private:
UnsafeCtorTag() = default;
template <typename U, typename OtherWeaknessPolicy,
typename OtherLocationPolicy, typename OtherCheckingPolicy>
friend class BasicCrossThreadPersistent;
};
BasicCrossThreadPersistent(
UnsafeCtorTag, T* raw,
const SourceLocation& loc = SourceLocation::Current())
: CrossThreadPersistentBase(raw), LocationPolicy(loc) {
if (!IsValid(raw)) return;
CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
SetNode(region.AllocateNode(this, &TraceAsRoot));
this->CheckPointer(raw);
}
BasicCrossThreadPersistent(
T& raw, const SourceLocation& loc = SourceLocation::Current())
: BasicCrossThreadPersistent(&raw, loc) {}
template <typename U, typename MemberBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType,
typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicCrossThreadPersistent(
internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
MemberCheckingPolicy, MemberStorageType>
member,
const SourceLocation& loc = SourceLocation::Current())
: BasicCrossThreadPersistent(member.Get(), loc) {}
BasicCrossThreadPersistent(
const BasicCrossThreadPersistent& other,
const SourceLocation& loc = SourceLocation::Current())
: BasicCrossThreadPersistent(loc) {
// Invoke operator=.
*this = other;
}
// Heterogeneous ctor.
template <typename U, typename OtherWeaknessPolicy,
typename OtherLocationPolicy, typename OtherCheckingPolicy,
typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicCrossThreadPersistent(
const BasicCrossThreadPersistent<U, OtherWeaknessPolicy,
OtherLocationPolicy,
OtherCheckingPolicy>& other,
const SourceLocation& loc = SourceLocation::Current())
: BasicCrossThreadPersistent(loc) {
*this = other;
}
BasicCrossThreadPersistent(
BasicCrossThreadPersistent&& other,
const SourceLocation& loc = SourceLocation::Current()) noexcept {
// Invoke operator=.
*this = std::move(other);
}
BasicCrossThreadPersistent& operator=(
const BasicCrossThreadPersistent& other) {
PersistentRegionLock guard;
AssignSafe(guard, other.Get());
return *this;
}
template <typename U, typename OtherWeaknessPolicy,
typename OtherLocationPolicy, typename OtherCheckingPolicy,
typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicCrossThreadPersistent& operator=(
const BasicCrossThreadPersistent<U, OtherWeaknessPolicy,
OtherLocationPolicy,
OtherCheckingPolicy>& other) {
PersistentRegionLock guard;
AssignSafe(guard, other.Get());
return *this;
}
BasicCrossThreadPersistent& operator=(BasicCrossThreadPersistent&& other) {
if (this == &other) return *this;
Clear();
PersistentRegionLock guard;
PersistentBase::operator=(std::move(other));
LocationPolicy::operator=(std::move(other));
if (!IsValid(GetValue())) return *this;
GetNode()->UpdateOwner(this);
other.SetValue(nullptr);
other.SetNode(nullptr);
this->CheckPointer(Get());
return *this;
}
/**
* Assigns a raw pointer.
*
* Note: **Not thread-safe.**
*/
BasicCrossThreadPersistent& operator=(T* other) {
AssignUnsafe(other);
return *this;
}
// Assignment from member.
template <typename U, typename MemberBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType,
typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicCrossThreadPersistent& operator=(
internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
MemberCheckingPolicy, MemberStorageType>
member) {
return operator=(member.Get());
}
/**
* Assigns a nullptr.
*
* \returns the handle.
*/
BasicCrossThreadPersistent& operator=(std::nullptr_t) {
Clear();
return *this;
}
/**
* Assigns the sentinel pointer.
*
* \returns the handle.
*/
BasicCrossThreadPersistent& operator=(SentinelPointer s) {
PersistentRegionLock guard;
AssignSafe(guard, s);
return *this;
}
/**
* Returns a pointer to the stored object.
*
* Note: **Not thread-safe.**
*
* \returns a pointer to the stored object.
*/
// CFI cast exemption to allow passing SentinelPointer through T* and support
// heterogeneous assignments between different Member and Persistent handles
// based on their actual types.
V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
return static_cast<T*>(const_cast<void*>(GetValue()));
}
/**
* Clears the stored object.
*/
void Clear() {
PersistentRegionLock guard;
AssignSafe(guard, nullptr);
}
/**
* Returns a pointer to the stored object and releases it.
*
* Note: **Not thread-safe.**
*
* \returns a pointer to the stored object.
*/
T* Release() {
T* result = Get();
Clear();
return result;
}
/**
* Conversio to boolean.
*
* Note: **Not thread-safe.**
*
* \returns true if an actual object has been stored and false otherwise.
*/
explicit operator bool() const { return Get(); }
/**
* Conversion to object of type T.
*
* Note: **Not thread-safe.**
*
* \returns the object.
*/
operator T*() const { return Get(); }
/**
* Dereferences the stored object.
*
* Note: **Not thread-safe.**
*/
T* operator->() const { return Get(); }
T& operator*() const { return *Get(); }
template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy,
typename OtherLocationPolicy = LocationPolicy,
typename OtherCheckingPolicy = CheckingPolicy>
BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
OtherCheckingPolicy>
To() const {
using OtherBasicCrossThreadPersistent =
BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
OtherCheckingPolicy>;
PersistentRegionLock guard;
return OtherBasicCrossThreadPersistent(
typename OtherBasicCrossThreadPersistent::UnsafeCtorTag(),
static_cast<U*>(Get()));
}
template <typename U = T,
typename = typename std::enable_if<!BasicCrossThreadPersistent<
U, WeaknessPolicy>::IsStrongPersistent::value>::type>
BasicCrossThreadPersistent<U, internal::StrongCrossThreadPersistentPolicy>
Lock() const {
return BasicCrossThreadPersistent<
U, internal::StrongCrossThreadPersistentPolicy>(*this);
}
private:
static bool IsValid(const void* ptr) {
return ptr && ptr != kSentinelPointer;
}
static void TraceAsRoot(RootVisitor& root_visitor, const void* ptr) {
root_visitor.Trace(*static_cast<const BasicCrossThreadPersistent*>(ptr));
}
void AssignUnsafe(T* ptr) {
const void* old_value = GetValue();
if (IsValid(old_value)) {
PersistentRegionLock guard;
old_value = GetValue();
// The fast path check (IsValid()) does not acquire the lock. Reload
// the value to ensure the reference has not been cleared.
if (IsValid(old_value)) {
CrossThreadPersistentRegion& region =
this->GetPersistentRegion(old_value);
if (IsValid(ptr) && (&region == &this->GetPersistentRegion(ptr))) {
SetValue(ptr);
this->CheckPointer(ptr);
return;
}
region.FreeNode(GetNode());
SetNode(nullptr);
} else {
CPPGC_DCHECK(!GetNode());
}
}
SetValue(ptr);
if (!IsValid(ptr)) return;
PersistentRegionLock guard;
SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &TraceAsRoot));
this->CheckPointer(ptr);
}
void AssignSafe(PersistentRegionLock&, T* ptr) {
PersistentRegionLock::AssertLocked();
const void* old_value = GetValue();
if (IsValid(old_value)) {
CrossThreadPersistentRegion& region =
this->GetPersistentRegion(old_value);
if (IsValid(ptr) && (&region == &this->GetPersistentRegion(ptr))) {
SetValue(ptr);
this->CheckPointer(ptr);
return;
}
region.FreeNode(GetNode());
SetNode(nullptr);
}
SetValue(ptr);
if (!IsValid(ptr)) return;
SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &TraceAsRoot));
this->CheckPointer(ptr);
}
void ClearFromGC() const {
if (IsValid(GetValueFromGC())) {
WeaknessPolicy::GetPersistentRegion(GetValueFromGC())
.FreeNode(GetNodeFromGC());
CrossThreadPersistentBase::ClearFromGC();
}
}
// See Get() for details.
V8_CLANG_NO_SANITIZE("cfi-unrelated-cast")
T* GetFromGC() const {
return static_cast<T*>(const_cast<void*>(GetValueFromGC()));
}
friend class internal::RootVisitor;
};
template <typename T, typename LocationPolicy, typename CheckingPolicy>
struct IsWeak<
BasicCrossThreadPersistent<T, internal::WeakCrossThreadPersistentPolicy,
LocationPolicy, CheckingPolicy>>
: std::true_type {};
} // namespace internal
namespace subtle {
/**
* **DO NOT USE: Has known caveats, see below.**
*
* CrossThreadPersistent allows retaining objects from threads other than the
* thread the owning heap is operating on.
*
* Known caveats:
* - Does not protect the heap owning an object from terminating.
* - Reaching transitively through the graph is unsupported as objects may be
* moved concurrently on the thread owning the object.
*/
template <typename T>
using CrossThreadPersistent = internal::BasicCrossThreadPersistent<
T, internal::StrongCrossThreadPersistentPolicy>;
/**
* **DO NOT USE: Has known caveats, see below.**
*
* CrossThreadPersistent allows weakly retaining objects from threads other than
* the thread the owning heap is operating on.
*
* Known caveats:
* - Does not protect the heap owning an object from terminating.
* - Reaching transitively through the graph is unsupported as objects may be
* moved concurrently on the thread owning the object.
*/
template <typename T>
using WeakCrossThreadPersistent = internal::BasicCrossThreadPersistent<
T, internal::WeakCrossThreadPersistentPolicy>;
} // namespace subtle
} // namespace cppgc
#endif // INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_

97
deps/v8/include/cppgc/custom-space.h vendored Normal file
View File

@ -0,0 +1,97 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_CUSTOM_SPACE_H_
#define INCLUDE_CPPGC_CUSTOM_SPACE_H_
#include <stddef.h>
namespace cppgc {
/**
* Index identifying a custom space.
*/
struct CustomSpaceIndex {
constexpr CustomSpaceIndex(size_t value) : value(value) {} // NOLINT
size_t value;
};
/**
* Top-level base class for custom spaces. Users must inherit from CustomSpace
* below.
*/
class CustomSpaceBase {
public:
virtual ~CustomSpaceBase() = default;
virtual CustomSpaceIndex GetCustomSpaceIndex() const = 0;
virtual bool IsCompactable() const = 0;
};
/**
* Base class custom spaces should directly inherit from. The class inheriting
* from `CustomSpace` must define `kSpaceIndex` as unique space index. These
* indices need for form a sequence starting at 0.
*
* Example:
* \code
* class CustomSpace1 : public CustomSpace<CustomSpace1> {
* public:
* static constexpr CustomSpaceIndex kSpaceIndex = 0;
* };
* class CustomSpace2 : public CustomSpace<CustomSpace2> {
* public:
* static constexpr CustomSpaceIndex kSpaceIndex = 1;
* };
* \endcode
*/
template <typename ConcreteCustomSpace>
class CustomSpace : public CustomSpaceBase {
public:
/**
* Compaction is only supported on spaces that manually manage slots
* recording.
*/
static constexpr bool kSupportsCompaction = false;
CustomSpaceIndex GetCustomSpaceIndex() const final {
return ConcreteCustomSpace::kSpaceIndex;
}
bool IsCompactable() const final {
return ConcreteCustomSpace::kSupportsCompaction;
}
};
/**
* User-overridable trait that allows pinning types to custom spaces.
*/
template <typename T, typename = void>
struct SpaceTrait {
using Space = void;
};
namespace internal {
template <typename CustomSpace>
struct IsAllocatedOnCompactableSpaceImpl {
static constexpr bool value = CustomSpace::kSupportsCompaction;
};
template <>
struct IsAllocatedOnCompactableSpaceImpl<void> {
// Non-custom spaces are by default not compactable.
static constexpr bool value = false;
};
template <typename T>
struct IsAllocatedOnCompactableSpace {
public:
static constexpr bool value =
IsAllocatedOnCompactableSpaceImpl<typename SpaceTrait<T>::Space>::value;
};
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_CUSTOM_SPACE_H_

View File

@ -0,0 +1,68 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_DEFAULT_PLATFORM_H_
#define INCLUDE_CPPGC_DEFAULT_PLATFORM_H_
#include <memory>
#include "cppgc/platform.h"
#include "libplatform/libplatform.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
/**
* Platform provided by cppgc. Uses V8's DefaultPlatform provided by
* libplatform internally. Exception: `GetForegroundTaskRunner()`, see below.
*/
class V8_EXPORT DefaultPlatform : public Platform {
public:
using IdleTaskSupport = v8::platform::IdleTaskSupport;
explicit DefaultPlatform(
int thread_pool_size = 0,
IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
std::unique_ptr<TracingController> tracing_controller = {})
: v8_platform_(v8::platform::NewDefaultPlatform(
thread_pool_size, idle_task_support,
v8::platform::InProcessStackDumping::kDisabled,
std::move(tracing_controller))) {}
cppgc::PageAllocator* GetPageAllocator() override {
return v8_platform_->GetPageAllocator();
}
double MonotonicallyIncreasingTime() override {
return v8_platform_->MonotonicallyIncreasingTime();
}
std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner(
TaskPriority priority) override {
// V8's default platform creates a new task runner when passed the
// `v8::Isolate` pointer the first time. For non-default platforms this will
// require getting the appropriate task runner.
return v8_platform_->GetForegroundTaskRunner(kNoIsolate, priority);
}
std::unique_ptr<cppgc::JobHandle> PostJob(
cppgc::TaskPriority priority,
std::unique_ptr<cppgc::JobTask> job_task) override {
return v8_platform_->PostJob(priority, std::move(job_task));
}
TracingController* GetTracingController() override {
return v8_platform_->GetTracingController();
}
v8::Platform* GetV8Platform() const { return v8_platform_.get(); }
protected:
static constexpr v8::Isolate* kNoIsolate = nullptr;
std::unique_ptr<v8::Platform> v8_platform_;
};
} // namespace cppgc
#endif // INCLUDE_CPPGC_DEFAULT_PLATFORM_H_

View File

@ -0,0 +1,100 @@
// 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.
#ifndef INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_
#define INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_
#include <cstddef>
#include "cppgc/allocation.h"
#include "cppgc/internal/logging.h"
#include "cppgc/type-traits.h"
namespace cppgc {
class HeapHandle;
namespace subtle {
template <typename T>
void FreeUnreferencedObject(HeapHandle& heap_handle, T& object);
template <typename T>
bool Resize(T& object, AdditionalBytes additional_bytes);
} // namespace subtle
namespace internal {
class ExplicitManagementImpl final {
private:
V8_EXPORT static void FreeUnreferencedObject(HeapHandle&, void*);
V8_EXPORT static bool Resize(void*, size_t);
template <typename T>
friend void subtle::FreeUnreferencedObject(HeapHandle&, T&);
template <typename T>
friend bool subtle::Resize(T&, AdditionalBytes);
};
} // namespace internal
namespace subtle {
/**
* Informs the garbage collector that `object` can be immediately reclaimed. The
* destructor may not be invoked immediately but only on next garbage
* collection.
*
* It is up to the embedder to guarantee that no other object holds a reference
* to `object` after calling `FreeUnreferencedObject()`. In case such a
* reference exists, it's use results in a use-after-free.
*
* To aid in using the API, `FreeUnreferencedObject()` may be called from
* destructors on objects that would be reclaimed in the same garbage collection
* cycle.
*
* \param heap_handle The corresponding heap.
* \param object Reference to an object that is of type `GarbageCollected` and
* should be immediately reclaimed.
*/
template <typename T>
void FreeUnreferencedObject(HeapHandle& heap_handle, T& object) {
static_assert(IsGarbageCollectedTypeV<T>,
"Object must be of type GarbageCollected.");
internal::ExplicitManagementImpl::FreeUnreferencedObject(heap_handle,
&object);
}
/**
* Tries to resize `object` of type `T` with additional bytes on top of
* sizeof(T). Resizing is only useful with trailing inlined storage, see e.g.
* `MakeGarbageCollected(AllocationHandle&, AdditionalBytes)`.
*
* `Resize()` performs growing or shrinking as needed and may skip the operation
* for internal reasons, see return value.
*
* It is up to the embedder to guarantee that in case of shrinking a larger
* object down, the reclaimed area is not used anymore. Any subsequent use
* results in a use-after-free.
*
* The `object` must be live when calling `Resize()`.
*
* \param object Reference to an object that is of type `GarbageCollected` and
* should be resized.
* \param additional_bytes Bytes in addition to sizeof(T) that the object should
* provide.
* \returns true when the operation was successful and the result can be relied
* on, and false otherwise.
*/
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);
}
} // namespace subtle
} // namespace cppgc
#endif // INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_

View File

@ -0,0 +1,114 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
#define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
#include "cppgc/internal/api-constants.h"
#include "cppgc/platform.h"
#include "cppgc/trace-trait.h"
#include "cppgc/type-traits.h"
namespace cppgc {
class Visitor;
/**
* Base class for managed objects. Only descendent types of `GarbageCollected`
* can be constructed using `MakeGarbageCollected()`. Must be inherited from as
* left-most base class.
*
* Types inheriting from GarbageCollected must provide a method of
* signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
* pointers to the visitor and delegates to garbage-collected base classes.
* The method must be virtual if the type is not directly a child of
* GarbageCollected and marked as final.
*
* \code
* // Example using final class.
* class FinalType final : public GarbageCollected<FinalType> {
* public:
* void Trace(cppgc::Visitor* visitor) const {
* // Dispatch using visitor->Trace(...);
* }
* };
*
* // Example using non-final base class.
* class NonFinalBase : public GarbageCollected<NonFinalBase> {
* public:
* virtual void Trace(cppgc::Visitor*) const {}
* };
*
* class FinalChild final : public NonFinalBase {
* public:
* void Trace(cppgc::Visitor* visitor) const final {
* // Dispatch using visitor->Trace(...);
* NonFinalBase::Trace(visitor);
* }
* };
* \endcode
*/
template <typename T>
class GarbageCollected {
public:
using IsGarbageCollectedTypeMarker = void;
using ParentMostGarbageCollectedType = T;
// Must use MakeGarbageCollected.
void* operator new(size_t) = delete;
void* operator new[](size_t) = delete;
// The garbage collector is taking care of reclaiming the object. Also,
// virtual destructor requires an unambiguous, accessible 'operator delete'.
void operator delete(void*) {
#ifdef V8_ENABLE_CHECKS
internal::Fatal(
"Manually deleting a garbage collected object is not allowed");
#endif // V8_ENABLE_CHECKS
}
void operator delete[](void*) = delete;
protected:
GarbageCollected() = default;
};
/**
* Base class for managed mixin objects. Such objects cannot be constructed
* directly but must be mixed into the inheritance hierarchy of a
* GarbageCollected object.
*
* Types inheriting from GarbageCollectedMixin must override a virtual method
* of signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
* pointers to the visitor and delegates to base classes.
*
* \code
* class Mixin : public GarbageCollectedMixin {
* public:
* void Trace(cppgc::Visitor* visitor) const override {
* // Dispatch using visitor->Trace(...);
* }
* };
* \endcode
*/
class GarbageCollectedMixin {
public:
using IsGarbageCollectedMixinTypeMarker = void;
// Must use MakeGarbageCollected.
void* operator new(size_t) = delete;
void* operator new[](size_t) = delete;
// The garbage collector is taking care of reclaiming the object.
// Not override the non-array varaint of `delete` to not conflict with the
// operator in GarbageCollected above.
void operator delete[](void*) = delete;
/**
* This Trace method must be overriden by objects inheriting from
* GarbageCollectedMixin.
*/
virtual void Trace(cppgc::Visitor*) const {}
};
} // namespace cppgc
#endif // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_

309
deps/v8/include/cppgc/heap-consistency.h vendored Normal file
View File

@ -0,0 +1,309 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_HEAP_CONSISTENCY_H_
#define INCLUDE_CPPGC_HEAP_CONSISTENCY_H_
#include <cstddef>
#include "cppgc/internal/write-barrier.h"
#include "cppgc/macros.h"
#include "cppgc/member.h"
#include "cppgc/trace-trait.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
class HeapHandle;
namespace subtle {
/**
* **DO NOT USE: Use the appropriate managed types.**
*
* Consistency helpers that aid in maintaining a consistent internal state of
* the garbage collector.
*/
class HeapConsistency final {
public:
using WriteBarrierParams = internal::WriteBarrier::Params;
using WriteBarrierType = internal::WriteBarrier::Type;
/**
* Gets the required write barrier type for a specific write.
*
* \param slot Slot containing the pointer to the object. The slot itself
* must reside in an object that has been allocated using
* `MakeGarbageCollected()`.
* \param value The pointer to the object. May be an interior pointer to an
* interface of the actual object.
* \param params Parameters that may be used for actual write barrier calls.
* Only filled if return value indicates that a write barrier is needed. The
* contents of the `params` are an implementation detail.
* \returns whether a write barrier is needed and which barrier to invoke.
*/
static V8_INLINE WriteBarrierType GetWriteBarrierType(
const void* slot, const void* value, WriteBarrierParams& params) {
return internal::WriteBarrier::GetWriteBarrierType(slot, value, params);
}
/**
* Gets the required write barrier type for a specific write. This override is
* only used for all the BasicMember types.
*
* \param slot Slot containing the pointer to the object. The slot itself
* must reside in an object that has been allocated using
* `MakeGarbageCollected()`.
* \param value The pointer to the object held via `BasicMember`.
* \param params Parameters that may be used for actual write barrier calls.
* Only filled if return value indicates that a write barrier is needed. The
* contents of the `params` are an implementation detail.
* \returns whether a write barrier is needed and which barrier to invoke.
*/
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy, typename StorageType>
static V8_INLINE WriteBarrierType GetWriteBarrierType(
const internal::BasicMember<T, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy, StorageType>& value,
WriteBarrierParams& params) {
return internal::WriteBarrier::GetWriteBarrierType(
value.GetRawSlot(), value.GetRawStorage(), params);
}
/**
* Gets the required write barrier type for a specific write.
*
* \param slot Slot to some part of an object. The object must not necessarily
have been allocated using `MakeGarbageCollected()` but can also live
off-heap or on stack.
* \param params Parameters that may be used for actual write barrier calls.
* Only filled if return value indicates that a write barrier is needed. The
* contents of the `params` are an implementation detail.
* \param callback Callback returning the corresponding heap handle. The
* callback is only invoked if the heap cannot otherwise be figured out. The
* callback must not allocate.
* \returns whether a write barrier is needed and which barrier to invoke.
*/
template <typename HeapHandleCallback>
static V8_INLINE WriteBarrierType
GetWriteBarrierType(const void* slot, WriteBarrierParams& params,
HeapHandleCallback callback) {
return internal::WriteBarrier::GetWriteBarrierType(slot, params, callback);
}
/**
* Gets the required write barrier type for a specific write.
* This version is meant to be used in conjunction with with a marking write
* barrier barrier which doesn't consider the slot.
*
* \param value The pointer to the object. May be an interior pointer to an
* interface of the actual object.
* \param params Parameters that may be used for actual write barrier calls.
* Only filled if return value indicates that a write barrier is needed. The
* contents of the `params` are an implementation detail.
* \returns whether a write barrier is needed and which barrier to invoke.
*/
static V8_INLINE WriteBarrierType
GetWriteBarrierType(const void* value, WriteBarrierParams& params) {
return internal::WriteBarrier::GetWriteBarrierType(value, params);
}
/**
* Conservative Dijkstra-style write barrier that processes an object if it
* has not yet been processed.
*
* \param params The parameters retrieved from `GetWriteBarrierType()`.
* \param object The pointer to the object. May be an interior pointer to
* an interface of the actual object.
*/
static V8_INLINE void DijkstraWriteBarrier(const WriteBarrierParams& params,
const void* object) {
internal::WriteBarrier::DijkstraMarkingBarrier(params, object);
}
/**
* Conservative Dijkstra-style write barrier that processes a range of
* elements if they have not yet been processed.
*
* \param params The parameters retrieved from `GetWriteBarrierType()`.
* \param first_element Pointer to the first element that should be processed.
* The slot itself must reside in an object that has been allocated using
* `MakeGarbageCollected()`.
* \param element_size Size of the element in bytes.
* \param number_of_elements Number of elements that should be processed,
* starting with `first_element`.
* \param trace_callback The trace callback that should be invoked for each
* element if necessary.
*/
static V8_INLINE void DijkstraWriteBarrierRange(
const WriteBarrierParams& params, const void* first_element,
size_t element_size, size_t number_of_elements,
TraceCallback trace_callback) {
internal::WriteBarrier::DijkstraMarkingBarrierRange(
params, first_element, element_size, number_of_elements,
trace_callback);
}
/**
* Steele-style write barrier that re-processes an object if it has already
* been processed.
*
* \param params The parameters retrieved from `GetWriteBarrierType()`.
* \param object The pointer to the object which must point to an object that
* has been allocated using `MakeGarbageCollected()`. Interior pointers are
* not supported.
*/
static V8_INLINE void SteeleWriteBarrier(const WriteBarrierParams& params,
const void* object) {
internal::WriteBarrier::SteeleMarkingBarrier(params, object);
}
/**
* Generational barrier for maintaining consistency when running with multiple
* generations.
*
* \param params The parameters retrieved from `GetWriteBarrierType()`.
* \param slot Slot containing the pointer to the object. The slot itself
* must reside in an object that has been allocated using
* `MakeGarbageCollected()`.
*/
static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params,
const void* slot) {
internal::WriteBarrier::GenerationalBarrier<
internal::WriteBarrier::GenerationalBarrierType::kPreciseSlot>(params,
slot);
}
/**
* Generational barrier for maintaining consistency when running with multiple
* generations. This version is used when slot contains uncompressed pointer.
*
* \param params The parameters retrieved from `GetWriteBarrierType()`.
* \param slot Uncompressed slot containing the direct pointer to the object.
* The slot itself must reside in an object that has been allocated using
* `MakeGarbageCollected()`.
*/
static V8_INLINE void GenerationalBarrierForUncompressedSlot(
const WriteBarrierParams& params, const void* uncompressed_slot) {
internal::WriteBarrier::GenerationalBarrier<
internal::WriteBarrier::GenerationalBarrierType::
kPreciseUncompressedSlot>(params, uncompressed_slot);
}
/**
* Generational barrier for source object that may contain outgoing pointers
* to objects in young generation.
*
* \param params The parameters retrieved from `GetWriteBarrierType()`.
* \param inner_pointer Pointer to the source object.
*/
static V8_INLINE void GenerationalBarrierForSourceObject(
const WriteBarrierParams& params, const void* inner_pointer) {
internal::WriteBarrier::GenerationalBarrier<
internal::WriteBarrier::GenerationalBarrierType::kImpreciseSlot>(
params, inner_pointer);
}
private:
HeapConsistency() = delete;
};
/**
* Disallows garbage collection finalizations. Any garbage collection triggers
* result in a crash when in this scope.
*
* Note that the garbage collector already covers paths that can lead to garbage
* collections, so user code does not require checking
* `IsGarbageCollectionAllowed()` before allocations.
*/
class V8_EXPORT V8_NODISCARD DisallowGarbageCollectionScope final {
CPPGC_STACK_ALLOCATED();
public:
/**
* \returns whether garbage collections are currently allowed.
*/
static bool IsGarbageCollectionAllowed(HeapHandle& heap_handle);
/**
* Enters a disallow garbage collection scope. Must be paired with `Leave()`.
* Prefer a scope instance of `DisallowGarbageCollectionScope`.
*
* \param heap_handle The corresponding heap.
*/
static void Enter(HeapHandle& heap_handle);
/**
* Leaves a disallow garbage collection scope. Must be paired with `Enter()`.
* Prefer a scope instance of `DisallowGarbageCollectionScope`.
*
* \param heap_handle The corresponding heap.
*/
static void Leave(HeapHandle& heap_handle);
/**
* Constructs a scoped object that automatically enters and leaves a disallow
* garbage collection scope based on its lifetime.
*
* \param heap_handle The corresponding heap.
*/
explicit DisallowGarbageCollectionScope(HeapHandle& heap_handle);
~DisallowGarbageCollectionScope();
DisallowGarbageCollectionScope(const DisallowGarbageCollectionScope&) =
delete;
DisallowGarbageCollectionScope& operator=(
const DisallowGarbageCollectionScope&) = delete;
private:
HeapHandle& heap_handle_;
};
/**
* Avoids invoking garbage collection finalizations. Already running garbage
* collection phase are unaffected by this scope.
*
* Should only be used temporarily as the scope has an impact on memory usage
* and follow up garbage collections.
*/
class V8_EXPORT V8_NODISCARD NoGarbageCollectionScope final {
CPPGC_STACK_ALLOCATED();
public:
/**
* Enters a no garbage collection scope. Must be paired with `Leave()`. Prefer
* a scope instance of `NoGarbageCollectionScope`.
*
* \param heap_handle The corresponding heap.
*/
static void Enter(HeapHandle& heap_handle);
/**
* Leaves a no garbage collection scope. Must be paired with `Enter()`. Prefer
* a scope instance of `NoGarbageCollectionScope`.
*
* \param heap_handle The corresponding heap.
*/
static void Leave(HeapHandle& heap_handle);
/**
* Constructs a scoped object that automatically enters and leaves a no
* garbage collection scope based on its lifetime.
*
* \param heap_handle The corresponding heap.
*/
explicit NoGarbageCollectionScope(HeapHandle& heap_handle);
~NoGarbageCollectionScope();
NoGarbageCollectionScope(const NoGarbageCollectionScope&) = delete;
NoGarbageCollectionScope& operator=(const NoGarbageCollectionScope&) = delete;
private:
HeapHandle& heap_handle_;
};
} // namespace subtle
} // namespace cppgc
#endif // INCLUDE_CPPGC_HEAP_CONSISTENCY_H_

48
deps/v8/include/cppgc/heap-handle.h vendored Normal file
View File

@ -0,0 +1,48 @@
// 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 INCLUDE_CPPGC_HEAP_HANDLE_H_
#define INCLUDE_CPPGC_HEAP_HANDLE_H_
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
class HeapBase;
class WriteBarrierTypeForCagedHeapPolicy;
class WriteBarrierTypeForNonCagedHeapPolicy;
} // namespace internal
/**
* Opaque handle used for additional heap APIs.
*/
class HeapHandle {
public:
// Deleted copy ctor to avoid treating the type by value.
HeapHandle(const HeapHandle&) = delete;
HeapHandle& operator=(const HeapHandle&) = delete;
private:
HeapHandle() = default;
V8_INLINE bool is_incremental_marking_in_progress() const {
return is_incremental_marking_in_progress_;
}
V8_INLINE bool is_young_generation_enabled() const {
return is_young_generation_enabled_;
}
bool is_incremental_marking_in_progress_ = false;
bool is_young_generation_enabled_ = false;
friend class internal::HeapBase;
friend class internal::WriteBarrierTypeForCagedHeapPolicy;
friend class internal::WriteBarrierTypeForNonCagedHeapPolicy;
};
} // namespace cppgc
#endif // INCLUDE_CPPGC_HEAP_HANDLE_H_

82
deps/v8/include/cppgc/heap-state.h vendored Normal file
View File

@ -0,0 +1,82 @@
// 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.
#ifndef INCLUDE_CPPGC_HEAP_STATE_H_
#define INCLUDE_CPPGC_HEAP_STATE_H_
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
class HeapHandle;
namespace subtle {
/**
* Helpers to peek into heap-internal state.
*/
class V8_EXPORT HeapState final {
public:
/**
* Returns whether the garbage collector is marking. This API is experimental
* and is expected to be removed in future.
*
* \param heap_handle The corresponding heap.
* \returns true if the garbage collector is currently marking, and false
* otherwise.
*/
static bool IsMarking(const HeapHandle& heap_handle);
/*
* Returns whether the garbage collector is sweeping. This API is experimental
* and is expected to be removed in future.
*
* \param heap_handle The corresponding heap.
* \returns true if the garbage collector is currently sweeping, and false
* otherwise.
*/
static bool IsSweeping(const HeapHandle& heap_handle);
/*
* Returns whether the garbage collector is currently sweeping on the thread
* owning this heap. This API allows the caller to determine whether it has
* been called from a destructor of a managed object. This API is experimental
* and may be removed in future.
*
* \param heap_handle The corresponding heap.
* \returns true if the garbage collector is currently sweeping on this
* thread, and false otherwise.
*/
static bool IsSweepingOnOwningThread(const HeapHandle& heap_handle);
/**
* Returns whether the garbage collector is in the atomic pause, i.e., the
* mutator is stopped from running. This API is experimental and is expected
* to be removed in future.
*
* \param heap_handle The corresponding heap.
* \returns true if the garbage collector is currently in the atomic pause,
* and false otherwise.
*/
static bool IsInAtomicPause(const HeapHandle& heap_handle);
/**
* Returns whether the last garbage collection was finalized conservatively
* (i.e., with a non-empty stack). This API is experimental and is expected to
* be removed in future.
*
* \param heap_handle The corresponding heap.
* \returns true if the last garbage collection was finalized conservatively,
* and false otherwise.
*/
static bool PreviousGCWasConservative(const HeapHandle& heap_handle);
private:
HeapState() = delete;
};
} // namespace subtle
} // namespace cppgc
#endif // INCLUDE_CPPGC_HEAP_STATE_H_

122
deps/v8/include/cppgc/heap-statistics.h vendored Normal file
View File

@ -0,0 +1,122 @@
// 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.
#ifndef INCLUDE_CPPGC_HEAP_STATISTICS_H_
#define INCLUDE_CPPGC_HEAP_STATISTICS_H_
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace cppgc {
/**
* `HeapStatistics` contains memory consumption and utilization statistics for a
* cppgc heap.
*/
struct HeapStatistics final {
/**
* Specifies the detail level of the heap statistics. Brief statistics contain
* only the top-level allocated and used memory statistics for the entire
* heap. Detailed statistics also contain a break down per space and page, as
* well as freelist statistics and object type histograms. Note that used
* memory reported by brief statistics and detailed statistics might differ
* slightly.
*/
enum DetailLevel : uint8_t {
kBrief,
kDetailed,
};
/**
* Object statistics for a single type.
*/
struct ObjectStatsEntry {
/**
* Number of allocated bytes.
*/
size_t allocated_bytes;
/**
* Number of allocated objects.
*/
size_t object_count;
};
/**
* Page granularity statistics. For each page the statistics record the
* allocated memory size and overall used memory size for the page.
*/
struct PageStatistics {
/** Overall committed amount of memory for the page. */
size_t committed_size_bytes = 0;
/** Resident amount of memory held by the page. */
size_t resident_size_bytes = 0;
/** Amount of memory actually used on the page. */
size_t used_size_bytes = 0;
/** Statistics for object allocated on the page. Filled only when
* NameProvider::SupportsCppClassNamesAsObjectNames() is true. */
std::vector<ObjectStatsEntry> object_statistics;
};
/**
* Statistics of the freelist (used only in non-large object spaces). For
* each bucket in the freelist the statistics record the bucket size, the
* number of freelist entries in the bucket, and the overall allocated memory
* consumed by these freelist entries.
*/
struct FreeListStatistics {
/** bucket sizes in the freelist. */
std::vector<size_t> bucket_size;
/** number of freelist entries per bucket. */
std::vector<size_t> free_count;
/** memory size consumed by freelist entries per size. */
std::vector<size_t> free_size;
};
/**
* Space granularity statistics. For each space the statistics record the
* space name, the amount of allocated memory and overall used memory for the
* space. The statistics also contain statistics for each of the space's
* pages, its freelist and the objects allocated on the space.
*/
struct SpaceStatistics {
/** The space name */
std::string name;
/** Overall committed amount of memory for the heap. */
size_t committed_size_bytes = 0;
/** Resident amount of memory held by the heap. */
size_t resident_size_bytes = 0;
/** Amount of memory actually used on the space. */
size_t used_size_bytes = 0;
/** Statistics for each of the pages in the space. */
std::vector<PageStatistics> page_stats;
/** Statistics for the freelist of the space. */
FreeListStatistics free_list_stats;
};
/** Overall committed amount of memory for the heap. */
size_t committed_size_bytes = 0;
/** Resident amount of memory held by the heap. */
size_t resident_size_bytes = 0;
/** Amount of memory actually used on the heap. */
size_t used_size_bytes = 0;
/** Memory retained in the page pool, not used directly by the heap. */
size_t pooled_memory_size_bytes = 0;
/** Detail level of this HeapStatistics. */
DetailLevel detail_level;
/** Statistics for each of the spaces in the heap. Filled only when
* `detail_level` is `DetailLevel::kDetailed`. */
std::vector<SpaceStatistics> space_stats;
/**
* Vector of `cppgc::GarbageCollected` type names.
*/
std::vector<std::string> type_names;
};
} // namespace cppgc
#endif // INCLUDE_CPPGC_HEAP_STATISTICS_H_

202
deps/v8/include/cppgc/heap.h vendored Normal file
View File

@ -0,0 +1,202 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_HEAP_H_
#define INCLUDE_CPPGC_HEAP_H_
#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>
#include "cppgc/common.h"
#include "cppgc/custom-space.h"
#include "cppgc/platform.h"
#include "v8config.h" // NOLINT(build/include_directory)
/**
* cppgc - A C++ garbage collection library.
*/
namespace cppgc {
class AllocationHandle;
class HeapHandle;
/**
* Implementation details of cppgc. Those details are considered internal and
* may change at any point in time without notice. Users should never rely on
* the contents of this namespace.
*/
namespace internal {
class Heap;
} // namespace internal
class V8_EXPORT Heap {
public:
/**
* Specifies the stack state the embedder is in.
*/
using StackState = EmbedderStackState;
/**
* Specifies whether conservative stack scanning is supported.
*/
enum class StackSupport : uint8_t {
/**
* Conservative stack scan is supported.
*/
kSupportsConservativeStackScan,
/**
* Conservative stack scan is not supported. Embedders may use this option
* when using custom infrastructure that is unsupported by the library.
*/
kNoConservativeStackScan,
};
/**
* Specifies supported marking types.
*/
enum class MarkingType : uint8_t {
/**
* Atomic stop-the-world marking. This option does not require any write
* barriers but is the most intrusive in terms of jank.
*/
kAtomic,
/**
* Incremental marking interleaves marking with the rest of the application
* workload on the same thread.
*/
kIncremental,
/**
* Incremental and concurrent marking.
*/
kIncrementalAndConcurrent
};
/**
* Specifies supported sweeping types.
*/
enum class SweepingType : uint8_t {
/**
* Atomic stop-the-world sweeping. All of sweeping is performed at once.
*/
kAtomic,
/**
* Incremental sweeping interleaves sweeping with the rest of the
* application workload on the same thread.
*/
kIncremental,
/**
* Incremental and concurrent sweeping. Sweeping is split and interleaved
* with the rest of the application.
*/
kIncrementalAndConcurrent
};
/**
* Constraints for a Heap setup.
*/
struct ResourceConstraints {
/**
* Allows the heap to grow to some initial size in bytes before triggering
* garbage collections. This is useful when it is known that applications
* need a certain minimum heap to run to avoid repeatedly invoking the
* garbage collector when growing the heap.
*/
size_t initial_heap_size_bytes = 0;
};
/**
* Options specifying Heap properties (e.g. custom spaces) when initializing a
* heap through `Heap::Create()`.
*/
struct HeapOptions {
/**
* Creates reasonable defaults for instantiating a Heap.
*
* \returns the HeapOptions that can be passed to `Heap::Create()`.
*/
static HeapOptions Default() { return {}; }
/**
* Custom spaces added to heap are required to have indices forming a
* numbered sequence starting at 0, i.e., their `kSpaceIndex` must
* correspond to the index they reside in the vector.
*/
std::vector<std::unique_ptr<CustomSpaceBase>> custom_spaces;
/**
* Specifies whether conservative stack scan is supported. When conservative
* stack scan is not supported, the collector may try to invoke
* garbage collections using non-nestable task, which are guaranteed to have
* no interesting stack, through the provided Platform. If such tasks are
* not supported by the Platform, the embedder must take care of invoking
* the GC through `ForceGarbageCollectionSlow()`.
*/
StackSupport stack_support = StackSupport::kSupportsConservativeStackScan;
/**
* Specifies which types of marking are supported by the heap.
*/
MarkingType marking_support = MarkingType::kIncrementalAndConcurrent;
/**
* Specifies which types of sweeping are supported by the heap.
*/
SweepingType sweeping_support = SweepingType::kIncrementalAndConcurrent;
/**
* Resource constraints specifying various properties that the internal
* GC scheduler follows.
*/
ResourceConstraints resource_constraints;
};
/**
* Creates a new heap that can be used for object allocation.
*
* \param platform implemented and provided by the embedder.
* \param options HeapOptions specifying various properties for the Heap.
* \returns a new Heap instance.
*/
static std::unique_ptr<Heap> Create(
std::shared_ptr<Platform> platform,
HeapOptions options = HeapOptions::Default());
virtual ~Heap() = default;
/**
* Forces garbage collection.
*
* \param source String specifying the source (or caller) triggering a
* forced garbage collection.
* \param reason String specifying the reason for the forced garbage
* collection.
* \param stack_state The embedder stack state, see StackState.
*/
void ForceGarbageCollectionSlow(
const char* source, const char* reason,
StackState stack_state = StackState::kMayContainHeapPointers);
/**
* \returns the opaque handle for allocating objects using
* `MakeGarbageCollected()`.
*/
AllocationHandle& GetAllocationHandle();
/**
* \returns the opaque heap handle which may be used to refer to this heap in
* other APIs. Valid as long as the underlying `Heap` is alive.
*/
HeapHandle& GetHeapHandle();
private:
Heap() = default;
friend class internal::Heap;
};
} // namespace cppgc
#endif // INCLUDE_CPPGC_HEAP_H_

View File

@ -0,0 +1,75 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_API_CONSTANTS_H_
#define INCLUDE_CPPGC_INTERNAL_API_CONSTANTS_H_
#include <cstddef>
#include <cstdint>
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
// Embedders should not rely on this code!
// Internal constants to avoid exposing internal types on the API surface.
namespace api_constants {
constexpr size_t kKB = 1024;
constexpr size_t kMB = kKB * 1024;
constexpr size_t kGB = kMB * 1024;
// Offset of the uint16_t bitfield from the payload contaning the
// in-construction bit. This is subtracted from the payload pointer to get
// to the right bitfield.
static constexpr size_t kFullyConstructedBitFieldOffsetFromPayload =
2 * sizeof(uint16_t);
// Mask for in-construction bit.
static constexpr uint16_t kFullyConstructedBitMask = uint16_t{1};
static constexpr size_t kPageSizeBits = 17;
static constexpr size_t kPageSize = size_t{1} << kPageSizeBits;
static constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2;
#if defined(CPPGC_POINTER_COMPRESSION)
#if defined(CPPGC_ENABLE_LARGER_CAGE)
constexpr unsigned kPointerCompressionShift = 3;
#else // !defined(CPPGC_ENABLE_LARGER_CAGE)
constexpr unsigned kPointerCompressionShift = 1;
#endif // !defined(CPPGC_ENABLE_LARGER_CAGE)
#endif // !defined(CPPGC_POINTER_COMPRESSION)
#if defined(CPPGC_CAGED_HEAP)
constexpr size_t kCagedHeapDefaultReservationSize =
static_cast<size_t>(4) * kGB;
#if defined(CPPGC_POINTER_COMPRESSION)
constexpr size_t kCagedHeapMaxReservationSize =
size_t{1} << (31 + kPointerCompressionShift);
#else // !defined(CPPGC_POINTER_COMPRESSION)
constexpr size_t kCagedHeapMaxReservationSize =
kCagedHeapDefaultReservationSize;
#endif // !defined(CPPGC_POINTER_COMPRESSION)
constexpr size_t kCagedHeapReservationAlignment = kCagedHeapMaxReservationSize;
#endif // defined(CPPGC_CAGED_HEAP)
static constexpr size_t kDefaultAlignment = sizeof(void*);
// Maximum support alignment for a type as in `alignof(T)`.
static constexpr size_t kMaxSupportedAlignment = 2 * kDefaultAlignment;
// Granularity of heap allocations.
constexpr size_t kAllocationGranularity = sizeof(void*);
// Default cacheline size.
constexpr size_t kCachelineSize = 64;
} // namespace api_constants
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_API_CONSTANTS_H_

View File

@ -0,0 +1,48 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_
#define INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_
#include <atomic>
namespace cppgc {
namespace internal {
// A flag which provides a fast check whether a scope may be entered on the
// current thread, without needing to access thread-local storage or mutex. Can
// have false positives (i.e., spuriously report that it might be entered), so
// it is expected that this will be used in tandem with a precise check that the
// scope is in fact entered on that thread.
//
// Example:
// g_frobnicating_flag.MightBeEntered() &&
// ThreadLocalFrobnicator().IsFrobnicating()
//
// Relaxed atomic operations are sufficient, since:
// - all accesses remain atomic
// - each thread must observe its own operations in order
// - no thread ever exits the flag more times than it enters (if used correctly)
// And so if a thread observes zero, it must be because it has observed an equal
// number of exits as entries.
class AtomicEntryFlag final {
public:
void Enter() { entries_.fetch_add(1, std::memory_order_relaxed); }
void Exit() { entries_.fetch_sub(1, std::memory_order_relaxed); }
// Returns false only if the current thread is not between a call to Enter
// and a call to Exit. Returns true if this thread or another thread may
// currently be in the scope guarded by this flag.
bool MightBeEntered() const {
return entries_.load(std::memory_order_relaxed) != 0;
}
private:
std::atomic_int entries_{0};
};
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_

View File

@ -0,0 +1,43 @@
// 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 INCLUDE_CPPGC_INTERNAL_BASE_PAGE_HANDLE_H_
#define INCLUDE_CPPGC_INTERNAL_BASE_PAGE_HANDLE_H_
#include "cppgc/heap-handle.h"
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/logging.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
// The class is needed in the header to allow for fast access to HeapHandle in
// the write barrier.
class BasePageHandle {
public:
static V8_INLINE BasePageHandle* FromPayload(void* payload) {
return reinterpret_cast<BasePageHandle*>(
reinterpret_cast<uintptr_t>(payload) & ~(api_constants::kPageSize - 1));
}
static V8_INLINE const BasePageHandle* FromPayload(const void* payload) {
return FromPayload(const_cast<void*>(payload));
}
HeapHandle& heap_handle() { return heap_handle_; }
const HeapHandle& heap_handle() const { return heap_handle_; }
protected:
explicit BasePageHandle(HeapHandle& heap_handle) : heap_handle_(heap_handle) {
CPPGC_DCHECK(reinterpret_cast<uintptr_t>(this) % api_constants::kPageSize ==
0);
}
HeapHandle& heap_handle_;
};
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_BASE_PAGE_HANDLE_H_

View File

@ -0,0 +1,117 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
#define INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
#include <array>
#include <cstddef>
#include <cstdint>
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/caged-heap.h"
#include "cppgc/internal/logging.h"
#include "cppgc/platform.h"
#include "v8config.h" // NOLINT(build/include_directory)
#if __cpp_lib_bitopts
#include <bit>
#endif // __cpp_lib_bitopts
#if defined(CPPGC_CAGED_HEAP)
namespace cppgc {
namespace internal {
class HeapBase;
class HeapBaseHandle;
#if defined(CPPGC_YOUNG_GENERATION)
// AgeTable is the bytemap needed for the fast generation check in the write
// barrier. AgeTable contains entries that correspond to 4096 bytes memory
// regions (cards). Each entry in the table represents generation of the objects
// that reside on the corresponding card (young, old or mixed).
class V8_EXPORT AgeTable final {
static constexpr size_t kRequiredSize = 1 * api_constants::kMB;
static constexpr size_t kAllocationGranularity =
api_constants::kAllocationGranularity;
public:
// Represents age of the objects living on a single card.
enum class Age : uint8_t { kOld, kYoung, kMixed };
// When setting age for a range, consider or ignore ages of the adjacent
// cards.
enum class AdjacentCardsPolicy : uint8_t { kConsider, kIgnore };
static constexpr size_t kCardSizeInBytes =
api_constants::kCagedHeapDefaultReservationSize / kRequiredSize;
static constexpr size_t CalculateAgeTableSizeForHeapSize(size_t heap_size) {
return heap_size / kCardSizeInBytes;
}
void SetAge(uintptr_t cage_offset, Age age) {
table_[card(cage_offset)] = age;
}
V8_INLINE Age GetAge(uintptr_t cage_offset) const {
return table_[card(cage_offset)];
}
void SetAgeForRange(uintptr_t cage_offset_begin, uintptr_t cage_offset_end,
Age age, AdjacentCardsPolicy adjacent_cards_policy);
Age GetAgeForRange(uintptr_t cage_offset_begin,
uintptr_t cage_offset_end) const;
void ResetForTesting();
private:
V8_INLINE size_t card(uintptr_t offset) const {
constexpr size_t kGranularityBits =
#if __cpp_lib_bitopts
std::countr_zero(static_cast<uint32_t>(kCardSizeInBytes));
#elif V8_HAS_BUILTIN_CTZ
__builtin_ctz(static_cast<uint32_t>(kCardSizeInBytes));
#else //! V8_HAS_BUILTIN_CTZ
// Hardcode and check with assert.
12;
#endif // !V8_HAS_BUILTIN_CTZ
static_assert((1 << kGranularityBits) == kCardSizeInBytes);
const size_t entry = offset >> kGranularityBits;
CPPGC_DCHECK(CagedHeapBase::GetAgeTableSize() > entry);
return entry;
}
#if defined(V8_CC_GNU)
// gcc disallows flexible arrays in otherwise empty classes.
Age table_[0];
#else // !defined(V8_CC_GNU)
Age table_[];
#endif // !defined(V8_CC_GNU)
};
#endif // CPPGC_YOUNG_GENERATION
struct CagedHeapLocalData final {
V8_INLINE static CagedHeapLocalData& Get() {
return *reinterpret_cast<CagedHeapLocalData*>(CagedHeapBase::GetBase());
}
static constexpr size_t CalculateLocalDataSizeForHeapSize(size_t heap_size) {
return AgeTable::CalculateAgeTableSizeForHeapSize(heap_size);
}
#if defined(CPPGC_YOUNG_GENERATION)
AgeTable age_table;
#endif
};
} // namespace internal
} // namespace cppgc
#endif // defined(CPPGC_CAGED_HEAP)
#endif // INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_

View File

@ -0,0 +1,64 @@
// 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 INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_
#define INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_
#include <climits>
#include <cstddef>
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/base-page-handle.h"
#include "v8config.h" // NOLINT(build/include_directory)
#if defined(CPPGC_CAGED_HEAP)
namespace cppgc {
namespace internal {
class V8_EXPORT CagedHeapBase {
public:
V8_INLINE static uintptr_t OffsetFromAddress(const void* address) {
return reinterpret_cast<uintptr_t>(address) &
(api_constants::kCagedHeapReservationAlignment - 1);
}
V8_INLINE static bool IsWithinCage(const void* address) {
CPPGC_DCHECK(g_heap_base_);
return (reinterpret_cast<uintptr_t>(address) &
~(api_constants::kCagedHeapReservationAlignment - 1)) ==
g_heap_base_;
}
V8_INLINE static bool AreWithinCage(const void* addr1, const void* addr2) {
#if defined(CPPGC_POINTER_COMPRESSION)
static constexpr size_t kHeapBaseShift =
31 + api_constants::kPointerCompressionShift;
#else // !defined(CPPGC_POINTER_COMPRESSION)
static constexpr size_t kHeapBaseShift = sizeof(uint32_t) * CHAR_BIT;
#endif // !defined(CPPGC_POINTER_COMPRESSION)
static_assert((static_cast<size_t>(1) << kHeapBaseShift) ==
api_constants::kCagedHeapMaxReservationSize);
CPPGC_DCHECK(g_heap_base_);
return !(((reinterpret_cast<uintptr_t>(addr1) ^ g_heap_base_) |
(reinterpret_cast<uintptr_t>(addr2) ^ g_heap_base_)) >>
kHeapBaseShift);
}
V8_INLINE static uintptr_t GetBase() { return g_heap_base_; }
V8_INLINE static size_t GetAgeTableSize() { return g_age_table_size_; }
private:
friend class CagedHeap;
static uintptr_t g_heap_base_;
static size_t g_age_table_size_;
};
} // namespace internal
} // namespace cppgc
#endif // defined(CPPGC_CAGED_HEAP)
#endif // INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_

View File

@ -0,0 +1,46 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_COMPILER_SPECIFIC_H_
#define INCLUDE_CPPGC_INTERNAL_COMPILER_SPECIFIC_H_
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
#if defined(__has_attribute)
#define CPPGC_HAS_ATTRIBUTE(FEATURE) __has_attribute(FEATURE)
#else
#define CPPGC_HAS_ATTRIBUTE(FEATURE) 0
#endif
#if defined(__has_cpp_attribute)
#define CPPGC_HAS_CPP_ATTRIBUTE(FEATURE) __has_cpp_attribute(FEATURE)
#else
#define CPPGC_HAS_CPP_ATTRIBUTE(FEATURE) 0
#endif
// [[no_unique_address]] comes in C++20 but supported in clang with -std >=
// c++11.
#if defined(V8_CC_MSVC) && CPPGC_HAS_CPP_ATTRIBUTE(msvc::no_unique_address)
// Unfortunately MSVC ignores [[no_unique_address]] (see
// https://devblogs.microsoft.com/cppblog/msvc-cpp20-and-the-std-cpp20-switch/#msvc-extensions-and-abi),
// and clang-cl matches it for ABI compatibility reasons. We need to prefer
// [[msvc::no_unique_address]] when available if we actually want any effect.
#define CPPGC_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
#elif CPPGC_HAS_CPP_ATTRIBUTE(no_unique_address)
#define CPPGC_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else
#define CPPGC_NO_UNIQUE_ADDRESS
#endif
#if CPPGC_HAS_ATTRIBUTE(unused)
#define CPPGC_UNUSED __attribute__((unused))
#else
#define CPPGC_UNUSED
#endif
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_COMPILER_SPECIFIC_H_

View File

@ -0,0 +1,41 @@
// 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.
#ifndef INCLUDE_CPPGC_INTERNAL_CONDITIONAL_STACK_ALLOCATED_H_
#define INCLUDE_CPPGC_INTERNAL_CONDITIONAL_STACK_ALLOCATED_H_
#include <type_traits>
#include "cppgc/macros.h" // NOLINT(build/include_directory)
#include "cppgc/type-traits.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
// Base class that is marked as stack allocated if T is either marked as stack
// allocated or a traceable type.
template <typename T>
class ConditionalStackAllocatedBase;
template <typename T>
concept RequiresStackAllocated =
!std::is_void_v<T> &&
(cppgc::IsStackAllocatedType<T> || cppgc::internal::IsTraceableV<T> ||
cppgc::IsGarbageCollectedOrMixinTypeV<T>);
template <typename T>
requires(RequiresStackAllocated<T>)
class ConditionalStackAllocatedBase<T> {
public:
CPPGC_STACK_ALLOCATED();
};
template <typename T>
requires(!RequiresStackAllocated<T>)
class ConditionalStackAllocatedBase<T> {};
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_CONDITIONAL_STACK_ALLOCATED_H_

View File

@ -0,0 +1,93 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_
#define INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_
#include <type_traits>
#include "cppgc/type-traits.h"
namespace cppgc {
namespace internal {
using FinalizationCallback = void (*)(void*);
template <typename T, typename = void>
struct HasFinalizeGarbageCollectedObject : std::false_type {};
template <typename T>
struct HasFinalizeGarbageCollectedObject<
T,
std::void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>>
: std::true_type {};
// The FinalizerTraitImpl specifies how to finalize objects.
template <typename T, bool isFinalized>
struct FinalizerTraitImpl;
template <typename T>
struct FinalizerTraitImpl<T, true> {
private:
// Dispatch to custom FinalizeGarbageCollectedObject().
struct Custom {
static void Call(void* obj) {
static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
}
};
// Dispatch to regular destructor.
struct Destructor {
static void Call(void* obj) { static_cast<T*>(obj)->~T(); }
};
using FinalizeImpl =
std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value, Custom,
Destructor>;
public:
static void Finalize(void* obj) {
static_assert(sizeof(T), "T must be fully defined");
FinalizeImpl::Call(obj);
}
};
template <typename T>
struct FinalizerTraitImpl<T, false> {
static void Finalize(void* obj) {
static_assert(sizeof(T), "T must be fully defined");
}
};
// The FinalizerTrait is used to determine if a type requires finalization and
// what finalization means.
template <typename T>
struct FinalizerTrait {
private:
// Object has a finalizer if it has
// - a custom FinalizeGarbageCollectedObject method, or
// - a destructor.
static constexpr bool kNonTrivialFinalizer =
internal::HasFinalizeGarbageCollectedObject<T>::value ||
!std::is_trivially_destructible<typename std::remove_cv<T>::type>::value;
static void Finalize(void* obj) {
internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj);
}
public:
static constexpr bool HasFinalizer() { return kNonTrivialFinalizer; }
// The callback used to finalize an object of type T.
static constexpr FinalizationCallback kCallback =
kNonTrivialFinalizer ? Finalize : nullptr;
};
template <typename T>
constexpr FinalizationCallback FinalizerTrait<T>::kCallback;
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_

150
deps/v8/include/cppgc/internal/gc-info.h vendored Normal file
View File

@ -0,0 +1,150 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_GC_INFO_H_
#define INCLUDE_CPPGC_INTERNAL_GC_INFO_H_
#include <atomic>
#include <cstdint>
#include <type_traits>
#include "cppgc/internal/finalizer-trait.h"
#include "cppgc/internal/logging.h"
#include "cppgc/internal/name-trait.h"
#include "cppgc/trace-trait.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
using GCInfoIndex = uint16_t;
struct V8_EXPORT EnsureGCInfoIndexTrait final {
// Acquires a new GC info object and updates `registered_index` with the index
// that identifies that new info accordingly.
template <typename T>
V8_INLINE static GCInfoIndex EnsureIndex(
std::atomic<GCInfoIndex>& registered_index) {
return EnsureGCInfoIndexTraitDispatch<T>{}(registered_index);
}
private:
template <typename T, bool = FinalizerTrait<T>::HasFinalizer(),
bool = NameTrait<T>::HasNonHiddenName()>
struct EnsureGCInfoIndexTraitDispatch;
static GCInfoIndex V8_PRESERVE_MOST
EnsureGCInfoIndex(std::atomic<GCInfoIndex>&, TraceCallback,
FinalizationCallback, NameCallback);
static GCInfoIndex V8_PRESERVE_MOST EnsureGCInfoIndex(
std::atomic<GCInfoIndex>&, TraceCallback, FinalizationCallback);
static GCInfoIndex V8_PRESERVE_MOST
EnsureGCInfoIndex(std::atomic<GCInfoIndex>&, TraceCallback, NameCallback);
static GCInfoIndex V8_PRESERVE_MOST
EnsureGCInfoIndex(std::atomic<GCInfoIndex>&, TraceCallback);
};
#define DISPATCH(has_finalizer, has_non_hidden_name, function) \
template <typename T> \
struct EnsureGCInfoIndexTrait::EnsureGCInfoIndexTraitDispatch< \
T, has_finalizer, has_non_hidden_name> { \
V8_INLINE GCInfoIndex \
operator()(std::atomic<GCInfoIndex>& registered_index) { \
return function; \
} \
};
// ------------------------------------------------------- //
// DISPATCH(has_finalizer, has_non_hidden_name, function) //
// ------------------------------------------------------- //
DISPATCH(true, true, //
EnsureGCInfoIndex(registered_index, //
TraceTrait<T>::Trace, //
FinalizerTrait<T>::kCallback, //
NameTrait<T>::GetName)) //
DISPATCH(true, false, //
EnsureGCInfoIndex(registered_index, //
TraceTrait<T>::Trace, //
FinalizerTrait<T>::kCallback)) //
DISPATCH(false, true, //
EnsureGCInfoIndex(registered_index, //
TraceTrait<T>::Trace, //
NameTrait<T>::GetName)) //
DISPATCH(false, false, //
EnsureGCInfoIndex(registered_index, //
TraceTrait<T>::Trace)) //
#undef DISPATCH
// Trait determines how the garbage collector treats objects wrt. to traversing,
// finalization, and naming.
template <typename T>
struct GCInfoTrait final {
V8_INLINE static GCInfoIndex Index() {
static_assert(sizeof(T), "T must be fully defined");
static std::atomic<GCInfoIndex>
registered_index; // Uses zero initialization.
GCInfoIndex index = registered_index.load(std::memory_order_acquire);
if (V8_UNLIKELY(!index)) {
index = EnsureGCInfoIndexTrait::EnsureIndex<T>(registered_index);
CPPGC_DCHECK(index != 0);
CPPGC_DCHECK(index == registered_index.load(std::memory_order_acquire));
}
return index;
}
static constexpr void CheckCallbacksAreDefined() {
// No USE() macro available.
(void)static_cast<TraceCallback>(TraceTrait<T>::Trace);
(void)static_cast<FinalizationCallback>(FinalizerTrait<T>::kCallback);
(void)static_cast<NameCallback>(NameTrait<T>::GetName);
}
};
// Fold types based on finalizer behavior. Note that finalizer characteristics
// align with trace behavior, i.e., destructors are virtual when trace methods
// are and vice versa.
template <typename T, typename ParentMostGarbageCollectedType>
struct GCInfoFolding final {
static constexpr bool kHasVirtualDestructorAtBase =
std::has_virtual_destructor<ParentMostGarbageCollectedType>::value;
static constexpr bool kBothTypesAreTriviallyDestructible =
std::is_trivially_destructible<ParentMostGarbageCollectedType>::value &&
std::is_trivially_destructible<T>::value;
static constexpr bool kHasCustomFinalizerDispatchAtBase =
internal::HasFinalizeGarbageCollectedObject<
ParentMostGarbageCollectedType>::value;
#ifdef CPPGC_SUPPORTS_OBJECT_NAMES
static constexpr bool kWantsDetailedObjectNames = true;
#else // !CPPGC_SUPPORTS_OBJECT_NAMES
static constexpr bool kWantsDetailedObjectNames = false;
#endif // !CPPGC_SUPPORTS_OBJECT_NAMES
// Always true. Forces the compiler to resolve callbacks which ensures that
// both modes don't break without requiring compiling a separate
// configuration. Only a single GCInfo (for `ResultType` below) will actually
// be instantiated but existence (and well-formedness) of all callbacks is
// checked.
static constexpr bool WantToFold() {
if constexpr ((kHasVirtualDestructorAtBase ||
kBothTypesAreTriviallyDestructible ||
kHasCustomFinalizerDispatchAtBase) &&
!kWantsDetailedObjectNames) {
GCInfoTrait<T>::CheckCallbacksAreDefined();
GCInfoTrait<ParentMostGarbageCollectedType>::CheckCallbacksAreDefined();
return true;
}
return false;
}
// Folding would regress name resolution when deriving names from C++
// class names as it would just folds a name to the base class name.
using ResultType =
std::conditional_t<WantToFold(), ParentMostGarbageCollectedType, T>;
};
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_GC_INFO_H_

View File

@ -0,0 +1,50 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_LOGGING_H_
#define INCLUDE_CPPGC_INTERNAL_LOGGING_H_
#include "cppgc/source-location.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
void V8_EXPORT DCheckImpl(const char*,
const SourceLocation& = SourceLocation::Current());
[[noreturn]] void V8_EXPORT
FatalImpl(const char*, const SourceLocation& = SourceLocation::Current());
// Used to ignore -Wunused-variable.
template <typename>
struct EatParams {};
#ifdef CPPGC_ENABLE_API_CHECKS
#define CPPGC_DCHECK_MSG(condition, message) \
do { \
if (V8_UNLIKELY(!(condition))) { \
::cppgc::internal::DCheckImpl(message); \
} \
} while (false)
#else // !CPPGC_ENABLE_API_CHECKS
#define CPPGC_DCHECK_MSG(condition, message) \
(static_cast<void>(::cppgc::internal::EatParams<decltype( \
static_cast<void>(condition), message)>{}))
#endif // !CPPGC_ENABLE_API_CHECKS
#define CPPGC_DCHECK(condition) CPPGC_DCHECK_MSG(condition, #condition)
#define CPPGC_CHECK_MSG(condition, message) \
do { \
if (V8_UNLIKELY(!(condition))) { \
::cppgc::internal::FatalImpl(message); \
} \
} while (false)
#define CPPGC_CHECK(condition) CPPGC_CHECK_MSG(condition, #condition)
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_LOGGING_H_

View File

@ -0,0 +1,305 @@
// 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 INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_
#define INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_
#include <atomic>
#include <cstddef>
#include <type_traits>
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/caged-heap.h"
#include "cppgc/internal/logging.h"
#include "cppgc/sentinel-pointer.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
enum class WriteBarrierSlotType {
kCompressed,
kUncompressed,
};
#if defined(CPPGC_POINTER_COMPRESSION)
#if defined(__clang__)
// Attribute const allows the compiler to assume that CageBaseGlobal::g_base_
// doesn't change (e.g. across calls) and thereby avoid redundant loads.
#define CPPGC_CONST __attribute__((const))
#define CPPGC_REQUIRE_CONSTANT_INIT \
__attribute__((require_constant_initialization))
#else // defined(__clang__)
#define CPPGC_CONST
#define CPPGC_REQUIRE_CONSTANT_INIT
#endif // defined(__clang__)
class V8_EXPORT CageBaseGlobal final {
public:
V8_INLINE CPPGC_CONST static uintptr_t Get() {
CPPGC_DCHECK(IsBaseConsistent());
return g_base_.base;
}
V8_INLINE CPPGC_CONST static bool IsSet() {
CPPGC_DCHECK(IsBaseConsistent());
return (g_base_.base & ~kLowerHalfWordMask) != 0;
}
private:
// We keep the lower halfword as ones to speed up decompression.
static constexpr uintptr_t kLowerHalfWordMask =
(api_constants::kCagedHeapReservationAlignment - 1);
static union alignas(api_constants::kCachelineSize) Base {
uintptr_t base;
char cache_line[api_constants::kCachelineSize];
} g_base_ CPPGC_REQUIRE_CONSTANT_INIT;
CageBaseGlobal() = delete;
V8_INLINE static bool IsBaseConsistent() {
return kLowerHalfWordMask == (g_base_.base & kLowerHalfWordMask);
}
friend class CageBaseGlobalUpdater;
};
#undef CPPGC_REQUIRE_CONSTANT_INIT
#undef CPPGC_CONST
class V8_TRIVIAL_ABI CompressedPointer final {
public:
struct AtomicInitializerTag {};
using IntegralType = uint32_t;
static constexpr auto kWriteBarrierSlotType =
WriteBarrierSlotType::kCompressed;
V8_INLINE CompressedPointer() : value_(0u) {}
V8_INLINE explicit CompressedPointer(const void* value,
AtomicInitializerTag) {
StoreAtomic(value);
}
V8_INLINE explicit CompressedPointer(const void* ptr)
: value_(Compress(ptr)) {}
V8_INLINE explicit CompressedPointer(std::nullptr_t) : value_(0u) {}
V8_INLINE explicit CompressedPointer(SentinelPointer)
: value_(kCompressedSentinel) {}
V8_INLINE const void* Load() const { return Decompress(value_); }
V8_INLINE const void* LoadAtomic() const {
return Decompress(
reinterpret_cast<const std::atomic<IntegralType>&>(value_).load(
std::memory_order_relaxed));
}
V8_INLINE void Store(const void* ptr) { value_ = Compress(ptr); }
V8_INLINE void StoreAtomic(const void* value) {
reinterpret_cast<std::atomic<IntegralType>&>(value_).store(
Compress(value), std::memory_order_relaxed);
}
V8_INLINE void Clear() { value_ = 0u; }
V8_INLINE bool IsCleared() const { return !value_; }
V8_INLINE bool IsSentinel() const { return value_ == kCompressedSentinel; }
V8_INLINE uint32_t GetAsInteger() const { return value_; }
V8_INLINE friend bool operator==(CompressedPointer a, CompressedPointer b) {
return a.value_ == b.value_;
}
V8_INLINE friend bool operator!=(CompressedPointer a, CompressedPointer b) {
return a.value_ != b.value_;
}
V8_INLINE friend bool operator<(CompressedPointer a, CompressedPointer b) {
return a.value_ < b.value_;
}
V8_INLINE friend bool operator<=(CompressedPointer a, CompressedPointer b) {
return a.value_ <= b.value_;
}
V8_INLINE friend bool operator>(CompressedPointer a, CompressedPointer b) {
return a.value_ > b.value_;
}
V8_INLINE friend bool operator>=(CompressedPointer a, CompressedPointer b) {
return a.value_ >= b.value_;
}
static V8_INLINE IntegralType Compress(const void* ptr) {
static_assert(SentinelPointer::kSentinelValue ==
1 << api_constants::kPointerCompressionShift,
"The compression scheme relies on the sentinel encoded as 1 "
"<< kPointerCompressionShift");
static constexpr size_t kGigaCageMask =
~(api_constants::kCagedHeapReservationAlignment - 1);
static constexpr size_t kPointerCompressionShiftMask =
(1 << api_constants::kPointerCompressionShift) - 1;
CPPGC_DCHECK(CageBaseGlobal::IsSet());
const uintptr_t base = CageBaseGlobal::Get();
CPPGC_DCHECK(!ptr || ptr == kSentinelPointer ||
(base & kGigaCageMask) ==
(reinterpret_cast<uintptr_t>(ptr) & kGigaCageMask));
CPPGC_DCHECK(
(reinterpret_cast<uintptr_t>(ptr) & kPointerCompressionShiftMask) == 0);
const auto uptr = reinterpret_cast<uintptr_t>(ptr);
// Shift the pointer and truncate.
auto compressed = static_cast<IntegralType>(
uptr >> api_constants::kPointerCompressionShift);
// Normal compressed pointers must have the MSB set. This is guaranteed by
// the cage alignment.
CPPGC_DCHECK((!compressed || compressed == kCompressedSentinel) ||
(compressed & (1 << 31)));
return compressed;
}
static V8_INLINE void* Decompress(IntegralType ptr) {
CPPGC_DCHECK(CageBaseGlobal::IsSet());
const uintptr_t base = CageBaseGlobal::Get();
return Decompress(ptr, base);
}
static V8_INLINE void* Decompress(IntegralType ptr, uintptr_t base) {
CPPGC_DCHECK(CageBaseGlobal::IsSet());
CPPGC_DCHECK(base == CageBaseGlobal::Get());
// Sign-extend compressed pointer to full width. This ensure that normal
// pointers have only 1s in the base part of the address. It's also
// important to shift the unsigned value, as otherwise it would result in
// undefined behavior.
const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr))
<< api_constants::kPointerCompressionShift;
// Set the base part of the address for normal compressed pointers. Note
// that nullptr and the sentinel value do not have 1s in the base part and
// remain as-is in this operation.
return reinterpret_cast<void*>(mask & base);
}
// For a given memory `address`, this method iterates all possible pointers
// that can be reasonably recovered with the current compression scheme and
// passes them to `callback`.
template <typename Callback>
static V8_INLINE void VisitPossiblePointers(const void* address,
Callback callback);
private:
static constexpr IntegralType kCompressedSentinel =
SentinelPointer::kSentinelValue >>
api_constants::kPointerCompressionShift;
// All constructors initialize `value_`. Do not add a default value here as it
// results in a non-atomic write on some builds, even when the atomic version
// of the constructor is used.
IntegralType value_;
};
template <typename Callback>
// static
void CompressedPointer::VisitPossiblePointers(const void* address,
Callback callback) {
const uintptr_t base = CageBaseGlobal::Get();
CPPGC_DCHECK(base);
// We may have random compressed pointers on stack (e.g. due to inlined
// collections). These could be present in both halfwords.
const uint32_t compressed_low =
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(address));
callback(CompressedPointer::Decompress(compressed_low, base));
const uint32_t compressed_high = static_cast<uint32_t>(
reinterpret_cast<uintptr_t>(address) >> (sizeof(uint32_t) * CHAR_BIT));
callback(CompressedPointer::Decompress(compressed_high, base));
// Iterate possible intermediate values, see `Decompress()`. The intermediate
// value of decompressing is a 64-bit value where 35 bits are the offset. We
// don't assume sign extension is stored and recover that part.
//
// Note that this case conveniently also recovers the full pointer.
static constexpr uintptr_t kBitForIntermediateValue =
(sizeof(uint32_t) * CHAR_BIT) + api_constants::kPointerCompressionShift;
static constexpr uintptr_t kSignExtensionMask =
~((uintptr_t{1} << kBitForIntermediateValue) - 1);
const uintptr_t intermediate_sign_extended =
reinterpret_cast<uintptr_t>(address) | kSignExtensionMask;
callback(reinterpret_cast<void*>(intermediate_sign_extended & base));
}
#endif // defined(CPPGC_POINTER_COMPRESSION)
class V8_TRIVIAL_ABI RawPointer final {
public:
struct AtomicInitializerTag {};
using IntegralType = uintptr_t;
static constexpr auto kWriteBarrierSlotType =
WriteBarrierSlotType::kUncompressed;
V8_INLINE RawPointer() : ptr_(nullptr) {}
V8_INLINE explicit RawPointer(const void* ptr, AtomicInitializerTag) {
StoreAtomic(ptr);
}
V8_INLINE explicit RawPointer(const void* ptr) : ptr_(ptr) {}
V8_INLINE const void* Load() const { return ptr_; }
V8_INLINE const void* LoadAtomic() const {
return reinterpret_cast<const std::atomic<const void*>&>(ptr_).load(
std::memory_order_relaxed);
}
V8_INLINE void Store(const void* ptr) { ptr_ = ptr; }
V8_INLINE void StoreAtomic(const void* ptr) {
reinterpret_cast<std::atomic<const void*>&>(ptr_).store(
ptr, std::memory_order_relaxed);
}
V8_INLINE void Clear() { ptr_ = nullptr; }
V8_INLINE bool IsCleared() const { return !ptr_; }
V8_INLINE bool IsSentinel() const { return ptr_ == kSentinelPointer; }
V8_INLINE uintptr_t GetAsInteger() const {
return reinterpret_cast<uintptr_t>(ptr_);
}
V8_INLINE friend bool operator==(RawPointer a, RawPointer b) {
return a.ptr_ == b.ptr_;
}
V8_INLINE friend bool operator!=(RawPointer a, RawPointer b) {
return a.ptr_ != b.ptr_;
}
V8_INLINE friend bool operator<(RawPointer a, RawPointer b) {
return a.ptr_ < b.ptr_;
}
V8_INLINE friend bool operator<=(RawPointer a, RawPointer b) {
return a.ptr_ <= b.ptr_;
}
V8_INLINE friend bool operator>(RawPointer a, RawPointer b) {
return a.ptr_ > b.ptr_;
}
V8_INLINE friend bool operator>=(RawPointer a, RawPointer b) {
return a.ptr_ >= b.ptr_;
}
template <typename Callback>
static V8_INLINE void VisitPossiblePointers(const void* address,
Callback callback) {
// Pass along the full pointer.
return callback(const_cast<void*>(address));
}
private:
// All constructors initialize `ptr_`. Do not add a default value here as it
// results in a non-atomic write on some builds, even when the atomic version
// of the constructor is used.
const void* ptr_;
};
#if defined(CPPGC_POINTER_COMPRESSION)
using DefaultMemberStorage = CompressedPointer;
#else // !defined(CPPGC_POINTER_COMPRESSION)
using DefaultMemberStorage = RawPointer;
#endif // !defined(CPPGC_POINTER_COMPRESSION)
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_

View File

@ -0,0 +1,141 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
#define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include "cppgc/name-provider.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
#if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__)
#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 1
// Provides constexpr c-string storage for a name of fixed |Size| characters.
// Automatically appends terminating 0 byte.
template <size_t Size>
struct NameBuffer {
char name[Size + 1]{};
static constexpr NameBuffer FromCString(const char* str) {
NameBuffer result;
for (size_t i = 0; i < Size; ++i) result.name[i] = str[i];
result.name[Size] = 0;
return result;
}
};
template <typename T>
const char* GetTypename() {
static constexpr char kSelfPrefix[] =
"const char *cppgc::internal::GetTypename() [T =";
static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix,
sizeof(kSelfPrefix) - 1) == 0,
"The prefix must match");
static constexpr const char* kTypenameStart =
__PRETTY_FUNCTION__ + sizeof(kSelfPrefix);
static constexpr size_t kTypenameSize =
__builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1;
// NameBuffer is an indirection that is needed to make sure that only a
// substring of __PRETTY_FUNCTION__ gets materialized in the binary.
static constexpr auto buffer =
NameBuffer<kTypenameSize>::FromCString(kTypenameStart);
return buffer.name;
}
#else
#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 0
#endif
struct HeapObjectName {
const char* value;
bool name_was_hidden;
};
enum class HeapObjectNameForUnnamedObject : uint8_t {
kUseClassNameIfSupported,
kUseHiddenName,
};
class V8_EXPORT NameTraitBase {
protected:
static HeapObjectName GetNameFromTypeSignature(const char*);
};
// Trait that specifies how the garbage collector retrieves the name for a
// given object.
template <typename T>
class NameTrait final : public NameTraitBase {
public:
static constexpr bool HasNonHiddenName() {
#if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
return true;
#elif CPPGC_SUPPORTS_OBJECT_NAMES
return true;
#else // !CPPGC_SUPPORTS_OBJECT_NAMES
return std::is_base_of<NameProvider, T>::value;
#endif // !CPPGC_SUPPORTS_OBJECT_NAMES
}
static HeapObjectName GetName(
const void* obj, HeapObjectNameForUnnamedObject name_retrieval_mode) {
return GetNameFor(static_cast<const T*>(obj), name_retrieval_mode);
}
private:
static HeapObjectName GetNameFor(const NameProvider* name_provider,
HeapObjectNameForUnnamedObject) {
// Objects inheriting from `NameProvider` are not considered unnamed as
// users already provided a name for them.
return {name_provider->GetHumanReadableName(), false};
}
static HeapObjectName GetNameFor(
const void*, HeapObjectNameForUnnamedObject name_retrieval_mode) {
if (name_retrieval_mode == HeapObjectNameForUnnamedObject::kUseHiddenName)
return {NameProvider::kHiddenName, true};
#if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
return {GetTypename<T>(), false};
#elif CPPGC_SUPPORTS_OBJECT_NAMES
#if defined(V8_CC_GNU)
#define PRETTY_FUNCTION_VALUE __PRETTY_FUNCTION__
#elif defined(V8_CC_MSVC)
#define PRETTY_FUNCTION_VALUE __FUNCSIG__
#else
#define PRETTY_FUNCTION_VALUE nullptr
#endif
static const HeapObjectName leaky_name =
GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE);
return leaky_name;
#undef PRETTY_FUNCTION_VALUE
#else // !CPPGC_SUPPORTS_OBJECT_NAMES
// We wanted to use a class name but were unable to provide one due to
// compiler limitations or build configuration. As such, return the hidden
// name with name_was_hidden=false, which will cause this object to be
// visible in the snapshot.
return {NameProvider::kHiddenName, false};
#endif // !CPPGC_SUPPORTS_OBJECT_NAMES
}
};
using NameCallback = HeapObjectName (*)(const void*,
HeapObjectNameForUnnamedObject);
} // namespace internal
} // namespace cppgc
#undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
#endif // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_

View File

@ -0,0 +1,219 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
#define INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
#include <array>
#include <memory>
#include <vector>
#include "cppgc/internal/logging.h"
#include "cppgc/trace-trait.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
class CrossThreadPersistentRegion;
class FatalOutOfMemoryHandler;
class HeapBase;
class RootVisitor;
// PersistentNode represents a variant of two states:
// 1) traceable node with a back pointer to the Persistent object;
// 2) freelist entry.
class PersistentNode final {
public:
PersistentNode() = default;
PersistentNode(const PersistentNode&) = delete;
PersistentNode& operator=(const PersistentNode&) = delete;
void InitializeAsUsedNode(void* owner, TraceRootCallback trace) {
CPPGC_DCHECK(trace);
owner_ = owner;
trace_ = trace;
}
void InitializeAsFreeNode(PersistentNode* next) {
next_ = next;
trace_ = nullptr;
}
void UpdateOwner(void* owner) {
CPPGC_DCHECK(IsUsed());
owner_ = owner;
}
PersistentNode* FreeListNext() const {
CPPGC_DCHECK(!IsUsed());
return next_;
}
void Trace(RootVisitor& root_visitor) const {
CPPGC_DCHECK(IsUsed());
trace_(root_visitor, owner_);
}
bool IsUsed() const { return trace_; }
void* owner() const {
CPPGC_DCHECK(IsUsed());
return owner_;
}
private:
// PersistentNode acts as a designated union:
// If trace_ != nullptr, owner_ points to the corresponding Persistent handle.
// Otherwise, next_ points to the next freed PersistentNode.
union {
void* owner_ = nullptr;
PersistentNode* next_;
};
TraceRootCallback trace_ = nullptr;
};
class V8_EXPORT PersistentRegionBase {
using PersistentNodeSlots = std::array<PersistentNode, 256u>;
public:
// Clears Persistent fields to avoid stale pointers after heap teardown.
~PersistentRegionBase();
PersistentRegionBase(const PersistentRegionBase&) = delete;
PersistentRegionBase& operator=(const PersistentRegionBase&) = delete;
void Iterate(RootVisitor&);
size_t NodesInUse() const;
void ClearAllUsedNodes();
protected:
explicit PersistentRegionBase(const FatalOutOfMemoryHandler& oom_handler);
PersistentNode* TryAllocateNodeFromFreeList(void* owner,
TraceRootCallback trace) {
PersistentNode* node = nullptr;
if (V8_LIKELY(free_list_head_)) {
node = free_list_head_;
free_list_head_ = free_list_head_->FreeListNext();
CPPGC_DCHECK(!node->IsUsed());
node->InitializeAsUsedNode(owner, trace);
nodes_in_use_++;
}
return node;
}
void FreeNode(PersistentNode* node) {
CPPGC_DCHECK(node);
CPPGC_DCHECK(node->IsUsed());
node->InitializeAsFreeNode(free_list_head_);
free_list_head_ = node;
CPPGC_DCHECK(nodes_in_use_ > 0);
nodes_in_use_--;
}
PersistentNode* RefillFreeListAndAllocateNode(void* owner,
TraceRootCallback trace);
private:
template <typename PersistentBaseClass>
void ClearAllUsedNodes();
void RefillFreeList();
std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_;
PersistentNode* free_list_head_ = nullptr;
size_t nodes_in_use_ = 0;
const FatalOutOfMemoryHandler& oom_handler_;
friend class CrossThreadPersistentRegion;
};
// Variant of PersistentRegionBase that checks whether the allocation and
// freeing happens only on the thread that created the heap.
class V8_EXPORT PersistentRegion final : public PersistentRegionBase {
public:
V8_INLINE PersistentRegion(const HeapBase& heap,
const FatalOutOfMemoryHandler& oom_handler)
: PersistentRegionBase(oom_handler), heap_(heap) {
CPPGC_DCHECK(IsCreationThread());
}
// Clears Persistent fields to avoid stale pointers after heap teardown.
~PersistentRegion() = default;
PersistentRegion(const PersistentRegion&) = delete;
PersistentRegion& operator=(const PersistentRegion&) = delete;
V8_INLINE PersistentNode* AllocateNode(void* owner, TraceRootCallback trace) {
CPPGC_DCHECK(IsCreationThread());
auto* node = TryAllocateNodeFromFreeList(owner, trace);
if (V8_LIKELY(node)) return node;
// Slow path allocation allows for checking thread correspondence.
CPPGC_CHECK(IsCreationThread());
return RefillFreeListAndAllocateNode(owner, trace);
}
V8_INLINE void FreeNode(PersistentNode* node) {
CPPGC_DCHECK(IsCreationThread());
PersistentRegionBase::FreeNode(node);
}
private:
bool IsCreationThread();
const HeapBase& heap_;
};
// CrossThreadPersistent uses PersistentRegionBase but protects it using this
// lock when needed.
class V8_EXPORT PersistentRegionLock final {
public:
PersistentRegionLock();
~PersistentRegionLock();
static void AssertLocked();
};
// Variant of PersistentRegionBase that checks whether the PersistentRegionLock
// is locked.
class V8_EXPORT CrossThreadPersistentRegion final
: protected PersistentRegionBase {
public:
explicit CrossThreadPersistentRegion(const FatalOutOfMemoryHandler&);
// Clears Persistent fields to avoid stale pointers after heap teardown.
~CrossThreadPersistentRegion();
CrossThreadPersistentRegion(const CrossThreadPersistentRegion&) = delete;
CrossThreadPersistentRegion& operator=(const CrossThreadPersistentRegion&) =
delete;
V8_INLINE PersistentNode* AllocateNode(void* owner, TraceRootCallback trace) {
PersistentRegionLock::AssertLocked();
auto* node = TryAllocateNodeFromFreeList(owner, trace);
if (V8_LIKELY(node)) return node;
return RefillFreeListAndAllocateNode(owner, trace);
}
V8_INLINE void FreeNode(PersistentNode* node) {
PersistentRegionLock::AssertLocked();
PersistentRegionBase::FreeNode(node);
}
void Iterate(RootVisitor&);
size_t NodesInUse() const;
void ClearAllUsedNodes();
};
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_

View File

@ -0,0 +1,280 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_
#define INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_
#include <cstdint>
#include <type_traits>
#include "cppgc/internal/member-storage.h"
#include "cppgc/internal/write-barrier.h"
#include "cppgc/sentinel-pointer.h"
#include "cppgc/source-location.h"
#include "cppgc/type-traits.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
class HeapBase;
class PersistentRegion;
class CrossThreadPersistentRegion;
// Tags to distinguish between strong and weak member types.
class StrongMemberTag;
class WeakMemberTag;
class UntracedMemberTag;
struct DijkstraWriteBarrierPolicy {
// Since in initializing writes the source object is always white, having no
// barrier doesn't break the tri-color invariant.
V8_INLINE static void InitializingBarrier(const void*, const void*) {}
V8_INLINE static void InitializingBarrier(const void*, RawPointer storage) {
}
#if defined(CPPGC_POINTER_COMPRESSION)
V8_INLINE static void InitializingBarrier(const void*,
CompressedPointer storage) {}
#endif
template <WriteBarrierSlotType SlotType>
V8_INLINE static void AssigningBarrier(const void* slot,
const void* value) {
#ifdef CPPGC_SLIM_WRITE_BARRIER
if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
#else // !CPPGC_SLIM_WRITE_BARRIER
WriteBarrier::Params params;
const WriteBarrier::Type type =
WriteBarrier::GetWriteBarrierType(slot, value, params);
WriteBarrier(type, params, slot, value);
#endif // !CPPGC_SLIM_WRITE_BARRIER
}
template <WriteBarrierSlotType SlotType>
V8_INLINE static void AssigningBarrier(const void* slot, RawPointer storage) {
static_assert(
SlotType == WriteBarrierSlotType::kUncompressed,
"Assigning storages of Member and UncompressedMember is not supported");
#ifdef CPPGC_SLIM_WRITE_BARRIER
if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
#else // !CPPGC_SLIM_WRITE_BARRIER
WriteBarrier::Params params;
const WriteBarrier::Type type =
WriteBarrier::GetWriteBarrierType(slot, storage, params);
WriteBarrier(type, params, slot, storage.Load());
#endif // !CPPGC_SLIM_WRITE_BARRIER
}
#if defined(CPPGC_POINTER_COMPRESSION)
template <WriteBarrierSlotType SlotType>
V8_INLINE static void AssigningBarrier(const void* slot,
CompressedPointer storage) {
static_assert(
SlotType == WriteBarrierSlotType::kCompressed,
"Assigning storages of Member and UncompressedMember is not supported");
#ifdef CPPGC_SLIM_WRITE_BARRIER
if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
#else // !CPPGC_SLIM_WRITE_BARRIER
WriteBarrier::Params params;
const WriteBarrier::Type type =
WriteBarrier::GetWriteBarrierType(slot, storage, params);
WriteBarrier(type, params, slot, storage.Load());
#endif // !CPPGC_SLIM_WRITE_BARRIER
}
#endif // defined(CPPGC_POINTER_COMPRESSION)
private:
V8_INLINE static void WriteBarrier(WriteBarrier::Type type,
const WriteBarrier::Params& params,
const void* slot, const void* value) {
switch (type) {
case WriteBarrier::Type::kGenerational:
WriteBarrier::GenerationalBarrier<
WriteBarrier::GenerationalBarrierType::kPreciseSlot>(params, slot);
break;
case WriteBarrier::Type::kMarking:
WriteBarrier::DijkstraMarkingBarrier(params, value);
break;
case WriteBarrier::Type::kNone:
break;
}
}
};
struct NoWriteBarrierPolicy {
V8_INLINE static void InitializingBarrier(const void*, const void*) {}
V8_INLINE static void InitializingBarrier(const void*, RawPointer storage) {}
#if defined(CPPGC_POINTER_COMPRESSION)
V8_INLINE static void InitializingBarrier(const void*,
CompressedPointer storage) {}
#endif
template <WriteBarrierSlotType>
V8_INLINE static void AssigningBarrier(const void*, const void*) {}
template <WriteBarrierSlotType, typename MemberStorage>
V8_INLINE static void AssigningBarrier(const void*, MemberStorage) {}
};
class V8_EXPORT SameThreadEnabledCheckingPolicyBase {
protected:
void CheckPointerImpl(const void* ptr, bool points_to_payload,
bool check_off_heap_assignments);
const HeapBase* heap_ = nullptr;
};
template <bool kCheckOffHeapAssignments>
class V8_EXPORT SameThreadEnabledCheckingPolicy
: private SameThreadEnabledCheckingPolicyBase {
protected:
template <typename T>
V8_INLINE void CheckPointer(RawPointer raw_pointer) {
if (raw_pointer.IsCleared() || raw_pointer.IsSentinel()) {
return;
}
CheckPointersImplTrampoline<T>::Call(
this, static_cast<const T*>(raw_pointer.Load()));
}
#if defined(CPPGC_POINTER_COMPRESSION)
template <typename T>
V8_INLINE void CheckPointer(CompressedPointer compressed_pointer) {
if (compressed_pointer.IsCleared() || compressed_pointer.IsSentinel()) {
return;
}
CheckPointersImplTrampoline<T>::Call(
this, static_cast<const T*>(compressed_pointer.Load()));
}
#endif
template <typename T>
void CheckPointer(const T* ptr) {
if (!ptr || (kSentinelPointer == ptr)) {
return;
}
CheckPointersImplTrampoline<T>::Call(this, ptr);
}
private:
template <typename T, bool = IsCompleteV<T>>
struct CheckPointersImplTrampoline {
static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
policy->CheckPointerImpl(ptr, false, kCheckOffHeapAssignments);
}
};
template <typename T>
struct CheckPointersImplTrampoline<T, true> {
static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
policy->CheckPointerImpl(ptr, IsGarbageCollectedTypeV<T>,
kCheckOffHeapAssignments);
}
};
};
class DisabledCheckingPolicy {
protected:
template <typename T>
V8_INLINE void CheckPointer(T*) {}
template <typename T>
V8_INLINE void CheckPointer(RawPointer) {}
#if defined(CPPGC_POINTER_COMPRESSION)
template <typename T>
V8_INLINE void CheckPointer(CompressedPointer) {}
#endif
};
#ifdef CPPGC_ENABLE_SLOW_API_CHECKS
// Off heap members are not connected to object graph and thus cannot ressurect
// dead objects.
using DefaultMemberCheckingPolicy =
SameThreadEnabledCheckingPolicy<false /* kCheckOffHeapAssignments*/>;
using DefaultPersistentCheckingPolicy =
SameThreadEnabledCheckingPolicy<true /* kCheckOffHeapAssignments*/>;
#else // !CPPGC_ENABLE_SLOW_API_CHECKS
using DefaultMemberCheckingPolicy = DisabledCheckingPolicy;
using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
#endif // !CPPGC_ENABLE_SLOW_API_CHECKS
// For CT(W)P neither marking information (for value), nor objectstart bitmap
// (for slot) are guaranteed to be present because there's no synchronization
// between heaps after marking.
using DefaultCrossThreadPersistentCheckingPolicy = DisabledCheckingPolicy;
class KeepLocationPolicy {
public:
constexpr const SourceLocation& Location() const { return location_; }
protected:
constexpr KeepLocationPolicy() = default;
constexpr explicit KeepLocationPolicy(const SourceLocation& location)
: location_(location) {}
// KeepLocationPolicy must not copy underlying source locations.
KeepLocationPolicy(const KeepLocationPolicy&) = delete;
KeepLocationPolicy& operator=(const KeepLocationPolicy&) = delete;
// Location of the original moved from object should be preserved.
KeepLocationPolicy(KeepLocationPolicy&&) = default;
KeepLocationPolicy& operator=(KeepLocationPolicy&&) = default;
private:
SourceLocation location_;
};
class IgnoreLocationPolicy {
public:
constexpr SourceLocation Location() const { return {}; }
protected:
constexpr IgnoreLocationPolicy() = default;
constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {}
};
#if CPPGC_SUPPORTS_OBJECT_NAMES
using DefaultLocationPolicy = KeepLocationPolicy;
#else
using DefaultLocationPolicy = IgnoreLocationPolicy;
#endif
struct StrongPersistentPolicy {
using IsStrongPersistent = std::true_type;
static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
};
struct WeakPersistentPolicy {
using IsStrongPersistent = std::false_type;
static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
};
struct StrongCrossThreadPersistentPolicy {
using IsStrongPersistent = std::true_type;
static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
const void* object);
};
struct WeakCrossThreadPersistentPolicy {
using IsStrongPersistent = std::false_type;
static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
const void* object);
};
// Forward declarations setting up the default policies.
template <typename T, typename WeaknessPolicy,
typename LocationPolicy = DefaultLocationPolicy,
typename CheckingPolicy = DefaultCrossThreadPersistentCheckingPolicy>
class BasicCrossThreadPersistent;
template <typename T, typename WeaknessPolicy,
typename LocationPolicy = DefaultLocationPolicy,
typename CheckingPolicy = DefaultPersistentCheckingPolicy>
class BasicPersistent;
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy = DefaultMemberCheckingPolicy,
typename StorageType = DefaultMemberStorage>
class BasicMember;
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_

View File

@ -0,0 +1,487 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
#define INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
#include <cstddef>
#include <cstdint>
#include "cppgc/heap-handle.h"
#include "cppgc/heap-state.h"
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/atomic-entry-flag.h"
#include "cppgc/internal/base-page-handle.h"
#include "cppgc/internal/member-storage.h"
#include "cppgc/platform.h"
#include "cppgc/sentinel-pointer.h"
#include "cppgc/trace-trait.h"
#include "v8config.h" // NOLINT(build/include_directory)
#if defined(CPPGC_CAGED_HEAP)
#include "cppgc/internal/caged-heap-local-data.h"
#include "cppgc/internal/caged-heap.h"
#endif
namespace cppgc {
class HeapHandle;
namespace internal {
#if defined(CPPGC_CAGED_HEAP)
class WriteBarrierTypeForCagedHeapPolicy;
#else // !CPPGC_CAGED_HEAP
class WriteBarrierTypeForNonCagedHeapPolicy;
#endif // !CPPGC_CAGED_HEAP
class V8_EXPORT WriteBarrier final {
public:
enum class Type : uint8_t {
kNone,
kMarking,
kGenerational,
};
enum class GenerationalBarrierType : uint8_t {
kPreciseSlot,
kPreciseUncompressedSlot,
kImpreciseSlot,
};
struct Params {
HeapHandle* heap = nullptr;
#if V8_ENABLE_CHECKS
Type type = Type::kNone;
#endif // !V8_ENABLE_CHECKS
#if defined(CPPGC_CAGED_HEAP)
uintptr_t slot_offset = 0;
uintptr_t value_offset = 0;
#endif // CPPGC_CAGED_HEAP
};
enum class ValueMode {
kValuePresent,
kNoValuePresent,
};
// Returns the required write barrier for a given `slot` and `value`.
static V8_INLINE Type GetWriteBarrierType(const void* slot, const void* value,
Params& params);
// Returns the required write barrier for a given `slot` and `value`.
template <typename MemberStorage>
static V8_INLINE Type GetWriteBarrierType(const void* slot, MemberStorage,
Params& params);
// Returns the required write barrier for a given `slot`.
template <typename HeapHandleCallback>
static V8_INLINE Type GetWriteBarrierType(const void* slot, Params& params,
HeapHandleCallback callback);
// Returns the required write barrier for a given `value`.
static V8_INLINE Type GetWriteBarrierType(const void* value, Params& params);
#ifdef CPPGC_SLIM_WRITE_BARRIER
// A write barrier that combines `GenerationalBarrier()` and
// `DijkstraMarkingBarrier()`. We only pass a single parameter here to clobber
// as few registers as possible.
template <WriteBarrierSlotType>
static V8_NOINLINE void V8_PRESERVE_MOST
CombinedWriteBarrierSlow(const void* slot);
#endif // CPPGC_SLIM_WRITE_BARRIER
static V8_INLINE void DijkstraMarkingBarrier(const Params& params,
const void* object);
static V8_INLINE void DijkstraMarkingBarrierRange(
const Params& params, const void* first_element, size_t element_size,
size_t number_of_elements, TraceCallback trace_callback);
static V8_INLINE void SteeleMarkingBarrier(const Params& params,
const void* object);
#if defined(CPPGC_YOUNG_GENERATION)
template <GenerationalBarrierType>
static V8_INLINE void GenerationalBarrier(const Params& params,
const void* slot);
#else // !CPPGC_YOUNG_GENERATION
template <GenerationalBarrierType>
static V8_INLINE void GenerationalBarrier(const Params& params,
const void* slot){}
#endif // CPPGC_YOUNG_GENERATION
#if V8_ENABLE_CHECKS
static void CheckParams(Type expected_type, const Params& params);
#else // !V8_ENABLE_CHECKS
static void CheckParams(Type expected_type, const Params& params) {}
#endif // !V8_ENABLE_CHECKS
// The FlagUpdater class allows cppgc internal to update
// |write_barrier_enabled_|.
class FlagUpdater;
static bool IsEnabled() { return write_barrier_enabled_.MightBeEntered(); }
private:
WriteBarrier() = delete;
#if defined(CPPGC_CAGED_HEAP)
using WriteBarrierTypePolicy = WriteBarrierTypeForCagedHeapPolicy;
#else // !CPPGC_CAGED_HEAP
using WriteBarrierTypePolicy = WriteBarrierTypeForNonCagedHeapPolicy;
#endif // !CPPGC_CAGED_HEAP
static void DijkstraMarkingBarrierSlow(const void* value);
static void DijkstraMarkingBarrierSlowWithSentinelCheck(const void* value);
static void DijkstraMarkingBarrierRangeSlow(HeapHandle& heap_handle,
const void* first_element,
size_t element_size,
size_t number_of_elements,
TraceCallback trace_callback);
static void SteeleMarkingBarrierSlow(const void* value);
static void SteeleMarkingBarrierSlowWithSentinelCheck(const void* value);
#if defined(CPPGC_YOUNG_GENERATION)
static CagedHeapLocalData& GetLocalData(HeapHandle&);
static void GenerationalBarrierSlow(const CagedHeapLocalData& local_data,
const AgeTable& age_table,
const void* slot, uintptr_t value_offset,
HeapHandle* heap_handle);
static void GenerationalBarrierForUncompressedSlotSlow(
const CagedHeapLocalData& local_data, const AgeTable& age_table,
const void* slot, uintptr_t value_offset, HeapHandle* heap_handle);
static void GenerationalBarrierForSourceObjectSlow(
const CagedHeapLocalData& local_data, const void* object,
HeapHandle* heap_handle);
#endif // CPPGC_YOUNG_GENERATION
static AtomicEntryFlag write_barrier_enabled_;
};
template <WriteBarrier::Type type>
V8_INLINE WriteBarrier::Type SetAndReturnType(WriteBarrier::Params& params) {
if constexpr (type == WriteBarrier::Type::kNone)
return WriteBarrier::Type::kNone;
#if V8_ENABLE_CHECKS
params.type = type;
#endif // !V8_ENABLE_CHECKS
return type;
}
#if defined(CPPGC_CAGED_HEAP)
class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
public:
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
}
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback,
typename MemberStorage>
static V8_INLINE WriteBarrier::Type Get(const void* slot, MemberStorage value,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
}
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* value,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
return GetNoSlot(value, params, callback);
}
private:
WriteBarrierTypeForCagedHeapPolicy() = delete;
template <typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type GetNoSlot(const void* value,
WriteBarrier::Params& params,
HeapHandleCallback) {
const bool within_cage = CagedHeapBase::IsWithinCage(value);
if (!within_cage) return WriteBarrier::Type::kNone;
// We know that |value| points either within the normal page or to the
// beginning of large-page, so extract the page header by bitmasking.
BasePageHandle* page =
BasePageHandle::FromPayload(const_cast<void*>(value));
HeapHandle& heap_handle = page->heap_handle();
if (V8_UNLIKELY(heap_handle.is_incremental_marking_in_progress())) {
return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
}
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
}
template <WriteBarrier::ValueMode value_mode>
struct ValueModeDispatch;
};
template <>
struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
WriteBarrier::ValueMode::kValuePresent> {
template <typename HeapHandleCallback, typename MemberStorage>
static V8_INLINE WriteBarrier::Type Get(const void* slot,
MemberStorage storage,
WriteBarrier::Params& params,
HeapHandleCallback) {
if (V8_LIKELY(!WriteBarrier::IsEnabled()))
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
return BarrierEnabledGet(slot, storage.Load(), params);
}
template <typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value,
WriteBarrier::Params& params,
HeapHandleCallback) {
if (V8_LIKELY(!WriteBarrier::IsEnabled()))
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
return BarrierEnabledGet(slot, value, params);
}
private:
static V8_INLINE WriteBarrier::Type BarrierEnabledGet(
const void* slot, const void* value, WriteBarrier::Params& params) {
const bool within_cage = CagedHeapBase::AreWithinCage(slot, value);
if (!within_cage) return WriteBarrier::Type::kNone;
// We know that |value| points either within the normal page or to the
// beginning of large-page, so extract the page header by bitmasking.
BasePageHandle* page =
BasePageHandle::FromPayload(const_cast<void*>(value));
HeapHandle& heap_handle = page->heap_handle();
if (V8_LIKELY(!heap_handle.is_incremental_marking_in_progress())) {
#if defined(CPPGC_YOUNG_GENERATION)
if (!heap_handle.is_young_generation_enabled())
return WriteBarrier::Type::kNone;
params.heap = &heap_handle;
params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
params.value_offset = CagedHeapBase::OffsetFromAddress(value);
return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
#else // !CPPGC_YOUNG_GENERATION
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
#endif // !CPPGC_YOUNG_GENERATION
}
// Use marking barrier.
params.heap = &heap_handle;
return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
}
};
template <>
struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
WriteBarrier::ValueMode::kNoValuePresent> {
template <typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* slot, const void*,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
if (V8_LIKELY(!WriteBarrier::IsEnabled()))
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
HeapHandle& handle = callback();
#if defined(CPPGC_YOUNG_GENERATION)
if (V8_LIKELY(!handle.is_incremental_marking_in_progress())) {
if (!handle.is_young_generation_enabled()) {
return WriteBarrier::Type::kNone;
}
params.heap = &handle;
// Check if slot is on stack.
if (V8_UNLIKELY(!CagedHeapBase::IsWithinCage(slot))) {
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
}
params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
}
#else // !defined(CPPGC_YOUNG_GENERATION)
if (V8_UNLIKELY(!handle.is_incremental_marking_in_progress())) {
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
}
#endif // !defined(CPPGC_YOUNG_GENERATION)
params.heap = &handle;
return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
}
};
#endif // CPPGC_CAGED_HEAP
class V8_EXPORT WriteBarrierTypeForNonCagedHeapPolicy final {
public:
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
}
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* slot, RawPointer value,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
return ValueModeDispatch<value_mode>::Get(slot, value.Load(), params,
callback);
}
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* value,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
// The slot will never be used in `Get()` below.
return Get<WriteBarrier::ValueMode::kValuePresent>(nullptr, value, params,
callback);
}
private:
template <WriteBarrier::ValueMode value_mode>
struct ValueModeDispatch;
WriteBarrierTypeForNonCagedHeapPolicy() = delete;
};
template <>
struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
WriteBarrier::ValueMode::kValuePresent> {
template <typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void*, const void* object,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
// The following check covers nullptr as well as sentinel pointer.
if (object <= static_cast<void*>(kSentinelPointer)) {
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
}
if (V8_LIKELY(!WriteBarrier::IsEnabled())) {
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
}
// We know that |object| is within the normal page or in the beginning of a
// large page, so extract the page header by bitmasking.
BasePageHandle* page =
BasePageHandle::FromPayload(const_cast<void*>(object));
HeapHandle& heap_handle = page->heap_handle();
if (V8_LIKELY(heap_handle.is_incremental_marking_in_progress())) {
return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
}
return SetAndReturnType<WriteBarrier::Type::kNone>(params);
}
};
template <>
struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
WriteBarrier::ValueMode::kNoValuePresent> {
template <typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void*, const void*,
WriteBarrier::Params& params,
HeapHandleCallback callback) {
if (V8_UNLIKELY(WriteBarrier::IsEnabled())) {
HeapHandle& handle = callback();
if (V8_LIKELY(handle.is_incremental_marking_in_progress())) {
params.heap = &handle;
return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
}
}
return WriteBarrier::Type::kNone;
}
};
// static
WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
const void* slot, const void* value, WriteBarrier::Params& params) {
return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
params, []() {});
}
// static
template <typename MemberStorage>
WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
const void* slot, MemberStorage value, WriteBarrier::Params& params) {
return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
params, []() {});
}
// static
template <typename HeapHandleCallback>
WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
const void* slot, WriteBarrier::Params& params,
HeapHandleCallback callback) {
return WriteBarrierTypePolicy::Get<ValueMode::kNoValuePresent>(
slot, nullptr, params, callback);
}
// static
WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
const void* value, WriteBarrier::Params& params) {
return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(value, params,
[]() {});
}
// static
void WriteBarrier::DijkstraMarkingBarrier(const Params& params,
const void* object) {
CheckParams(Type::kMarking, params);
#if defined(CPPGC_CAGED_HEAP)
// Caged heap already filters out sentinels.
DijkstraMarkingBarrierSlow(object);
#else // !CPPGC_CAGED_HEAP
DijkstraMarkingBarrierSlowWithSentinelCheck(object);
#endif // !CPPGC_CAGED_HEAP
}
// static
void WriteBarrier::DijkstraMarkingBarrierRange(const Params& params,
const void* first_element,
size_t element_size,
size_t number_of_elements,
TraceCallback trace_callback) {
CheckParams(Type::kMarking, params);
DijkstraMarkingBarrierRangeSlow(*params.heap, first_element, element_size,
number_of_elements, trace_callback);
}
// static
void WriteBarrier::SteeleMarkingBarrier(const Params& params,
const void* object) {
CheckParams(Type::kMarking, params);
#if defined(CPPGC_CAGED_HEAP)
// Caged heap already filters out sentinels.
SteeleMarkingBarrierSlow(object);
#else // !CPPGC_CAGED_HEAP
SteeleMarkingBarrierSlowWithSentinelCheck(object);
#endif // !CPPGC_CAGED_HEAP
}
#if defined(CPPGC_YOUNG_GENERATION)
// static
template <WriteBarrier::GenerationalBarrierType type>
void WriteBarrier::GenerationalBarrier(const Params& params, const void* slot) {
CheckParams(Type::kGenerational, params);
const CagedHeapLocalData& local_data = CagedHeapLocalData::Get();
const AgeTable& age_table = local_data.age_table;
// Bail out if the slot (precise or imprecise) is in young generation.
if (V8_LIKELY(age_table.GetAge(params.slot_offset) == AgeTable::Age::kYoung))
return;
// Dispatch between different types of barriers.
// TODO(chromium:1029379): Consider reload local_data in the slow path to
// reduce register pressure.
if constexpr (type == GenerationalBarrierType::kPreciseSlot) {
GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset,
params.heap);
} else if constexpr (type ==
GenerationalBarrierType::kPreciseUncompressedSlot) {
GenerationalBarrierForUncompressedSlotSlow(
local_data, age_table, slot, params.value_offset, params.heap);
} else {
GenerationalBarrierForSourceObjectSlow(local_data, slot, params.heap);
}
}
#endif // !CPPGC_YOUNG_GENERATION
} // namespace internal
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_

78
deps/v8/include/cppgc/liveness-broker.h vendored Normal file
View File

@ -0,0 +1,78 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_LIVENESS_BROKER_H_
#define INCLUDE_CPPGC_LIVENESS_BROKER_H_
#include "cppgc/heap.h"
#include "cppgc/member.h"
#include "cppgc/sentinel-pointer.h"
#include "cppgc/trace-trait.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
namespace internal {
class LivenessBrokerFactory;
} // namespace internal
/**
* The broker is passed to weak callbacks to allow (temporarily) querying
* the liveness state of an object. References to non-live objects must be
* cleared when `IsHeapObjectAlive()` returns false.
*
* \code
* class GCedWithCustomWeakCallback final
* : public GarbageCollected<GCedWithCustomWeakCallback> {
* public:
* UntracedMember<Bar> bar;
*
* void CustomWeakCallbackMethod(const LivenessBroker& broker) {
* if (!broker.IsHeapObjectAlive(bar))
* bar = nullptr;
* }
*
* void Trace(cppgc::Visitor* visitor) const {
* visitor->RegisterWeakCallbackMethod<
* GCedWithCustomWeakCallback,
* &GCedWithCustomWeakCallback::CustomWeakCallbackMethod>(this);
* }
* };
* \endcode
*/
class V8_EXPORT LivenessBroker final {
public:
template <typename T>
bool IsHeapObjectAlive(const T* object) const {
// - nullptr objects are considered alive to allow weakness to be used from
// stack while running into a conservative GC. Treating nullptr as dead
// would mean that e.g. custom collections could not be strongified on
// stack.
// - Sentinel pointers are also preserved in weakness and not cleared.
return !object || object == kSentinelPointer ||
IsHeapObjectAliveImpl(
TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
}
template <typename T>
bool IsHeapObjectAlive(const WeakMember<T>& weak_member) const {
return IsHeapObjectAlive<T>(weak_member.Get());
}
template <typename T>
bool IsHeapObjectAlive(const UntracedMember<T>& untraced_member) const {
return IsHeapObjectAlive<T>(untraced_member.Get());
}
private:
LivenessBroker() = default;
bool IsHeapObjectAliveImpl(const void*) const;
friend class internal::LivenessBrokerFactory;
};
} // namespace cppgc
#endif // INCLUDE_CPPGC_LIVENESS_BROKER_H_

56
deps/v8/include/cppgc/macros.h vendored Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INCLUDE_CPPGC_MACROS_H_
#define INCLUDE_CPPGC_MACROS_H_
#include <cstddef>
#include "cppgc/internal/compiler-specific.h"
namespace cppgc {
#define CPPGC_DISALLOW_NEW() \
public: \
using IsDisallowNewMarker CPPGC_UNUSED = int; \
void* operator new(size_t, void* location) { return location; } \
void* operator new(size_t) = delete; \
static_assert(true, "Force semicolon.")
// Use CPPGC_STACK_ALLOCATED if the object is only stack allocated.
// Add the CPPGC_STACK_ALLOCATED_IGNORE annotation on a case-by-case basis when
// enforcement of CPPGC_STACK_ALLOCATED should be suppressed.
#if defined(__clang__)
#define CPPGC_STACK_ALLOCATED() \
public: \
using IsStackAllocatedTypeMarker CPPGC_UNUSED = int; \
\
private: \
void* operator new(size_t) = delete; \
void* operator new(size_t, void*) = delete; \
static_assert(true, "Force semicolon.")
#define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason) \
__attribute__((annotate("stack_allocated_ignore")))
#define CPPGC_PLUGIN_IGNORE(bug_or_reason) \
__attribute__((annotate("blink_gc_plugin_ignore"), \
annotate("stack_allocated_ignore")))
#else // !defined(__clang__)
#define CPPGC_STACK_ALLOCATED() static_assert(true, "Force semicolon.")
#define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason)
#define CPPGC_PLUGIN_IGNORE(bug_or_reason)
#endif // !defined(__clang__)
template <typename T>
concept IsStackAllocatedType =
requires { typename T::IsStackAllocatedTypeMarker; };
} // namespace cppgc
#endif // INCLUDE_CPPGC_MACROS_H_

Some files were not shown because too many files have changed in this diff Show More