1 | // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
---|---|
2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RUNTIME_VM_POINTER_TAGGING_H_ |
6 | #define RUNTIME_VM_POINTER_TAGGING_H_ |
7 | |
8 | #include "platform/assert.h" |
9 | #include "platform/globals.h" |
10 | |
11 | // This header defines constants associated with pointer tagging: |
12 | // |
13 | // * which bits determine whether or not this is a Smi value or a heap |
14 | // pointer; |
15 | // * which bits determine whether this is a pointer into a new or an old |
16 | // space. |
17 | |
18 | namespace dart { |
19 | |
20 | // Dart VM aligns all objects by 2 words in in the old space and misaligns them |
21 | // in new space. This allows to distinguish new and old pointers by their bits. |
22 | // |
23 | // Note: these bits depend on the word size. |
24 | template <intptr_t word_size, intptr_t word_size_log2> |
25 | struct ObjectAlignment { |
26 | // Alignment offsets are used to determine object age. |
27 | static constexpr intptr_t kNewObjectAlignmentOffset = word_size; |
28 | static constexpr intptr_t kOldObjectAlignmentOffset = 0; |
29 | static constexpr intptr_t kNewObjectBitPosition = word_size_log2; |
30 | |
31 | // Object sizes are aligned to kObjectAlignment. |
32 | static constexpr intptr_t kObjectAlignment = 2 * word_size; |
33 | static constexpr intptr_t kObjectAlignmentLog2 = word_size_log2 + 1; |
34 | static constexpr intptr_t kObjectAlignmentMask = kObjectAlignment - 1; |
35 | |
36 | // Discriminate between true and false based on the alignment bit. |
37 | static constexpr intptr_t kBoolValueBitPosition = kObjectAlignmentLog2; |
38 | static constexpr intptr_t kBoolValueMask = 1 << kBoolValueBitPosition; |
39 | |
40 | static constexpr intptr_t kTrueOffsetFromNull = kObjectAlignment * 2; |
41 | static constexpr intptr_t kFalseOffsetFromNull = kObjectAlignment * 3; |
42 | }; |
43 | |
44 | using HostObjectAlignment = ObjectAlignment<kWordSize, kWordSizeLog2>; |
45 | |
46 | static constexpr intptr_t kNewObjectAlignmentOffset = |
47 | HostObjectAlignment::kNewObjectAlignmentOffset; |
48 | static constexpr intptr_t kOldObjectAlignmentOffset = |
49 | HostObjectAlignment::kOldObjectAlignmentOffset; |
50 | static constexpr intptr_t kNewObjectBitPosition = |
51 | HostObjectAlignment::kNewObjectBitPosition; |
52 | static constexpr intptr_t kObjectAlignment = |
53 | HostObjectAlignment::kObjectAlignment; |
54 | static constexpr intptr_t kObjectAlignmentLog2 = |
55 | HostObjectAlignment::kObjectAlignmentLog2; |
56 | static constexpr intptr_t kObjectAlignmentMask = |
57 | HostObjectAlignment::kObjectAlignmentMask; |
58 | static constexpr intptr_t kBoolValueBitPosition = |
59 | HostObjectAlignment::kBoolValueBitPosition; |
60 | static constexpr intptr_t kBoolValueMask = HostObjectAlignment::kBoolValueMask; |
61 | static constexpr intptr_t kTrueOffsetFromNull = |
62 | HostObjectAlignment::kTrueOffsetFromNull; |
63 | static constexpr intptr_t kFalseOffsetFromNull = |
64 | HostObjectAlignment::kFalseOffsetFromNull; |
65 | |
66 | // The largest value of kObjectAlignment across all configurations. |
67 | static constexpr intptr_t kMaxObjectAlignment = 16; |
68 | COMPILE_ASSERT(kMaxObjectAlignment >= kObjectAlignment); |
69 | |
70 | // On all targets heap pointers are tagged by set least significant bit. |
71 | // |
72 | // To recover address of the actual heap object kHeapObjectTag needs to be |
73 | // subtracted from the tagged pointer value. |
74 | // |
75 | // Smi-s (small integers) have least significant bit cleared. |
76 | // |
77 | // To recover the integer value tagged pointer value needs to be shifted |
78 | // right by kSmiTagShift. |
79 | enum { |
80 | kSmiTag = 0, |
81 | kHeapObjectTag = 1, |
82 | kSmiTagSize = 1, |
83 | kSmiTagMask = 1, |
84 | kSmiTagShift = 1, |
85 | }; |
86 | |
87 | } // namespace dart |
88 | |
89 | #endif // RUNTIME_VM_POINTER_TAGGING_H_ |
90 |