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 | |
12 | namespace v8 { |
13 | namespace internal { |
14 | |
15 | #if V8_TARGET_ARCH_64_BIT |
16 | // Compresses full-pointer representation of a tagged value to on-heap |
17 | // representation. |
18 | V8_INLINE Tagged_t CompressTagged(Address tagged) { |
19 | return static_cast<Tagged_t>(static_cast<uint32_t>(tagged)); |
20 | } |
21 | |
22 | enum class OnHeapAddressKind { |
23 | kAnyOnHeapAddress, |
24 | kIsolateRoot, |
25 | }; |
26 | |
27 | // Calculates isolate root value from any on-heap address. |
28 | template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress> |
29 | V8_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. |
37 | template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress> |
38 | V8_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. |
48 | template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress> |
49 | V8_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 | |
70 | STATIC_ASSERT(kPtrComprHeapReservationSize == |
71 | Internals::kPtrComprHeapReservationSize); |
72 | STATIC_ASSERT(kPtrComprIsolateRootBias == Internals::kPtrComprIsolateRootBias); |
73 | STATIC_ASSERT(kPtrComprIsolateRootAlignment == |
74 | Internals::kPtrComprIsolateRootAlignment); |
75 | |
76 | #endif // V8_COMPRESS_POINTERS |
77 | |
78 | #else |
79 | |
80 | V8_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 |