visaljs 0.0.0-stage → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +45 -2
- package/cli.js +8084 -0
- package/node/include/js_node.h +46 -0
- package/node/prelude/async_hooks.js +88 -0
- package/node/prelude/buffer.js +31 -0
- package/node/prelude/crypto.js +114 -0
- package/node/prelude/events.js +227 -0
- package/node/prelude/fs.js +79 -0
- package/node/prelude/http.js +536 -0
- package/node/prelude/http2.js +30 -0
- package/node/prelude/internal/crypto/asym.js +333 -0
- package/node/prelude/internal/crypto/cipher.js +205 -0
- package/node/prelude/internal/crypto/hash.js +137 -0
- package/node/prelude/internal/crypto/kdf.js +182 -0
- package/node/prelude/internal/crypto/keys.js +603 -0
- package/node/prelude/internal/crypto/random.js +118 -0
- package/node/prelude/internal/crypto/util.js +76 -0
- package/node/prelude/internal/errors.js +88 -0
- package/node/prelude/internal/querystring.js +105 -0
- package/node/prelude/module.js +53 -0
- package/node/prelude/net.js +51 -0
- package/node/prelude/os.js +129 -0
- package/node/prelude/path.js +257 -0
- package/node/prelude/process.js +21 -0
- package/node/prelude/querystring.js +469 -0
- package/node/prelude/stream.js +1327 -0
- package/node/prelude/stream_promises.js +7 -0
- package/node/prelude/stream_web.js +6 -0
- package/node/prelude/string_decoder.js +236 -0
- package/node/prelude/tty.js +18 -0
- package/node/prelude/url.js +1156 -0
- package/node/prelude/util.js +64 -0
- package/node/prelude/zlib.js +81 -0
- package/node/src/host_fs.c +126 -0
- package/node/src/host_http.c +486 -0
- package/node/src/host_os.c +505 -0
- package/node/src/host_sys.c +78 -0
- package/node/third_party/libuv/LICENSE +19 -0
- package/node/third_party/libuv/include/uv/aix.h +32 -0
- package/node/third_party/libuv/include/uv/bsd.h +34 -0
- package/node/third_party/libuv/include/uv/darwin.h +61 -0
- package/node/third_party/libuv/include/uv/errno.h +483 -0
- package/node/third_party/libuv/include/uv/linux.h +34 -0
- package/node/third_party/libuv/include/uv/os390.h +33 -0
- package/node/third_party/libuv/include/uv/posix.h +31 -0
- package/node/third_party/libuv/include/uv/sunos.h +44 -0
- package/node/third_party/libuv/include/uv/threadpool.h +37 -0
- package/node/third_party/libuv/include/uv/tree.h +521 -0
- package/node/third_party/libuv/include/uv/unix.h +512 -0
- package/node/third_party/libuv/include/uv/version.h +43 -0
- package/node/third_party/libuv/include/uv/win.h +698 -0
- package/node/third_party/libuv/include/uv.h +1990 -0
- package/node/third_party/libuv/src/fs-poll.c +290 -0
- package/node/third_party/libuv/src/heap-inl.h +245 -0
- package/node/third_party/libuv/src/idna.c +560 -0
- package/node/third_party/libuv/src/idna.h +31 -0
- package/node/third_party/libuv/src/inet.c +298 -0
- package/node/third_party/libuv/src/queue.h +90 -0
- package/node/third_party/libuv/src/random.c +123 -0
- package/node/third_party/libuv/src/strscpy.c +38 -0
- package/node/third_party/libuv/src/strscpy.h +39 -0
- package/node/third_party/libuv/src/strtok.c +52 -0
- package/node/third_party/libuv/src/strtok.h +27 -0
- package/node/third_party/libuv/src/thread-common.c +175 -0
- package/node/third_party/libuv/src/threadpool.c +419 -0
- package/node/third_party/libuv/src/timer.c +200 -0
- package/node/third_party/libuv/src/unix/async.c +418 -0
- package/node/third_party/libuv/src/unix/bsd-ifaddrs.c +164 -0
- package/node/third_party/libuv/src/unix/core.c +2104 -0
- package/node/third_party/libuv/src/unix/darwin-proctitle.c +176 -0
- package/node/third_party/libuv/src/unix/darwin-stub.h +97 -0
- package/node/third_party/libuv/src/unix/darwin-syscalls.h +17 -0
- package/node/third_party/libuv/src/unix/darwin.c +237 -0
- package/node/third_party/libuv/src/unix/dl.c +80 -0
- package/node/third_party/libuv/src/unix/fs.c +2303 -0
- package/node/third_party/libuv/src/unix/fsevents.c +906 -0
- package/node/third_party/libuv/src/unix/getaddrinfo.c +252 -0
- package/node/third_party/libuv/src/unix/getnameinfo.c +121 -0
- package/node/third_party/libuv/src/unix/internal.h +530 -0
- package/node/third_party/libuv/src/unix/kqueue.c +667 -0
- package/node/third_party/libuv/src/unix/linux.c +2761 -0
- package/node/third_party/libuv/src/unix/loop-watcher.c +68 -0
- package/node/third_party/libuv/src/unix/loop.c +240 -0
- package/node/third_party/libuv/src/unix/pipe.c +555 -0
- package/node/third_party/libuv/src/unix/poll.c +159 -0
- package/node/third_party/libuv/src/unix/process.c +1123 -0
- package/node/third_party/libuv/src/unix/procfs-exepath.c +45 -0
- package/node/third_party/libuv/src/unix/proctitle.c +157 -0
- package/node/third_party/libuv/src/unix/random-devurandom.c +93 -0
- package/node/third_party/libuv/src/unix/random-getentropy.c +57 -0
- package/node/third_party/libuv/src/unix/random-getrandom.c +86 -0
- package/node/third_party/libuv/src/unix/random-sysctl-linux.c +99 -0
- package/node/third_party/libuv/src/unix/signal.c +581 -0
- package/node/third_party/libuv/src/unix/stream.c +1567 -0
- package/node/third_party/libuv/src/unix/tcp.c +673 -0
- package/node/third_party/libuv/src/unix/thread.c +975 -0
- package/node/third_party/libuv/src/unix/tty.c +510 -0
- package/node/third_party/libuv/src/unix/udp.c +1434 -0
- package/node/third_party/libuv/src/uv-common.c +1051 -0
- package/node/third_party/libuv/src/uv-common.h +474 -0
- package/node/third_party/libuv/src/uv-data-getter-setters.c +119 -0
- package/node/third_party/libuv/src/version.c +45 -0
- package/node/third_party/llhttp/LICENSE +22 -0
- package/node/third_party/llhttp/api.c +509 -0
- package/node/third_party/llhttp/http.c +170 -0
- package/node/third_party/llhttp/llhttp.c +10099 -0
- package/node/third_party/llhttp/llhttp.h +907 -0
- package/package.json +25 -4
- package/runtime/include/js_atoms.gen.h +68 -0
- package/runtime/include/js_atoms.h +54 -0
- package/runtime/include/js_bigint.h +93 -0
- package/runtime/include/js_buffer.h +79 -0
- package/runtime/include/js_builtins.h +168 -0
- package/runtime/include/js_console.h +58 -0
- package/runtime/include/js_convert.h +22 -0
- package/runtime/include/js_core.def +188 -0
- package/runtime/include/js_crypto.h +58 -0
- package/runtime/include/js_error.h +37 -0
- package/runtime/include/js_exception.h +65 -0
- package/runtime/include/js_function.h +167 -0
- package/runtime/include/js_gc.h +195 -0
- package/runtime/include/js_generator.h +96 -0
- package/runtime/include/js_host.h +19 -0
- package/runtime/include/js_jobs.h +84 -0
- package/runtime/include/js_module.h +16 -0
- package/runtime/include/js_object.h +384 -0
- package/runtime/include/js_ops.h +111 -0
- package/runtime/include/js_promise.h +45 -0
- package/runtime/include/js_regexp.h +25 -0
- package/runtime/include/js_runtime.h +30 -0
- package/runtime/include/js_symbol.h +62 -0
- package/runtime/include/js_web.h +110 -0
- package/runtime/include/jscell.h +48 -0
- package/runtime/include/jscontext.h +240 -0
- package/runtime/include/jsnum.h +42 -0
- package/runtime/include/jsstring.h +161 -0
- package/runtime/include/jsvalue.h +142 -0
- package/runtime/src/arguments.c +115 -0
- package/runtime/src/array.c +1145 -0
- package/runtime/src/arraybuffer.c +608 -0
- package/runtime/src/async_iter.c +479 -0
- package/runtime/src/atoms.c +157 -0
- package/runtime/src/base64.c +107 -0
- package/runtime/src/bigint.c +1189 -0
- package/runtime/src/blob.c +371 -0
- package/runtime/src/buffer.c +1357 -0
- package/runtime/src/builtin_table.c +100 -0
- package/runtime/src/builtins.c +987 -0
- package/runtime/src/builtins_util.h +53 -0
- package/runtime/src/collections.c +912 -0
- package/runtime/src/components.c +28 -0
- package/runtime/src/console.c +637 -0
- package/runtime/src/convert.c +82 -0
- package/runtime/src/core_all.c +21 -0
- package/runtime/src/crypto.c +116 -0
- package/runtime/src/crypto_asym.c +644 -0
- package/runtime/src/crypto_cipher.c +671 -0
- package/runtime/src/crypto_hash.c +260 -0
- package/runtime/src/crypto_host.c +414 -0
- package/runtime/src/crypto_internal.h +304 -0
- package/runtime/src/crypto_kdf.c +143 -0
- package/runtime/src/crypto_key.c +171 -0
- package/runtime/src/crypto_pkey.c +794 -0
- package/runtime/src/crypto_subtle.c +1675 -0
- package/runtime/src/date.c +940 -0
- package/runtime/src/domexception.c +169 -0
- package/runtime/src/elements.c +312 -0
- package/runtime/src/elements.h +45 -0
- package/runtime/src/encoding.c +485 -0
- package/runtime/src/error.c +297 -0
- package/runtime/src/events.c +793 -0
- package/runtime/src/exception.c +56 -0
- package/runtime/src/fetch.c +772 -0
- package/runtime/src/function.c +530 -0
- package/runtime/src/gc.c +803 -0
- package/runtime/src/generator.c +218 -0
- package/runtime/src/global.c +119 -0
- package/runtime/src/headers.c +557 -0
- package/runtime/src/inspect.c +1792 -0
- package/runtime/src/internal.h +80 -0
- package/runtime/src/iterate.c +94 -0
- package/runtime/src/iterator.c +409 -0
- package/runtime/src/jobs.c +337 -0
- package/runtime/src/jsnum.c +353 -0
- package/runtime/src/json.c +1028 -0
- package/runtime/src/math.c +243 -0
- package/runtime/src/module.c +336 -0
- package/runtime/src/number.c +176 -0
- package/runtime/src/object.c +1265 -0
- package/runtime/src/ops.c +322 -0
- package/runtime/src/os.c +196 -0
- package/runtime/src/os.h +29 -0
- package/runtime/src/process.c +432 -0
- package/runtime/src/promise.c +721 -0
- package/runtime/src/proxy.c +570 -0
- package/runtime/src/reflect.c +194 -0
- package/runtime/src/regexp.c +1141 -0
- package/runtime/src/regexp_anchor.h +34 -0
- package/runtime/src/regexp_message.h +32 -0
- package/runtime/src/shape.c +294 -0
- package/runtime/src/shape.h +46 -0
- package/runtime/src/streams.c +1046 -0
- package/runtime/src/streams.h +47 -0
- package/runtime/src/string.c +364 -0
- package/runtime/src/string_builtins.c +837 -0
- package/runtime/src/symbol.c +143 -0
- package/runtime/src/test_host.c +59 -0
- package/runtime/src/typedarray.c +1330 -0
- package/runtime/src/tznames.gen.h +712 -0
- package/runtime/src/uri.c +169 -0
- package/runtime/src/url.c +2116 -0
- package/runtime/src/weak.c +486 -0
- package/runtime/src/web.c +214 -0
- package/runtime/src/wrapper.c +59 -0
- package/runtime/src/writable.c +1486 -0
- package/runtime/third_party/ada-idna/LICENSE-MIT +18 -0
- package/runtime/third_party/ada-idna/README.md +27 -0
- package/runtime/third_party/ada-idna/convert.mjs +83 -0
- package/runtime/third_party/ada-idna/idna.c +416 -0
- package/runtime/third_party/ada-idna/idna.h +15 -0
- package/runtime/third_party/ada-idna/idna_tables.h +2657 -0
- package/runtime/third_party/bearssl/LICENSE.txt +21 -0
- package/runtime/third_party/bearssl/README.txt +136 -0
- package/runtime/third_party/bearssl/VERSION +1 -0
- package/runtime/third_party/bearssl/inc/bearssl.h +183 -0
- package/runtime/third_party/bearssl/inc/bearssl_aead.h +1059 -0
- package/runtime/third_party/bearssl/inc/bearssl_block.h +2618 -0
- package/runtime/third_party/bearssl/inc/bearssl_ec.h +967 -0
- package/runtime/third_party/bearssl/inc/bearssl_hash.h +1346 -0
- package/runtime/third_party/bearssl/inc/bearssl_hmac.h +241 -0
- package/runtime/third_party/bearssl/inc/bearssl_kdf.h +284 -0
- package/runtime/third_party/bearssl/inc/bearssl_pem.h +294 -0
- package/runtime/third_party/bearssl/inc/bearssl_prf.h +150 -0
- package/runtime/third_party/bearssl/inc/bearssl_rand.h +397 -0
- package/runtime/third_party/bearssl/inc/bearssl_rsa.h +1655 -0
- package/runtime/third_party/bearssl/inc/bearssl_ssl.h +4296 -0
- package/runtime/third_party/bearssl/inc/bearssl_x509.h +1474 -0
- package/runtime/third_party/bearssl/src/aead/ccm.c +346 -0
- package/runtime/third_party/bearssl/src/aead/eax.c +525 -0
- package/runtime/third_party/bearssl/src/aead/gcm.c +318 -0
- package/runtime/third_party/bearssl/src/codec/ccopy.c +44 -0
- package/runtime/third_party/bearssl/src/codec/dec16be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec16le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec32be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec32le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec64be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/dec64le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc16be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc16le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc32be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc32le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc64be.c +38 -0
- package/runtime/third_party/bearssl/src/codec/enc64le.c +38 -0
- package/runtime/third_party/bearssl/src/codec/pemdec.c +526 -0
- package/runtime/third_party/bearssl/src/codec/pemdec.t0 +314 -0
- package/runtime/third_party/bearssl/src/codec/pemenc.c +173 -0
- package/runtime/third_party/bearssl/src/config.h +247 -0
- package/runtime/third_party/bearssl/src/ec/ec_all_m15.c +121 -0
- package/runtime/third_party/bearssl/src/ec/ec_all_m31.c +171 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_i15.c +398 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_i31.c +390 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m15.c +1478 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m31.c +800 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m62.c +605 -0
- package/runtime/third_party/bearssl/src/ec/ec_c25519_m64.c +831 -0
- package/runtime/third_party/bearssl/src/ec/ec_curve25519.c +46 -0
- package/runtime/third_party/bearssl/src/ec/ec_default.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ec_keygen.c +86 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m15.c +2124 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m31.c +1469 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m62.c +1765 -0
- package/runtime/third_party/bearssl/src/ec/ec_p256_m64.c +1781 -0
- package/runtime/third_party/bearssl/src/ec/ec_prime_i15.c +824 -0
- package/runtime/third_party/bearssl/src/ec/ec_prime_i31.c +826 -0
- package/runtime/third_party/bearssl/src/ec/ec_pubkey.c +85 -0
- package/runtime/third_party/bearssl/src/ec/ec_secp256r1.c +51 -0
- package/runtime/third_party/bearssl/src/ec/ec_secp384r1.c +57 -0
- package/runtime/third_party/bearssl/src/ec/ec_secp521r1.c +64 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_atr.c +134 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_sign_asn1.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_sign_raw.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_vrfy_asn1.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_default_vrfy_raw.c +36 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_bits.c +47 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_sign_asn1.c +45 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_sign_raw.c +174 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_vrfy_asn1.c +48 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i15_vrfy_raw.c +166 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_bits.c +47 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_sign_asn1.c +45 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_sign_raw.c +173 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_vrfy_asn1.c +48 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_i31_vrfy_raw.c +165 -0
- package/runtime/third_party/bearssl/src/ec/ecdsa_rta.c +121 -0
- package/runtime/third_party/bearssl/src/hash/dig_oid.c +84 -0
- package/runtime/third_party/bearssl/src/hash/dig_size.c +50 -0
- package/runtime/third_party/bearssl/src/hash/ghash_ctmul.c +345 -0
- package/runtime/third_party/bearssl/src/hash/ghash_ctmul32.c +251 -0
- package/runtime/third_party/bearssl/src/hash/ghash_ctmul64.c +154 -0
- package/runtime/third_party/bearssl/src/hash/ghash_pclmul.c +389 -0
- package/runtime/third_party/bearssl/src/hash/ghash_pwr8.c +411 -0
- package/runtime/third_party/bearssl/src/hash/md5.c +208 -0
- package/runtime/third_party/bearssl/src/hash/md5sha1.c +141 -0
- package/runtime/third_party/bearssl/src/hash/mgf1.c +56 -0
- package/runtime/third_party/bearssl/src/hash/multihash.c +166 -0
- package/runtime/third_party/bearssl/src/hash/sha1.c +191 -0
- package/runtime/third_party/bearssl/src/hash/sha2big.c +285 -0
- package/runtime/third_party/bearssl/src/hash/sha2small.c +341 -0
- package/runtime/third_party/bearssl/src/inner.h +2577 -0
- package/runtime/third_party/bearssl/src/int/i15_add.c +46 -0
- package/runtime/third_party/bearssl/src/int/i15_bitlen.c +44 -0
- package/runtime/third_party/bearssl/src/int/i15_decmod.c +124 -0
- package/runtime/third_party/bearssl/src/int/i15_decode.c +56 -0
- package/runtime/third_party/bearssl/src/int/i15_decred.c +100 -0
- package/runtime/third_party/bearssl/src/int/i15_encode.c +56 -0
- package/runtime/third_party/bearssl/src/int/i15_fmont.c +59 -0
- package/runtime/third_party/bearssl/src/int/i15_iszero.c +39 -0
- package/runtime/third_party/bearssl/src/int/i15_moddiv.c +465 -0
- package/runtime/third_party/bearssl/src/int/i15_modpow.c +50 -0
- package/runtime/third_party/bearssl/src/int/i15_modpow2.c +160 -0
- package/runtime/third_party/bearssl/src/int/i15_montmul.c +184 -0
- package/runtime/third_party/bearssl/src/int/i15_mulacc.c +61 -0
- package/runtime/third_party/bearssl/src/int/i15_muladd.c +173 -0
- package/runtime/third_party/bearssl/src/int/i15_ninv15.c +38 -0
- package/runtime/third_party/bearssl/src/int/i15_reduce.c +66 -0
- package/runtime/third_party/bearssl/src/int/i15_rshift.c +47 -0
- package/runtime/third_party/bearssl/src/int/i15_sub.c +46 -0
- package/runtime/third_party/bearssl/src/int/i15_tmont.c +36 -0
- package/runtime/third_party/bearssl/src/int/i31_add.c +46 -0
- package/runtime/third_party/bearssl/src/int/i31_bitlen.c +44 -0
- package/runtime/third_party/bearssl/src/int/i31_decmod.c +124 -0
- package/runtime/third_party/bearssl/src/int/i31_decode.c +57 -0
- package/runtime/third_party/bearssl/src/int/i31_decred.c +103 -0
- package/runtime/third_party/bearssl/src/int/i31_encode.c +79 -0
- package/runtime/third_party/bearssl/src/int/i31_fmont.c +60 -0
- package/runtime/third_party/bearssl/src/int/i31_iszero.c +39 -0
- package/runtime/third_party/bearssl/src/int/i31_moddiv.c +488 -0
- package/runtime/third_party/bearssl/src/int/i31_modpow.c +65 -0
- package/runtime/third_party/bearssl/src/int/i31_modpow2.c +160 -0
- package/runtime/third_party/bearssl/src/int/i31_montmul.c +127 -0
- package/runtime/third_party/bearssl/src/int/i31_mulacc.c +74 -0
- package/runtime/third_party/bearssl/src/int/i31_muladd.c +157 -0
- package/runtime/third_party/bearssl/src/int/i31_ninv31.c +39 -0
- package/runtime/third_party/bearssl/src/int/i31_reduce.c +66 -0
- package/runtime/third_party/bearssl/src/int/i31_rshift.c +47 -0
- package/runtime/third_party/bearssl/src/int/i31_sub.c +46 -0
- package/runtime/third_party/bearssl/src/int/i31_tmont.c +36 -0
- package/runtime/third_party/bearssl/src/int/i32_add.c +51 -0
- package/runtime/third_party/bearssl/src/int/i32_bitlen.c +44 -0
- package/runtime/third_party/bearssl/src/int/i32_decmod.c +77 -0
- package/runtime/third_party/bearssl/src/int/i32_decode.c +63 -0
- package/runtime/third_party/bearssl/src/int/i32_decred.c +107 -0
- package/runtime/third_party/bearssl/src/int/i32_div32.c +56 -0
- package/runtime/third_party/bearssl/src/int/i32_encode.c +72 -0
- package/runtime/third_party/bearssl/src/int/i32_fmont.c +60 -0
- package/runtime/third_party/bearssl/src/int/i32_iszero.c +39 -0
- package/runtime/third_party/bearssl/src/int/i32_modpow.c +65 -0
- package/runtime/third_party/bearssl/src/int/i32_montmul.c +69 -0
- package/runtime/third_party/bearssl/src/int/i32_mulacc.c +56 -0
- package/runtime/third_party/bearssl/src/int/i32_muladd.c +138 -0
- package/runtime/third_party/bearssl/src/int/i32_ninv32.c +39 -0
- package/runtime/third_party/bearssl/src/int/i32_reduce.c +66 -0
- package/runtime/third_party/bearssl/src/int/i32_sub.c +51 -0
- package/runtime/third_party/bearssl/src/int/i32_tmont.c +36 -0
- package/runtime/third_party/bearssl/src/int/i62_modpow2.c +493 -0
- package/runtime/third_party/bearssl/src/kdf/hkdf.c +107 -0
- package/runtime/third_party/bearssl/src/kdf/shake.c +590 -0
- package/runtime/third_party/bearssl/src/mac/hmac.c +122 -0
- package/runtime/third_party/bearssl/src/mac/hmac_ct.c +193 -0
- package/runtime/third_party/bearssl/src/rand/aesctr_drbg.c +206 -0
- package/runtime/third_party/bearssl/src/rand/hmac_drbg.c +157 -0
- package/runtime/third_party/bearssl/src/rand/sysrng.c +252 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_keygen.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_modulus.c +36 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_oaep_decrypt.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_oaep_encrypt.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pkcs1_sign.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pkcs1_vrfy.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_priv.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_privexp.c +36 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pss_sign.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pss_vrfy.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pub.c +38 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_default_pubexp.c +36 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_keygen.c +583 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_modulus.c +99 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_oaep_decrypt.c +41 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_oaep_encrypt.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pkcs1_sign.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.c +43 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_priv.c +209 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_privexp.c +320 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pss_sign.c +40 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pss_vrfy.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pub.c +113 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i15_pubexp.c +152 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_keygen.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_keygen_inner.c +608 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_modulus.c +99 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_oaep_decrypt.c +41 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_oaep_encrypt.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pkcs1_sign.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.c +43 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_priv.c +203 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_privexp.c +318 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pss_sign.c +40 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pss_vrfy.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pub.c +106 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i31_pubexp.c +152 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_oaep_decrypt.c +41 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_oaep_encrypt.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pkcs1_sign.c +37 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.c +43 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_priv.c +160 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pss_sign.c +40 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pss_vrfy.c +44 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i32_pub.c +77 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_keygen.c +57 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_oaep_decrypt.c +61 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_oaep_encrypt.c +64 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pkcs1_sign.c +57 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.c +63 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_priv.c +223 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pss_sign.c +60 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pss_vrfy.c +64 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_i62_pub.c +125 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_oaep_pad.c +112 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_oaep_unpad.c +145 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pkcs1_sig_pad.c +100 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pkcs1_sig_unpad.c +121 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pss_sig_pad.c +106 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_pss_sig_unpad.c +121 -0
- package/runtime/third_party/bearssl/src/rsa/rsa_ssl_decrypt.c +52 -0
- package/runtime/third_party/bearssl/src/settings.c +306 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_cbcdec.c +69 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_cbcenc.c +67 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_ctr.c +84 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_ctrcbc.c +142 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_dec.c +254 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_big_enc.c +157 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_common.c +112 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct.c +328 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64.c +398 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_cbcdec.c +104 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_cbcenc.c +81 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_ctr.c +114 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_ctrcbc.c +433 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_dec.c +159 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct64_enc.c +115 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_cbcdec.c +111 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_cbcenc.c +91 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_ctr.c +116 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_ctrcbc.c +422 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_dec.c +170 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_ct_enc.c +112 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8.c +445 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_cbcdec.c +670 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_cbcenc.c +417 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_ctr.c +717 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_ctrcbc.c +946 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_cbcdec.c +69 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_cbcenc.c +67 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_ctr.c +84 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_ctrcbc.c +142 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_dec.c +176 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_small_enc.c +129 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni.c +240 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_cbcdec.c +223 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_cbcenc.c +122 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_ctr.c +211 -0
- package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_ctrcbc.c +596 -0
- package/runtime/third_party/bearssl/src/symcipher/chacha20_ct.c +106 -0
- package/runtime/third_party/bearssl/src/symcipher/chacha20_sse2.c +237 -0
- package/runtime/third_party/bearssl/src/symcipher/des_ct.c +411 -0
- package/runtime/third_party/bearssl/src/symcipher/des_ct_cbcdec.c +87 -0
- package/runtime/third_party/bearssl/src/symcipher/des_ct_cbcenc.c +69 -0
- package/runtime/third_party/bearssl/src/symcipher/des_support.c +166 -0
- package/runtime/third_party/bearssl/src/symcipher/des_tab.c +310 -0
- package/runtime/third_party/bearssl/src/symcipher/des_tab_cbcdec.c +85 -0
- package/runtime/third_party/bearssl/src/symcipher/des_tab_cbcenc.c +67 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmul.c +260 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmul32.c +297 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmulq.c +475 -0
- package/runtime/third_party/bearssl/src/symcipher/poly1305_i15.c +221 -0
- package/runtime/third_party/bearssl/src/x509/asn1.t0 +757 -0
- package/runtime/third_party/bearssl/src/x509/asn1enc.c +93 -0
- package/runtime/third_party/bearssl/src/x509/encode_ec_pk8der.c +110 -0
- package/runtime/third_party/bearssl/src/x509/encode_ec_rawder.c +161 -0
- package/runtime/third_party/bearssl/src/x509/encode_rsa_pk8der.c +97 -0
- package/runtime/third_party/bearssl/src/x509/encode_rsa_rawder.c +96 -0
- package/runtime/third_party/bearssl/src/x509/skey_decoder.c +653 -0
- package/runtime/third_party/bearssl/src/x509/skey_decoder.t0 +376 -0
- package/runtime/third_party/bearssl/src/x509/x509_decoder.c +776 -0
- package/runtime/third_party/bearssl/src/x509/x509_decoder.t0 +324 -0
- package/runtime/third_party/bearssl/src/x509/x509_knownkey.c +105 -0
- package/runtime/third_party/bearssl/src/x509/x509_minimal.c +1722 -0
- package/runtime/third_party/bearssl/src/x509/x509_minimal.t0 +1526 -0
- package/runtime/third_party/bearssl/src/x509/x509_minimal_full.c +59 -0
- package/runtime/third_party/quickjs-dtoa/LICENSE +22 -0
- package/runtime/third_party/quickjs-dtoa/README.md +23 -0
- package/runtime/third_party/quickjs-dtoa/dtoa.c +1640 -0
- package/runtime/third_party/quickjs-dtoa/dtoa.h +83 -0
- package/runtime/third_party/quickjs-dtoa/dtoa_compat.h +89 -0
- package/runtime/third_party/quickjs-regexp/LICENSE +22 -0
- package/runtime/third_party/quickjs-regexp/README.md +22 -0
- package/runtime/third_party/quickjs-regexp/cutils.c +641 -0
- package/runtime/third_party/quickjs-regexp/cutils.h +457 -0
- package/runtime/third_party/quickjs-regexp/libregexp-opcode.h +73 -0
- package/runtime/third_party/quickjs-regexp/libregexp.c +3448 -0
- package/runtime/third_party/quickjs-regexp/libregexp.h +65 -0
- package/runtime/third_party/quickjs-regexp/libunicode-table.h +5206 -0
- package/runtime/third_party/quickjs-regexp/libunicode.c +2124 -0
- package/runtime/third_party/quickjs-regexp/libunicode.h +196 -0
- package/runtime/third_party/v8-ieee754/LICENSE +61 -0
- package/runtime/third_party/v8-ieee754/README.md +22 -0
- package/runtime/third_party/v8-ieee754/convert.py +84 -0
- package/runtime/third_party/v8-ieee754/ieee754.c +3030 -0
- package/runtime/third_party/v8-ieee754/ieee754.h +27 -0
- package/runtime/tools/regexp_compile.c +90 -0
package/runtime/src/gc.c
ADDED
|
@@ -0,0 +1,803 @@
|
|
|
1
|
+
/* Heap and garbage collector (ADR 0002).
|
|
2
|
+
*
|
|
3
|
+
* Allocation bits say which cells hold a value. They are exact whenever the
|
|
4
|
+
* world is stopped:
|
|
5
|
+
* - sweeping a block sets them to its mark bits (only survivors);
|
|
6
|
+
* - when a block becomes the allocation block of its class, every cell's
|
|
7
|
+
* bit is set, because the allocator may hand out any of them;
|
|
8
|
+
* - stopping the world clears the bits of the cells still on a free list.
|
|
9
|
+
* Only the allocation block of a class has cells on a free list.
|
|
10
|
+
*/
|
|
11
|
+
#include "js_gc.h"
|
|
12
|
+
|
|
13
|
+
#include <setjmp.h>
|
|
14
|
+
#include <stdarg.h>
|
|
15
|
+
#include <stdio.h>
|
|
16
|
+
#include <stdlib.h>
|
|
17
|
+
#include <string.h>
|
|
18
|
+
|
|
19
|
+
#include "internal.h"
|
|
20
|
+
#include "js_builtins.h"
|
|
21
|
+
#include "jscontext.h"
|
|
22
|
+
#include "os.h"
|
|
23
|
+
|
|
24
|
+
const uint16_t js_size_class_bytes[JS_NUM_SIZE_CLASSES] = {
|
|
25
|
+
16, 32, 48, 64, 80, 96, 112, 128,
|
|
26
|
+
160, 192, 224, 256,
|
|
27
|
+
320, 384, 448, 512,
|
|
28
|
+
640, 768, 896, 1024,
|
|
29
|
+
1280, 1536, 1792, 2048,
|
|
30
|
+
2560, 3072, 3584, 4096,
|
|
31
|
+
5120, 6144, 7168, 8192,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
struct JSTracer {
|
|
35
|
+
JSHeap *heap;
|
|
36
|
+
size_t sp; /* mark stack depth */
|
|
37
|
+
const void *stack_low; /* the conservative scan covers [stack_low, stack_base) */
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
_Noreturn void js_fatal(const char *fmt, ...) {
|
|
41
|
+
char msg[512];
|
|
42
|
+
va_list ap;
|
|
43
|
+
va_start(ap, fmt);
|
|
44
|
+
int n = snprintf(msg, sizeof msg, "jsrt: fatal: ");
|
|
45
|
+
vsnprintf(msg + n, sizeof msg - (size_t)n - 1, fmt, ap);
|
|
46
|
+
va_end(ap);
|
|
47
|
+
strcat(msg, "\n");
|
|
48
|
+
fputs(msg, stderr); /* one write, so the message arrives whole */
|
|
49
|
+
exit(70); /* EX_SOFTWARE */
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static void *xrealloc(void *p, size_t size) {
|
|
53
|
+
void *q = realloc(p, size);
|
|
54
|
+
if (!q) js_fatal("out of memory (%zu bytes of GC metadata)", size);
|
|
55
|
+
return q;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* ADR 0001: every cell address must fit in 48 bits. */
|
|
59
|
+
static void check_address(const void *p, size_t size) {
|
|
60
|
+
if ((uintptr_t)p + size > (UINT64_C(1) << 48))
|
|
61
|
+
js_fatal("heap memory mapped above 2^48 (%p)", p);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* ---- Cell classes ------------------------------------------------------ */
|
|
65
|
+
|
|
66
|
+
static void value_array_visit(JSCell *c, JSTracer *trc) {
|
|
67
|
+
JSValueArray *a = (JSValueArray *)c;
|
|
68
|
+
for (uint32_t i = 0; i < c->aux; i++) js_trace_value(trc, a->values[i]);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static const JSCellClass value_array_class = { "ValueArray", value_array_visit, NULL };
|
|
72
|
+
|
|
73
|
+
static const JSCellClass bigint_class = { "BigInt", NULL, NULL }; /* limbs only (ADR 0016) */
|
|
74
|
+
|
|
75
|
+
static const JSCellClass *const cell_classes[JS_CELL_KIND_COUNT] = {
|
|
76
|
+
[JS_CELL_STR_FLAT] = &js_flat_string_class,
|
|
77
|
+
[JS_CELL_STR_ROPE] = &js_rope_class,
|
|
78
|
+
[JS_CELL_STR_SLICE] = &js_slice_class,
|
|
79
|
+
[JS_CELL_VALUE_ARRAY] = &value_array_class,
|
|
80
|
+
[JS_CELL_SHAPE] = &js_shape_cell_class,
|
|
81
|
+
[JS_CELL_ACCESSOR] = &js_accessor_cell_class,
|
|
82
|
+
[JS_CELL_ELEMENTS] = &js_elements_cell_class,
|
|
83
|
+
[JS_CELL_ENV] = &js_env_cell_class,
|
|
84
|
+
[JS_CELL_SYMBOL] = &js_symbol_cell_class,
|
|
85
|
+
[JS_CELL_BIGINT] = &bigint_class,
|
|
86
|
+
[JS_CELL_OBJECT] = &js_object_cell_class,
|
|
87
|
+
[JS_CELL_ARRAY] = &js_object_cell_class,
|
|
88
|
+
[JS_CELL_FUNCTION] = &js_object_cell_class,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
static const JSCellClass *class_of(JSCell *c) {
|
|
92
|
+
return c->kind == JS_CELL_HOST ? ((JSHostCell *)c)->cls : cell_classes[c->kind];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* ---- Bitmaps ----------------------------------------------------------- */
|
|
96
|
+
|
|
97
|
+
static char *block_cell(JSBlock *b, uint32_t i) {
|
|
98
|
+
return (char *)b + JS_BLOCK_FIRST_CELL + (size_t)i * b->cell_size;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static uint32_t cell_index(JSBlock *b, const void *c) {
|
|
102
|
+
return (uint32_t)(((const char *)c - (const char *)b - JS_BLOCK_FIRST_CELL) / b->cell_size);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static int bit_get(const uint64_t *bits, uint32_t i) { return (int)((bits[i / 64] >> (i % 64)) & 1); }
|
|
106
|
+
static void bit_set(uint64_t *bits, uint32_t i) { bits[i / 64] |= UINT64_C(1) << (i % 64); }
|
|
107
|
+
static void bit_clear(uint64_t *bits, uint32_t i) { bits[i / 64] &= ~(UINT64_C(1) << (i % 64)); }
|
|
108
|
+
|
|
109
|
+
static void set_all_allocated(JSBlock *b) {
|
|
110
|
+
uint32_t full = b->cell_count / 64, rest = b->cell_count % 64;
|
|
111
|
+
memset(b->alloc_bits, 0xFF, full * sizeof(uint64_t));
|
|
112
|
+
if (rest) b->alloc_bits[full] = (UINT64_C(1) << rest) - 1;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* ---- Block set: which 64 KiB chunks are small-object blocks ------------ */
|
|
116
|
+
|
|
117
|
+
static size_t block_hash(uintptr_t b) {
|
|
118
|
+
uint64_t x = (uint64_t)(b >> 16) * UINT64_C(0x9E3779B97F4A7C15);
|
|
119
|
+
return (size_t)(x >> 32);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static void bloom_add(JSHeap *h, uintptr_t b) {
|
|
123
|
+
size_t bit = block_hash(b) & 255;
|
|
124
|
+
h->block_bloom[bit / 64] |= UINT64_C(1) << (bit % 64);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static int bloom_maybe(const JSHeap *h, uintptr_t b) {
|
|
128
|
+
size_t bit = block_hash(b) & 255;
|
|
129
|
+
return (int)((h->block_bloom[bit / 64] >> (bit % 64)) & 1);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static void block_set_put(uintptr_t *keys, size_t cap, uintptr_t b) {
|
|
133
|
+
size_t i = block_hash(b) & (cap - 1);
|
|
134
|
+
while (keys[i]) i = (i + 1) & (cap - 1);
|
|
135
|
+
keys[i] = b;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static void block_set_add(JSHeap *h, uintptr_t b) {
|
|
139
|
+
if (2 * (h->block_set_count + 1) > h->block_set_cap) { /* load factor <= 1/2 */
|
|
140
|
+
size_t cap = h->block_set_cap ? h->block_set_cap * 2 : 64;
|
|
141
|
+
uintptr_t *keys = calloc(cap, sizeof *keys);
|
|
142
|
+
if (!keys) js_fatal("out of memory growing the block set");
|
|
143
|
+
for (size_t i = 0; i < h->block_set_cap; i++)
|
|
144
|
+
if (h->block_set[i]) block_set_put(keys, cap, h->block_set[i]);
|
|
145
|
+
free(h->block_set);
|
|
146
|
+
h->block_set = keys;
|
|
147
|
+
h->block_set_cap = cap;
|
|
148
|
+
}
|
|
149
|
+
block_set_put(h->block_set, h->block_set_cap, b);
|
|
150
|
+
h->block_set_count++;
|
|
151
|
+
bloom_add(h, b);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static int block_set_contains(const JSHeap *h, uintptr_t b) {
|
|
155
|
+
if (!h->block_set_cap || !bloom_maybe(h, b)) return 0;
|
|
156
|
+
for (size_t i = block_hash(b) & (h->block_set_cap - 1);; i = (i + 1) & (h->block_set_cap - 1)) {
|
|
157
|
+
if (h->block_set[i] == b) return 1;
|
|
158
|
+
if (!h->block_set[i]) return 0;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Linear probing: shift later entries of the probe run back into the hole. */
|
|
163
|
+
static void block_set_remove(JSHeap *h, uintptr_t b) {
|
|
164
|
+
size_t mask = h->block_set_cap - 1, i = block_hash(b) & mask;
|
|
165
|
+
while (h->block_set[i] != b) {
|
|
166
|
+
if (!h->block_set[i]) return;
|
|
167
|
+
i = (i + 1) & mask;
|
|
168
|
+
}
|
|
169
|
+
h->block_set[i] = 0;
|
|
170
|
+
h->block_set_count--;
|
|
171
|
+
for (size_t j = (i + 1) & mask; h->block_set[j]; j = (j + 1) & mask) {
|
|
172
|
+
size_t home = block_hash(h->block_set[j]) & mask;
|
|
173
|
+
int stays = i <= j ? (i < home && home <= j) : (i < home || home <= j);
|
|
174
|
+
if (!stays) {
|
|
175
|
+
h->block_set[i] = h->block_set[j];
|
|
176
|
+
h->block_set[j] = 0;
|
|
177
|
+
i = j;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/* The Bloom filter keeps the bit: it only ever answers "maybe". */
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static void note_mapping(JSHeap *h, const void *p, size_t size) {
|
|
184
|
+
uintptr_t lo = (uintptr_t)p, hi = lo + size;
|
|
185
|
+
if (!h->min_addr || lo < h->min_addr) h->min_addr = lo;
|
|
186
|
+
if (hi > h->max_addr) h->max_addr = hi;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* ---- Small-object blocks ----------------------------------------------- */
|
|
190
|
+
|
|
191
|
+
static JSBlock *map_block(JSHeap *h) {
|
|
192
|
+
JSBlock *b = js_os_map_aligned(JS_BLOCK_SIZE, JS_BLOCK_SIZE);
|
|
193
|
+
if (!b) js_fatal("out of memory mapping a heap block");
|
|
194
|
+
check_address(b, JS_BLOCK_SIZE);
|
|
195
|
+
note_mapping(h, b, JS_BLOCK_SIZE);
|
|
196
|
+
block_set_add(h, (uintptr_t)b);
|
|
197
|
+
h->block_count++;
|
|
198
|
+
return b;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Makes `b` the allocation block of its class with `list` (`n` cells) as
|
|
202
|
+
* the free list. */
|
|
203
|
+
static void *start_allocating(JSHeap *h, JSBlock *b, JSFreeCell *list, uint32_t n) {
|
|
204
|
+
h->allocated_since_gc += (size_t)n * b->cell_size;
|
|
205
|
+
set_all_allocated(b);
|
|
206
|
+
h->current[b->size_class] = b;
|
|
207
|
+
h->free[b->size_class] = list->next;
|
|
208
|
+
return list;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Gives an empty block to size class `sc`; returns its first cell. */
|
|
212
|
+
static void *block_init(JSHeap *h, JSBlock *b, unsigned sc) {
|
|
213
|
+
uint32_t size = js_size_class_bytes[sc];
|
|
214
|
+
memset(b, 0, sizeof *b);
|
|
215
|
+
b->map_size = JS_BLOCK_SIZE;
|
|
216
|
+
b->cell_size = size;
|
|
217
|
+
b->cell_count = (uint32_t)((JS_BLOCK_SIZE - JS_BLOCK_FIRST_CELL) / size);
|
|
218
|
+
b->size_class = (uint8_t)sc;
|
|
219
|
+
|
|
220
|
+
JSFreeCell *head = NULL;
|
|
221
|
+
for (uint32_t i = b->cell_count; i-- > 0;) {
|
|
222
|
+
JSFreeCell *c = (JSFreeCell *)block_cell(b, i);
|
|
223
|
+
c->next = head;
|
|
224
|
+
head = c;
|
|
225
|
+
}
|
|
226
|
+
b->next = h->blocks[sc];
|
|
227
|
+
h->blocks[sc] = b;
|
|
228
|
+
return start_allocating(h, b, head, b->cell_count);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static void finalize_cell(JSRuntime *rt, JSCell *c) {
|
|
232
|
+
const JSCellClass *cls = class_of(c);
|
|
233
|
+
if (cls->finalize) cls->finalize(rt, c);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Returns the dead cells of `b` as a free list (finalize_dead already ran their finalizers).
|
|
237
|
+
* Afterwards only the survivors count as allocated. */
|
|
238
|
+
static JSFreeCell *sweep_block(JSBlock *b, uint32_t *live_out) {
|
|
239
|
+
JSFreeCell *head = NULL;
|
|
240
|
+
uint32_t live = 0;
|
|
241
|
+
for (uint32_t i = b->cell_count; i-- > 0;) {
|
|
242
|
+
if (bit_get(b->mark_bits, i)) {
|
|
243
|
+
live++;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
JSFreeCell *f = (JSFreeCell *)block_cell(b, i);
|
|
247
|
+
f->next = head;
|
|
248
|
+
head = f;
|
|
249
|
+
}
|
|
250
|
+
memcpy(b->alloc_bits, b->mark_bits, sizeof b->alloc_bits);
|
|
251
|
+
b->unswept = 0;
|
|
252
|
+
if (!live) b->has_finalizable = 0;
|
|
253
|
+
*live_out = live;
|
|
254
|
+
return head;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
static void unmap_block(JSHeap *h, JSBlock *b) {
|
|
258
|
+
block_set_remove(h, (uintptr_t)b);
|
|
259
|
+
js_os_unmap(b, JS_BLOCK_SIZE);
|
|
260
|
+
h->block_count--;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* Keeps a few empty blocks for reuse by any class; the rest go back to the OS. */
|
|
264
|
+
static void release_empty_block(JSHeap *h, JSBlock *b) {
|
|
265
|
+
if (h->empty_count >= JS_EMPTY_POOL_MAX) {
|
|
266
|
+
unmap_block(h, b);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
b->next = h->empty;
|
|
270
|
+
h->empty = b;
|
|
271
|
+
h->empty_count++;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* Sweeps the next unswept block of class `sc`. Returns 0 when there is none;
|
|
275
|
+
* otherwise stores its free list (NULL if it had no dead cells) in *list and
|
|
276
|
+
* the list's length in *n. */
|
|
277
|
+
static int sweep_next(JSRuntime *rt, unsigned sc, JSFreeCell **list, uint32_t *n) {
|
|
278
|
+
JSHeap *h = &rt->heap;
|
|
279
|
+
JSBlock **link = h->sweep_link[sc];
|
|
280
|
+
while (*link && !(*link)->unswept) link = &(*link)->next;
|
|
281
|
+
JSBlock *b = *link;
|
|
282
|
+
if (!b) {
|
|
283
|
+
h->sweep_link[sc] = link;
|
|
284
|
+
return 0;
|
|
285
|
+
}
|
|
286
|
+
uint32_t live;
|
|
287
|
+
JSFreeCell *free_list = sweep_block(b, &live);
|
|
288
|
+
*n = b->cell_count - live; /* before b may be unmapped below */
|
|
289
|
+
if (!live) {
|
|
290
|
+
*link = b->next; /* unlink; an empty block can serve any class */
|
|
291
|
+
release_empty_block(h, b);
|
|
292
|
+
free_list = NULL;
|
|
293
|
+
} else {
|
|
294
|
+
link = &b->next;
|
|
295
|
+
}
|
|
296
|
+
h->sweep_link[sc] = link;
|
|
297
|
+
*list = free_list;
|
|
298
|
+
return 1;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static int should_collect(const JSHeap *h) {
|
|
302
|
+
size_t threshold = h->live_after_gc > h->min_heap ? h->live_after_gc : h->min_heap;
|
|
303
|
+
return h->allocated_since_gc > threshold;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
static int over_limit(const JSRuntime *rt, size_t more) {
|
|
307
|
+
return rt->heap.heap_limit && js_heap_size(rt) + more > rt->heap.heap_limit;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
static _Noreturn void heap_limit_reached(const JSHeap *h) {
|
|
311
|
+
js_fatal("heap limit reached (%zu MiB)", h->heap_limit >> 20);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
#ifdef JS_GC_STRESS
|
|
315
|
+
/* Collects on every allocation (every JS_GC_STRESS_INTERVAL-th). */
|
|
316
|
+
static void stress_tick(JSContext *ctx) {
|
|
317
|
+
JSHeap *h = &ctx->rt->heap;
|
|
318
|
+
if (!h->in_gc && ++h->stress_counter >= h->stress_interval) {
|
|
319
|
+
h->stress_counter = 0;
|
|
320
|
+
js_gc(ctx);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
#endif
|
|
324
|
+
|
|
325
|
+
/* Lazily sweeps blocks of class `sc` until one has a dead cell to reuse. */
|
|
326
|
+
static void *sweep_for(JSRuntime *rt, unsigned sc) {
|
|
327
|
+
JSFreeCell *list;
|
|
328
|
+
uint32_t n;
|
|
329
|
+
while (sweep_next(rt, sc, &list, &n)) {
|
|
330
|
+
if (list) return start_allocating(&rt->heap, js_block_of(list), list, n);
|
|
331
|
+
}
|
|
332
|
+
return NULL;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
void *js_alloc_slow(JSContext *ctx, unsigned sc) {
|
|
336
|
+
JSRuntime *rt = ctx->rt;
|
|
337
|
+
JSHeap *h = &rt->heap;
|
|
338
|
+
#ifdef JS_GC_STRESS
|
|
339
|
+
stress_tick(ctx);
|
|
340
|
+
JSFreeCell *c = h->free[sc];
|
|
341
|
+
if (c) {
|
|
342
|
+
h->free[sc] = c->next;
|
|
343
|
+
return c;
|
|
344
|
+
}
|
|
345
|
+
#endif
|
|
346
|
+
for (int collected = 0;; collected = 1) {
|
|
347
|
+
void *cell = sweep_for(rt, sc);
|
|
348
|
+
if (cell) return cell;
|
|
349
|
+
JSBlock *b = h->empty;
|
|
350
|
+
if (b) {
|
|
351
|
+
h->empty = b->next;
|
|
352
|
+
h->empty_count--;
|
|
353
|
+
return block_init(h, b, sc);
|
|
354
|
+
}
|
|
355
|
+
if (!collected && !h->in_gc && (should_collect(h) || over_limit(rt, JS_BLOCK_SIZE))) {
|
|
356
|
+
js_gc(ctx);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (over_limit(rt, JS_BLOCK_SIZE)) heap_limit_reached(h);
|
|
360
|
+
return block_init(h, map_block(h), sc);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/* ---- Large objects ----------------------------------------------------- */
|
|
365
|
+
|
|
366
|
+
/* Returns empty blocks to the OS to make room under the heap limit. */
|
|
367
|
+
static void drain_empty_pool(JSHeap *h) {
|
|
368
|
+
while (h->empty) {
|
|
369
|
+
JSBlock *b = h->empty;
|
|
370
|
+
h->empty = b->next;
|
|
371
|
+
h->empty_count--;
|
|
372
|
+
unmap_block(h, b);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
static JSCell *alloc_large(JSContext *ctx, size_t size) {
|
|
377
|
+
JSRuntime *rt = ctx->rt;
|
|
378
|
+
JSHeap *h = &rt->heap;
|
|
379
|
+
size_t page = js_os_page_size();
|
|
380
|
+
size_t map_size = (JS_BLOCK_FIRST_CELL + size + page - 1) & ~(page - 1);
|
|
381
|
+
#ifdef JS_GC_STRESS
|
|
382
|
+
stress_tick(ctx);
|
|
383
|
+
#endif
|
|
384
|
+
if (!h->in_gc && (should_collect(h) || over_limit(rt, map_size))) js_gc(ctx); /* large objects are swept eagerly */
|
|
385
|
+
if (over_limit(rt, map_size)) drain_empty_pool(h);
|
|
386
|
+
if (over_limit(rt, map_size)) heap_limit_reached(h);
|
|
387
|
+
h->allocated_since_gc += map_size;
|
|
388
|
+
JSBlock *b = js_os_map_aligned(map_size, JS_BLOCK_SIZE); /* zero-filled */
|
|
389
|
+
if (!b) js_fatal("out of memory allocating %zu bytes", size);
|
|
390
|
+
check_address(b, map_size);
|
|
391
|
+
note_mapping(h, b, map_size);
|
|
392
|
+
b->map_size = map_size;
|
|
393
|
+
b->cell_size = (uint32_t)(size <= UINT32_MAX ? size : UINT32_MAX);
|
|
394
|
+
b->cell_count = 1;
|
|
395
|
+
b->is_large = 1;
|
|
396
|
+
b->alloc_bits[0] = 1;
|
|
397
|
+
|
|
398
|
+
if (h->large_count == h->large_cap) {
|
|
399
|
+
h->large_cap = h->large_cap ? h->large_cap * 2 : 16;
|
|
400
|
+
h->large = xrealloc(h->large, h->large_cap * sizeof *h->large);
|
|
401
|
+
}
|
|
402
|
+
size_t i = h->large_count; /* keep sorted by address */
|
|
403
|
+
while (i > 0 && h->large[i - 1] > b) {
|
|
404
|
+
h->large[i] = h->large[i - 1];
|
|
405
|
+
i--;
|
|
406
|
+
}
|
|
407
|
+
h->large[i] = b;
|
|
408
|
+
h->large_count++;
|
|
409
|
+
h->large_bytes += map_size;
|
|
410
|
+
return (JSCell *)block_cell(b, 0);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
static void sweep_large(JSRuntime *rt) {
|
|
414
|
+
JSHeap *h = &rt->heap;
|
|
415
|
+
size_t kept = 0;
|
|
416
|
+
for (size_t i = 0; i < h->large_count; i++) {
|
|
417
|
+
JSBlock *b = h->large[i];
|
|
418
|
+
if (b->mark_bits[0] & 1) {
|
|
419
|
+
h->large[kept++] = b;
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
h->large_bytes -= b->map_size;
|
|
423
|
+
js_os_unmap(b, b->map_size);
|
|
424
|
+
}
|
|
425
|
+
h->large_count = kept;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/* ---- Allocation entry points ------------------------------------------- */
|
|
429
|
+
|
|
430
|
+
JSCell *js_alloc_cell(JSContext *ctx, JSCellKind kind, size_t size) {
|
|
431
|
+
JSCell *c = size <= JS_MAX_SMALL_SIZE ? js_alloc_small(ctx, js_size_class(size))
|
|
432
|
+
: alloc_large(ctx, size);
|
|
433
|
+
c->kind = (uint8_t)kind;
|
|
434
|
+
return c;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
JSValueArray *js_alloc_value_array(JSContext *ctx, uint32_t length) {
|
|
438
|
+
JSCell *c = js_alloc_cell(ctx, JS_CELL_VALUE_ARRAY,
|
|
439
|
+
sizeof(JSValueArray) + (size_t)length * sizeof(JSValue));
|
|
440
|
+
c->aux = length;
|
|
441
|
+
return (JSValueArray *)c;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
JSHostCell *js_alloc_host_cell(JSContext *ctx, const JSCellClass *cls, size_t size) {
|
|
445
|
+
if (size < sizeof(JSHostCell)) size = sizeof(JSHostCell);
|
|
446
|
+
JSHostCell *h = (JSHostCell *)js_alloc_cell(ctx, JS_CELL_HOST, size);
|
|
447
|
+
h->cls = cls;
|
|
448
|
+
if (cls->finalize) {
|
|
449
|
+
h->cell.flags |= JS_CELL_FINALIZABLE;
|
|
450
|
+
js_block_of(h)->has_finalizable = 1;
|
|
451
|
+
}
|
|
452
|
+
return h;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/* ---- Roots ------------------------------------------------------------- */
|
|
456
|
+
|
|
457
|
+
void js_register_roots(JSRuntime *rt, JSValue *slots, size_t n) {
|
|
458
|
+
JSHeap *h = &rt->heap;
|
|
459
|
+
if (h->root_table_count == h->root_table_cap) {
|
|
460
|
+
h->root_table_cap = h->root_table_cap ? h->root_table_cap * 2 : 8;
|
|
461
|
+
h->root_tables = xrealloc(h->root_tables, h->root_table_cap * sizeof *h->root_tables);
|
|
462
|
+
}
|
|
463
|
+
h->root_tables[h->root_table_count++] = (struct JSRootTable){ slots, n };
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
void js_add_root(JSRuntime *rt, JSValue *slot) {
|
|
467
|
+
JSHeap *h = &rt->heap;
|
|
468
|
+
if (h->root_count == h->root_cap) {
|
|
469
|
+
h->root_cap = h->root_cap ? h->root_cap * 2 : 16;
|
|
470
|
+
h->roots = xrealloc(h->roots, h->root_cap * sizeof *h->roots);
|
|
471
|
+
}
|
|
472
|
+
h->roots[h->root_count++] = slot;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
void js_remove_root(JSRuntime *rt, JSValue *slot) {
|
|
476
|
+
JSHeap *h = &rt->heap;
|
|
477
|
+
for (size_t i = h->root_count; i-- > 0;) {
|
|
478
|
+
if (h->roots[i] == slot) {
|
|
479
|
+
h->roots[i] = h->roots[--h->root_count];
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/* ---- Marking ----------------------------------------------------------- */
|
|
486
|
+
|
|
487
|
+
void js_trace_cell(JSTracer *trc, JSCell *c) {
|
|
488
|
+
if (js_cell_is_static(c)) return;
|
|
489
|
+
JSBlock *b = js_block_of(c);
|
|
490
|
+
uint32_t i = cell_index(b, c);
|
|
491
|
+
if (bit_get(b->mark_bits, i)) return;
|
|
492
|
+
bit_set(b->mark_bits, i);
|
|
493
|
+
JSHeap *h = trc->heap;
|
|
494
|
+
if (trc->sp == h->mark_stack_cap) {
|
|
495
|
+
h->mark_stack_cap = h->mark_stack_cap ? h->mark_stack_cap * 2 : 4096;
|
|
496
|
+
h->mark_stack = xrealloc(h->mark_stack, h->mark_stack_cap * sizeof *h->mark_stack);
|
|
497
|
+
}
|
|
498
|
+
h->mark_stack[trc->sp++] = c;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
bool js_gc_is_marked(const JSCell *c) {
|
|
502
|
+
if (js_cell_is_static(c)) return true;
|
|
503
|
+
JSBlock *b = js_block_of(c);
|
|
504
|
+
return bit_get(b->mark_bits, cell_index(b, c));
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
void js_trace_value(JSTracer *trc, JSValue v) {
|
|
508
|
+
if (js_is_cell(v)) js_trace_cell(trc, js_as_cell(v));
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/* Explicit stack, never recursion: ropes and linked lists can be very deep. */
|
|
512
|
+
static void drain(JSTracer *trc) {
|
|
513
|
+
while (trc->sp) {
|
|
514
|
+
JSCell *c = trc->heap->mark_stack[--trc->sp];
|
|
515
|
+
const JSCellClass *cls = class_of(c);
|
|
516
|
+
if (cls->visit) cls->visit(c, trc);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
static void mark_roots(JSRuntime *rt, JSTracer *trc) {
|
|
521
|
+
JSHeap *h = &rt->heap;
|
|
522
|
+
js_trace_value(trc, rt->exception); /* ADR 0004, invariant 4 */
|
|
523
|
+
js_trace_value(trc, rt->symbol_registry);
|
|
524
|
+
js_jobs_trace(rt, trc); /* queued jobs, unhandled rejections (ADR 0008) */
|
|
525
|
+
js_weak_trace_roots(rt, trc); /* the WeakRef kept-alive set */
|
|
526
|
+
for (JSContext *realm = rt->realms; realm; realm = realm->next_realm)
|
|
527
|
+
for (unsigned i = 0; i < JS_INTRINSIC_COUNT; i++) js_trace_value(trc, realm->intrinsics[i]);
|
|
528
|
+
for (size_t t = 0; t < h->root_table_count; t++)
|
|
529
|
+
for (size_t i = 0; i < h->root_tables[t].n; i++) js_trace_value(trc, h->root_tables[t].slots[i]);
|
|
530
|
+
for (size_t i = 0; i < h->root_count; i++) js_trace_value(trc, *h->roots[i]);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/* ---- Conservative roots ------------------------------------------------ */
|
|
534
|
+
|
|
535
|
+
static JSBlock *find_large(const JSHeap *h, uintptr_t w) {
|
|
536
|
+
size_t lo = 0, hi = h->large_count;
|
|
537
|
+
while (lo < hi) { /* last object starting at or below w */
|
|
538
|
+
size_t mid = (lo + hi) / 2;
|
|
539
|
+
if ((uintptr_t)h->large[mid] <= w) lo = mid + 1;
|
|
540
|
+
else hi = mid;
|
|
541
|
+
}
|
|
542
|
+
if (!lo) return NULL;
|
|
543
|
+
JSBlock *b = h->large[lo - 1];
|
|
544
|
+
return w < (uintptr_t)b + b->map_size ? b : NULL;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/* The allocated cell that `w` points into (interior pointers included), or NULL. */
|
|
548
|
+
static JSCell *find_cell(const JSHeap *h, uintptr_t w) {
|
|
549
|
+
if (w < h->min_addr || w >= h->max_addr) return NULL; /* also rejects doubles, int32s */
|
|
550
|
+
uintptr_t base = w & ~(uintptr_t)(JS_BLOCK_SIZE - 1);
|
|
551
|
+
JSBlock *b;
|
|
552
|
+
uint32_t i;
|
|
553
|
+
if (block_set_contains(h, base)) {
|
|
554
|
+
b = (JSBlock *)base;
|
|
555
|
+
if (w < base + JS_BLOCK_FIRST_CELL) return NULL;
|
|
556
|
+
i = (uint32_t)((w - base - JS_BLOCK_FIRST_CELL) / b->cell_size);
|
|
557
|
+
if (i >= b->cell_count) return NULL;
|
|
558
|
+
} else {
|
|
559
|
+
b = find_large(h, w);
|
|
560
|
+
if (!b || w < (uintptr_t)b + JS_BLOCK_FIRST_CELL) return NULL;
|
|
561
|
+
i = 0;
|
|
562
|
+
}
|
|
563
|
+
return bit_get(b->alloc_bits, i) ? (JSCell *)block_cell(b, i) : NULL;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
#if defined(__clang__) || defined(__GNUC__)
|
|
567
|
+
#define JS_NOINLINE __attribute__((noinline))
|
|
568
|
+
#define JS_NO_ASAN __attribute__((no_sanitize_address))
|
|
569
|
+
#else
|
|
570
|
+
#define JS_NOINLINE __declspec(noinline)
|
|
571
|
+
#define JS_NO_ASAN
|
|
572
|
+
#endif
|
|
573
|
+
|
|
574
|
+
#if defined(__SANITIZE_ADDRESS__)
|
|
575
|
+
#define JS_ASAN 1
|
|
576
|
+
#elif defined(__has_feature)
|
|
577
|
+
#if __has_feature(address_sanitizer)
|
|
578
|
+
#define JS_ASAN 1
|
|
579
|
+
#endif
|
|
580
|
+
#endif
|
|
581
|
+
|
|
582
|
+
#ifdef JS_ASAN
|
|
583
|
+
/* ASan's use-after-return mode moves locals to a "fake stack" in heap memory,
|
|
584
|
+
* where the conservative scan can't see them. Keep them on the real stack. */
|
|
585
|
+
const char *__asan_default_options(void);
|
|
586
|
+
const char *__asan_default_options(void) { return "detect_stack_use_after_return=0"; }
|
|
587
|
+
#endif
|
|
588
|
+
|
|
589
|
+
/* Scans the mutator's stack: from js_gc's frame (which holds the spilled
|
|
590
|
+
* registers) up to the stack base. The collector's own deeper frames are
|
|
591
|
+
* not roots, and would hold stale pointers from sweeping.
|
|
592
|
+
* Reads the whole range on purpose, redzones included. */
|
|
593
|
+
static JS_NO_ASAN void mark_stack(JSTracer *trc) {
|
|
594
|
+
const uintptr_t *p = (const uintptr_t *)((uintptr_t)trc->stack_low & ~(uintptr_t)(sizeof(uintptr_t) - 1));
|
|
595
|
+
const uintptr_t *end = (const uintptr_t *)trc->heap->stack_base;
|
|
596
|
+
for (; p < end; p++) {
|
|
597
|
+
JSCell *c = find_cell(trc->heap, *p);
|
|
598
|
+
if (c) js_trace_cell(trc, c);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/* ---- Collection -------------------------------------------------------- */
|
|
603
|
+
|
|
604
|
+
/* Makes the allocation bits exact: cells still on a free list aren't allocated. */
|
|
605
|
+
static void stop_allocation(JSHeap *h) {
|
|
606
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++) {
|
|
607
|
+
JSBlock *b = h->current[sc];
|
|
608
|
+
for (JSFreeCell *c = h->free[sc]; c; c = c->next) bit_clear(b->alloc_bits, cell_index(b, c));
|
|
609
|
+
h->free[sc] = NULL;
|
|
610
|
+
h->current[sc] = NULL;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/* Unswept blocks may hold dead cells whose children are already reused.
|
|
615
|
+
* Sweep them before marking so that nothing can resurrect such a cell. */
|
|
616
|
+
static void finish_sweeping(JSRuntime *rt) {
|
|
617
|
+
JSFreeCell *list;
|
|
618
|
+
uint32_t n;
|
|
619
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++)
|
|
620
|
+
while (sweep_next(rt, sc, &list, &n)) {}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
static unsigned popcount64(uint64_t x) {
|
|
624
|
+
#if defined(_MSC_VER) && !defined(__clang__)
|
|
625
|
+
return (unsigned)__popcnt64(x);
|
|
626
|
+
#else
|
|
627
|
+
return (unsigned)__builtin_popcountll(x);
|
|
628
|
+
#endif
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
static size_t marked_bytes(const JSHeap *h) {
|
|
632
|
+
size_t bytes = 0;
|
|
633
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++)
|
|
634
|
+
for (JSBlock *b = h->blocks[sc]; b; b = b->next) {
|
|
635
|
+
size_t cells = 0;
|
|
636
|
+
for (unsigned w = 0; w < JS_BITMAP_WORDS; w++) cells += popcount64(b->mark_bits[w]);
|
|
637
|
+
bytes += cells * b->cell_size;
|
|
638
|
+
}
|
|
639
|
+
return bytes + h->large_bytes; /* after sweep_large: only survivors remain */
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/* Runs the finalizers of the dead cells, all of them, before any memory is freed or reused. A
|
|
643
|
+
* finalizer may read other cells: an object's reaches its class through its shape, which may be
|
|
644
|
+
* dead too, and which lazy sweeping could otherwise free and reuse before the object's own block
|
|
645
|
+
* is swept. Each finalized cell loses JS_CELL_FINALIZABLE, so nothing finalizes it twice. */
|
|
646
|
+
static void finalize_dead(JSRuntime *rt) {
|
|
647
|
+
JSHeap *h = &rt->heap;
|
|
648
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++)
|
|
649
|
+
for (JSBlock *b = h->blocks[sc]; b; b = b->next) {
|
|
650
|
+
if (!b->has_finalizable) continue;
|
|
651
|
+
for (uint32_t i = 0; i < b->cell_count; i++) {
|
|
652
|
+
JSCell *c = (JSCell *)block_cell(b, i);
|
|
653
|
+
if (bit_get(b->alloc_bits, i) && !bit_get(b->mark_bits, i) && (c->flags & JS_CELL_FINALIZABLE)) {
|
|
654
|
+
finalize_cell(rt, c);
|
|
655
|
+
c->flags &= (uint16_t)~JS_CELL_FINALIZABLE;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
for (size_t i = 0; i < h->large_count; i++) {
|
|
660
|
+
JSBlock *b = h->large[i];
|
|
661
|
+
JSCell *c = (JSCell *)block_cell(b, 0);
|
|
662
|
+
if (!(b->mark_bits[0] & 1) && (c->flags & JS_CELL_FINALIZABLE)) {
|
|
663
|
+
finalize_cell(rt, c);
|
|
664
|
+
c->flags &= (uint16_t)~JS_CELL_FINALIZABLE;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
static JS_NOINLINE void collect(JSContext *ctx, const void *stack_low) {
|
|
670
|
+
JSRuntime *rt = ctx->rt;
|
|
671
|
+
JSHeap *h = &rt->heap;
|
|
672
|
+
if (h->in_gc) js_fatal("js_gc called during a collection (from a finalizer?)");
|
|
673
|
+
h->in_gc = 1;
|
|
674
|
+
stop_allocation(h);
|
|
675
|
+
finish_sweeping(rt);
|
|
676
|
+
|
|
677
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++)
|
|
678
|
+
for (JSBlock *b = h->blocks[sc]; b; b = b->next) memset(b->mark_bits, 0, sizeof b->mark_bits);
|
|
679
|
+
for (size_t i = 0; i < h->large_count; i++) h->large[i]->mark_bits[0] = 0;
|
|
680
|
+
|
|
681
|
+
JSTracer trc = { h, 0, stack_low };
|
|
682
|
+
mark_roots(rt, &trc);
|
|
683
|
+
mark_stack(&trc);
|
|
684
|
+
drain(&trc);
|
|
685
|
+
while (js_weak_ephemerons(rt, &trc)) drain(&trc); /* a WeakMap value lives if its key does */
|
|
686
|
+
js_weak_sweep(rt);
|
|
687
|
+
js_atoms_sweep(rt); /* weak references, before anything is freed */
|
|
688
|
+
js_shapes_sweep(rt);
|
|
689
|
+
js_prop_caches_sweep(rt);
|
|
690
|
+
|
|
691
|
+
finalize_dead(rt);
|
|
692
|
+
sweep_large(rt);
|
|
693
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++) {
|
|
694
|
+
for (JSBlock *b = h->blocks[sc]; b; b = b->next) b->unswept = 1;
|
|
695
|
+
h->sweep_link[sc] = &h->blocks[sc];
|
|
696
|
+
}
|
|
697
|
+
h->live_after_gc = marked_bytes(h);
|
|
698
|
+
h->allocated_since_gc = 0;
|
|
699
|
+
h->gc_count++;
|
|
700
|
+
h->in_gc = 0;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/* Spills the mutator's callee-saved registers into this frame, then
|
|
704
|
+
* collects in deeper frames that the stack scan doesn't cover. */
|
|
705
|
+
JS_NOINLINE void js_gc(JSContext *ctx) {
|
|
706
|
+
jmp_buf regs;
|
|
707
|
+
memset(®s, 0, sizeof regs); /* no stale words in the parts setjmp skips */
|
|
708
|
+
#if defined(__clang__) || defined(__GNUC__)
|
|
709
|
+
__builtin_unwind_init();
|
|
710
|
+
#endif
|
|
711
|
+
setjmp(regs);
|
|
712
|
+
collect(ctx, ®s);
|
|
713
|
+
(void)*(volatile char *)®s; /* keep this frame alive: no tail call */
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/* ---- Runtime lifetime -------------------------------------------------- */
|
|
717
|
+
|
|
718
|
+
JSRuntime *js_runtime_new(void) {
|
|
719
|
+
JSRuntime *rt = calloc(1, sizeof *rt);
|
|
720
|
+
if (!rt) js_fatal("out of memory creating a runtime");
|
|
721
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++) rt->heap.sweep_link[sc] = &rt->heap.blocks[sc];
|
|
722
|
+
void *stack_low;
|
|
723
|
+
js_os_stack_bounds(&stack_low, &rt->heap.stack_base);
|
|
724
|
+
rt->stack_limit = (uintptr_t)stack_low + JS_STACK_MARGIN;
|
|
725
|
+
rt->exception = JS_EMPTY;
|
|
726
|
+
rt->symbol_registry = JS_UNDEFINED;
|
|
727
|
+
rt->heap.min_heap = JS_GC_MIN_HEAP;
|
|
728
|
+
const char *limit = getenv("JS_HEAP_LIMIT_MB");
|
|
729
|
+
if (limit) rt->heap.heap_limit = (size_t)strtoull(limit, NULL, 10) << 20;
|
|
730
|
+
const char *interval = getenv("JS_GC_STRESS_INTERVAL");
|
|
731
|
+
rt->heap.stress_interval = interval ? (size_t)strtoull(interval, NULL, 10) : 1;
|
|
732
|
+
js_atoms_init(rt);
|
|
733
|
+
return rt;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
void js_set_heap_limit(JSRuntime *rt, size_t bytes) {
|
|
737
|
+
rt->heap.heap_limit = bytes;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
size_t js_heap_size(const JSRuntime *rt) {
|
|
741
|
+
return rt->heap.block_count * JS_BLOCK_SIZE + rt->heap.large_bytes;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/* Runs the finalizers of every allocated cell in `b` that has one. */
|
|
745
|
+
static void finalize_block(JSRuntime *rt, JSBlock *b) {
|
|
746
|
+
if (!b->has_finalizable) return;
|
|
747
|
+
for (uint32_t i = 0; i < b->cell_count; i++) {
|
|
748
|
+
JSCell *c = (JSCell *)block_cell(b, i);
|
|
749
|
+
if (bit_get(b->alloc_bits, i) && (c->flags & JS_CELL_FINALIZABLE)) finalize_cell(rt, c);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
void js_runtime_free(JSRuntime *rt) {
|
|
754
|
+
JSHeap *h = &rt->heap;
|
|
755
|
+
stop_allocation(h);
|
|
756
|
+
/* every finalizer first, then the memory: a finalizer may read cells in other blocks (shapes) */
|
|
757
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++)
|
|
758
|
+
for (JSBlock *b = h->blocks[sc]; b; b = b->next) finalize_block(rt, b);
|
|
759
|
+
for (size_t i = 0; i < h->large_count; i++) finalize_block(rt, h->large[i]);
|
|
760
|
+
for (unsigned sc = 0; sc < JS_NUM_SIZE_CLASSES; sc++) {
|
|
761
|
+
for (JSBlock *b = h->blocks[sc], *next; b; b = next) {
|
|
762
|
+
next = b->next;
|
|
763
|
+
js_os_unmap(b, JS_BLOCK_SIZE);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
for (JSBlock *b = h->empty, *next; b; b = next) {
|
|
767
|
+
next = b->next;
|
|
768
|
+
js_os_unmap(b, JS_BLOCK_SIZE);
|
|
769
|
+
}
|
|
770
|
+
for (size_t i = 0; i < h->large_count; i++) js_os_unmap(h->large[i], h->large[i]->map_size);
|
|
771
|
+
js_atoms_free(rt);
|
|
772
|
+
js_shapes_free(rt);
|
|
773
|
+
js_prop_caches_free(rt);
|
|
774
|
+
js_jobs_free(rt);
|
|
775
|
+
js_weak_free(rt);
|
|
776
|
+
while (rt->realms) js_context_free(rt->realms); /* e.g. $262.createRealm()'s */
|
|
777
|
+
free(h->large);
|
|
778
|
+
free(h->block_set);
|
|
779
|
+
free(h->root_tables);
|
|
780
|
+
free(h->roots);
|
|
781
|
+
free(h->mark_stack);
|
|
782
|
+
free(rt);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
JSContext *js_context_new(JSRuntime *rt) {
|
|
786
|
+
JSContext *ctx = calloc(1, sizeof *ctx);
|
|
787
|
+
if (!ctx) js_fatal("out of memory creating a context");
|
|
788
|
+
ctx->rt = rt;
|
|
789
|
+
ctx->stack_limit = rt->stack_limit;
|
|
790
|
+
for (unsigned i = 0; i < JS_INTRINSIC_COUNT; i++) ctx->intrinsics[i] = JS_UNDEFINED;
|
|
791
|
+
ctx->next_realm = rt->realms;
|
|
792
|
+
rt->realms = ctx;
|
|
793
|
+
js_realm_init(ctx);
|
|
794
|
+
js_install_recorded_components(ctx); /* the program's optional built-ins (ADR 0014) */
|
|
795
|
+
return ctx;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
void js_context_free(JSContext *ctx) {
|
|
799
|
+
JSContext **link = &ctx->rt->realms;
|
|
800
|
+
while (*link != ctx) link = &(*link)->next_realm;
|
|
801
|
+
*link = ctx->next_realm;
|
|
802
|
+
free(ctx);
|
|
803
|
+
}
|