1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_RUNTIME_RUNTIME_GLOBALS_H_
#define ART_RUNTIME_RUNTIME_GLOBALS_H_
#include <android-base/logging.h>
#include "base/bit_utils.h"
#include "base/globals.h"
#include "base/macros.h"
namespace art HIDDEN {
// Size of Dex virtual registers.
static constexpr size_t kVRegSize = 4;
#ifdef ART_PAGE_SIZE_AGNOSTIC
// Accessor for the page size constant local to the libart.
//
// The value is only available after the Runtime initialization started - to ensure there is no
// static initialization order issues where initialization of other values is dependent on the page
// size. In those cases, GetPageSizeSlow() should be used.
struct PageSize {
PageSize()
: is_initialized_(true), is_access_allowed_(false) {}
constexpr ALWAYS_INLINE operator size_t() const {
DCHECK(is_initialized_ && is_access_allowed_);
return value_;
}
private:
friend class Runtime;
void AllowAccess() {
SetAccessAllowed(true);
}
void DisallowAccess() {
SetAccessAllowed(false);
}
void SetAccessAllowed(bool is_allowed) {
// is_initialized_ is set to true when the page size value is initialized during the static
// initialization. This CHECK is added as an auxiliary way to help catching incorrect use of
// the method.
CHECK(is_initialized_);
is_access_allowed_ = is_allowed;
}
// The page size value.
//
// It is declared as a static constant value to ensure compiler recognizes that it doesn't change
// once it is initialized.
//
// It is declared as "hidden" i.e. local to the libart, to ensure:
// - no other library can access it, so no static initialization dependency from other libraries
// is possible;
// - the variable can be addressed via offset from the program counter, instead of the global
// offset table which would've added another level of indirection.
static const size_t value_ ALWAYS_HIDDEN;
// There are two flags in the accessor which help to ensure the value is accessed only after the
// static initialization is complete.
//
// is_initialized_ is used to assert the page size value is indeed initialized when the value
// access is allowed and when it is accessed.
//
// is_access_allowed_ is used to ensure the value is only accessed after Runtime initialization
// started.
const bool is_initialized_;
bool is_access_allowed_;
};
// gPageSize should only be used within libart. For most of the other cases MemMap::GetPageSize()
// or GetPageSizeSlow() should be used. See also the comment for GetPageSizeSlow().
extern PageSize gPageSize ALWAYS_HIDDEN;
#else
static constexpr size_t gPageSize = kMinPageSize;
#endif
// In the page-size-agnostic configuration the compiler may not recognise gPageSize as a
// power-of-two value, and may therefore miss opportunities to optimize: divisions via a
// right-shift, modulo via a bitwise-AND.
// Here, define two functions which use the optimized implementations explicitly, which should be
// used when dividing by or applying modulo of the page size. For simplificty, the same functions
// are used under both configurations, as they optimize the page-size-agnostic configuration while
// only replicating what the compiler already does on the non-page-size-agnostic configuration.
static constexpr ALWAYS_INLINE size_t DivideByPageSize(size_t num) {
return (num >> WhichPowerOf2(static_cast<size_t>(gPageSize)));
}
static constexpr ALWAYS_INLINE size_t ModuloPageSize(size_t num) {
return (num & (gPageSize-1));
}
// Returns whether the given memory offset can be used for generating
// an implicit null check.
static inline bool CanDoImplicitNullCheckOn(uintptr_t offset) {
#ifdef ART_USE_RESTRICTED_MODE
UNUSED(offset);
return false;
#else
return offset < gPageSize;
#endif // ART_USE_RESTRICTED_MODE
}
// Required object alignment
static constexpr size_t kObjectAlignmentShift = 3;
static constexpr size_t kObjectAlignment = 1u << kObjectAlignmentShift;
// Garbage collector constants.
static constexpr bool kMovingCollector = true;
static constexpr bool kMarkCompactSupport = false && kMovingCollector;
// True if we allow moving classes.
static constexpr bool kMovingClasses = !kMarkCompactSupport;
// When using the Concurrent Collectors (CC or CMC), if
// `ART_USE_GENERATIONAL_GC` is true, enable generational collection by default,
// i.e. use sticky-bit CC/CMC for minor collections and (full) CC/CMC for major
// collections.
// This default value can be overridden with the runtime option
// `-Xgc:[no]generational_gc`.
//
// TODO(b/67628039): Consider either:
// - renaming this to a better descriptive name (e.g.
// `ART_USE_GENERATIONAL_GC_BY_DEFAULT`); or
// - removing `ART_USE_GENERATIONAL_GC` and having a fixed default value.
// Any of these changes will require adjusting users of this preprocessor
// directive and the corresponding build system environment variable (e.g. in
// ART's continuous testing).
#ifdef ART_USE_GENERATIONAL_GC
static constexpr bool kEnableGenerationalGCByDefault = true;
#else
static constexpr bool kEnableGenerationalGCByDefault = false;
#endif
// If true, enable the tlab allocator by default.
#ifdef ART_USE_TLAB
static constexpr bool kUseTlab = true;
#else
static constexpr bool kUseTlab = false;
#endif
// Kinds of tracing clocks.
enum class TraceClockSource {
kThreadCpu,
kWall,
kDual, // Both wall and thread CPU clocks.
};
#if defined(__linux__)
static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kDual;
#else
static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kWall;
#endif
static constexpr bool kDefaultMustRelocate = true;
// Size of a heap reference.
static constexpr size_t kHeapReferenceSize = sizeof(uint32_t);
} // namespace art
#endif // ART_RUNTIME_RUNTIME_GLOBALS_H_
|