Commit c439efda authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ptr-compr] Introduce compression scheme class

... which will contain all compression scheme related functions.
This will allow introducing custom compression schemes for certain
cases and use the compression scheme class as a template argument for
TaggedField or OffHeapCompressedObjectSlot implementations.

Bug: v8:7703, v8:11880
Change-Id: Ic78d36b7021110d6a4797a3150547a224d942b32
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3899262Reviewed-by: 's avatarJakob Linke <jgruber@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83302}
parent be5dff6b
......@@ -671,7 +671,8 @@ HeapObject RelocInfo::target_object(PtrComprCageBase cage_base) {
Tagged_t compressed =
Assembler::target_compressed_address_at(pc_, constant_pool_);
DCHECK(!HAS_SMI_TAG(compressed));
Object obj(DecompressTaggedPointer(cage_base, compressed));
Object obj(V8HeapCompressionScheme::DecompressTaggedPointer(cage_base,
compressed));
// Embedding of compressed Code objects must not happen when external code
// space is enabled, because CodeDataContainers must be used instead.
DCHECK_IMPLIES(V8_EXTERNAL_CODE_SPACE_BOOL,
......@@ -703,7 +704,9 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
// No need to flush icache since no instructions were changed.
} else if (IsCompressedEmbeddedObject(rmode_)) {
Assembler::set_target_compressed_address_at(
pc_, constant_pool_, CompressTagged(target.ptr()), icache_flush_mode);
pc_, constant_pool_,
V8HeapCompressionScheme::CompressTagged(target.ptr()),
icache_flush_mode);
} else {
DCHECK(IsFullEmbeddedObject(rmode_));
Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
......
......@@ -150,7 +150,7 @@ HeapObject RelocInfo::target_object(PtrComprCageBase cage_base) {
if (IsDataEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
} else if (IsCompressedEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(DecompressTaggedAny(
return HeapObject::cast(Object(V8HeapCompressionScheme::DecompressTaggedAny(
cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else {
......@@ -189,7 +189,9 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
// No need to flush icache since no instructions were changed.
} else if (IsCompressedEmbeddedObject(rmode_)) {
Assembler::set_target_compressed_address_at(
pc_, constant_pool_, CompressTagged(target.ptr()), icache_flush_mode);
pc_, constant_pool_,
V8HeapCompressionScheme::CompressTagged(target.ptr()),
icache_flush_mode);
} else {
DCHECK(IsFullEmbeddedObject(rmode_));
Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
......
......@@ -164,7 +164,7 @@ HeapObject RelocInfo::target_object(PtrComprCageBase cage_base) {
if (IsDataEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
} else if (IsCompressedEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(DecompressTaggedAny(
return HeapObject::cast(Object(V8HeapCompressionScheme::DecompressTaggedAny(
cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else {
......@@ -199,7 +199,9 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
// No need to flush icache since no instructions were changed.
} else if (IsCompressedEmbeddedObject(rmode_)) {
Assembler::set_target_compressed_address_at(
pc_, constant_pool_, CompressTagged(target.ptr()), icache_flush_mode);
pc_, constant_pool_,
V8HeapCompressionScheme::CompressTagged(target.ptr()),
icache_flush_mode);
} else {
DCHECK(IsFullEmbeddedObject(rmode_));
Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
......
......@@ -144,7 +144,7 @@ HeapObject RelocInfo::target_object(PtrComprCageBase cage_base) {
if (IsDataEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
} else if (IsCompressedEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(DecompressTaggedAny(
return HeapObject::cast(Object(V8HeapCompressionScheme::DecompressTaggedAny(
cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else {
......@@ -183,7 +183,9 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
// No need to flush icache since no instructions were changed.
} else if (IsCompressedEmbeddedObject(rmode_)) {
Assembler::set_target_compressed_address_at(
pc_, constant_pool_, CompressTagged(target.ptr()), icache_flush_mode);
pc_, constant_pool_,
V8HeapCompressionScheme::CompressTagged(target.ptr()),
icache_flush_mode);
} else {
DCHECK(IsFullEmbeddedObject(rmode_));
Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
......
......@@ -326,7 +326,8 @@ HeapObject RelocInfo::target_object(PtrComprCageBase cage_base) {
if (IsCompressedEmbeddedObject(rmode_)) {
Tagged_t compressed = ReadUnalignedValue<Tagged_t>(pc_);
DCHECK(!HAS_SMI_TAG(compressed));
Object obj(DecompressTaggedPointer(cage_base, compressed));
Object obj(V8HeapCompressionScheme::DecompressTaggedPointer(cage_base,
compressed));
// Embedding of compressed Code objects must not happen when external code
// space is enabled, because CodeDataContainers must be used instead.
DCHECK_IMPLIES(V8_EXTERNAL_CODE_SPACE_BOOL,
......@@ -380,7 +381,7 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
DCHECK(IsCodeTarget(rmode_) || IsEmbeddedObjectMode(rmode_));
if (IsCompressedEmbeddedObject(rmode_)) {
DCHECK(COMPRESS_POINTERS_BOOL);
Tagged_t tagged = CompressTagged(target.ptr());
Tagged_t tagged = V8HeapCompressionScheme::CompressTagged(target.ptr());
WriteUnalignedValue(pc_, tagged);
} else {
DCHECK(IsFullEmbeddedObject(rmode_) || IsDataEmbeddedObject(rmode_));
......@@ -424,7 +425,8 @@ void RelocInfo::WipeOut() {
WriteUnalignedValue(pc_, kNullAddress);
} else if (IsCompressedEmbeddedObject(rmode_)) {
Address smi_address = Smi::FromInt(0).ptr();
WriteUnalignedValue(pc_, CompressTagged(smi_address));
WriteUnalignedValue(pc_,
V8HeapCompressionScheme::CompressTagged(smi_address));
} else if (IsCodeTarget(rmode_) || IsNearBuiltinEntry(rmode_) ||
IsRuntimeEntry(rmode_)) {
// Effectively write zero into the relocation.
......
......@@ -903,6 +903,8 @@ class CompressedObjectSlot;
class CompressedMaybeObjectSlot;
class CompressedMapWordSlot;
class CompressedHeapObjectSlot;
class V8HeapCompressionScheme;
template <typename CompressionScheme>
class OffHeapCompressedObjectSlot;
class FullObjectSlot;
class FullMaybeObjectSlot;
......@@ -931,15 +933,16 @@ struct SlotTraits {
using TObjectSlot = CompressedObjectSlot;
using TMaybeObjectSlot = CompressedMaybeObjectSlot;
using THeapObjectSlot = CompressedHeapObjectSlot;
using TOffHeapObjectSlot = OffHeapCompressedObjectSlot;
using TCodeObjectSlot = OffHeapCompressedObjectSlot;
using TOffHeapObjectSlot =
OffHeapCompressedObjectSlot<V8HeapCompressionScheme>;
using TCodeObjectSlot = OffHeapCompressedObjectSlot<V8HeapCompressionScheme>;
#else
using TObjectSlot = FullObjectSlot;
using TMaybeObjectSlot = FullMaybeObjectSlot;
using THeapObjectSlot = FullHeapObjectSlot;
using TOffHeapObjectSlot = OffHeapFullObjectSlot;
using TCodeObjectSlot = OffHeapFullObjectSlot;
#endif
#endif // V8_COMPRESS_POINTERS
};
// An ObjectSlot instance describes a kTaggedSize-sized on-heap field ("slot")
......
......@@ -26,74 +26,102 @@ Address PtrComprCageBase::address() const {
return ret;
}
// Compresses full-pointer representation of a tagged value to on-heap
// representation.
V8_INLINE Tagged_t CompressTagged(Address tagged) {
return static_cast<Tagged_t>(static_cast<uint32_t>(tagged));
}
//
// V8HeapCompressionScheme
//
V8_INLINE constexpr Address GetPtrComprCageBaseAddress(Address on_heap_addr) {
// static
Address V8HeapCompressionScheme::GetPtrComprCageBaseAddress(
Address on_heap_addr) {
return RoundDown<kPtrComprCageBaseAlignment>(on_heap_addr);
}
V8_INLINE Address GetPtrComprCageBaseAddress(PtrComprCageBase cage_base) {
// static
Address V8HeapCompressionScheme::GetPtrComprCageBaseAddress(
PtrComprCageBase cage_base) {
return cage_base.address();
}
V8_INLINE constexpr PtrComprCageBase GetPtrComprCageBaseFromOnHeapAddress(
Address address) {
return PtrComprCageBase(GetPtrComprCageBaseAddress(address));
// static
Tagged_t V8HeapCompressionScheme::CompressTagged(Address tagged) {
return static_cast<Tagged_t>(static_cast<uint32_t>(tagged));
}
// Decompresses smi value.
V8_INLINE Address DecompressTaggedSigned(Tagged_t raw_value) {
// static
Address V8HeapCompressionScheme::DecompressTaggedSigned(Tagged_t raw_value) {
// For runtime code the upper 32-bits of the Smi value do not matter.
return static_cast<Address>(raw_value);
}
// Decompresses weak or strong heap object pointer or forwarding pointer,
// preserving both weak- and smi- tags.
// static
template <typename TOnHeapAddress>
V8_INLINE Address DecompressTaggedPointer(TOnHeapAddress on_heap_addr,
Tagged_t raw_value) {
Address V8HeapCompressionScheme::DecompressTaggedPointer(
TOnHeapAddress on_heap_addr, Tagged_t raw_value) {
return GetPtrComprCageBaseAddress(on_heap_addr) +
static_cast<Address>(raw_value);
}
// Decompresses any tagged value, preserving both weak- and smi- tags.
// static
template <typename TOnHeapAddress>
V8_INLINE Address DecompressTaggedAny(TOnHeapAddress on_heap_addr,
Tagged_t raw_value) {
Address V8HeapCompressionScheme::DecompressTaggedAny(
TOnHeapAddress on_heap_addr, Tagged_t raw_value) {
return DecompressTaggedPointer(on_heap_addr, raw_value);
}
//
// Misc functions.
//
V8_INLINE PtrComprCageBase
GetPtrComprCageBaseFromOnHeapAddress(Address address) {
return PtrComprCageBase(
V8HeapCompressionScheme::GetPtrComprCageBaseAddress(address));
}
#else
V8_INLINE Tagged_t CompressTagged(Address tagged) { UNREACHABLE(); }
//
// V8HeapCompressionScheme
//
V8_INLINE constexpr PtrComprCageBase GetPtrComprCageBaseFromOnHeapAddress(
Address address) {
return PtrComprCageBase();
// static
Address V8HeapCompressionScheme::GetPtrComprCageBaseAddress(
Address on_heap_addr) {
UNREACHABLE();
}
V8_INLINE Address DecompressTaggedSigned(Tagged_t raw_value) { UNREACHABLE(); }
// static
Tagged_t V8HeapCompressionScheme::CompressTagged(Address tagged) {
UNREACHABLE();
}
template <typename TOnHeapAddress>
V8_INLINE Address DecompressTaggedPointer(TOnHeapAddress on_heap_addr,
Tagged_t raw_value) {
// static
Address V8HeapCompressionScheme::DecompressTaggedSigned(Tagged_t raw_value) {
UNREACHABLE();
}
template <typename TOnHeapAddress>
V8_INLINE Address DecompressTaggedAny(TOnHeapAddress on_heap_addr,
Tagged_t raw_value) {
Address V8HeapCompressionScheme::DecompressTaggedPointer(
TOnHeapAddress on_heap_addr, Tagged_t raw_value) {
UNREACHABLE();
}
V8_INLINE Address GetPtrComprCageBaseAddress(Address on_heap_addr) {
// static
template <typename TOnHeapAddress>
Address V8HeapCompressionScheme::DecompressTaggedAny(
TOnHeapAddress on_heap_addr, Tagged_t raw_value) {
UNREACHABLE();
}
//
// Misc functions.
//
V8_INLINE constexpr PtrComprCageBase GetPtrComprCageBaseFromOnHeapAddress(
Address address) {
return PtrComprCageBase();
}
#endif // V8_COMPRESS_POINTERS
V8_INLINE PtrComprCageBase GetPtrComprCageBase(HeapObject object) {
......
......@@ -8,8 +8,43 @@
#include "src/base/memory.h"
#include "src/common/globals.h"
namespace v8 {
namespace internal {
namespace v8::internal {
// This is just a collection of compression scheme related functions. Having
// such a class allows plugging different decompression scheme in certain
// places by introducing another CompressionScheme class with a customized
// implementation. This is useful, for example, for CodeDataContainer::code
// field (see CodeObjectSlot).
class V8HeapCompressionScheme {
public:
V8_INLINE static Address GetPtrComprCageBaseAddress(Address on_heap_addr);
V8_INLINE static Address GetPtrComprCageBaseAddress(
PtrComprCageBase cage_base);
// Compresses full-pointer representation of a tagged value to on-heap
// representation.
V8_INLINE static Tagged_t CompressTagged(Address tagged);
// Decompresses smi value.
V8_INLINE static Address DecompressTaggedSigned(Tagged_t raw_value);
// Decompresses weak or strong heap object pointer or forwarding pointer,
// preserving both weak- and smi- tags.
template <typename TOnHeapAddress>
V8_INLINE static Address DecompressTaggedPointer(TOnHeapAddress on_heap_addr,
Tagged_t raw_value);
// Decompresses any tagged value, preserving both weak- and smi- tags.
template <typename TOnHeapAddress>
V8_INLINE static Address DecompressTaggedAny(TOnHeapAddress on_heap_addr,
Tagged_t raw_value);
};
#ifdef V8_EXTERNAL_CODE_SPACE
// Compression scheme used for fields containing Code objects (namely for the
// CodeDataContainer::code field).
using ExternalCodeCompressionScheme = V8HeapCompressionScheme;
#endif // V8_EXTERNAL_CODE_SPACE
// Accessors for fields that may be unaligned due to pointer compression.
......@@ -49,7 +84,6 @@ static inline void WriteMaybeUnalignedValue(Address p, V value) {
}
}
} // namespace internal
} // namespace v8
} // namespace v8::internal
#endif // V8_COMMON_PTR_COMPR_H_
......@@ -1291,7 +1291,8 @@ int TranslatedState::CreateNextTranslatedValue(
Address TranslatedState::DecompressIfNeeded(intptr_t value) {
if (COMPRESS_POINTERS_BOOL) {
return DecompressTaggedAny(isolate(), static_cast<uint32_t>(value));
return V8HeapCompressionScheme::DecompressTaggedAny(
isolate(), static_cast<uint32_t>(value));
} else {
return value;
}
......
......@@ -1922,7 +1922,8 @@ void WasmStruct::WasmStructPrint(std::ostream& os) {
case wasm::kRtt: {
Tagged_t raw = base::ReadUnalignedValue<Tagged_t>(field_address);
#if V8_COMPRESS_POINTERS
Address obj = DecompressTaggedPointer(address(), raw);
Address obj =
V8HeapCompressionScheme::DecompressTaggedPointer(address(), raw);
#else
Address obj = raw;
#endif
......@@ -2929,8 +2930,8 @@ inline i::Object GetObjectFromRaw(void* object) {
if (RoundDown<i::kPtrComprCageBaseAlignment>(object_ptr) == i::kNullAddress) {
// Try to decompress pointer.
i::Isolate* isolate = i::Isolate::Current();
object_ptr =
i::DecompressTaggedAny(isolate, static_cast<i::Tagged_t>(object_ptr));
object_ptr = i::V8HeapCompressionScheme::DecompressTaggedAny(
isolate, static_cast<i::Tagged_t>(object_ptr));
}
#endif
return i::Object(object_ptr);
......
......@@ -1109,8 +1109,8 @@ void VisitSpillSlot(Isolate* isolate, RootVisitor* v,
if (!HAS_SMI_TAG(value) && value <= 0xffffffff) {
// We don't need to update smi values or full pointers.
was_compressed = true;
*spill_slot.location() =
DecompressTaggedPointer(cage_base, static_cast<Tagged_t>(value));
*spill_slot.location() = V8HeapCompressionScheme::DecompressTaggedPointer(
cage_base, static_cast<Tagged_t>(value));
if (DEBUG_BOOL) {
// Ensure that the spill slot contains correct heap object.
HeapObject raw = HeapObject::cast(Object(*spill_slot.location()));
......@@ -1144,8 +1144,8 @@ void VisitSpillSlot(Isolate* isolate, RootVisitor* v,
if (!HAS_SMI_TAG(compressed_value)) {
was_compressed = slot_contents <= 0xFFFFFFFF;
// We don't need to update smi values.
*spill_slot.location() =
DecompressTaggedPointer(cage_base, compressed_value);
*spill_slot.location() = V8HeapCompressionScheme::DecompressTaggedPointer(
cage_base, compressed_value);
}
}
#endif
......@@ -1154,7 +1154,8 @@ void VisitSpillSlot(Isolate* isolate, RootVisitor* v,
if (was_compressed) {
// Restore compression. Generated code should be able to trust that
// compressed spill slots remain compressed.
*spill_slot.location() = CompressTagged(*spill_slot.location());
*spill_slot.location() =
V8HeapCompressionScheme::CompressTagged(*spill_slot.location());
}
#endif
}
......
......@@ -115,7 +115,7 @@ Object Isolate::VerifyBuiltinsResult(Object result) {
// because that's the assumption in generated code (which might call this
// builtin).
if (!result.IsSmi()) {
DCHECK_EQ(result.ptr(), DecompressTaggedPointer(
DCHECK_EQ(result.ptr(), V8HeapCompressionScheme::DecompressTaggedPointer(
this, static_cast<Tagged_t>(result.ptr())));
}
#endif
......@@ -131,12 +131,12 @@ ObjectPair Isolate::VerifyBuiltinsResult(ObjectPair pair) {
// because that's the assumption in generated code (which might call this
// builtin).
if (!HAS_SMI_TAG(pair.x)) {
DCHECK_EQ(pair.x,
DecompressTaggedPointer(this, static_cast<Tagged_t>(pair.x)));
DCHECK_EQ(pair.x, V8HeapCompressionScheme::DecompressTaggedPointer(
this, static_cast<Tagged_t>(pair.x)));
}
if (!HAS_SMI_TAG(pair.y)) {
DCHECK_EQ(pair.y,
DecompressTaggedPointer(this, static_cast<Tagged_t>(pair.y)));
DCHECK_EQ(pair.y, V8HeapCompressionScheme::DecompressTaggedPointer(
this, static_cast<Tagged_t>(pair.y)));
}
#endif // V8_COMPRESS_POINTERS
#endif // V8_HOST_ARCH_64_BIT
......
......@@ -4286,9 +4286,14 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
}
#ifdef V8_EXTERNAL_CODE_SPACE
if (heap_.code_range()) {
code_cage_base_ = GetPtrComprCageBaseAddress(heap_.code_range()->base());
code_cage_base_ = ExternalCodeCompressionScheme::GetPtrComprCageBaseAddress(
heap_.code_range()->base());
} else {
code_cage_base_ = cage_base();
CHECK(jitless_);
// In jitless mode the code space pages will be allocated in the main
// pointer compression cage.
code_cage_base_ =
ExternalCodeCompressionScheme::GetPtrComprCageBaseAddress(cage_base());
}
#endif // V8_EXTERNAL_CODE_SPACE
......
......@@ -147,15 +147,14 @@ bool CodeRange::InitReservation(v8::PageAllocator* page_allocator,
if (!VirtualMemoryCage::InitReservation(params)) return false;
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// Ensure that the code range does not cross the 4Gb boundary and thus
// default compression scheme of truncating the Code pointers to 32-bits
// still works.
Address base = page_allocator_->begin();
Address last = base + page_allocator_->size() - 1;
CHECK_EQ(GetPtrComprCageBaseAddress(base),
GetPtrComprCageBaseAddress(last));
}
#ifdef V8_EXTERNAL_CODE_SPACE
// Ensure that ExternalCodeCompressionScheme is applicable to all objects
// stored in the code range.
Address base = page_allocator_->begin();
Address last = base + page_allocator_->size() - 1;
CHECK_EQ(ExternalCodeCompressionScheme::GetPtrComprCageBaseAddress(base),
ExternalCodeCompressionScheme::GetPtrComprCageBaseAddress(last));
#endif // V8_EXTERNAL_CODE_SPACE
// On some platforms, specifically Win64, we need to reserve some pages at
// the beginning of an executable space. See
......
......@@ -185,7 +185,9 @@ ReadOnlyHeap* PointerCompressedReadOnlyArtifacts::GetReadOnlyHeapForIsolate(
Address isolate_root = isolate->isolate_root();
for (Object original_object : original_cache) {
Address original_address = original_object.ptr();
Address new_address = isolate_root + CompressTagged(original_address);
Address new_address =
isolate_root +
V8HeapCompressionScheme::CompressTagged(original_address);
Object new_object = Object(new_address);
cache.push_back(new_object);
}
......@@ -235,7 +237,8 @@ void PointerCompressedReadOnlyArtifacts::Initialize(
pages_.push_back(new_page);
shared_memory_.push_back(std::move(shared_memory));
// This is just CompressTagged but inlined so it will always compile.
Tagged_t compressed_address = CompressTagged(page->address());
Tagged_t compressed_address =
V8HeapCompressionScheme::CompressTagged(page->address());
page_offsets_.push_back(compressed_address);
// 3. Update the accounting stats so the allocated bytes are for the new
......
......@@ -39,13 +39,15 @@ SlotCallbackResult UpdateTypedSlotHelper::UpdateTypedSlot(Heap* heap,
return UpdateEmbeddedPointer(heap, &rinfo, callback);
}
case SlotType::kConstPoolEmbeddedObjectCompressed: {
HeapObject old_target = HeapObject::cast(Object(
DecompressTaggedAny(heap->isolate(), base::Memory<Tagged_t>(addr))));
HeapObject old_target =
HeapObject::cast(Object(V8HeapCompressionScheme::DecompressTaggedAny(
heap->isolate(), base::Memory<Tagged_t>(addr))));
HeapObject new_target = old_target;
SlotCallbackResult result = callback(FullMaybeObjectSlot(&new_target));
DCHECK(!HasWeakHeapObjectTag(new_target));
if (new_target != old_target) {
base::Memory<Tagged_t>(addr) = CompressTagged(new_target.ptr());
base::Memory<Tagged_t>(addr) =
V8HeapCompressionScheme::CompressTagged(new_target.ptr());
}
return result;
}
......@@ -82,8 +84,8 @@ HeapObject UpdateTypedSlotHelper::GetTargetObject(Heap* heap,
return rinfo.target_object(heap->isolate());
}
case SlotType::kConstPoolEmbeddedObjectCompressed: {
Address full =
DecompressTaggedAny(heap->isolate(), base::Memory<Tagged_t>(addr));
Address full = V8HeapCompressionScheme::DecompressTaggedAny(
heap->isolate(), base::Memory<Tagged_t>(addr));
return HeapObject::cast(Object(full));
}
case SlotType::kConstPoolEmbeddedObjectFull: {
......
......@@ -1436,15 +1436,21 @@ Object CodeDataContainer::raw_code() const {
}
Object CodeDataContainer::raw_code(PtrComprCageBase cage_base) const {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
Object value = TaggedField<Object, kCodeOffset>::load(cage_base, *this);
#ifdef V8_EXTERNAL_CODE_SPACE
Object value = ExternalCodeField::load(cage_base, *this);
return value;
#else
UNREACHABLE();
#endif // V8_EXTERNAL_CODE_SPACE
}
void CodeDataContainer::set_raw_code(Object value, WriteBarrierMode mode) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
TaggedField<Object, kCodeOffset>::Release_Store(*this, value);
#ifdef V8_EXTERNAL_CODE_SPACE
ExternalCodeField::Release_Store(*this, value);
CONDITIONAL_WRITE_BARRIER(*this, kCodeOffset, value, mode);
#else
UNREACHABLE();
#endif // V8_EXTERNAL_CODE_SPACE
}
Object CodeDataContainer::raw_code(RelaxedLoadTag tag) const {
......@@ -1454,10 +1460,12 @@ Object CodeDataContainer::raw_code(RelaxedLoadTag tag) const {
Object CodeDataContainer::raw_code(PtrComprCageBase cage_base,
RelaxedLoadTag) const {
Object value =
TaggedField<Object, kCodeOffset>::Relaxed_Load(cage_base, *this);
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
#ifdef V8_EXTERNAL_CODE_SPACE
Object value = ExternalCodeField::Relaxed_Load(cage_base, *this);
return value;
#else
UNREACHABLE();
#endif // V8_EXTERNAL_CODE_SPACE
}
ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
......
......@@ -266,6 +266,11 @@ class CodeDataContainer : public HeapObject {
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, CODE_DATA_FIELDS)
#undef CODE_DATA_FIELDS
#ifdef V8_EXTERNAL_CODE_SPACE
using ExternalCodeField =
TaggedField<Object, kCodeOffset, ExternalCodeCompressionScheme>;
#endif
class BodyDescriptor;
// Flags layout.
......
......@@ -11,8 +11,7 @@
#include "src/objects/compressed-slots.h"
#include "src/objects/maybe-object-inl.h"
namespace v8 {
namespace internal {
namespace v8::internal {
//
// CompressedObjectSlot implementation.
......@@ -36,16 +35,16 @@ bool CompressedObjectSlot::contains_map_value(Address raw_value) const {
Object CompressedObjectSlot::operator*() const {
Tagged_t value = *location();
return Object(DecompressTaggedAny(address(), value));
return Object(TCompressionScheme::DecompressTaggedAny(address(), value));
}
Object CompressedObjectSlot::load(PtrComprCageBase cage_base) const {
Tagged_t value = *location();
return Object(DecompressTaggedAny(cage_base, value));
return Object(TCompressionScheme::DecompressTaggedAny(cage_base, value));
}
void CompressedObjectSlot::store(Object value) const {
*location() = CompressTagged(value.ptr());
*location() = TCompressionScheme::CompressTagged(value.ptr());
}
void CompressedObjectSlot::store_map(Map map) const {
......@@ -64,36 +63,36 @@ Map CompressedObjectSlot::load_map() const {
Object CompressedObjectSlot::Acquire_Load() const {
AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location());
return Object(DecompressTaggedAny(address(), value));
return Object(TCompressionScheme::DecompressTaggedAny(address(), value));
}
Object CompressedObjectSlot::Relaxed_Load() const {
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
return Object(DecompressTaggedAny(address(), value));
return Object(TCompressionScheme::DecompressTaggedAny(address(), value));
}
Object CompressedObjectSlot::Relaxed_Load(PtrComprCageBase cage_base) const {
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
return Object(DecompressTaggedAny(cage_base, value));
return Object(TCompressionScheme::DecompressTaggedAny(cage_base, value));
}
void CompressedObjectSlot::Relaxed_Store(Object value) const {
Tagged_t ptr = CompressTagged(value.ptr());
Tagged_t ptr = TCompressionScheme::CompressTagged(value.ptr());
AsAtomicTagged::Relaxed_Store(location(), ptr);
}
void CompressedObjectSlot::Release_Store(Object value) const {
Tagged_t ptr = CompressTagged(value.ptr());
Tagged_t ptr = TCompressionScheme::CompressTagged(value.ptr());
AsAtomicTagged::Release_Store(location(), ptr);
}
Object CompressedObjectSlot::Release_CompareAndSwap(Object old,
Object target) const {
Tagged_t old_ptr = CompressTagged(old.ptr());
Tagged_t target_ptr = CompressTagged(target.ptr());
Tagged_t old_ptr = TCompressionScheme::CompressTagged(old.ptr());
Tagged_t target_ptr = TCompressionScheme::CompressTagged(target.ptr());
Tagged_t result =
AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr);
return Object(DecompressTaggedAny(address(), result));
return Object(TCompressionScheme::DecompressTaggedAny(address(), result));
}
//
......@@ -102,38 +101,38 @@ Object CompressedObjectSlot::Release_CompareAndSwap(Object old,
MaybeObject CompressedMaybeObjectSlot::operator*() const {
Tagged_t value = *location();
return MaybeObject(DecompressTaggedAny(address(), value));
return MaybeObject(TCompressionScheme::DecompressTaggedAny(address(), value));
}
MaybeObject CompressedMaybeObjectSlot::load(PtrComprCageBase cage_base) const {
Tagged_t value = *location();
return MaybeObject(DecompressTaggedAny(cage_base, value));
return MaybeObject(TCompressionScheme::DecompressTaggedAny(cage_base, value));
}
void CompressedMaybeObjectSlot::store(MaybeObject value) const {
*location() = CompressTagged(value.ptr());
*location() = TCompressionScheme::CompressTagged(value.ptr());
}
MaybeObject CompressedMaybeObjectSlot::Relaxed_Load() const {
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
return MaybeObject(DecompressTaggedAny(address(), value));
return MaybeObject(TCompressionScheme::DecompressTaggedAny(address(), value));
}
MaybeObject CompressedMaybeObjectSlot::Relaxed_Load(
PtrComprCageBase cage_base) const {
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
return MaybeObject(DecompressTaggedAny(cage_base, value));
return MaybeObject(TCompressionScheme::DecompressTaggedAny(cage_base, value));
}
void CompressedMaybeObjectSlot::Relaxed_Store(MaybeObject value) const {
Tagged_t ptr = CompressTagged(value.ptr());
Tagged_t ptr = TCompressionScheme::CompressTagged(value.ptr());
AsAtomicTagged::Relaxed_Store(location(), ptr);
}
void CompressedMaybeObjectSlot::Release_CompareAndSwap(
MaybeObject old, MaybeObject target) const {
Tagged_t old_ptr = CompressTagged(old.ptr());
Tagged_t target_ptr = CompressTagged(target.ptr());
Tagged_t old_ptr = TCompressionScheme::CompressTagged(old.ptr());
Tagged_t target_ptr = TCompressionScheme::CompressTagged(target.ptr());
AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr);
}
......@@ -143,73 +142,86 @@ void CompressedMaybeObjectSlot::Release_CompareAndSwap(
HeapObjectReference CompressedHeapObjectSlot::operator*() const {
Tagged_t value = *location();
return HeapObjectReference(DecompressTaggedPointer(address(), value));
return HeapObjectReference(
TCompressionScheme::DecompressTaggedPointer(address(), value));
}
HeapObjectReference CompressedHeapObjectSlot::load(
PtrComprCageBase cage_base) const {
Tagged_t value = *location();
return HeapObjectReference(DecompressTaggedPointer(cage_base, value));
return HeapObjectReference(
TCompressionScheme::DecompressTaggedPointer(cage_base, value));
}
void CompressedHeapObjectSlot::store(HeapObjectReference value) const {
*location() = CompressTagged(value.ptr());
*location() = TCompressionScheme::CompressTagged(value.ptr());
}
HeapObject CompressedHeapObjectSlot::ToHeapObject() const {
Tagged_t value = *location();
DCHECK(HAS_STRONG_HEAP_OBJECT_TAG(value));
return HeapObject::cast(Object(DecompressTaggedPointer(address(), value)));
return HeapObject::cast(
Object(TCompressionScheme::DecompressTaggedPointer(address(), value)));
}
void CompressedHeapObjectSlot::StoreHeapObject(HeapObject value) const {
*location() = CompressTagged(value.ptr());
*location() = TCompressionScheme::CompressTagged(value.ptr());
}
//
// OffHeapCompressedObjectSlot implementation.
//
Object OffHeapCompressedObjectSlot::load(PtrComprCageBase cage_base) const {
Tagged_t value = *location();
return Object(DecompressTaggedAny(cage_base, value));
template <typename CompressionScheme>
Object OffHeapCompressedObjectSlot<CompressionScheme>::load(
PtrComprCageBase cage_base) const {
Tagged_t value = *TSlotBase::location();
return Object(CompressionScheme::DecompressTaggedAny(cage_base, value));
}
void OffHeapCompressedObjectSlot::store(Object value) const {
*location() = CompressTagged(value.ptr());
template <typename CompressionScheme>
void OffHeapCompressedObjectSlot<CompressionScheme>::store(Object value) const {
*TSlotBase::location() = CompressionScheme::CompressTagged(value.ptr());
}
Object OffHeapCompressedObjectSlot::Relaxed_Load(
template <typename CompressionScheme>
Object OffHeapCompressedObjectSlot<CompressionScheme>::Relaxed_Load(
PtrComprCageBase cage_base) const {
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location());
return Object(DecompressTaggedAny(cage_base, value));
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(TSlotBase::location());
return Object(CompressionScheme::DecompressTaggedAny(cage_base, value));
}
Object OffHeapCompressedObjectSlot::Acquire_Load(
template <typename CompressionScheme>
Object OffHeapCompressedObjectSlot<CompressionScheme>::Acquire_Load(
PtrComprCageBase cage_base) const {
AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location());
return Object(DecompressTaggedAny(cage_base, value));
AtomicTagged_t value = AsAtomicTagged::Acquire_Load(TSlotBase::location());
return Object(CompressionScheme::DecompressTaggedAny(cage_base, value));
}
void OffHeapCompressedObjectSlot::Relaxed_Store(Object value) const {
Tagged_t ptr = CompressTagged(value.ptr());
AsAtomicTagged::Relaxed_Store(location(), ptr);
template <typename CompressionScheme>
void OffHeapCompressedObjectSlot<CompressionScheme>::Relaxed_Store(
Object value) const {
Tagged_t ptr = CompressionScheme::CompressTagged(value.ptr());
AsAtomicTagged::Relaxed_Store(TSlotBase::location(), ptr);
}
void OffHeapCompressedObjectSlot::Release_Store(Object value) const {
Tagged_t ptr = CompressTagged(value.ptr());
AsAtomicTagged::Release_Store(location(), ptr);
template <typename CompressionScheme>
void OffHeapCompressedObjectSlot<CompressionScheme>::Release_Store(
Object value) const {
Tagged_t ptr = CompressionScheme::CompressTagged(value.ptr());
AsAtomicTagged::Release_Store(TSlotBase::location(), ptr);
}
void OffHeapCompressedObjectSlot::Release_CompareAndSwap(Object old,
Object target) const {
Tagged_t old_ptr = CompressTagged(old.ptr());
Tagged_t target_ptr = CompressTagged(target.ptr());
AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr);
template <typename CompressionScheme>
void OffHeapCompressedObjectSlot<CompressionScheme>::Release_CompareAndSwap(
Object old, Object target) const {
Tagged_t old_ptr = CompressionScheme::CompressTagged(old.ptr());
Tagged_t target_ptr = CompressionScheme::CompressTagged(target.ptr());
AsAtomicTagged::Release_CompareAndSwap(TSlotBase::location(), old_ptr,
target_ptr);
}
} // namespace internal
} // namespace v8
} // namespace v8::internal
#endif // V8_COMPRESS_POINTERS
......
......@@ -8,16 +8,19 @@
#include "include/v8config.h"
#include "src/objects/slots.h"
namespace v8 {
namespace internal {
namespace v8::internal {
#ifdef V8_COMPRESS_POINTERS
class V8HeapCompressionScheme;
// A CompressedObjectSlot instance describes a kTaggedSize-sized field ("slot")
// holding a compressed tagged pointer (smi or heap object).
// Its address() is the address of the slot.
// The slot's contents can be read and written using operator* and store().
class CompressedObjectSlot : public SlotBase<CompressedObjectSlot, Tagged_t> {
public:
using TCompressionScheme = V8HeapCompressionScheme;
using TObject = Object;
using THeapObjectSlot = CompressedHeapObjectSlot;
......@@ -64,6 +67,7 @@ class CompressedObjectSlot : public SlotBase<CompressedObjectSlot, Tagged_t> {
class CompressedMaybeObjectSlot
: public SlotBase<CompressedMaybeObjectSlot, Tagged_t> {
public:
using TCompressionScheme = V8HeapCompressionScheme;
using TObject = MaybeObject;
using THeapObjectSlot = CompressedHeapObjectSlot;
......@@ -100,6 +104,8 @@ class CompressedMaybeObjectSlot
class CompressedHeapObjectSlot
: public SlotBase<CompressedHeapObjectSlot, Tagged_t> {
public:
using TCompressionScheme = V8HeapCompressionScheme;
CompressedHeapObjectSlot() : SlotBase(kNullAddress) {}
explicit CompressedHeapObjectSlot(Address ptr) : SlotBase(ptr) {}
explicit CompressedHeapObjectSlot(Object* ptr)
......@@ -123,18 +129,23 @@ class CompressedHeapObjectSlot
// and so does not provide an operator* with implicit Isolate* calculation.
// Its address() is the address of the slot.
// The slot's contents can be read and written using load() and store().
template <typename CompressionScheme>
class OffHeapCompressedObjectSlot
: public SlotBase<OffHeapCompressedObjectSlot, Tagged_t> {
: public SlotBase<OffHeapCompressedObjectSlot<CompressionScheme>,
Tagged_t> {
public:
using TSlotBase =
SlotBase<OffHeapCompressedObjectSlot<CompressionScheme>, Tagged_t>;
using TCompressionScheme = CompressionScheme;
using TObject = Object;
using THeapObjectSlot = OffHeapCompressedObjectSlot;
using THeapObjectSlot = OffHeapCompressedObjectSlot<CompressionScheme>;
static constexpr bool kCanBeWeak = false;
OffHeapCompressedObjectSlot() : SlotBase(kNullAddress) {}
explicit OffHeapCompressedObjectSlot(Address ptr) : SlotBase(ptr) {}
OffHeapCompressedObjectSlot() : TSlotBase(kNullAddress) {}
explicit OffHeapCompressedObjectSlot(Address ptr) : TSlotBase(ptr) {}
explicit OffHeapCompressedObjectSlot(const uint32_t* ptr)
: SlotBase(reinterpret_cast<Address>(ptr)) {}
: TSlotBase(reinterpret_cast<Address>(ptr)) {}
inline Object load(PtrComprCageBase cage_base) const;
inline void store(Object value) const;
......@@ -148,7 +159,6 @@ class OffHeapCompressedObjectSlot
#endif // V8_COMPRESS_POINTERS
} // namespace internal
} // namespace v8
} // namespace v8::internal
#endif // V8_OBJECTS_COMPRESSED_SLOTS_H_
......@@ -479,8 +479,8 @@ void SortIndices(Isolate* isolate, Handle<FixedArray> indices,
AtomicSlot end(start + sort_size);
std::sort(start, end, [isolate](Tagged_t elementA, Tagged_t elementB) {
#ifdef V8_COMPRESS_POINTERS
Object a(DecompressTaggedAny(isolate, elementA));
Object b(DecompressTaggedAny(isolate, elementB));
Object a(V8HeapCompressionScheme::DecompressTaggedAny(isolate, elementA));
Object b(V8HeapCompressionScheme::DecompressTaggedAny(isolate, elementB));
#else
Object a(elementA);
Object b(elementB);
......
......@@ -84,8 +84,8 @@ HeapObjectReference HeapObjectReference::ClearedValue(
#ifdef V8_COMPRESS_POINTERS
// This is necessary to make pointer decompression computation also
// suitable for cleared weak references.
Address raw_value =
DecompressTaggedPointer(cage_base, kClearedWeakHeapObjectLower32);
Address raw_value = V8HeapCompressionScheme::DecompressTaggedPointer(
cage_base, kClearedWeakHeapObjectLower32);
#else
Address raw_value = kClearedWeakHeapObjectLower32;
#endif
......
......@@ -36,7 +36,7 @@ class MaybeObject : public TaggedImpl<HeapObjectReferenceType::WEAK, Address> {
#endif
private:
template <typename TFieldType, int kFieldOffset>
template <typename TFieldType, int kFieldOffset, typename CompressionScheme>
friend class TaggedField;
};
......
......@@ -18,14 +18,14 @@
// Since this changes visibility, it should always be last in a class
// definition.
#define OBJECT_CONSTRUCTORS(Type, ...) \
public: \
constexpr Type() : __VA_ARGS__() {} \
\
protected: \
template <typename TFieldType, int kFieldOffset> \
friend class TaggedField; \
\
#define OBJECT_CONSTRUCTORS(Type, ...) \
public: \
constexpr Type() : __VA_ARGS__() {} \
\
protected: \
template <typename TFieldType, int kFieldOffset, typename CompressionScheme> \
friend class TaggedField; \
\
explicit inline Type(Address ptr)
#define OBJECT_CONSTRUCTORS_IMPL(Type, Super) \
......@@ -698,15 +698,15 @@ static_assert(sizeof(unsigned) == sizeof(uint32_t),
set(IndexForEntry(i) + k##name##Offset, value); \
}
#define TQ_OBJECT_CONSTRUCTORS(Type) \
public: \
constexpr Type() = default; \
\
protected: \
template <typename TFieldType, int kFieldOffset> \
friend class TaggedField; \
\
inline explicit Type(Address ptr); \
#define TQ_OBJECT_CONSTRUCTORS(Type) \
public: \
constexpr Type() = default; \
\
protected: \
template <typename TFieldType, int kFieldOffset, typename CompressionScheme> \
friend class TaggedField; \
\
inline explicit Type(Address ptr); \
friend class TorqueGenerated##Type<Type, Super>;
#define TQ_OBJECT_CONSTRUCTORS_IMPL(Type) \
......
......@@ -733,14 +733,19 @@ HeapObject MapWord::ToForwardingAddress() {
HeapObject MapWord::ToForwardingAddress(PtrComprCageBase host_cage_base) {
DCHECK(IsForwardingAddress());
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// Recompress value_ using proper host_cage_base since the map word
// has the upper 32 bits that correspond to the main cage base value.
Address value =
DecompressTaggedPointer(host_cage_base, CompressTagged(value_));
return HeapObject::FromAddress(value);
}
#ifdef V8_EXTERNAL_CODE_SPACE
// Recompress value_ using proper host_cage_base and compression scheme
// since the map word is decompressed using the default compression scheme
// in an assumption it'll contain Map pointer.
// TODO(v8:11880): this code must be updated once a different scheme is used
// for external code fields.
Tagged_t compressed = V8HeapCompressionScheme::CompressTagged(value_);
Address value = V8HeapCompressionScheme::DecompressTaggedPointer(
host_cage_base, compressed);
return HeapObject::FromAddress(value);
#else
return HeapObject::FromAddress(value_);
#endif // V8_EXTERNAL_CODE_SPACE
}
#ifdef VERIFY_HEAP
......
......@@ -904,7 +904,7 @@ class MapWord {
private:
// HeapObject calls the private constructor and directly reads the value.
friend class HeapObject;
template <typename TFieldType, int kFieldOffset>
template <typename TFieldType, int kFieldOffset, typename CompressionScheme>
friend class TaggedField;
explicit MapWord(Address value) : value_(value) {}
......
......@@ -272,7 +272,7 @@ inline void CopyTagged(Address dst, const Address src, size_t num_tagged) {
// Sets |counter| number of kTaggedSize-sized values starting at |start| slot.
inline void MemsetTagged(Tagged_t* start, Object value, size_t counter) {
#ifdef V8_COMPRESS_POINTERS
Tagged_t raw_value = CompressTagged(value.ptr());
Tagged_t raw_value = V8HeapCompressionScheme::CompressTagged(value.ptr());
MemsetUint32(start, raw_value, counter);
#else
Address raw_value = value.ptr();
......
This diff is collapsed.
......@@ -6,19 +6,19 @@
#define V8_OBJECTS_TAGGED_FIELD_H_
#include "src/common/globals.h"
#include "src/common/ptr-compr.h"
#include "src/objects/objects.h"
#include "src/objects/tagged-value.h"
namespace v8 {
namespace internal {
namespace v8::internal {
// This helper static class represents a tagged field of type T at offset
// kFieldOffset inside some host HeapObject.
// For full-pointer mode this type adds no overhead but when pointer
// compression is enabled such class allows us to use proper decompression
// function depending on the field type.
template <typename T, int kFieldOffset = 0>
template <typename T, int kFieldOffset = 0,
typename CompressionScheme = V8HeapCompressionScheme>
class TaggedField : public AllStatic {
public:
static_assert(std::is_base_of<Object, T>::value ||
......@@ -91,7 +91,6 @@ class TaggedField : public AllStatic {
static inline Tagged_t full_to_tagged(Address value);
};
} // namespace internal
} // namespace v8
} // namespace v8::internal
#endif // V8_OBJECTS_TAGGED_FIELD_H_
......@@ -34,7 +34,8 @@ Smi TaggedImpl<kRefType, StorageType>::ToSmi() const {
return Smi(ptr_);
}
// Implementation for compressed pointers.
return Smi(DecompressTaggedSigned(static_cast<Tagged_t>(ptr_)));
return Smi(
CompressionScheme::DecompressTaggedSigned(static_cast<Tagged_t>(ptr_)));
}
//
......@@ -111,8 +112,9 @@ bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfStrong(
if (kIsFull) return GetHeapObjectIfStrong(result);
// Implementation for compressed pointers.
if (IsStrong()) {
*result = HeapObject::cast(
Object(DecompressTaggedPointer(isolate, static_cast<Tagged_t>(ptr_))));
*result =
HeapObject::cast(Object(CompressionScheme::DecompressTaggedPointer(
isolate, static_cast<Tagged_t>(ptr_))));
return true;
}
return false;
......@@ -136,8 +138,8 @@ HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeStrong(
if (kIsFull) return GetHeapObjectAssumeStrong();
// Implementation for compressed pointers.
DCHECK(IsStrong());
return HeapObject::cast(
Object(DecompressTaggedPointer(isolate, static_cast<Tagged_t>(ptr_))));
return HeapObject::cast(Object(CompressionScheme::DecompressTaggedPointer(
isolate, static_cast<Tagged_t>(ptr_))));
}
//
......@@ -222,12 +224,12 @@ HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObject(
DCHECK(!IsSmi());
if (kCanBeWeak) {
DCHECK(!IsCleared());
return HeapObject::cast(Object(DecompressTaggedPointer(
return HeapObject::cast(Object(CompressionScheme::DecompressTaggedPointer(
isolate, static_cast<Tagged_t>(ptr_) & ~kWeakHeapObjectMask)));
} else {
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
return HeapObject::cast(
Object(DecompressTaggedPointer(isolate, static_cast<Tagged_t>(ptr_))));
return HeapObject::cast(Object(CompressionScheme::DecompressTaggedPointer(
isolate, static_cast<Tagged_t>(ptr_))));
}
}
......@@ -250,7 +252,8 @@ Object TaggedImpl<kRefType, StorageType>::GetHeapObjectOrSmi(
if (kIsFull) return GetHeapObjectOrSmi();
// Implementation for compressed pointers.
if (IsSmi()) {
return Object(DecompressTaggedSigned(static_cast<Tagged_t>(ptr_)));
return Object(
CompressionScheme::DecompressTaggedSigned(static_cast<Tagged_t>(ptr_)));
}
return GetHeapObject(isolate);
}
......
......@@ -30,6 +30,10 @@ bool V8_EXPORT_PRIVATE CheckObjectComparisonAllowed(Address a, Address b);
template <HeapObjectReferenceType kRefType, typename StorageType>
class TaggedImpl {
public:
// Compressed TaggedImpl are never used for external Code pointers, so
// we can use this shorter alias for calling decompression functions.
using CompressionScheme = V8HeapCompressionScheme;
static_assert(std::is_same<StorageType, Address>::value ||
std::is_same<StorageType, Tagged_t>::value,
"StorageType must be either Address or Tagged_t");
......
......@@ -21,7 +21,7 @@ namespace internal {
inline StrongTaggedValue::StrongTaggedValue(Object o)
:
#ifdef V8_COMPRESS_POINTERS
TaggedImpl(CompressTagged(o.ptr()))
TaggedImpl(CompressionScheme::CompressTagged(o.ptr()))
#else
TaggedImpl(o.ptr())
#endif
......@@ -30,7 +30,7 @@ inline StrongTaggedValue::StrongTaggedValue(Object o)
Object StrongTaggedValue::ToObject(Isolate* isolate, StrongTaggedValue object) {
#ifdef V8_COMPRESS_POINTERS
return Object(DecompressTaggedAny(isolate, object.ptr()));
return Object(CompressionScheme::DecompressTaggedAny(isolate, object.ptr()));
#else
return Object(object.ptr());
#endif
......@@ -39,7 +39,7 @@ Object StrongTaggedValue::ToObject(Isolate* isolate, StrongTaggedValue object) {
inline TaggedValue::TaggedValue(MaybeObject o)
:
#ifdef V8_COMPRESS_POINTERS
TaggedImpl(CompressTagged(o.ptr()))
TaggedImpl(CompressionScheme::CompressTagged(o.ptr()))
#else
TaggedImpl(o.ptr())
#endif
......@@ -48,7 +48,8 @@ inline TaggedValue::TaggedValue(MaybeObject o)
MaybeObject TaggedValue::ToMaybeObject(Isolate* isolate, TaggedValue object) {
#ifdef V8_COMPRESS_POINTERS
return MaybeObject(DecompressTaggedAny(isolate, object.ptr()));
return MaybeObject(
CompressionScheme::DecompressTaggedAny(isolate, object.ptr()));
#else
return MaybeObject(object.ptr());
#endif
......
......@@ -102,7 +102,8 @@ static void DumpKnownObject(FILE* out, i::Heap* heap, const char* space_name,
static void DumpSpaceFirstPageAddress(FILE* out, i::BaseSpace* space,
i::Address first_page) {
const char* name = space->name();
i::Tagged_t compressed = i::CompressTagged(first_page);
i::Tagged_t compressed =
i::V8HeapCompressionScheme::CompressTagged(first_page);
uintptr_t unsigned_compressed = static_cast<uint32_t>(compressed);
i::PrintF(out, " 0x%08" V8PRIxPTR ": \"%s\",\n", unsigned_compressed, name);
}
......
......@@ -23,8 +23,10 @@ bool IsPointerCompressed(uintptr_t address) {
uintptr_t EnsureDecompressed(uintptr_t address,
uintptr_t any_uncompressed_ptr) {
if (!COMPRESS_POINTERS_BOOL || !IsPointerCompressed(address)) return address;
return i::DecompressTaggedAny(any_uncompressed_ptr,
static_cast<i::Tagged_t>(address));
// TODO(v8:11880): ExternalCodeCompressionScheme might be needed here for
// decompressing Code pointers from external code space.
return i::V8HeapCompressionScheme::DecompressTaggedAny(
any_uncompressed_ptr, static_cast<i::Tagged_t>(address));
}
d::PropertyKind GetArrayKind(d::MemoryAccessResult mem_result) {
......
......@@ -64,13 +64,16 @@ if (hasattr(v8heapconst, 'HEAP_FIRST_PAGES')): # Only exists in ptr-compr build
out = out + ' if (heap_addresses->any_heap_pointer == 0) {\n'
out = out + ' heap_addresses->any_heap_pointer = any_uncompressed_ptr;\n'
out = out + ' }\n'
# If we ever try to apply this to CodeSpace we might need to use
# ExternalCodeCompressionScheme instead of V8HeapCompressionScheme for
# decompressing external code pointers below.
expected_spaces = set(['map_space', 'read_only_space', 'old_space'])
for offset, space_name in v8heapconst.HEAP_FIRST_PAGES.items():
if (space_name in expected_spaces):
out = out + ' if (heap_addresses->' + space_name + '_first_page == 0) {\n'
out = out + ' heap_addresses->' + space_name + \
'_first_page = i::DecompressTaggedPointer(any_uncompressed_ptr, ' + \
str(offset) + ');\n'
'_first_page = i::V8HeapCompressionScheme::DecompressTaggedPointer(' + \
'any_uncompressed_ptr, ' + str(offset) + ');\n'
out = out + ' }\n'
out = out + '}\n'
......
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