cppgc: Return 4GB cage back

The 2GB cage caused new OOMs on M106. While those issues are being
investigated, this CL returns the 4GB back. The pointer compression is
still enabled.

Bug: chromium:1325007, chromium:1354660
Change-Id: I4fa4fabece2910ca84913d8df201acfbdf4b26e2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3865004
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82834}
This commit is contained in:
Anton Bikineev 2022-08-30 16:52:38 +02:00 committed by V8 LUCI CQ
parent 30a7e40553
commit d16db0754a
8 changed files with 55 additions and 1 deletions

View File

@ -844,6 +844,9 @@ if (cppgc_enable_young_generation) {
if (cppgc_enable_pointer_compression) {
enabled_external_cppgc_defines += [ "CPPGC_POINTER_COMPRESSION" ]
}
if (cppgc_enable_2gb_cage) {
enabled_external_cppgc_defines += [ "CPPGC_2GB_CAGE" ]
}
disabled_external_cppgc_defines =
external_cppgc_defines - enabled_external_cppgc_defines

View File

@ -100,6 +100,10 @@ declare_args() {
# Enable pointer compression in cppgc.
cppgc_enable_pointer_compression = false
# Enable 2gb cage for fast compression/decompression. Currently disabled
# due to an increased number of OOMs.
cppgc_enable_2gb_cage = false
# Enable advanced BigInt algorithms, costing about 10-30 KB binary size
# depending on platform. Disabled on Android to save binary size.
v8_advanced_bigint_algorithms = !is_android
@ -154,7 +158,7 @@ if (is_debug && !v8_optimized_debug) {
# TODO(crbug.com/621335) Rework this so that we don't have the confusion
# between "optimize_speed" and "optimize_max".
if ((is_posix && !is_android) && !using_sanitizer) {
if (is_posix && !is_android && !using_sanitizer) {
v8_add_configs += [ "//build/config/compiler:optimize_speed" ]
} else {
v8_add_configs += [ "//build/config/compiler:optimize_max" ]

View File

@ -41,7 +41,11 @@ constexpr size_t kGuardPageSize = 4096;
static constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2;
#if defined(CPPGC_CAGED_HEAP)
#if defined(CPPGC_2GB_CAGE)
constexpr size_t kCagedHeapReservationSize = static_cast<size_t>(2) * kGB;
#else // !defined(CPPGC_2GB_CAGE)
constexpr size_t kCagedHeapReservationSize = static_cast<size_t>(4) * kGB;
#endif // !defined(CPPGC_2GB_CAGE)
constexpr size_t kCagedHeapReservationAlignment = kCagedHeapReservationSize;
constexpr size_t kCagedHeapNormalPageReservationSize =

View File

@ -72,7 +72,11 @@ class V8_EXPORT AgeTable final {
__builtin_ctz(static_cast<uint32_t>(kCardSizeInBytes));
#else //! V8_HAS_BUILTIN_CTZ
// Hardcode and check with assert.
#if defined(CPPGC_2GB_CAGE)
11;
#else // !defined(CPPGC_2GB_CAGE)
12;
#endif // !defined(CPPGC_2GB_CAGE)
#endif // !V8_HAS_BUILTIN_CTZ
static_assert((1 << kGranularityBits) == kCardSizeInBytes);
const size_t entry = offset >> kGranularityBits;

View File

@ -32,7 +32,11 @@ class V8_EXPORT CagedHeapBase {
}
V8_INLINE static bool AreWithinCage(const void* addr1, const void* addr2) {
#if defined(CPPGC_2GB_CAGE)
static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT - 1;
#else //! defined(CPPGC_2GB_CAGE)
static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT;
#endif //! defined(CPPGC_2GB_CAGE)
static_assert((static_cast<size_t>(1) << kHalfWordShift) ==
api_constants::kCagedHeapReservationSize);
CPPGC_DCHECK(g_heap_base_);

View File

@ -124,9 +124,15 @@ class CompressedPointer final {
(base & kGigaCageMask) ==
(reinterpret_cast<uintptr_t>(ptr) & kGigaCageMask));
#if defined(CPPGC_2GB_CAGE)
// Truncate the pointer.
auto compressed =
static_cast<IntegralType>(reinterpret_cast<uintptr_t>(ptr));
#else // !defined(CPPGC_2GB_CAGE)
const auto uptr = reinterpret_cast<uintptr_t>(ptr);
// Shift the pointer by one and truncate.
auto compressed = static_cast<IntegralType>(uptr >> 1);
#endif // !defined(CPPGC_2GB_CAGE)
// Normal compressed pointers must have the MSB set.
CPPGC_DCHECK((!compressed || compressed == kCompressedSentinel) ||
(compressed & (1 << 31)));
@ -138,13 +144,24 @@ class CompressedPointer final {
const uintptr_t base = CageBaseGlobal::Get();
// Treat compressed pointer as signed and cast it to uint64_t, which will
// sign-extend it.
#if defined(CPPGC_2GB_CAGE)
const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr));
#else // !defined(CPPGC_2GB_CAGE)
// Then, shift the result by one. It's important to shift the unsigned
// value, as otherwise it would result in undefined behavior.
const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr)) << 1;
#endif // !defined(CPPGC_2GB_CAGE)
return reinterpret_cast<void*>(mask & base);
}
private:
#if defined(CPPGC_2GB_CAGE)
static constexpr IntegralType kCompressedSentinel =
SentinelPointer::kSentinelValue;
#else // !defined(CPPGC_2GB_CAGE)
static constexpr IntegralType kCompressedSentinel =
SentinelPointer::kSentinelValue >> 1;
#endif // !defined(CPPGC_2GB_CAGE)
// All constructors initialize `value_`. Do not add a default value here as it
// results in a non-atomic write on some builds, even when the atomic version
// of the constructor is used.

View File

@ -73,7 +73,11 @@ constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2;
constexpr GCInfoIndex kFreeListGCInfoIndex = 0;
constexpr size_t kFreeListEntrySize = 2 * sizeof(uintptr_t);
#if defined(CPPGC_2GB_CAGE)
constexpr size_t kCagedHeapReservationSize = static_cast<size_t>(2) * kGB;
#else // !defined(CPPGC_2GB_CAGE)
constexpr size_t kCagedHeapReservationSize = static_cast<size_t>(4) * kGB;
#endif // !defined(CPPGC_2GB_CAGE)
constexpr size_t kCagedHeapReservationAlignment = kCagedHeapReservationSize;
// TODO(v8:12231): To reduce OOM probability, instead of the fixed-size
// reservation consider to use a moving needle implementation or simply

View File

@ -108,6 +108,20 @@ void ConservativeTracingVisitor::TraceConservativelyIfNeeded(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer) >>
(sizeof(uint32_t) * CHAR_BIT))));
try_trace(decompressed_high);
#if !defined(CPPGC_2GB_CAGE)
// In addition, check half-compressed halfwords, since the compiler is free to
// spill intermediate results of compression/decompression onto the stack.
const uintptr_t base = CagedHeapBase::GetBase();
DCHECK(base);
auto intermediate_decompressed_low = reinterpret_cast<Address>(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer)) | base);
try_trace(intermediate_decompressed_low);
auto intermediate_decompressed_high = reinterpret_cast<Address>(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer) >>
(sizeof(uint32_t) * CHAR_BIT)) |
base);
try_trace(intermediate_decompressed_high);
#endif // !defined(CPPGC_2GB_CAGE)
#endif // defined(CPPGC_POINTER_COMPRESSION)
}