• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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_ZONE_ZONE_COMPRESSION_H_
6 #define V8_ZONE_ZONE_COMPRESSION_H_
7 
8 #include "src/base/bits.h"
9 #include "src/common/globals.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // This struct provides untyped implementation of zone compression scheme.
15 //
16 // The compression scheme relies on the following assumptions:
17 // 1) all zones containing compressed pointers are allocated in the same "zone
18 //    cage" of kReservationSize size and kReservationAlignment-aligned.
19 //    Attempt to compress pointer to an object stored outside of the "cage"
20 //    will silently succeed but it will later produce wrong result after
21 //    decompression.
22 // 2) compression is just a masking away bits above kReservationAlignment.
23 // 3) nullptr is compressed to 0, thus there must be no valid objects allocated
24 //    at the beginning of the "zone cage". Ideally, the first page of the cage
25 //    should be unmapped in order to catch attempts to use decompressed nullptr
26 //    value earlier.
27 // 4) decompression requires "zone cage" address value, which is computed on
28 //    the fly from an arbitrary address pointing somewhere to the "zone cage".
29 // 5) decompression requires special casing for nullptr.
30 struct ZoneCompression {
31   static const size_t kReservationSize = size_t{2} * GB;
32   static const size_t kReservationAlignment =
33       COMPRESS_ZONES_BOOL ? size_t{4} * GB : 1;
34 
35   static_assert(base::bits::IsPowerOfTwo(kReservationAlignment),
36                 "Bad zone alignment");
37 
38   static const size_t kOffsetMask = kReservationAlignment - 1;
39 
base_ofZoneCompression40   inline static Address base_of(const void* zone_pointer) {
41     return reinterpret_cast<Address>(zone_pointer) & ~kOffsetMask;
42   }
43 
CheckSameBaseZoneCompression44   inline static bool CheckSameBase(const void* p1, const void* p2) {
45     if (p1 == nullptr || p2 == nullptr) return true;
46     CHECK_EQ(base_of(p1), base_of(p2));
47     return true;
48   }
49 
CompressZoneCompression50   inline static uint32_t Compress(const void* value) {
51     Address raw_value = reinterpret_cast<Address>(value);
52     uint32_t compressed_value = static_cast<uint32_t>(raw_value & kOffsetMask);
53     DCHECK_IMPLIES(compressed_value == 0, value == nullptr);
54     DCHECK_LT(compressed_value, kReservationSize);
55     return compressed_value;
56   }
57 
DecompressZoneCompression58   inline static Address Decompress(const void* zone_pointer,
59                                    uint32_t compressed_value) {
60     if (compressed_value == 0) return kNullAddress;
61     return base_of(zone_pointer) + compressed_value;
62   }
63 };
64 
65 }  // namespace internal
66 }  // namespace v8
67 
68 #endif  // V8_ZONE_ZONE_COMPRESSION_H_
69