Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v8,tools: expose necessary V8 defines #50820

Merged
merged 1 commit into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 50 additions & 10 deletions common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,16 @@

'v8_win64_unwinding_info': 1,

# TODO(refack): make v8-perfetto happen
# Variables controlling external defines exposed in public headers.
'v8_enable_conservative_stack_scanning%': 0,
'v8_enable_direct_local%': 0,
'v8_enable_map_packing%': 0,
'v8_enable_pointer_compression_shared_cage%': 0,
'v8_enable_sandbox%': 0,
'v8_enable_v8_checks%': 0,
'v8_enable_zone_compression%': 0,
'v8_use_perfetto': 0,
'tsan%': 0,
gengjiawen marked this conversation as resolved.
Show resolved Hide resolved

##### end V8 defaults #####

Expand Down Expand Up @@ -134,7 +142,7 @@
}],
],
},
'defines': [ 'DEBUG', '_DEBUG', 'V8_ENABLE_CHECKS' ],
'defines': [ 'DEBUG', '_DEBUG' ],
'cflags': [ '-g', '-O0' ],
'conditions': [
['OS in "aix os400"', {
Expand Down Expand Up @@ -257,11 +265,8 @@
}
},

# Defines these mostly for node-gyp to pickup, and warn addon authors of
# imminent V8 deprecations, also to sync how dependencies are configured.
# Defines these mostly for node-gyp to pickup.
'defines': [
'V8_DEPRECATION_WARNINGS',
'V8_IMMINENT_DEPRECATION_WARNINGS',
'_GLIBCXX_USE_CXX11_ABI=1',
],

Expand Down Expand Up @@ -369,15 +374,50 @@
}],
],
}],
# The defines bellow must include all things from the external_v8_defines
# list in v8/BUILD.gn.
['v8_enable_v8_checks == 1', {
'defines': ['V8_ENABLE_CHECKS'],
}],
['v8_enable_pointer_compression == 1', {
'defines': [
'V8_COMPRESS_POINTERS',
'V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE',
],
'defines': ['V8_COMPRESS_POINTERS'],
}],
['v8_enable_pointer_compression_shared_cage == 1', {
'defines': ['V8_COMPRESS_POINTERS_IN_SHARED_CAGE'],
}],
['v8_enable_pointer_compression == 1 and v8_enable_pointer_compression_shared_cage != 1', {
'defines': ['V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE'],
}],
['v8_enable_pointer_compression == 1 or v8_enable_31bit_smis_on_64bit_arch == 1', {
'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH'],
}],
['v8_enable_zone_compression == 1', {
'defines': ['V8_COMPRESS_ZONES',],
}],
['v8_enable_sandbox == 1', {
'defines': ['V8_ENABLE_SANDBOX',],
}],
['v8_deprecation_warnings == 1', {
'defines': ['V8_DEPRECATION_WARNINGS',],
}],
['v8_imminent_deprecation_warnings == 1', {
'defines': ['V8_IMMINENT_DEPRECATION_WARNINGS',],
}],
['v8_use_perfetto == 1', {
'defines': ['V8_USE_PERFETTO',],
}],
['v8_enable_map_packing == 1', {
'defines': ['V8_MAP_PACKING',],
}],
['tsan == 1', {
'defines': ['V8_IS_TSAN',],
}],
['v8_enable_conservative_stack_scanning == 1', {
'defines': ['V8_ENABLE_CONSERVATIVE_STACK_SCANNING',],
}],
['v8_enable_direct_local == 1', {
'defines': ['V8_ENABLE_DIRECT_LOCAL',],
}],
['OS == "win"', {
'defines': [
'WIN32',
Expand Down
1 change: 1 addition & 0 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,7 @@ def configure_v8(o):
o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
o['variables']['v8_enable_shared_ro_heap'] = 0 if options.enable_pointer_compression or options.disable_shared_ro_heap else 1
o['variables']['v8_enable_extensible_ro_snapshot'] = 0
o['variables']['v8_enable_v8_checks'] = 1 if options.debug else 0
o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0
o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform)
o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8)
Expand Down
118 changes: 91 additions & 27 deletions tools/generate_config_gypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,69 +7,133 @@
# This script reads the configurations of GN and outputs a config.gypi file that
# will be used to populate process.config.variables.

import argparse
import re
import os
import subprocess
import sys

root_dir = os.path.dirname(os.path.dirname(__file__))
sys.path.append(os.path.join(root_dir, 'node', 'tools'))
import getmoduleversion
sys.path.append(os.path.dirname(__file__))
import getnapibuildversion

# The defines bellow must include all things from the external_v8_defines list
# in v8/BUILD.gn.
# TODO(zcbenz): Import from v8_features.json once this change gets into Node:
# https://chromium-review.googlesource.com/c/v8/v8/+/5040612
V8_FEATURE_DEFINES = {
'v8_enable_v8_checks': 'V8_ENABLE_CHECKS',
'v8_enable_pointer_compression': 'V8_COMPRESS_POINTERS',
'v8_enable_pointer_compression_shared_cage': 'V8_COMPRESS_POINTERS_IN_SHARED_CAGE',
'v8_enable_31bit_smis_on_64bit_arch': 'V8_31BIT_SMIS_ON_64BIT_ARCH',
'v8_enable_zone_compression': 'V8_COMPRESS_ZONES',
'v8_enable_sandbox': 'V8_ENABLE_SANDBOX',
'v8_deprecation_warnings': 'V8_DEPRECATION_WARNINGS',
'v8_imminent_deprecation_warnings': 'V8_IMMINENT_DEPRECATION_WARNINGS',
'v8_use_perfetto': 'V8_USE_PERFETTO',
'v8_enable_map_packing': 'V8_MAP_PACKING',
'tsan': 'V8_IS_TSAN',
'v8_enable_conservative_stack_scanning': 'V8_ENABLE_CONSERVATIVE_STACK_SCANNING',
'v8_enable_direct_local': 'V8_ENABLE_DIRECT_LOCAL',
}

# Regex used for parsing results of "gn args".
GN_RE = re.compile(r'(\w+)\s+=\s+(.*?)$', re.MULTILINE)

if sys.platform == 'win32':
GN = 'gn.exe'
else:
GN = 'gn'

def bool_to_number(v):
return 1 if v else 0

def bool_string_to_number(v):
return 1 if v == 'true' else 0
return bool_to_number(v == 'true')

def get_gn_config(out_dir):
# Read args from GN configurations.
gn_args = subprocess.check_output(
[GN, 'args', '--list', '--short', '-C', out_dir])
config = dict(re.findall(GN_RE, gn_args.decode()))
# Get napi_build_version from Node, which is not part of GN args.
config['napi_build_version'] = getnapibuildversion.get_napi_version()
return config

def get_v8_config(out_dir, node_gn_path):
# For args that have default values in V8's GN configurations, we can not rely
# on the values printed by "gn args", because most of them would be empty
# strings, and the actual value would depend on the logics in v8/BUILD.gn.
# So we print out the defines and deduce the feature from them instead.
node_defines = subprocess.check_output(
[GN, 'desc', '-C', out_dir, node_gn_path + ":libnode", 'defines']).decode().split('\n')
v8_config = {}
for feature, define in V8_FEATURE_DEFINES.items():
v8_config[feature] = bool_to_number(define in node_defines)
return v8_config

def translate_config(config):
return {
def translate_config(out_dir, config, v8_config):
config_gypi = {
'target_defaults': {
'default_configuration':
'Debug' if config['is_debug'] == 'true' else 'Release',
},
'variables': {
'asan': bool_string_to_number(config['is_asan']),
'enable_lto': config['use_thin_lto'],
'is_debug': bool_string_to_number(config['is_debug']),
'llvm_version': 13,
'napi_build_version': config['napi_build_version'],
'node_builtin_shareable_builtins':
eval(config['node_builtin_shareable_builtins']),
'node_module_version': int(config['node_module_version']),
'node_shared': bool_string_to_number(config['is_component_build']),
'node_use_openssl': config['node_use_openssl'],
'node_use_node_code_cache': config['node_use_node_code_cache'],
'node_use_node_snapshot': config['node_use_node_snapshot'],
'v8_enable_31bit_smis_on_64bit_arch':
bool_string_to_number(config['v8_enable_31bit_smis_on_64bit_arch']),
'v8_enable_pointer_compression':
bool_string_to_number(config['v8_enable_pointer_compression']),
'v8_enable_i18n_support':
bool_string_to_number(config['v8_enable_i18n_support']),
'v8_enable_inspector': # this is actually a node misnomer
bool_string_to_number(config['node_enable_inspector']),
'shlib_suffix': 'dylib' if sys.platform == 'darwin' else 'so',
'tsan': bool_string_to_number(config['is_tsan']),
# TODO(zcbenz): Shared components are not supported in GN config yet.
'node_shared': 'false',
'node_shared_brotli': 'false',
'node_shared_cares': 'false',
'node_shared_http_parser': 'false',
'node_shared_libuv': 'false',
'node_shared_nghttp2': 'false',
'node_shared_nghttp3': 'false',
'node_shared_ngtcp2': 'false',
'node_shared_openssl': 'false',
'node_shared_zlib': 'false',
}
}
config_gypi['variables'].update(v8_config)
return config_gypi

def main(gn_out_dir, output_file, depfile):
# Get GN config and parse into a dictionary.
if sys.platform == 'win32':
gn = 'gn.exe'
else:
gn = 'gn'
gnconfig = subprocess.check_output(
[gn, 'args', '--list', '--short', '-C', gn_out_dir])
config = dict(re.findall(GN_RE, gnconfig.decode('utf-8')))
config['node_module_version'] = getmoduleversion.get_version()
config['napi_build_version'] = getnapibuildversion.get_napi_version()
def main():
parser = argparse.ArgumentParser(
description='Generate config.gypi file from GN configurations')
parser.add_argument('target', help='path to generated config.gypi file')
parser.add_argument('--out-dir', help='path to the output directory',
default='out/Release')
parser.add_argument('--node-gn-path', help='path of the node target in GN',
default='//node')
parser.add_argument('--dep-file', help='path to an optional dep file',
default=None)
args, unknown_args = parser.parse_known_args()

config = get_gn_config(args.out_dir)
v8_config = get_v8_config(args.out_dir, args.node_gn_path)

# Write output.
with open(output_file, 'w') as f:
f.write(repr(translate_config(config)))
with open(args.target, 'w') as f:
f.write(repr(translate_config(args.out_dir, config, v8_config)))

# Write depfile. Force regenerating config.gypi when GN configs change.
with open(depfile, 'w') as f:
f.write('%s: %s '%(output_file, 'build.ninja'))
if args.dep_file:
with open(args.dep_file, 'w') as f:
f.write('%s: %s '%(args.target, 'build.ninja'))

if __name__ == '__main__':
main(sys.argv[1], sys.argv[2], sys.argv[3])
main()
37 changes: 29 additions & 8 deletions tools/v8_gypfiles/features.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@

# Enable pointer compression (sets -dV8_COMPRESS_POINTERS).
'v8_enable_pointer_compression%': 0,
'v8_enable_pointer_compression_shared_cage%': 0,
'v8_enable_31bit_smis_on_64bit_arch%': 0,

# Sets -dV8_SHORT_BUILTIN_CALLS
Expand Down Expand Up @@ -197,6 +198,15 @@
# currently implemented.
'v8_use_perfetto%': 0,

# Enable map packing & unpacking (sets -dV8_MAP_PACKING).
'v8_enable_map_packing%': 0,

# Scan the call stack conservatively during garbage collection.
'v8_enable_conservative_stack_scanning%': 0,

# Use direct pointers in local handles.
'v8_enable_direct_local%': 0,

# Controls the threshold for on-heap/off-heap Typed Arrays.
'v8_typed_array_max_size_in_heap%': 64,

Expand Down Expand Up @@ -345,10 +355,13 @@
'defines': ['ENABLE_VTUNE_JIT_INTERFACE',],
}],
['v8_enable_pointer_compression==1', {
'defines': [
'V8_COMPRESS_POINTERS',
'V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE',
],
'defines': ['V8_COMPRESS_POINTERS'],
}],
['v8_enable_pointer_compression_shared_cage==1', {
'defines': ['V8_COMPRESS_POINTERS_IN_SHARED_CAGE'],
}],
['v8_enable_pointer_compression==1 and v8_enable_pointer_compression_shared_cage==0', {
'defines': ['V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE'],
}],
['v8_enable_pointer_compression==1 or v8_enable_31bit_smis_on_64bit_arch==1', {
'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH',],
Expand Down Expand Up @@ -392,13 +405,9 @@
}],
['v8_deprecation_warnings==1', {
'defines': ['V8_DEPRECATION_WARNINGS',],
},{
'defines!': ['V8_DEPRECATION_WARNINGS',],
}],
['v8_imminent_deprecation_warnings==1', {
'defines': ['V8_IMMINENT_DEPRECATION_WARNINGS',],
},{
'defines!': ['V8_IMMINENT_DEPRECATION_WARNINGS',],
}],
['v8_enable_i18n_support==1', {
'defines': ['V8_INTL_SUPPORT',],
Expand Down Expand Up @@ -443,9 +452,21 @@
['v8_use_perfetto==1', {
'defines': ['V8_USE_PERFETTO',],
}],
['v8_enable_map_packing==1', {
'defines': ['V8_MAP_PACKING',],
}],
['v8_win64_unwinding_info==1', {
'defines': ['V8_WIN64_UNWINDING_INFO',],
}],
['tsan==1', {
'defines': ['V8_IS_TSAN',],
}],
['v8_enable_conservative_stack_scanning==1', {
'defines': ['V8_ENABLE_CONSERVATIVE_STACK_SCANNING',],
}],
['v8_enable_direct_local==1', {
'defines': ['V8_ENABLE_DIRECT_LOCAL',],
}],
['v8_enable_regexp_interpreter_threaded_dispatch==1', {
'defines': ['V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH',],
}],
Expand Down
9 changes: 5 additions & 4 deletions unofficial.gni
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,11 @@ template("node_gn_build") {
script = "tools/generate_config_gypi.py"
outputs = [ "$target_gen_dir/config.gypi" ]
depfile = "$target_gen_dir/$target_name.d"
script_args = [ "$root_build_dir" ]
script_args += outputs
script_args += [ depfile ]
args = rebase_path(script_args, root_build_dir)
args = rebase_path(outputs, root_build_dir) + [
"--out-dir", rebase_path(root_build_dir, root_build_dir),
"--dep-file", rebase_path(depfile, root_build_dir),
"--node-gn-path", node_path,
]
}

executable("node_js2c") {
Expand Down