node-linux-s390x 23.11.0 → 24.0.0
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/CHANGELOG.md +427 -1937
- package/LICENSE +2 -2
- package/README.md +2 -0
- package/bin/node +0 -0
- package/include/node/common.gypi +4 -11
- package/include/node/config.gypi +4 -6
- package/include/node/cppgc/allocation.h +1 -2
- package/include/node/cppgc/default-platform.h +3 -2
- package/include/node/cppgc/heap-consistency.h +1 -1
- package/include/node/cppgc/internal/api-constants.h +0 -17
- package/include/node/cppgc/internal/base-page-handle.h +2 -4
- package/include/node/cppgc/internal/caged-heap-local-data.h +0 -4
- package/include/node/cppgc/internal/caged-heap.h +0 -4
- package/include/node/cppgc/internal/conditional-stack-allocated.h +41 -0
- package/include/node/cppgc/internal/logging.h +3 -3
- package/include/node/cppgc/internal/member-storage.h +63 -20
- package/include/node/cppgc/internal/persistent-node.h +8 -3
- package/include/node/cppgc/internal/pointer-policies.h +48 -11
- package/include/node/cppgc/macros.h +21 -0
- package/include/node/cppgc/member.h +70 -36
- package/include/node/cppgc/name-provider.h +3 -0
- package/include/node/cppgc/platform.h +11 -0
- package/include/node/cppgc/type-traits.h +1 -0
- package/include/node/cppgc/visitor.h +25 -1
- package/include/node/libplatform/libplatform-export.h +2 -2
- package/include/node/libplatform/v8-tracing.h +0 -1
- package/include/node/node.h +58 -15
- package/include/node/node_version.h +3 -3
- package/include/node/v8-array-buffer.h +111 -34
- package/include/node/v8-callbacks.h +84 -26
- package/include/node/v8-context.h +7 -6
- package/include/node/v8-cppgc.h +2 -1
- package/include/node/v8-data.h +5 -0
- package/include/node/v8-debug.h +11 -0
- package/include/node/v8-embedder-heap.h +1 -32
- package/include/node/v8-exception.h +2 -0
- package/include/node/v8-function-callback.h +4 -33
- package/include/node/v8-function.h +7 -0
- package/include/node/v8-handle-base.h +18 -0
- package/include/node/v8-initialization.h +9 -1
- package/include/node/v8-internal.h +477 -399
- package/include/node/v8-isolate.h +218 -151
- package/include/node/v8-local-handle.h +56 -28
- package/include/node/v8-maybe.h +2 -1
- package/include/node/v8-memory-span.h +149 -24
- package/include/node/v8-message.h +9 -1
- package/include/node/v8-object.h +7 -2
- package/include/node/v8-persistent-handle.h +17 -17
- package/include/node/v8-platform.h +48 -13
- package/include/node/v8-primitive.h +131 -6
- package/include/node/v8-profiler.h +13 -1
- package/include/node/v8-proxy.h +0 -1
- package/include/node/v8-regexp.h +0 -1
- package/include/node/v8-sandbox.h +3 -3
- package/include/node/v8-script.h +21 -3
- package/include/node/v8-source-location.h +6 -1
- package/include/node/v8-template.h +8 -2
- package/include/node/v8-traced-handle.h +16 -17
- package/include/node/v8-typed-array.h +6 -10
- package/include/node/v8-value.h +18 -0
- package/include/node/v8-version.h +4 -4
- package/include/node/v8-wasm.h +24 -0
- package/include/node/v8-weak-callback-info.h +20 -12
- package/include/node/v8.h +3 -3
- package/include/node/v8config.h +34 -40
- package/package.json +1 -1
- package/share/doc/node/gdbinit +94 -30
- package/share/doc/node/lldb_commands.py +107 -13
- package/share/man/man1/node.1 +4 -1
- package/include/node/cppgc/ephemeron-pair.h +0 -30
package/LICENSE
CHANGED
|
@@ -1489,7 +1489,7 @@ The externally maintained libraries used by Node.js are:
|
|
|
1489
1489
|
This code is copyrighted by Sun Microsystems Inc. and released
|
|
1490
1490
|
under a 3-clause BSD license.
|
|
1491
1491
|
|
|
1492
|
-
- Valgrind client API header, located at
|
|
1492
|
+
- Valgrind client API header, located at third_party/valgrind/valgrind.h
|
|
1493
1493
|
This is released under the BSD license.
|
|
1494
1494
|
|
|
1495
1495
|
- The Wasm C/C++ API headers, located at third_party/wasm-api/wasm.{h,hh}
|
|
@@ -1774,7 +1774,7 @@ The externally maintained libraries used by Node.js are:
|
|
|
1774
1774
|
limitations under the License.
|
|
1775
1775
|
"""
|
|
1776
1776
|
|
|
1777
|
-
- simdutf, located at deps/simdutf, is licensed as follows:
|
|
1777
|
+
- simdutf, located at deps/v8/third_party/simdutf, is licensed as follows:
|
|
1778
1778
|
"""
|
|
1779
1779
|
Copyright 2021 The simdutf authors
|
|
1780
1780
|
|
package/README.md
CHANGED
|
@@ -317,6 +317,8 @@ For information about the governance of the Node.js project, see
|
|
|
317
317
|
**Kohei Ueno** <<kohei.ueno119@gmail.com>> (he/him)
|
|
318
318
|
* [daeyeon](https://github.com/daeyeon) -
|
|
319
319
|
**Daeyeon Jeong** <<daeyeon.dev@gmail.com>> (he/him)
|
|
320
|
+
* [dario-piotrowicz](https://github.com/dario-piotrowicz) -
|
|
321
|
+
**Dario Piotrowicz** <<dario.piotrowicz@gmail.com>> (he/him)
|
|
320
322
|
* [debadree25](https://github.com/debadree25) -
|
|
321
323
|
**Debadree Chatterjee** <<debadree333@gmail.com>> (he/him)
|
|
322
324
|
* [deokjinkim](https://github.com/deokjinkim) -
|
package/bin/node
CHANGED
|
Binary file
|
package/include/node/common.gypi
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
# Reset this number to 0 on major V8 upgrades.
|
|
40
40
|
# Increment by one for each non-official patch applied to deps/v8.
|
|
41
|
-
'v8_embedder_string': '-node.
|
|
41
|
+
'v8_embedder_string': '-node.10',
|
|
42
42
|
|
|
43
43
|
##### V8 defaults for Node.js #####
|
|
44
44
|
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a',
|
|
113
113
|
}],
|
|
114
114
|
# V8 pointer compression only supports 64bit architectures.
|
|
115
|
-
['target_arch in "arm ia32 mips mipsel
|
|
115
|
+
['target_arch in "arm ia32 mips mipsel"', {
|
|
116
116
|
'v8_enable_pointer_compression': 0,
|
|
117
117
|
'v8_enable_31bit_smis_on_64bit_arch': 0,
|
|
118
118
|
'v8_enable_sandbox': 0
|
|
@@ -528,10 +528,6 @@
|
|
|
528
528
|
'cflags': [ '-m64' ],
|
|
529
529
|
'ldflags': [ '-m64' ],
|
|
530
530
|
}],
|
|
531
|
-
[ 'host_arch=="ppc" and OS not in "aix os400"', {
|
|
532
|
-
'cflags': [ '-m32' ],
|
|
533
|
-
'ldflags': [ '-m32' ],
|
|
534
|
-
}],
|
|
535
531
|
[ 'host_arch=="ppc64" and OS not in "aix os400"', {
|
|
536
532
|
'cflags': [ '-m64', '-mminimal-toc' ],
|
|
537
533
|
'ldflags': [ '-m64' ],
|
|
@@ -552,10 +548,6 @@
|
|
|
552
548
|
'cflags': [ '-m64' ],
|
|
553
549
|
'ldflags': [ '-m64' ],
|
|
554
550
|
}],
|
|
555
|
-
[ 'target_arch=="ppc" and OS not in "aix os400"', {
|
|
556
|
-
'cflags': [ '-m32' ],
|
|
557
|
-
'ldflags': [ '-m32' ],
|
|
558
|
-
}],
|
|
559
551
|
[ 'target_arch=="ppc64" and OS not in "aix os400"', {
|
|
560
552
|
'cflags': [ '-m64', '-mminimal-toc' ],
|
|
561
553
|
'ldflags': [ '-m64' ],
|
|
@@ -576,6 +568,7 @@
|
|
|
576
568
|
}],
|
|
577
569
|
[ 'node_shared=="true"', {
|
|
578
570
|
'cflags': [ '-fPIC' ],
|
|
571
|
+
'ldflags': [ '-fPIC' ],
|
|
579
572
|
}],
|
|
580
573
|
],
|
|
581
574
|
}],
|
|
@@ -639,7 +632,7 @@
|
|
|
639
632
|
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
|
|
640
633
|
'GCC_STRICT_ALIASING': 'NO', # -fno-strict-aliasing
|
|
641
634
|
'PREBINDING': 'NO', # No -Wl,-prebind
|
|
642
|
-
'MACOSX_DEPLOYMENT_TARGET': '
|
|
635
|
+
'MACOSX_DEPLOYMENT_TARGET': '13.5', # -mmacosx-version-min=13.5
|
|
643
636
|
'USE_HEADERMAP': 'NO',
|
|
644
637
|
'WARNING_CFLAGS': [
|
|
645
638
|
'-Wall',
|
package/include/node/config.gypi
CHANGED
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
'force_dynamic_crt': 0,
|
|
21
21
|
'gas_version': '2.38',
|
|
22
22
|
'host_arch': 's390x',
|
|
23
|
-
'icu_data_in': '../../deps/icu-tmp/
|
|
23
|
+
'icu_data_in': '../../deps/icu-tmp/icudt77l.dat',
|
|
24
24
|
'icu_endianness': 'b',
|
|
25
25
|
'icu_gyp_path': 'tools/icu/icu-generic.gyp',
|
|
26
26
|
'icu_path': 'deps/icu-small',
|
|
27
27
|
'icu_small': 'false',
|
|
28
|
-
'icu_ver_major': '
|
|
28
|
+
'icu_ver_major': '77',
|
|
29
29
|
'libdir': 'lib',
|
|
30
30
|
'llvm_version': '0.0',
|
|
31
31
|
'napi_build_version': '10',
|
|
@@ -330,7 +330,6 @@
|
|
|
330
330
|
'lib/internal/test_runner/utils.js',
|
|
331
331
|
'lib/internal/timers.js',
|
|
332
332
|
'lib/internal/tls/secure-context.js',
|
|
333
|
-
'lib/internal/tls/secure-pair.js',
|
|
334
333
|
'lib/internal/trace_events_async_hooks.js',
|
|
335
334
|
'lib/internal/tty.js',
|
|
336
335
|
'lib/internal/url.js',
|
|
@@ -405,7 +404,7 @@
|
|
|
405
404
|
'lib/wasi.js',
|
|
406
405
|
'lib/worker_threads.js',
|
|
407
406
|
'lib/zlib.js'],
|
|
408
|
-
'node_module_version':
|
|
407
|
+
'node_module_version': 137,
|
|
409
408
|
'node_no_browser_globals': 'false',
|
|
410
409
|
'node_prefix': '/',
|
|
411
410
|
'node_quic': 'false',
|
|
@@ -441,7 +440,7 @@
|
|
|
441
440
|
'openssl_is_fips': 'false',
|
|
442
441
|
'openssl_quic': 'false',
|
|
443
442
|
'ossfuzz': 'false',
|
|
444
|
-
'shlib_suffix': 'so.
|
|
443
|
+
'shlib_suffix': 'so.137',
|
|
445
444
|
'single_executable_application': 'true',
|
|
446
445
|
'suppress_all_error_on_warn': 'false',
|
|
447
446
|
'target_arch': 's390x',
|
|
@@ -460,7 +459,6 @@
|
|
|
460
459
|
'v8_enable_object_print': 1,
|
|
461
460
|
'v8_enable_pointer_compression': 0,
|
|
462
461
|
'v8_enable_sandbox': 0,
|
|
463
|
-
'v8_enable_shared_ro_heap': 1,
|
|
464
462
|
'v8_enable_webassembly': 1,
|
|
465
463
|
'v8_optimized_debug': 1,
|
|
466
464
|
'v8_promise_internal_field_count': 1,
|
|
@@ -37,11 +37,12 @@ class V8_EXPORT DefaultPlatform : public Platform {
|
|
|
37
37
|
return v8_platform_->MonotonicallyIncreasingTime();
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner(
|
|
40
|
+
std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner(
|
|
41
|
+
TaskPriority priority) override {
|
|
41
42
|
// V8's default platform creates a new task runner when passed the
|
|
42
43
|
// `v8::Isolate` pointer the first time. For non-default platforms this will
|
|
43
44
|
// require getting the appropriate task runner.
|
|
44
|
-
return v8_platform_->GetForegroundTaskRunner(kNoIsolate);
|
|
45
|
+
return v8_platform_->GetForegroundTaskRunner(kNoIsolate, priority);
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
std::unique_ptr<cppgc::JobHandle> PostJob(
|
|
@@ -114,7 +114,7 @@ class HeapConsistency final {
|
|
|
114
114
|
* has not yet been processed.
|
|
115
115
|
*
|
|
116
116
|
* \param params The parameters retrieved from `GetWriteBarrierType()`.
|
|
117
|
-
* \param object The pointer to the object. May be an interior pointer to
|
|
117
|
+
* \param object The pointer to the object. May be an interior pointer to
|
|
118
118
|
* an interface of the actual object.
|
|
119
119
|
*/
|
|
120
120
|
static V8_INLINE void DijkstraWriteBarrier(const WriteBarrierParams& params,
|
|
@@ -33,16 +33,6 @@ static constexpr uint16_t kFullyConstructedBitMask = uint16_t{1};
|
|
|
33
33
|
static constexpr size_t kPageSizeBits = 17;
|
|
34
34
|
static constexpr size_t kPageSize = size_t{1} << kPageSizeBits;
|
|
35
35
|
|
|
36
|
-
#if defined(V8_HOST_ARCH_ARM64) && defined(V8_OS_DARWIN)
|
|
37
|
-
constexpr size_t kGuardPageSize = 0;
|
|
38
|
-
#elif defined(V8_HOST_ARCH_PPC64)
|
|
39
|
-
constexpr size_t kGuardPageSize = 0;
|
|
40
|
-
#elif defined(V8_HOST_ARCH_LOONG64) || defined(V8_HOST_ARCH_MIPS64)
|
|
41
|
-
constexpr size_t kGuardPageSize = 0;
|
|
42
|
-
#else
|
|
43
|
-
constexpr size_t kGuardPageSize = 4096;
|
|
44
|
-
#endif
|
|
45
|
-
|
|
46
36
|
static constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2;
|
|
47
37
|
|
|
48
38
|
#if defined(CPPGC_POINTER_COMPRESSION)
|
|
@@ -54,12 +44,6 @@ constexpr unsigned kPointerCompressionShift = 1;
|
|
|
54
44
|
#endif // !defined(CPPGC_POINTER_COMPRESSION)
|
|
55
45
|
|
|
56
46
|
#if defined(CPPGC_CAGED_HEAP)
|
|
57
|
-
#if defined(CPPGC_2GB_CAGE)
|
|
58
|
-
constexpr size_t kCagedHeapDefaultReservationSize =
|
|
59
|
-
static_cast<size_t>(2) * kGB;
|
|
60
|
-
constexpr size_t kCagedHeapMaxReservationSize =
|
|
61
|
-
kCagedHeapDefaultReservationSize;
|
|
62
|
-
#else // !defined(CPPGC_2GB_CAGE)
|
|
63
47
|
constexpr size_t kCagedHeapDefaultReservationSize =
|
|
64
48
|
static_cast<size_t>(4) * kGB;
|
|
65
49
|
#if defined(CPPGC_POINTER_COMPRESSION)
|
|
@@ -69,7 +53,6 @@ constexpr size_t kCagedHeapMaxReservationSize =
|
|
|
69
53
|
constexpr size_t kCagedHeapMaxReservationSize =
|
|
70
54
|
kCagedHeapDefaultReservationSize;
|
|
71
55
|
#endif // !defined(CPPGC_POINTER_COMPRESSION)
|
|
72
|
-
#endif // !defined(CPPGC_2GB_CAGE)
|
|
73
56
|
constexpr size_t kCagedHeapReservationAlignment = kCagedHeapMaxReservationSize;
|
|
74
57
|
#endif // defined(CPPGC_CAGED_HEAP)
|
|
75
58
|
|
|
@@ -19,9 +19,7 @@ class BasePageHandle {
|
|
|
19
19
|
public:
|
|
20
20
|
static V8_INLINE BasePageHandle* FromPayload(void* payload) {
|
|
21
21
|
return reinterpret_cast<BasePageHandle*>(
|
|
22
|
-
|
|
23
|
-
~(api_constants::kPageSize - 1)) +
|
|
24
|
-
api_constants::kGuardPageSize);
|
|
22
|
+
reinterpret_cast<uintptr_t>(payload) & ~(api_constants::kPageSize - 1));
|
|
25
23
|
}
|
|
26
24
|
static V8_INLINE const BasePageHandle* FromPayload(const void* payload) {
|
|
27
25
|
return FromPayload(const_cast<void*>(payload));
|
|
@@ -33,7 +31,7 @@ class BasePageHandle {
|
|
|
33
31
|
protected:
|
|
34
32
|
explicit BasePageHandle(HeapHandle& heap_handle) : heap_handle_(heap_handle) {
|
|
35
33
|
CPPGC_DCHECK(reinterpret_cast<uintptr_t>(this) % api_constants::kPageSize ==
|
|
36
|
-
|
|
34
|
+
0);
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
HeapHandle& heap_handle_;
|
|
@@ -77,11 +77,7 @@ class V8_EXPORT AgeTable final {
|
|
|
77
77
|
__builtin_ctz(static_cast<uint32_t>(kCardSizeInBytes));
|
|
78
78
|
#else //! V8_HAS_BUILTIN_CTZ
|
|
79
79
|
// Hardcode and check with assert.
|
|
80
|
-
#if defined(CPPGC_2GB_CAGE)
|
|
81
|
-
11;
|
|
82
|
-
#else // !defined(CPPGC_2GB_CAGE)
|
|
83
80
|
12;
|
|
84
|
-
#endif // !defined(CPPGC_2GB_CAGE)
|
|
85
81
|
#endif // !V8_HAS_BUILTIN_CTZ
|
|
86
82
|
static_assert((1 << kGranularityBits) == kCardSizeInBytes);
|
|
87
83
|
const size_t entry = offset >> kGranularityBits;
|
|
@@ -32,16 +32,12 @@ class V8_EXPORT CagedHeapBase {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
V8_INLINE static bool AreWithinCage(const void* addr1, const void* addr2) {
|
|
35
|
-
#if defined(CPPGC_2GB_CAGE)
|
|
36
|
-
static constexpr size_t kHeapBaseShift = sizeof(uint32_t) * CHAR_BIT - 1;
|
|
37
|
-
#else //! defined(CPPGC_2GB_CAGE)
|
|
38
35
|
#if defined(CPPGC_POINTER_COMPRESSION)
|
|
39
36
|
static constexpr size_t kHeapBaseShift =
|
|
40
37
|
31 + api_constants::kPointerCompressionShift;
|
|
41
38
|
#else // !defined(CPPGC_POINTER_COMPRESSION)
|
|
42
39
|
static constexpr size_t kHeapBaseShift = sizeof(uint32_t) * CHAR_BIT;
|
|
43
40
|
#endif // !defined(CPPGC_POINTER_COMPRESSION)
|
|
44
|
-
#endif //! defined(CPPGC_2GB_CAGE)
|
|
45
41
|
static_assert((static_cast<size_t>(1) << kHeapBaseShift) ==
|
|
46
42
|
api_constants::kCagedHeapMaxReservationSize);
|
|
47
43
|
CPPGC_DCHECK(g_heap_base_);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Copyright 2025 the V8 project authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
#ifndef INCLUDE_CPPGC_INTERNAL_CONDITIONAL_STACK_ALLOCATED_H_
|
|
6
|
+
#define INCLUDE_CPPGC_INTERNAL_CONDITIONAL_STACK_ALLOCATED_H_
|
|
7
|
+
|
|
8
|
+
#include <type_traits>
|
|
9
|
+
|
|
10
|
+
#include "cppgc/macros.h" // NOLINT(build/include_directory)
|
|
11
|
+
#include "cppgc/type-traits.h" // NOLINT(build/include_directory)
|
|
12
|
+
|
|
13
|
+
namespace cppgc {
|
|
14
|
+
namespace internal {
|
|
15
|
+
|
|
16
|
+
// Base class that is marked as stack allocated if T is either marked as stack
|
|
17
|
+
// allocated or a traceable type.
|
|
18
|
+
template <typename T>
|
|
19
|
+
class ConditionalStackAllocatedBase;
|
|
20
|
+
|
|
21
|
+
template <typename T>
|
|
22
|
+
concept RequiresStackAllocated =
|
|
23
|
+
!std::is_void_v<T> &&
|
|
24
|
+
(cppgc::IsStackAllocatedType<T> || cppgc::internal::IsTraceableV<T> ||
|
|
25
|
+
cppgc::IsGarbageCollectedOrMixinTypeV<T>);
|
|
26
|
+
|
|
27
|
+
template <typename T>
|
|
28
|
+
requires(RequiresStackAllocated<T>)
|
|
29
|
+
class ConditionalStackAllocatedBase<T> {
|
|
30
|
+
public:
|
|
31
|
+
CPPGC_STACK_ALLOCATED();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
template <typename T>
|
|
35
|
+
requires(!RequiresStackAllocated<T>)
|
|
36
|
+
class ConditionalStackAllocatedBase<T> {};
|
|
37
|
+
|
|
38
|
+
} // namespace internal
|
|
39
|
+
} // namespace cppgc
|
|
40
|
+
|
|
41
|
+
#endif // INCLUDE_CPPGC_INTERNAL_CONDITIONAL_STACK_ALLOCATED_H_
|
|
@@ -20,18 +20,18 @@ FatalImpl(const char*, const SourceLocation& = SourceLocation::Current());
|
|
|
20
20
|
template <typename>
|
|
21
21
|
struct EatParams {};
|
|
22
22
|
|
|
23
|
-
#
|
|
23
|
+
#ifdef CPPGC_ENABLE_API_CHECKS
|
|
24
24
|
#define CPPGC_DCHECK_MSG(condition, message) \
|
|
25
25
|
do { \
|
|
26
26
|
if (V8_UNLIKELY(!(condition))) { \
|
|
27
27
|
::cppgc::internal::DCheckImpl(message); \
|
|
28
28
|
} \
|
|
29
29
|
} while (false)
|
|
30
|
-
#else // !
|
|
30
|
+
#else // !CPPGC_ENABLE_API_CHECKS
|
|
31
31
|
#define CPPGC_DCHECK_MSG(condition, message) \
|
|
32
32
|
(static_cast<void>(::cppgc::internal::EatParams<decltype( \
|
|
33
33
|
static_cast<void>(condition), message)>{}))
|
|
34
|
-
#endif // !
|
|
34
|
+
#endif // !CPPGC_ENABLE_API_CHECKS
|
|
35
35
|
|
|
36
36
|
#define CPPGC_DCHECK(condition) CPPGC_DCHECK_MSG(condition, #condition)
|
|
37
37
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include <type_traits>
|
|
11
11
|
|
|
12
12
|
#include "cppgc/internal/api-constants.h"
|
|
13
|
+
#include "cppgc/internal/caged-heap.h"
|
|
13
14
|
#include "cppgc/internal/logging.h"
|
|
14
15
|
#include "cppgc/sentinel-pointer.h"
|
|
15
16
|
#include "v8config.h" // NOLINT(build/include_directory)
|
|
@@ -71,11 +72,17 @@ class V8_EXPORT CageBaseGlobal final {
|
|
|
71
72
|
|
|
72
73
|
class V8_TRIVIAL_ABI CompressedPointer final {
|
|
73
74
|
public:
|
|
75
|
+
struct AtomicInitializerTag {};
|
|
76
|
+
|
|
74
77
|
using IntegralType = uint32_t;
|
|
75
78
|
static constexpr auto kWriteBarrierSlotType =
|
|
76
79
|
WriteBarrierSlotType::kCompressed;
|
|
77
80
|
|
|
78
81
|
V8_INLINE CompressedPointer() : value_(0u) {}
|
|
82
|
+
V8_INLINE explicit CompressedPointer(const void* value,
|
|
83
|
+
AtomicInitializerTag) {
|
|
84
|
+
StoreAtomic(value);
|
|
85
|
+
}
|
|
79
86
|
V8_INLINE explicit CompressedPointer(const void* ptr)
|
|
80
87
|
: value_(Compress(ptr)) {}
|
|
81
88
|
V8_INLINE explicit CompressedPointer(std::nullptr_t) : value_(0u) {}
|
|
@@ -139,17 +146,12 @@ class V8_TRIVIAL_ABI CompressedPointer final {
|
|
|
139
146
|
CPPGC_DCHECK(
|
|
140
147
|
(reinterpret_cast<uintptr_t>(ptr) & kPointerCompressionShiftMask) == 0);
|
|
141
148
|
|
|
142
|
-
#if defined(CPPGC_2GB_CAGE)
|
|
143
|
-
// Truncate the pointer.
|
|
144
|
-
auto compressed =
|
|
145
|
-
static_cast<IntegralType>(reinterpret_cast<uintptr_t>(ptr));
|
|
146
|
-
#else // !defined(CPPGC_2GB_CAGE)
|
|
147
149
|
const auto uptr = reinterpret_cast<uintptr_t>(ptr);
|
|
148
150
|
// Shift the pointer and truncate.
|
|
149
151
|
auto compressed = static_cast<IntegralType>(
|
|
150
152
|
uptr >> api_constants::kPointerCompressionShift);
|
|
151
|
-
|
|
152
|
-
//
|
|
153
|
+
// Normal compressed pointers must have the MSB set. This is guaranteed by
|
|
154
|
+
// the cage alignment.
|
|
153
155
|
CPPGC_DCHECK((!compressed || compressed == kCompressedSentinel) ||
|
|
154
156
|
(compressed & (1 << 31)));
|
|
155
157
|
return compressed;
|
|
@@ -164,43 +166,77 @@ class V8_TRIVIAL_ABI CompressedPointer final {
|
|
|
164
166
|
static V8_INLINE void* Decompress(IntegralType ptr, uintptr_t base) {
|
|
165
167
|
CPPGC_DCHECK(CageBaseGlobal::IsSet());
|
|
166
168
|
CPPGC_DCHECK(base == CageBaseGlobal::Get());
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
#else // !defined(CPPGC_2GB_CAGE)
|
|
172
|
-
// Then, shift the result. It's important to shift the unsigned
|
|
173
|
-
// value, as otherwise it would result in undefined behavior.
|
|
169
|
+
// Sign-extend compressed pointer to full width. This ensure that normal
|
|
170
|
+
// pointers have only 1s in the base part of the address. It's also
|
|
171
|
+
// important to shift the unsigned value, as otherwise it would result in
|
|
172
|
+
// undefined behavior.
|
|
174
173
|
const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr))
|
|
175
174
|
<< api_constants::kPointerCompressionShift;
|
|
176
|
-
|
|
175
|
+
// Set the base part of the address for normal compressed pointers. Note
|
|
176
|
+
// that nullptr and the sentinel value do not have 1s in the base part and
|
|
177
|
+
// remain as-is in this operation.
|
|
177
178
|
return reinterpret_cast<void*>(mask & base);
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
// For a given memory `address`, this method iterates all possible pointers
|
|
182
|
+
// that can be reasonably recovered with the current compression scheme and
|
|
183
|
+
// passes them to `callback`.
|
|
184
|
+
template <typename Callback>
|
|
185
|
+
static V8_INLINE void VisitPossiblePointers(const void* address,
|
|
186
|
+
Callback callback);
|
|
187
|
+
|
|
180
188
|
private:
|
|
181
|
-
#if defined(CPPGC_2GB_CAGE)
|
|
182
|
-
static constexpr IntegralType kCompressedSentinel =
|
|
183
|
-
SentinelPointer::kSentinelValue;
|
|
184
|
-
#else // !defined(CPPGC_2GB_CAGE)
|
|
185
189
|
static constexpr IntegralType kCompressedSentinel =
|
|
186
190
|
SentinelPointer::kSentinelValue >>
|
|
187
191
|
api_constants::kPointerCompressionShift;
|
|
188
|
-
#endif // !defined(CPPGC_2GB_CAGE)
|
|
189
192
|
// All constructors initialize `value_`. Do not add a default value here as it
|
|
190
193
|
// results in a non-atomic write on some builds, even when the atomic version
|
|
191
194
|
// of the constructor is used.
|
|
192
195
|
IntegralType value_;
|
|
193
196
|
};
|
|
194
197
|
|
|
198
|
+
template <typename Callback>
|
|
199
|
+
// static
|
|
200
|
+
void CompressedPointer::VisitPossiblePointers(const void* address,
|
|
201
|
+
Callback callback) {
|
|
202
|
+
const uintptr_t base = CageBaseGlobal::Get();
|
|
203
|
+
CPPGC_DCHECK(base);
|
|
204
|
+
// We may have random compressed pointers on stack (e.g. due to inlined
|
|
205
|
+
// collections). These could be present in both halfwords.
|
|
206
|
+
const uint32_t compressed_low =
|
|
207
|
+
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(address));
|
|
208
|
+
callback(CompressedPointer::Decompress(compressed_low, base));
|
|
209
|
+
const uint32_t compressed_high = static_cast<uint32_t>(
|
|
210
|
+
reinterpret_cast<uintptr_t>(address) >> (sizeof(uint32_t) * CHAR_BIT));
|
|
211
|
+
callback(CompressedPointer::Decompress(compressed_high, base));
|
|
212
|
+
// Iterate possible intermediate values, see `Decompress()`. The intermediate
|
|
213
|
+
// value of decompressing is a 64-bit value where 35 bits are the offset. We
|
|
214
|
+
// don't assume sign extension is stored and recover that part.
|
|
215
|
+
//
|
|
216
|
+
// Note that this case conveniently also recovers the full pointer.
|
|
217
|
+
static constexpr uintptr_t kBitForIntermediateValue =
|
|
218
|
+
(sizeof(uint32_t) * CHAR_BIT) + api_constants::kPointerCompressionShift;
|
|
219
|
+
static constexpr uintptr_t kSignExtensionMask =
|
|
220
|
+
~((uintptr_t{1} << kBitForIntermediateValue) - 1);
|
|
221
|
+
const uintptr_t intermediate_sign_extended =
|
|
222
|
+
reinterpret_cast<uintptr_t>(address) | kSignExtensionMask;
|
|
223
|
+
callback(reinterpret_cast<void*>(intermediate_sign_extended & base));
|
|
224
|
+
}
|
|
225
|
+
|
|
195
226
|
#endif // defined(CPPGC_POINTER_COMPRESSION)
|
|
196
227
|
|
|
197
228
|
class V8_TRIVIAL_ABI RawPointer final {
|
|
198
229
|
public:
|
|
230
|
+
struct AtomicInitializerTag {};
|
|
231
|
+
|
|
199
232
|
using IntegralType = uintptr_t;
|
|
200
233
|
static constexpr auto kWriteBarrierSlotType =
|
|
201
234
|
WriteBarrierSlotType::kUncompressed;
|
|
202
235
|
|
|
203
236
|
V8_INLINE RawPointer() : ptr_(nullptr) {}
|
|
237
|
+
V8_INLINE explicit RawPointer(const void* ptr, AtomicInitializerTag) {
|
|
238
|
+
StoreAtomic(ptr);
|
|
239
|
+
}
|
|
204
240
|
V8_INLINE explicit RawPointer(const void* ptr) : ptr_(ptr) {}
|
|
205
241
|
|
|
206
242
|
V8_INLINE const void* Load() const { return ptr_; }
|
|
@@ -243,6 +279,13 @@ class V8_TRIVIAL_ABI RawPointer final {
|
|
|
243
279
|
return a.ptr_ >= b.ptr_;
|
|
244
280
|
}
|
|
245
281
|
|
|
282
|
+
template <typename Callback>
|
|
283
|
+
static V8_INLINE void VisitPossiblePointers(const void* address,
|
|
284
|
+
Callback callback) {
|
|
285
|
+
// Pass along the full pointer.
|
|
286
|
+
return callback(const_cast<void*>(address));
|
|
287
|
+
}
|
|
288
|
+
|
|
246
289
|
private:
|
|
247
290
|
// All constructors initialize `ptr_`. Do not add a default value here as it
|
|
248
291
|
// results in a non-atomic write on some builds, even when the atomic version
|
|
@@ -18,6 +18,7 @@ namespace internal {
|
|
|
18
18
|
|
|
19
19
|
class CrossThreadPersistentRegion;
|
|
20
20
|
class FatalOutOfMemoryHandler;
|
|
21
|
+
class HeapBase;
|
|
21
22
|
class RootVisitor;
|
|
22
23
|
|
|
23
24
|
// PersistentNode represents a variant of two states:
|
|
@@ -133,10 +134,14 @@ class V8_EXPORT PersistentRegionBase {
|
|
|
133
134
|
};
|
|
134
135
|
|
|
135
136
|
// Variant of PersistentRegionBase that checks whether the allocation and
|
|
136
|
-
// freeing happens only on the thread that created the
|
|
137
|
+
// freeing happens only on the thread that created the heap.
|
|
137
138
|
class V8_EXPORT PersistentRegion final : public PersistentRegionBase {
|
|
138
139
|
public:
|
|
139
|
-
|
|
140
|
+
V8_INLINE PersistentRegion(const HeapBase& heap,
|
|
141
|
+
const FatalOutOfMemoryHandler& oom_handler)
|
|
142
|
+
: PersistentRegionBase(oom_handler), heap_(heap) {
|
|
143
|
+
CPPGC_DCHECK(IsCreationThread());
|
|
144
|
+
}
|
|
140
145
|
// Clears Persistent fields to avoid stale pointers after heap teardown.
|
|
141
146
|
~PersistentRegion() = default;
|
|
142
147
|
|
|
@@ -161,7 +166,7 @@ class V8_EXPORT PersistentRegion final : public PersistentRegionBase {
|
|
|
161
166
|
private:
|
|
162
167
|
bool IsCreationThread();
|
|
163
168
|
|
|
164
|
-
|
|
169
|
+
const HeapBase& heap_;
|
|
165
170
|
};
|
|
166
171
|
|
|
167
172
|
// CrossThreadPersistent uses PersistentRegionBase but protects it using this
|
|
@@ -28,13 +28,19 @@ class WeakMemberTag;
|
|
|
28
28
|
class UntracedMemberTag;
|
|
29
29
|
|
|
30
30
|
struct DijkstraWriteBarrierPolicy {
|
|
31
|
-
V8_INLINE static void InitializingBarrier(const void*, const void*) {
|
|
32
31
|
// Since in initializing writes the source object is always white, having no
|
|
33
32
|
// barrier doesn't break the tri-color invariant.
|
|
34
|
-
|
|
33
|
+
V8_INLINE static void InitializingBarrier(const void*, const void*) {}
|
|
34
|
+
V8_INLINE static void InitializingBarrier(const void*, RawPointer storage) {
|
|
35
|
+
}
|
|
36
|
+
#if defined(CPPGC_POINTER_COMPRESSION)
|
|
37
|
+
V8_INLINE static void InitializingBarrier(const void*,
|
|
38
|
+
CompressedPointer storage) {}
|
|
39
|
+
#endif
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
template <WriteBarrierSlotType SlotType>
|
|
42
|
+
V8_INLINE static void AssigningBarrier(const void* slot,
|
|
43
|
+
const void* value) {
|
|
38
44
|
#ifdef CPPGC_SLIM_WRITE_BARRIER
|
|
39
45
|
if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
|
|
40
46
|
WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
|
|
@@ -44,7 +50,7 @@ struct DijkstraWriteBarrierPolicy {
|
|
|
44
50
|
WriteBarrier::GetWriteBarrierType(slot, value, params);
|
|
45
51
|
WriteBarrier(type, params, slot, value);
|
|
46
52
|
#endif // !CPPGC_SLIM_WRITE_BARRIER
|
|
47
|
-
|
|
53
|
+
}
|
|
48
54
|
|
|
49
55
|
template <WriteBarrierSlotType SlotType>
|
|
50
56
|
V8_INLINE static void AssigningBarrier(const void* slot, RawPointer storage) {
|
|
@@ -101,6 +107,11 @@ struct DijkstraWriteBarrierPolicy {
|
|
|
101
107
|
|
|
102
108
|
struct NoWriteBarrierPolicy {
|
|
103
109
|
V8_INLINE static void InitializingBarrier(const void*, const void*) {}
|
|
110
|
+
V8_INLINE static void InitializingBarrier(const void*, RawPointer storage) {}
|
|
111
|
+
#if defined(CPPGC_POINTER_COMPRESSION)
|
|
112
|
+
V8_INLINE static void InitializingBarrier(const void*,
|
|
113
|
+
CompressedPointer storage) {}
|
|
114
|
+
#endif
|
|
104
115
|
template <WriteBarrierSlotType>
|
|
105
116
|
V8_INLINE static void AssigningBarrier(const void*, const void*) {}
|
|
106
117
|
template <WriteBarrierSlotType, typename MemberStorage>
|
|
@@ -119,10 +130,29 @@ template <bool kCheckOffHeapAssignments>
|
|
|
119
130
|
class V8_EXPORT SameThreadEnabledCheckingPolicy
|
|
120
131
|
: private SameThreadEnabledCheckingPolicyBase {
|
|
121
132
|
protected:
|
|
133
|
+
template <typename T>
|
|
134
|
+
V8_INLINE void CheckPointer(RawPointer raw_pointer) {
|
|
135
|
+
if (raw_pointer.IsCleared() || raw_pointer.IsSentinel()) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
CheckPointersImplTrampoline<T>::Call(
|
|
139
|
+
this, static_cast<const T*>(raw_pointer.Load()));
|
|
140
|
+
}
|
|
141
|
+
#if defined(CPPGC_POINTER_COMPRESSION)
|
|
142
|
+
template <typename T>
|
|
143
|
+
V8_INLINE void CheckPointer(CompressedPointer compressed_pointer) {
|
|
144
|
+
if (compressed_pointer.IsCleared() || compressed_pointer.IsSentinel()) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
CheckPointersImplTrampoline<T>::Call(
|
|
148
|
+
this, static_cast<const T*>(compressed_pointer.Load()));
|
|
149
|
+
}
|
|
150
|
+
#endif
|
|
122
151
|
template <typename T>
|
|
123
152
|
void CheckPointer(const T* ptr) {
|
|
124
|
-
if (!ptr || (kSentinelPointer == ptr))
|
|
125
|
-
|
|
153
|
+
if (!ptr || (kSentinelPointer == ptr)) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
126
156
|
CheckPointersImplTrampoline<T>::Call(this, ptr);
|
|
127
157
|
}
|
|
128
158
|
|
|
@@ -145,20 +175,27 @@ class V8_EXPORT SameThreadEnabledCheckingPolicy
|
|
|
145
175
|
|
|
146
176
|
class DisabledCheckingPolicy {
|
|
147
177
|
protected:
|
|
148
|
-
|
|
178
|
+
template <typename T>
|
|
179
|
+
V8_INLINE void CheckPointer(T*) {}
|
|
180
|
+
template <typename T>
|
|
181
|
+
V8_INLINE void CheckPointer(RawPointer) {}
|
|
182
|
+
#if defined(CPPGC_POINTER_COMPRESSION)
|
|
183
|
+
template <typename T>
|
|
184
|
+
V8_INLINE void CheckPointer(CompressedPointer) {}
|
|
185
|
+
#endif
|
|
149
186
|
};
|
|
150
187
|
|
|
151
|
-
#ifdef
|
|
188
|
+
#ifdef CPPGC_ENABLE_SLOW_API_CHECKS
|
|
152
189
|
// Off heap members are not connected to object graph and thus cannot ressurect
|
|
153
190
|
// dead objects.
|
|
154
191
|
using DefaultMemberCheckingPolicy =
|
|
155
192
|
SameThreadEnabledCheckingPolicy<false /* kCheckOffHeapAssignments*/>;
|
|
156
193
|
using DefaultPersistentCheckingPolicy =
|
|
157
194
|
SameThreadEnabledCheckingPolicy<true /* kCheckOffHeapAssignments*/>;
|
|
158
|
-
#else // !
|
|
195
|
+
#else // !CPPGC_ENABLE_SLOW_API_CHECKS
|
|
159
196
|
using DefaultMemberCheckingPolicy = DisabledCheckingPolicy;
|
|
160
197
|
using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
|
|
161
|
-
#endif // !
|
|
198
|
+
#endif // !CPPGC_ENABLE_SLOW_API_CHECKS
|
|
162
199
|
// For CT(W)P neither marking information (for value), nor objectstart bitmap
|
|
163
200
|
// (for slot) are guaranteed to be present because there's no synchronization
|
|
164
201
|
// between heaps after marking.
|
|
@@ -11,10 +11,18 @@
|
|
|
11
11
|
|
|
12
12
|
namespace cppgc {
|
|
13
13
|
|
|
14
|
+
#define CPPGC_DISALLOW_NEW() \
|
|
15
|
+
public: \
|
|
16
|
+
using IsDisallowNewMarker CPPGC_UNUSED = int; \
|
|
17
|
+
void* operator new(size_t, void* location) { return location; } \
|
|
18
|
+
void* operator new(size_t) = delete; \
|
|
19
|
+
static_assert(true, "Force semicolon.")
|
|
20
|
+
|
|
14
21
|
// Use CPPGC_STACK_ALLOCATED if the object is only stack allocated.
|
|
15
22
|
// Add the CPPGC_STACK_ALLOCATED_IGNORE annotation on a case-by-case basis when
|
|
16
23
|
// enforcement of CPPGC_STACK_ALLOCATED should be suppressed.
|
|
17
24
|
#if defined(__clang__)
|
|
25
|
+
|
|
18
26
|
#define CPPGC_STACK_ALLOCATED() \
|
|
19
27
|
public: \
|
|
20
28
|
using IsStackAllocatedTypeMarker CPPGC_UNUSED = int; \
|
|
@@ -23,13 +31,26 @@ namespace cppgc {
|
|
|
23
31
|
void* operator new(size_t) = delete; \
|
|
24
32
|
void* operator new(size_t, void*) = delete; \
|
|
25
33
|
static_assert(true, "Force semicolon.")
|
|
34
|
+
|
|
26
35
|
#define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason) \
|
|
27
36
|
__attribute__((annotate("stack_allocated_ignore")))
|
|
37
|
+
|
|
38
|
+
#define CPPGC_PLUGIN_IGNORE(bug_or_reason) \
|
|
39
|
+
__attribute__((annotate("blink_gc_plugin_ignore"), \
|
|
40
|
+
annotate("stack_allocated_ignore")))
|
|
41
|
+
|
|
28
42
|
#else // !defined(__clang__)
|
|
43
|
+
|
|
29
44
|
#define CPPGC_STACK_ALLOCATED() static_assert(true, "Force semicolon.")
|
|
30
45
|
#define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason)
|
|
46
|
+
#define CPPGC_PLUGIN_IGNORE(bug_or_reason)
|
|
47
|
+
|
|
31
48
|
#endif // !defined(__clang__)
|
|
32
49
|
|
|
50
|
+
template <typename T>
|
|
51
|
+
concept IsStackAllocatedType =
|
|
52
|
+
requires { typename T::IsStackAllocatedTypeMarker; };
|
|
53
|
+
|
|
33
54
|
} // namespace cppgc
|
|
34
55
|
|
|
35
56
|
#endif // INCLUDE_CPPGC_MACROS_H_
|