Commit ee34ce48 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

cppgc: Fix allocation granularity on 32bit

Reduce the granularity to 4 bytes:
- Saves some memory on 32bit configurations
- Allows uniformly reasoning about HoH::ObjectSize() with
  RoundUp<kAllocationGranularity>(sizeof(T))

Change-Id: Ic87aa25839d9b8a99916c07d64e5e49864a6cb53
Bug: chromium:1056170
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2739628Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73267}
parent fff6cdf2
......@@ -9,6 +9,7 @@
#include <stdint.h>
#include "include/cppgc/internal/gc-info.h"
#include "src/base/build_config.h"
namespace cppgc {
namespace internal {
......@@ -30,9 +31,11 @@ enum class AccessMode : uint8_t { kNonAtomic, kAtomic };
// This means that any scalar type with stricter alignment requirements (in
// practice: long double) cannot be used unrestricted in garbage-collected
// objects.
//
// Note: We use the same allocation granularity on 32-bit and 64-bit systems.
#if defined(V8_TARGET_ARCH_64_BIT)
constexpr size_t kAllocationGranularity = 8;
#else // !V8_TARGET_ARCH_64_BIT
constexpr size_t kAllocationGranularity = 4;
#endif // !V8_TARGET_ARCH_64_BIT
constexpr size_t kAllocationMask = kAllocationGranularity - 1;
constexpr size_t kPageSizeLog2 = 17;
......
......@@ -37,16 +37,16 @@ namespace internal {
// | unused | 1 | |
// | in construction | 1 | In construction encoded as |false|. |
// +-----------------+------+------------------------------------------+
// | size | 14 | 17 bits because allocations are aligned. |
// | unused | 1 | |
// | size | 15 | 17 bits because allocations are aligned. |
// | mark bit | 1 | |
// +-----------------+------+------------------------------------------+
//
// Notes:
// - See |GCInfoTable| for constraints on GCInfoIndex.
// - |size| for regular objects is encoded with 14 bits but can actually
// - |size| for regular objects is encoded with 15 bits but can actually
// represent sizes up to |kBlinkPageSize| (2^17) because allocations are
// always 8 byte aligned (see kAllocationGranularity).
// always 4 byte aligned (see kAllocationGranularity) on 32bit. 64bit uses
// 8 byte aligned allocations which leaves 1 bit unused.
// - |size| for large objects is encoded as 0. The size of a large object is
// stored in |LargeObjectPage::PayloadSize()|.
// - |mark bit| and |in construction| bits are located in separate 16-bit halves
......@@ -113,18 +113,17 @@ class HeapObjectHeader {
using GCInfoIndexField = UnusedField1::Next<GCInfoIndex, 14>;
// Used in |encoded_low_|.
using MarkBitField = v8::base::BitField16<bool, 0, 1>;
using UnusedField2 = MarkBitField::Next<bool, 1>;
using SizeField = void; // Use EncodeSize/DecodeSize instead.
static constexpr size_t DecodeSize(uint16_t encoded) {
// Essentially, gets optimized to << 1.
using SizeField = UnusedField2::Next<size_t, 14>;
using SizeField = MarkBitField::Next<size_t, 15>;
return SizeField::decode(encoded) * kAllocationGranularity;
}
static constexpr uint16_t EncodeSize(size_t size) {
// Essentially, gets optimized to >> 1.
using SizeField = UnusedField2::Next<size_t, 14>;
using SizeField = MarkBitField::Next<size_t, 15>;
return SizeField::encode(size / kAllocationGranularity);
}
......@@ -144,6 +143,10 @@ class HeapObjectHeader {
uint16_t encoded_low_;
};
static_assert(kAllocationGranularity == sizeof(HeapObjectHeader),
"sizeof(HeapObjectHeader) must match allocation granularity to "
"guarantee alignment");
// static
HeapObjectHeader& HeapObjectHeader::FromPayload(void* payload) {
return *reinterpret_cast<HeapObjectHeader*>(static_cast<Address>(payload) -
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment