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
18namespace 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.
24template <intptr_t word_size, intptr_t word_size_log2>
25struct 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
44using HostObjectAlignment = ObjectAlignment<kWordSize, kWordSizeLog2>;
45
46static constexpr intptr_t kNewObjectAlignmentOffset =
47 HostObjectAlignment::kNewObjectAlignmentOffset;
48static constexpr intptr_t kOldObjectAlignmentOffset =
49 HostObjectAlignment::kOldObjectAlignmentOffset;
50static constexpr intptr_t kNewObjectBitPosition =
51 HostObjectAlignment::kNewObjectBitPosition;
52static constexpr intptr_t kObjectAlignment =
53 HostObjectAlignment::kObjectAlignment;
54static constexpr intptr_t kObjectAlignmentLog2 =
55 HostObjectAlignment::kObjectAlignmentLog2;
56static constexpr intptr_t kObjectAlignmentMask =
57 HostObjectAlignment::kObjectAlignmentMask;
58static constexpr intptr_t kBoolValueBitPosition =
59 HostObjectAlignment::kBoolValueBitPosition;
60static constexpr intptr_t kBoolValueMask = HostObjectAlignment::kBoolValueMask;
61static constexpr intptr_t kTrueOffsetFromNull =
62 HostObjectAlignment::kTrueOffsetFromNull;
63static constexpr intptr_t kFalseOffsetFromNull =
64 HostObjectAlignment::kFalseOffsetFromNull;
65
66// The largest value of kObjectAlignment across all configurations.
67static constexpr intptr_t kMaxObjectAlignment = 16;
68COMPILE_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.
79enum {
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