1// Copyright 2018 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 V8_PTR_COMPR_INL_H_
6#define V8_PTR_COMPR_INL_H_
7
8
9#include "include/v8-internal.h"
10#include "src/ptr-compr.h"
11
12namespace v8 {
13namespace internal {
14
15#if V8_TARGET_ARCH_64_BIT
16// Compresses full-pointer representation of a tagged value to on-heap
17// representation.
18V8_INLINE Tagged_t CompressTagged(Address tagged) {
19 return static_cast<Tagged_t>(static_cast<uint32_t>(tagged));
20}
21
22enum class OnHeapAddressKind {
23 kAnyOnHeapAddress,
24 kIsolateRoot,
25};
26
27// Calculates isolate root value from any on-heap address.
28template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress>
29V8_INLINE Address GetRootFromOnHeapAddress(Address on_heap_addr) {
30 if (kAddressKind == OnHeapAddressKind::kIsolateRoot) return on_heap_addr;
31 return RoundDown(on_heap_addr + kPtrComprIsolateRootBias,
32 kPtrComprIsolateRootAlignment);
33}
34
35// Decompresses weak or strong heap object pointer or forwarding pointer,
36// preserving both weak- and smi- tags.
37template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress>
38V8_INLINE Address DecompressTaggedPointer(Address on_heap_addr,
39 Tagged_t raw_value) {
40 // Current compression scheme requires |raw_value| to be sign-extended
41 // from int32_t to intptr_t.
42 intptr_t value = static_cast<intptr_t>(static_cast<int32_t>(raw_value));
43 Address root = GetRootFromOnHeapAddress<kAddressKind>(on_heap_addr);
44 return root + static_cast<Address>(value);
45}
46
47// Decompresses any tagged value, preserving both weak- and smi- tags.
48template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress>
49V8_INLINE Address DecompressTaggedAny(Address on_heap_addr,
50 Tagged_t raw_value) {
51 // Current compression scheme requires |raw_value| to be sign-extended
52 // from int32_t to intptr_t.
53 intptr_t value = static_cast<intptr_t>(static_cast<int32_t>(raw_value));
54 if (kUseBranchlessPtrDecompression) {
55 // |root_mask| is 0 if the |value| was a smi or -1 otherwise.
56 Address root_mask = static_cast<Address>(-(value & kSmiTagMask));
57 Address root_or_zero =
58 root_mask & GetRootFromOnHeapAddress<kAddressKind>(on_heap_addr);
59 return root_or_zero + static_cast<Address>(value);
60 } else {
61 return HAS_SMI_TAG(value)
62 ? static_cast<Address>(value)
63 : (GetRootFromOnHeapAddress<kAddressKind>(on_heap_addr) +
64 static_cast<Address>(value));
65 }
66}
67
68#ifdef V8_COMPRESS_POINTERS
69
70STATIC_ASSERT(kPtrComprHeapReservationSize ==
71 Internals::kPtrComprHeapReservationSize);
72STATIC_ASSERT(kPtrComprIsolateRootBias == Internals::kPtrComprIsolateRootBias);
73STATIC_ASSERT(kPtrComprIsolateRootAlignment ==
74 Internals::kPtrComprIsolateRootAlignment);
75
76#endif // V8_COMPRESS_POINTERS
77
78#else
79
80V8_INLINE Tagged_t CompressTagged(Address tagged) { UNREACHABLE(); }
81
82#endif // V8_TARGET_ARCH_64_BIT
83} // namespace internal
84} // namespace v8
85
86#endif // V8_PTR_COMPR_INL_H_
87