8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_CODE_AOTCODECACHE_HPP
26 #define SHARE_CODE_AOTCODECACHE_HPP
27
28 #include "runtime/stubInfo.hpp"
29
30 /*
31 * AOT Code Cache collects code from Code Cache and corresponding metadata
32 * during application training run.
33 * In following "production" runs this code and data can be loaded into
34 * Code Cache skipping its generation.
35 */
36
37 class CodeBuffer;
38 class RelocIterator;
39 class AOTCodeCache;
40 class AdapterBlob;
41 class ExceptionBlob;
42 class ImmutableOopMapSet;
43 class AsmRemarks;
44 class DbgStrings;
45
46 enum class vmIntrinsicID : int;
47 enum CompLevel : signed char;
48
49 #define DO_AOTCODEENTRY_KIND(Fn) \
50 Fn(None) \
51 Fn(Adapter) \
52 Fn(SharedBlob) \
53 Fn(C1Blob) \
54 Fn(C2Blob) \
55
56 // Descriptor of AOT Code Cache's entry
57 class AOTCodeEntry {
58 public:
59 enum Kind : s1 {
60 #define DECL_KIND_ENUM(kind) kind,
61 DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
62 #undef DECL_KIND_ENUM
63 Kind_count
64 };
65
66 private:
67 AOTCodeEntry* _next;
68 Kind _kind;
69 uint _id; // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod
70 uint _offset; // Offset to entry
71 uint _size; // Entry size
72 uint _name_offset; // Code blob name
73 uint _name_size;
74 uint _blob_offset; // Start of code in cache
75 bool _has_oop_maps;
76 address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations
77
78 public:
79 AOTCodeEntry(Kind kind, uint id,
80 uint offset, uint size,
81 uint name_offset, uint name_size,
82 uint blob_offset, bool has_oop_maps,
83 address dumptime_content_start_addr) {
84 _next = nullptr;
85 _kind = kind;
86 _id = id;
87 _offset = offset;
88 _size = size;
89 _name_offset = name_offset;
90 _name_size = name_size;
91 _blob_offset = blob_offset;
92 _has_oop_maps = has_oop_maps;
93 _dumptime_content_start_addr = dumptime_content_start_addr;
94 }
95 void* operator new(size_t x, AOTCodeCache* cache);
96 // Delete is a NOP
97 void operator delete( void *ptr ) {}
98
99 AOTCodeEntry* next() const { return _next; }
100 void set_next(AOTCodeEntry* next) { _next = next; }
101
102 Kind kind() const { return _kind; }
103 uint id() const { return _id; }
104
105 uint offset() const { return _offset; }
106 void set_offset(uint off) { _offset = off; }
107
108 uint size() const { return _size; }
109 uint name_offset() const { return _name_offset; }
110 uint name_size() const { return _name_size; }
111 uint blob_offset() const { return _blob_offset; }
112 bool has_oop_maps() const { return _has_oop_maps; }
113 address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
114
115 static bool is_valid_entry_kind(Kind kind) { return kind > None && kind < Kind_count; }
116 static bool is_blob(Kind kind) { return kind == SharedBlob || kind == C1Blob || kind == C2Blob; }
117 static bool is_adapter(Kind kind) { return kind == Adapter; }
118 };
119
120 // Addresses of stubs, blobs and runtime finctions called from compiled code.
121 class AOTCodeAddressTable : public CHeapObj<mtCode> {
122 private:
123 address* _extrs_addr;
124 address* _stubs_addr;
125 address* _shared_blobs_addr;
126 address* _C1_blobs_addr;
127 uint _extrs_length;
128 uint _stubs_length;
129 uint _shared_blobs_length;
130 uint _C1_blobs_length;
131
132 bool _extrs_complete;
133 bool _early_stubs_complete;
134 bool _shared_blobs_complete;
135 bool _early_c1_complete;
136 bool _complete;
137
138 public:
139 AOTCodeAddressTable() :
140 _extrs_addr(nullptr),
141 _stubs_addr(nullptr),
142 _shared_blobs_addr(nullptr),
143 _C1_blobs_addr(nullptr),
144 _extrs_length(0),
145 _stubs_length(0),
146 _shared_blobs_length(0),
147 _C1_blobs_length(0),
148 _extrs_complete(false),
149 _early_stubs_complete(false),
150 _shared_blobs_complete(false),
151 _early_c1_complete(false),
152 _complete(false)
153 { }
154 ~AOTCodeAddressTable();
155 void init_extrs();
156 void init_early_stubs();
157 void init_shared_blobs();
158 void init_early_c1();
159 const char* add_C_string(const char* str);
160 int id_for_C_string(address str);
161 address address_for_C_string(int idx);
162 int id_for_address(address addr, RelocIterator iter, CodeBlob* code_blob);
163 address address_for_id(int id);
164 };
165
166 class AOTCodeCache : public CHeapObj<mtCode> {
167
168 // Classes used to describe AOT code cache.
169 protected:
170 class Config {
171 address _compressedOopBase;
172 uint _compressedOopShift;
173 uint _compressedKlassShift;
174 uint _contendedPaddingWidth;
175 uint _gc;
176 enum Flags {
177 none = 0,
178 debugVM = 1,
179 compressedOops = 2,
180 compressedClassPointers = 4,
181 useTLAB = 8,
182 systemClassAssertions = 16,
183 userClassAssertions = 32,
184 enableContendedPadding = 64,
185 restrictContendedPadding = 128
186 };
187 uint _flags;
188
189 public:
190 void record();
191 bool verify() const;
192 };
193
194 class Header : public CHeapObj<mtCode> {
195 private:
196 enum {
197 AOT_CODE_VERSION = 1
198 };
199 uint _version; // AOT code version (should match when reading code cache)
200 uint _cache_size; // cache size in bytes
201 uint _strings_count; // number of recorded C strings
202 uint _strings_offset; // offset to recorded C strings
203 uint _entries_count; // number of recorded entries
204 uint _entries_offset; // offset of AOTCodeEntry array describing entries
205 uint _adapters_count;
206 uint _shared_blobs_count;
207 uint _C1_blobs_count;
208 uint _C2_blobs_count;
209 Config _config;
210
211 public:
212 void init(uint cache_size,
213 uint strings_count, uint strings_offset,
214 uint entries_count, uint entries_offset,
215 uint adapters_count, uint shared_blobs_count,
216 uint C1_blobs_count, uint C2_blobs_count) {
217 _version = AOT_CODE_VERSION;
218 _cache_size = cache_size;
219 _strings_count = strings_count;
220 _strings_offset = strings_offset;
221 _entries_count = entries_count;
222 _entries_offset = entries_offset;
223 _adapters_count = adapters_count;
224 _shared_blobs_count = shared_blobs_count;
225 _C1_blobs_count = C1_blobs_count;
226 _C2_blobs_count = C2_blobs_count;
227 _config.record();
228 }
229
230
231 uint cache_size() const { return _cache_size; }
232 uint strings_count() const { return _strings_count; }
233 uint strings_offset() const { return _strings_offset; }
234 uint entries_count() const { return _entries_count; }
235 uint entries_offset() const { return _entries_offset; }
236 uint adapters_count() const { return _adapters_count; }
237 uint shared_blobs_count() const { return _shared_blobs_count; }
238 uint C1_blobs_count() const { return _C1_blobs_count; }
239 uint C2_blobs_count() const { return _C2_blobs_count; }
240
241 bool verify(uint load_size) const;
242 bool verify_config() const { // Called after Universe initialized
243 return _config.verify();
244 }
245 };
246
247 // Continue with AOTCodeCache class definition.
248 private:
249 Header* _load_header;
250 char* _load_buffer; // Aligned buffer for loading cached code
251 char* _store_buffer; // Aligned buffer for storing cached code
252 char* _C_store_buffer; // Original unaligned buffer
253
254 uint _write_position; // Position in _store_buffer
255 uint _load_size; // Used when reading cache
256 uint _store_size; // Used when writing cache
257 bool _for_use; // AOT cache is open for using AOT code
258 bool _for_dump; // AOT cache is open for dumping AOT code
259 bool _closing; // Closing cache file
260 bool _failed; // Failed read/write to/from cache (cache is broken?)
261 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
262
263 AOTCodeAddressTable* _table;
264
265 AOTCodeEntry* _load_entries; // Used when reading cache
266 uint* _search_entries; // sorted by ID table [id, index]
267 AOTCodeEntry* _store_entries; // Used when writing cache
268 const char* _C_strings_buf; // Loaded buffer for _C_strings[] table
269 uint _store_entries_cnt;
270
271 static AOTCodeCache* open_for_use();
272 static AOTCodeCache* open_for_dump();
273
274 bool set_write_position(uint pos);
275 bool align_write();
276 address reserve_bytes(uint nbytes);
277 uint write_bytes(const void* buffer, uint nbytes);
278 const char* addr(uint offset) const { return _load_buffer + offset; }
279 static AOTCodeAddressTable* addr_table() {
280 return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
281 }
282
283 void set_lookup_failed() { _lookup_failed = true; }
284 void clear_lookup_failed() { _lookup_failed = false; }
285 bool lookup_failed() const { return _lookup_failed; }
286
287 public:
288 AOTCodeCache(bool is_dumping, bool is_using);
289 ~AOTCodeCache();
290
291 const char* cache_buffer() const { return _load_buffer; }
292 bool failed() const { return _failed; }
293 void set_failed() { _failed = true; }
294
295 static uint max_aot_code_size();
296
297 uint load_size() const { return _load_size; }
298 uint write_position() const { return _write_position; }
299
300 void load_strings();
301 int store_strings();
302
303 static void init_early_stubs_table() NOT_CDS_RETURN;
304 static void init_shared_blobs_table() NOT_CDS_RETURN;
305 static void init_early_c1_table() NOT_CDS_RETURN;
306
307 address address_for_C_string(int idx) const { return _table->address_for_C_string(idx); }
308 address address_for_id(int id) const { return _table->address_for_id(id); }
309
310 bool for_use() const { return _for_use && !_failed; }
311 bool for_dump() const { return _for_dump && !_failed; }
312
313 bool closing() const { return _closing; }
314
315 AOTCodeEntry* add_entry() {
316 _store_entries_cnt++;
317 _store_entries -= 1;
318 return _store_entries;
319 }
320
321 AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id);
322
323 bool finish_write();
324
325 bool write_relocations(CodeBlob& code_blob);
326 bool write_oop_map_set(CodeBlob& cb);
327 #ifndef PRODUCT
328 bool write_asm_remarks(CodeBlob& cb);
329 bool write_dbg_strings(CodeBlob& cb);
330 #endif // PRODUCT
331
332 // save and restore API for non-enumerable code blobs
333 static bool store_code_blob(CodeBlob& blob,
334 AOTCodeEntry::Kind entry_kind,
335 uint id, const char* name) NOT_CDS_RETURN_(false);
336
337 static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
338 uint id, const char* name) NOT_CDS_RETURN_(nullptr);
339
340 // save and restore API for enumerable code blobs
341 static bool store_code_blob(CodeBlob& blob,
342 AOTCodeEntry::Kind entry_kind,
343 BlobId id) NOT_CDS_RETURN_(false);
344
345 static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
346 BlobId id) NOT_CDS_RETURN_(nullptr);
347
348 static uint store_entries_cnt() {
349 if (is_on_for_dump()) {
350 return cache()->_store_entries_cnt;
351 }
352 return -1;
353 }
354
355 // Static access
356
357 private:
358 static AOTCodeCache* _cache;
359 DEBUG_ONLY( static bool _passed_init2; )
360
361 static bool open_cache(bool is_dumping, bool is_using);
362 bool verify_config() {
363 if (for_use()) {
364 return _load_header->verify_config();
365 }
366 return true;
367 }
368 public:
369 static AOTCodeCache* cache() { assert(_passed_init2, "Too early to ask"); return _cache; }
370 static void initialize() NOT_CDS_RETURN;
371 static void init2() NOT_CDS_RETURN;
372 static void close() NOT_CDS_RETURN;
373 static bool is_on() CDS_ONLY({ return cache() != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
374 static bool is_on_for_use() CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
375 static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);
376 static bool is_dumping_stub() NOT_CDS_RETURN_(false);
377 static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
378 static bool is_using_stub() NOT_CDS_RETURN_(false);
379 static bool is_using_adapter() NOT_CDS_RETURN_(false);
380 static void enable_caching() NOT_CDS_RETURN;
381 static void disable_caching() NOT_CDS_RETURN;
382 static bool is_caching_enabled() NOT_CDS_RETURN_(false);
383
384 static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
385
386 static void print_on(outputStream* st) NOT_CDS_RETURN;
387 };
388
389 // Concurent AOT code reader
390 class AOTCodeReader {
391 private:
392 const AOTCodeCache* _cache;
393 const AOTCodeEntry* _entry;
394 const char* _load_buffer; // Loaded cached code buffer
395 uint _read_position; // Position in _load_buffer
396 uint read_position() const { return _read_position; }
397 void set_read_position(uint pos);
398 const char* addr(uint offset) const { return _load_buffer + offset; }
399
400 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
401 void set_lookup_failed() { _lookup_failed = true; }
402 void clear_lookup_failed() { _lookup_failed = false; }
403 bool lookup_failed() const { return _lookup_failed; }
404
405 AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
406 public:
407 AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry);
408
409 CodeBlob* compile_code_blob(const char* name);
410
411 ImmutableOopMapSet* read_oop_map_set();
412
413 void fix_relocations(CodeBlob* code_blob);
414 #ifndef PRODUCT
415 void read_asm_remarks(AsmRemarks& asm_remarks);
416 void read_dbg_strings(DbgStrings& dbg_strings);
417 #endif // PRODUCT
418 };
419
420 #endif // SHARE_CODE_AOTCODECACHE_HPP
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_CODE_AOTCODECACHE_HPP
26 #define SHARE_CODE_AOTCODECACHE_HPP
27
28 #include "compiler/compilerDefinitions.hpp"
29 #include "memory/allocation.hpp"
30 #include "nmt/memTag.hpp"
31 #include "oops/oopsHierarchy.hpp"
32 #include "runtime/stubInfo.hpp"
33 #include "runtime/vm_version.hpp"
34 #include "utilities/exceptions.hpp"
35 #include "utilities/sizes.hpp"
36
37 /*
38 * AOT Code Cache collects code from Code Cache and corresponding metadata
39 * during application training run.
40 * In following "production" runs this code and data can be loaded into
41 * Code Cache skipping its generation.
42 * Additionaly special compiled code "preload" is generated with class initialization
43 * barriers which can be called on first Java method invocation.
44 */
45
46 class AbstractCompiler;
47 class AOTCodeCache;
48 class AsmRemarks;
49 class ciConstant;
50 class ciEnv;
51 class ciMethod;
52 class CodeBlob;
53 class CodeOffsets;
54 class CompileTask;
55 class DbgStrings;
56 class DebugInformationRecorder;
57 class Dependencies;
58 class ExceptionTable;
59 class ExceptionHandlerTable;
60 template<typename E>
61 class GrowableArray;
62 class ImmutableOopMapSet;
63 class ImplicitExceptionTable;
64 class JavaThread;
65 class Klass;
66 class methodHandle;
67 class Metadata;
68 class Method;
69 class nmethod;
70 class OopMapSet;
71 class OopRecorder;
72 class outputStream;
73 class RelocIterator;
74 class StubCodeGenerator;
75
76 enum class vmIntrinsicID : int;
77
78 #define DO_AOTCODEENTRY_KIND(Fn) \
79 Fn(None) \
80 Fn(Adapter) \
81 Fn(Stub) \
82 Fn(SharedBlob) \
83 Fn(C1Blob) \
84 Fn(C2Blob) \
85 Fn(Code) \
86
87 // Descriptor of AOT Code Cache's entry
88 class AOTCodeEntry {
89 public:
90 enum Kind : s1 {
91 #define DECL_KIND_ENUM(kind) kind,
92 DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
93 #undef DECL_KIND_ENUM
94 Kind_count
95 };
96
97 private:
98 Kind _kind;
99 uint _id; // Adapter's id, vmIntrinsic::ID for stub or Method's offset in AOTCache for nmethod
100 uint _offset; // Offset to entry
101 uint _size; // Entry size
102 uint _name_offset; // Method's or intrinsic name
103 uint _name_size;
104 uint _num_inlined_bytecodes;
105 uint _code_offset; // Start of code in cache
106 uint _code_size; // Total size of all code sections
107
108 uint _comp_level; // compilation level
109 uint _comp_id; // compilation id
110 bool _has_oop_maps;
111 bool _has_clinit_barriers; // Generated code has class init checks
112 bool _for_preload; // Code can be used for preload
113 bool _loaded; // Code was loaded
114 bool _not_entrant; // Deoptimized
115 bool _load_fail; // Failed to load due to some klass state
116 address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations
117
118 public:
119 // this constructor is used only by AOTCodeEntry::Stub
120 AOTCodeEntry(uint offset, uint size, uint name_offset, uint name_size,
121 uint code_offset, uint code_size,
122 Kind kind, uint id) {
123 assert(kind == AOTCodeEntry::Stub, "sanity check");
124 _kind = kind;
125 _id = id;
126 _offset = offset;
127 _size = size;
128 _name_offset = name_offset;
129 _name_size = name_size;
130 _code_offset = code_offset;
131 _code_size = code_size;
132
133 _dumptime_content_start_addr = nullptr;
134 _num_inlined_bytecodes = 0;
135 _comp_level = 0;
136 _comp_id = 0;
137 _has_oop_maps = false; // unused here
138 _has_clinit_barriers = false;
139 _for_preload = false;
140 _loaded = false;
141 _not_entrant = false;
142 _load_fail = false;
143 }
144
145 AOTCodeEntry(Kind kind, uint id,
146 uint offset, uint size,
147 uint name_offset, uint name_size,
148 uint blob_offset, bool has_oop_maps,
149 address dumptime_content_start_addr,
150 uint comp_level = 0,
151 uint comp_id = 0,
152 bool has_clinit_barriers = false,
153 bool for_preload = false) {
154 _kind = kind;
155 _id = id;
156 _offset = offset;
157 _size = size;
158 _name_offset = name_offset;
159 _name_size = name_size;
160 _code_offset = blob_offset;
161 _code_size = 0; // unused
162
163 _dumptime_content_start_addr = dumptime_content_start_addr;
164 _num_inlined_bytecodes = 0;
165
166 _comp_level = comp_level;
167 _comp_id = comp_id;
168 _has_oop_maps = has_oop_maps;
169 _has_clinit_barriers = has_clinit_barriers;
170 _for_preload = for_preload;
171 _loaded = false;
172 _not_entrant = false;
173 _load_fail = false;
174
175 _loaded = false;
176 _not_entrant = false;
177 _load_fail = false;
178 }
179
180 void* operator new(size_t x, AOTCodeCache* cache);
181 // Delete is a NOP
182 void operator delete( void *ptr ) {}
183
184 Method* method();
185
186 Kind kind() const { return _kind; }
187 uint id() const { return _id; }
188
189 uint offset() const { return _offset; }
190 void set_offset(uint off) { _offset = off; }
191
192 uint size() const { return _size; }
193 uint name_offset() const { return _name_offset; }
194 uint name_size() const { return _name_size; }
195 uint code_offset() const { return _code_offset; }
196 uint code_size() const { return _code_size; }
197
198 bool has_oop_maps() const { return _has_oop_maps; }
199 address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
200 uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
201 void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; }
202
203 uint comp_level() const { return _comp_level; }
204 uint comp_id() const { return _comp_id; }
205
206 bool has_clinit_barriers() const { return _has_clinit_barriers; }
207 bool for_preload() const { return _for_preload; }
208 bool is_loaded() const { return _loaded; }
209 void set_loaded() { _loaded = true; }
210
211 bool not_entrant() const { return _not_entrant; }
212 void set_not_entrant() { _not_entrant = true; }
213 void set_entrant() { _not_entrant = false; }
214
215 bool load_fail() const { return _load_fail; }
216 void set_load_fail() { _load_fail = true; }
217
218 void print(outputStream* st) const;
219
220 static bool is_valid_entry_kind(Kind kind) { return kind > None && kind < Kind_count; }
221 static bool is_blob(Kind kind) { return kind == SharedBlob || kind == C1Blob || kind == C2Blob; }
222 static bool is_adapter(Kind kind) { return kind == Adapter; }
223 bool is_code() { return _kind == Code; }
224 };
225
226 // Addresses of stubs, blobs and runtime finctions called from compiled code.
227 class AOTCodeAddressTable : public CHeapObj<mtCode> {
228 private:
229 address* _extrs_addr;
230 address* _stubs_addr;
231 address* _shared_blobs_addr;
232 address* _C1_blobs_addr;
233 address* _C2_blobs_addr;
234 uint _extrs_length;
235 uint _stubs_length;
236 uint _shared_blobs_length;
237 uint _C1_blobs_length;
238 uint _C2_blobs_length;
239
240 bool _extrs_complete;
241 bool _early_stubs_complete;
242 bool _shared_blobs_complete;
243 bool _early_c1_complete;
244 bool _c1_complete;
245 bool _c2_complete;
246 bool _complete;
247
248 public:
249 AOTCodeAddressTable() :
250 _extrs_addr(nullptr),
251 _stubs_addr(nullptr),
252 _shared_blobs_addr(nullptr),
253 _C1_blobs_addr(nullptr),
254 _C2_blobs_addr(nullptr),
255 _extrs_length(0),
256 _stubs_length(0),
257 _shared_blobs_length(0),
258 _C1_blobs_length(0),
259 _C2_blobs_length(0),
260 _extrs_complete(false),
261 _early_stubs_complete(false),
262 _shared_blobs_complete(false),
263 _early_c1_complete(false),
264 _c1_complete(false),
265 _c2_complete(false),
266 _complete(false)
267 { }
268 ~AOTCodeAddressTable();
269 void init_extrs();
270 void init_early_stubs();
271 void init_shared_blobs();
272 void init_stubs();
273 void init_early_c1();
274 void init_c1();
275 void init_c2();
276 const char* add_C_string(const char* str);
277 int id_for_C_string(address str);
278 address address_for_C_string(int idx);
279 int id_for_address(address addr, RelocIterator iter, CodeBlob* blob);
280 address address_for_id(int id);
281 bool c2_complete() const { return _c2_complete; }
282 bool c1_complete() const { return _c1_complete; }
283 };
284
285 struct AOTCodeSection {
286 public:
287 address _origin_address;
288 uint _size;
289 uint _offset;
290 };
291
292 enum class DataKind: int {
293 No_Data = -1,
294 Null = 0,
295 Klass = 1,
296 Method = 2,
297 String = 3,
298 MH_Oop = 4,
299 Primitive = 5, // primitive Class object
300 SysLoader = 6, // java_system_loader
301 PlaLoader = 7, // java_platform_loader
302 MethodCnts= 8
303 };
304
305 class AOTCodeCache : public CHeapObj<mtCode> {
306
307 // Classes used to describe AOT code cache.
308 protected:
309 class Config {
310 size_t _codeCacheSize;
311 address _compressedOopBase;
312 address _compressedKlassBase;
313 uint _compressedOopShift;
314 uint _compressedKlassShift;
315 uint _contendedPaddingWidth;
316 uint _objectAlignment;
317 uint _gc;
318 enum Flags {
319 none = 0,
320 debugVM = 2,
321 compressedOops = 4,
322 compressedClassPointers = 8,
323 useTLAB = 16,
324 systemClassAssertions = 32,
325 userClassAssertions = 64,
326 enableContendedPadding = 128,
327 restrictContendedPadding = 256,
328 preserveFramePointer = 512
329 };
330 uint _flags;
331 uint _cpu_features_offset; // offset in the cache where cpu features are stored
332
333 public:
334 void record(uint cpu_features_offset);
335 bool verify(AOTCodeCache* cache) const;
336 };
337
338 class Header : public CHeapObj<mtCode> {
339 private:
340 // Here should be version and other verification fields
341 enum {
342 AOT_CODE_VERSION = 1
343 };
344 uint _version; // AOT code version (should match when reading code cache)
345 uint _cache_size; // cache size in bytes
346 uint _strings_count; // number of recorded C strings
347 uint _strings_offset; // offset to recorded C strings
348 uint _entries_count; // number of recorded entries
349 uint _search_table_offset; // offset of table for looking up an AOTCodeEntry
350 uint _entries_offset; // offset of AOTCodeEntry array describing entries
351 uint _preload_entries_count; // entries for pre-loading code
352 uint _preload_entries_offset;
353 uint _adapters_count;
354 uint _shared_blobs_count;
355 uint _C1_blobs_count;
356 uint _C2_blobs_count;
357 uint _stubs_count;
358 Config _config; // must be the last element as there is trailing data stored immediately after Config
359
360 public:
361 void init(uint cache_size,
362 uint strings_count, uint strings_offset,
363 uint entries_count, uint search_table_offset, uint entries_offset,
364 uint preload_entries_count, uint preload_entries_offset,
365 uint adapters_count, uint shared_blobs_count,
366 uint C1_blobs_count, uint C2_blobs_count,
367 uint stubs_count, uint cpu_features_offset) {
368 _version = AOT_CODE_VERSION;
369 _cache_size = cache_size;
370 _strings_count = strings_count;
371 _strings_offset = strings_offset;
372 _entries_count = entries_count;
373 _search_table_offset = search_table_offset;
374 _entries_offset = entries_offset;
375 _preload_entries_count = preload_entries_count;
376 _preload_entries_offset = preload_entries_offset;
377 _adapters_count = adapters_count;
378 _shared_blobs_count = shared_blobs_count;
379 _C1_blobs_count = C1_blobs_count;
380 _C2_blobs_count = C2_blobs_count;
381 _stubs_count = stubs_count;
382
383 _config.record(cpu_features_offset);
384 }
385
386 uint cache_size() const { return _cache_size; }
387 uint strings_count() const { return _strings_count; }
388 uint strings_offset() const { return _strings_offset; }
389 uint entries_count() const { return _entries_count; }
390 uint search_table_offset() const { return _search_table_offset; }
391 uint entries_offset() const { return _entries_offset; }
392 uint preload_entries_count() const { return _preload_entries_count; }
393 uint preload_entries_offset() const { return _preload_entries_offset; }
394 uint adapters_count() const { return _adapters_count; }
395 uint shared_blobs_count() const { return _shared_blobs_count; }
396 uint C1_blobs_count() const { return _C1_blobs_count; }
397 uint C2_blobs_count() const { return _C2_blobs_count; }
398 uint stubs_count() const { return _stubs_count; }
399 uint nmethods_count() const { return _entries_count
400 - _stubs_count
401 - _shared_blobs_count
402 - _C1_blobs_count
403 - _C2_blobs_count
404 - _adapters_count; }
405
406 bool verify(uint load_size) const;
407 bool verify_config(AOTCodeCache* cache) const { // Called after Universe initialized
408 return _config.verify(cache);
409 }
410 };
411
412 // Continue with AOTCodeCache class definition.
413 private:
414 Header* _load_header;
415 char* _load_buffer; // Aligned buffer for loading AOT code
416 char* _store_buffer; // Aligned buffer for storing AOT code
417 char* _C_store_buffer; // Original unaligned buffer
418
419 uint _write_position; // Position in _store_buffer
420 uint _load_size; // Used when reading cache
421 uint _store_size; // Used when writing cache
422 bool _for_use; // AOT cache is open for using AOT code
423 bool _for_dump; // AOT cache is open for dumping AOT code
424 bool _closing; // Closing cache file
425 bool _failed; // Failed read/write to/from cache (cache is broken?)
426 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
427
428 bool _for_preload; // Code for preload
429 bool _has_clinit_barriers; // Code with clinit barriers
430
431 AOTCodeAddressTable* _table;
432
433 AOTCodeEntry* _load_entries; // Used when reading cache
434 uint* _search_entries; // sorted by ID table [id, index]
435 AOTCodeEntry* _store_entries; // Used when writing cache
436 const char* _C_strings_buf; // Loaded buffer for _C_strings[] table
437 uint _store_entries_cnt;
438
439 uint _compile_id;
440 uint _comp_level;
441 uint compile_id() const { return _compile_id; }
442 uint comp_level() const { return _comp_level; }
443
444 static AOTCodeCache* open_for_use();
445 static AOTCodeCache* open_for_dump();
446
447 bool set_write_position(uint pos);
448 bool align_write();
449
450 address reserve_bytes(uint nbytes);
451 uint write_bytes(const void* buffer, uint nbytes);
452 const char* addr(uint offset) const { return _load_buffer + offset; }
453 static AOTCodeAddressTable* addr_table() {
454 return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
455 }
456
457 void set_lookup_failed() { _lookup_failed = true; }
458 void clear_lookup_failed() { _lookup_failed = false; }
459 bool lookup_failed() const { return _lookup_failed; }
460
461 AOTCodeEntry* write_nmethod(nmethod* nm, bool for_preload);
462
463 // States:
464 // S >= 0: allow new readers, S readers are currently active
465 // S < 0: no new readers are allowed; (-S-1) readers are currently active
466 // (special case: S = -1 means no readers are active, and would never be active again)
467 static volatile int _nmethod_readers;
468
469 static void wait_for_no_nmethod_readers();
470
471 class ReadingMark {
472 private:
473 bool _failed;
474 public:
475 ReadingMark();
476 ~ReadingMark();
477 bool failed() {
478 return _failed;
479 }
480 };
481
482 public:
483 AOTCodeCache(bool is_dumping, bool is_using);
484 ~AOTCodeCache();
485
486 const char* cache_buffer() const { return _load_buffer; }
487 bool failed() const { return _failed; }
488 void set_failed() { _failed = true; }
489
490 static bool is_address_in_aot_cache(address p) NOT_CDS_RETURN_(false);
491 static uint max_aot_code_size();
492
493 uint load_size() const { return _load_size; }
494 uint write_position() const { return _write_position; }
495
496 void load_strings();
497 int store_strings();
498
499 static void init_early_stubs_table() NOT_CDS_RETURN;
500 static void init_shared_blobs_table() NOT_CDS_RETURN;
501 static void init_stubs_table() NOT_CDS_RETURN;
502 static void init_early_c1_table() NOT_CDS_RETURN;
503 static void init_c1_table() NOT_CDS_RETURN;
504 static void init_c2_table() NOT_CDS_RETURN;
505
506 address address_for_C_string(int idx) const { return _table->address_for_C_string(idx); }
507 address address_for_id(int id) const { return _table->address_for_id(id); }
508
509 bool for_use() const { return _for_use && !_failed; }
510 bool for_dump() const { return _for_dump && !_failed; }
511
512 bool closing() const { return _closing; }
513
514 AOTCodeEntry* add_entry() {
515 _store_entries_cnt++;
516 _store_entries -= 1;
517 return _store_entries;
518 }
519 void preload_aot_code(TRAPS);
520
521 AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id, uint comp_level = 0);
522 void invalidate_entry(AOTCodeEntry* entry);
523
524 void store_cpu_features(char*& buffer, uint buffer_size);
525
526 bool finish_write();
527
528 void log_stats_on_exit();
529
530 static bool load_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
531 static bool store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
532
533 bool write_klass(Klass* klass);
534 bool write_method(Method* method);
535
536 bool write_relocations(CodeBlob& code_blob, GrowableArray<Handle>* oop_list = nullptr, GrowableArray<Metadata*>* metadata_list = nullptr);
537
538 bool write_oop_map_set(CodeBlob& cb);
539 bool write_nmethod_reloc_immediates(GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
540
541 jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
542 Metadata* read_metadata(const methodHandle& comp_method);
543
544 bool write_oop(jobject& jo);
545 bool write_oop(oop obj);
546 bool write_metadata(Metadata* m);
547 bool write_oops(nmethod* nm);
548 bool write_metadata(nmethod* nm);
549
550 #ifndef PRODUCT
551 bool write_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table);
552 bool write_dbg_strings(DbgStrings& dbg_strings, bool use_string_table);
553 #endif // PRODUCT
554
555 // save and restore API for non-enumerable code blobs
556 static bool store_code_blob(CodeBlob& blob,
557 AOTCodeEntry::Kind entry_kind,
558 uint id, const char* name) NOT_CDS_RETURN_(false);
559
560 static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
561 uint id, const char* name) NOT_CDS_RETURN_(nullptr);
562
563 static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level) NOT_CDS_RETURN_(false);
564 static AOTCodeEntry* store_nmethod(nmethod* nm, AbstractCompiler* compiler, bool for_preload) NOT_CDS_RETURN_(nullptr);
565
566 // save and restore API for enumerable code blobs
567 static bool store_code_blob(CodeBlob& blob,
568 AOTCodeEntry::Kind entry_kind,
569 BlobId id) NOT_CDS_RETURN_(false);
570
571 static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
572 BlobId id) NOT_CDS_RETURN_(nullptr);
573
574 static uint store_entries_cnt() {
575 if (is_on_for_dump()) {
576 return cache()->_store_entries_cnt;
577 }
578 return -1;
579 }
580
581 // Static access
582
583 private:
584 static AOTCodeCache* _cache;
585 DEBUG_ONLY( static bool _passed_init2; )
586
587 static bool open_cache(bool is_dumping, bool is_using);
588
589 bool verify_config_on_use() {
590 if (for_use()) {
591 return _load_header->verify_config(this);
592 }
593 return true;
594 }
595 public:
596 static AOTCodeCache* cache() { assert(_passed_init2, "Too early to ask"); return _cache; }
597 static void initialize() NOT_CDS_RETURN;
598 static void init2() NOT_CDS_RETURN;
599 static void close() NOT_CDS_RETURN;
600 static bool is_on() CDS_ONLY({ return cache() != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
601 static bool is_code_load_thread_on() NOT_CDS_RETURN_(false);
602 static bool is_on_for_use() CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
603 static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);
604 static bool is_dumping_code() NOT_CDS_RETURN_(false);
605 static bool is_dumping_stub() NOT_CDS_RETURN_(false);
606 static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
607 static bool is_using_code() NOT_CDS_RETURN_(false);
608 static bool is_using_stub() NOT_CDS_RETURN_(false);
609 static bool is_using_adapter() NOT_CDS_RETURN_(false);
610 static void enable_caching() NOT_CDS_RETURN;
611 static void disable_caching() NOT_CDS_RETURN;
612 static bool is_caching_enabled() NOT_CDS_RETURN_(false);
613
614 // It is used before AOTCodeCache is initialized.
615 static bool maybe_dumping_code() NOT_CDS_RETURN_(false);
616
617 static bool allow_const_field(ciConstant& value) NOT_CDS_RETURN_(false);
618 static void invalidate(AOTCodeEntry* entry) NOT_CDS_RETURN;
619 static AOTCodeEntry* find_code_entry(const methodHandle& method, uint comp_level);
620 static void preload_code(JavaThread* thread) NOT_CDS_RETURN;
621
622 template<typename Function>
623 static void iterate(Function function) { // lambda enabled API
624 AOTCodeCache* cache = open_for_use();
625 if (cache != nullptr) {
626 ReadingMark rdmk;
627 if (rdmk.failed()) {
628 // Cache is closed, cannot touch anything.
629 return;
630 }
631
632 uint count = cache->_load_header->entries_count();
633 uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index]
634 AOTCodeEntry* load_entries = (AOTCodeEntry*)(search_entries + 2 * count);
635
636 for (uint i = 0; i < count; i++) {
637 int index = search_entries[2*i + 1];
638 AOTCodeEntry* entry = &(load_entries[index]);
639 function(entry);
640 }
641 }
642 }
643
644 static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
645
646 static void print_on(outputStream* st) NOT_CDS_RETURN;
647 static void print_statistics_on(outputStream* st) NOT_CDS_RETURN;
648 static void print_timers_on(outputStream* st) NOT_CDS_RETURN;
649 static void print_unused_entries_on(outputStream* st) NOT_CDS_RETURN;
650 };
651
652 // Concurent AOT code reader
653 class AOTCodeReader {
654 private:
655 const AOTCodeCache* _cache;
656 const AOTCodeEntry* _entry;
657 const char* _load_buffer; // Loaded AOT code buffer
658 uint _read_position; // Position in _load_buffer
659 uint read_position() const { return _read_position; }
660 void set_read_position(uint pos);
661 const char* addr(uint offset) const { return _load_buffer + offset; }
662
663 uint _compile_id;
664 uint _comp_level;
665 uint compile_id() const { return _compile_id; }
666 uint comp_level() const { return _comp_level; }
667
668 bool _preload; // Preloading code before method execution
669 bool _lookup_failed; // Failed to lookup for info (skip only this code load)
670 void set_lookup_failed() { _lookup_failed = true; }
671 void clear_lookup_failed() { _lookup_failed = false; }
672 bool lookup_failed() const { return _lookup_failed; }
673
674 public:
675 AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry, CompileTask* task);
676
677 AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
678
679 // convenience method to convert offset in AOTCodeEntry data to its address
680 bool compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompiler* compiler);
681
682 CodeBlob* compile_code_blob(const char* name);
683
684 Klass* read_klass(const methodHandle& comp_method);
685 Method* read_method(const methodHandle& comp_method);
686
687 oop read_oop(JavaThread* thread, const methodHandle& comp_method);
688 Metadata* read_metadata(const methodHandle& comp_method);
689 bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
690 bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
691
692 bool read_oop_metadata_list(JavaThread* thread, ciMethod* target, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list, OopRecorder* oop_recorder);
693 void apply_relocations(nmethod* nm, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list) NOT_CDS_RETURN;
694
695 ImmutableOopMapSet* read_oop_map_set();
696
697 void fix_relocations(CodeBlob* code_blob, GrowableArray<Handle>* oop_list = nullptr, GrowableArray<Metadata*>* metadata_list = nullptr) NOT_CDS_RETURN;
698 #ifndef PRODUCT
699 void read_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table) NOT_CDS_RETURN;
700 void read_dbg_strings(DbgStrings& dbg_strings, bool use_string_table) NOT_CDS_RETURN;
701 #endif // PRODUCT
702
703 void print_on(outputStream* st);
704 };
705
706 // +1 for preload code
707 const int AOTCompLevel_count = CompLevel_count + 1; // 6 levels indexed from 0 to 5
708
709 struct AOTCodeStats {
710 private:
711 struct {
712 uint _kind_cnt[AOTCodeEntry::Kind_count];
713 uint _nmethod_cnt[AOTCompLevel_count];
714 uint _clinit_barriers_cnt;
715 } ccstats; // AOT code stats
716
717 void check_kind(uint kind) { assert(kind >= AOTCodeEntry::None && kind < AOTCodeEntry::Kind_count, "Invalid AOTCodeEntry kind %d", kind); }
718 void check_complevel(uint lvl) { assert(lvl >= CompLevel_none && lvl < AOTCompLevel_count, "Invalid compilation level %d", lvl); }
719
720 public:
721 void inc_entry_cnt(uint kind) { check_kind(kind); ccstats._kind_cnt[kind] += 1; }
722 void inc_nmethod_cnt(uint lvl) { check_complevel(lvl); ccstats._nmethod_cnt[lvl] += 1; }
723 void inc_preload_cnt() { ccstats._nmethod_cnt[AOTCompLevel_count-1] += 1; }
724 void inc_clinit_barriers_cnt() { ccstats._clinit_barriers_cnt += 1; }
725
726 void collect_entry_stats(AOTCodeEntry* entry) {
727 inc_entry_cnt(entry->kind());
728 if (entry->is_code()) {
729 entry->for_preload() ? inc_nmethod_cnt(AOTCompLevel_count-1)
730 : inc_nmethod_cnt(entry->comp_level());
731 if (entry->has_clinit_barriers()) {
732 inc_clinit_barriers_cnt();
733 }
734 }
735 }
736
737 uint entry_count(uint kind) { check_kind(kind); return ccstats._kind_cnt[kind]; }
738 uint nmethod_count(uint lvl) { check_complevel(lvl); return ccstats._nmethod_cnt[lvl]; }
739 uint preload_count() { return ccstats._nmethod_cnt[AOTCompLevel_count-1]; }
740 uint clinit_barriers_count() { return ccstats._clinit_barriers_cnt; }
741
742 uint total_count() {
743 uint total = 0;
744 for (int kind = AOTCodeEntry::None; kind < AOTCodeEntry::Kind_count; kind++) {
745 total += ccstats._kind_cnt[kind];
746 }
747 return total;
748 }
749
750 static AOTCodeStats add_aot_code_stats(AOTCodeStats stats1, AOTCodeStats stats2);
751
752 // Runtime stats of the AOT code
753 private:
754 struct {
755 struct {
756 uint _loaded_cnt;
757 uint _invalidated_cnt;
758 uint _load_failed_cnt;
759 } _entry_kinds[AOTCodeEntry::Kind_count],
760 _nmethods[AOTCompLevel_count];
761 } rs; // rs = runtime stats
762
763 public:
764 void inc_entry_loaded_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._loaded_cnt += 1; }
765 void inc_entry_invalidated_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._invalidated_cnt += 1; }
766 void inc_entry_load_failed_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._load_failed_cnt += 1; }
767
768 void inc_nmethod_loaded_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._loaded_cnt += 1; }
769 void inc_nmethod_invalidated_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._invalidated_cnt += 1; }
770 void inc_nmethod_load_failed_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._load_failed_cnt += 1; }
771
772 uint entry_loaded_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._loaded_cnt; }
773 uint entry_invalidated_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._invalidated_cnt; }
774 uint entry_load_failed_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._load_failed_cnt; }
775
776 uint nmethod_loaded_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._loaded_cnt; }
777 uint nmethod_invalidated_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._invalidated_cnt; }
778 uint nmethod_load_failed_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._load_failed_cnt; }
779
780 void inc_loaded_cnt(AOTCodeEntry* entry) {
781 inc_entry_loaded_cnt(entry->kind());
782 if (entry->is_code()) {
783 entry->for_preload() ? inc_nmethod_loaded_cnt(AOTCompLevel_count-1)
784 : inc_nmethod_loaded_cnt(entry->comp_level());
785 }
786 }
787
788 void inc_invalidated_cnt(AOTCodeEntry* entry) {
789 inc_entry_invalidated_cnt(entry->kind());
790 if (entry->is_code()) {
791 entry->for_preload() ? inc_nmethod_invalidated_cnt(AOTCompLevel_count-1)
792 : inc_nmethod_invalidated_cnt(entry->comp_level());
793 }
794 }
795
796 void inc_load_failed_cnt(AOTCodeEntry* entry) {
797 inc_entry_load_failed_cnt(entry->kind());
798 if (entry->is_code()) {
799 entry->for_preload() ? inc_nmethod_load_failed_cnt(AOTCompLevel_count-1)
800 : inc_nmethod_load_failed_cnt(entry->comp_level());
801 }
802 }
803
804 void collect_entry_runtime_stats(AOTCodeEntry* entry) {
805 if (entry->is_loaded()) {
806 inc_loaded_cnt(entry);
807 }
808 if (entry->not_entrant()) {
809 inc_invalidated_cnt(entry);
810 }
811 if (entry->load_fail()) {
812 inc_load_failed_cnt(entry);
813 }
814 }
815
816 void collect_all_stats(AOTCodeEntry* entry) {
817 collect_entry_stats(entry);
818 collect_entry_runtime_stats(entry);
819 }
820
821 AOTCodeStats() {
822 memset(this, 0, sizeof(AOTCodeStats));
823 }
824 };
825
826 // code cache internal runtime constants area used by AOT code
827 class AOTRuntimeConstants {
828 friend class AOTCodeCache;
829 private:
830 uint _grain_shift;
831 uint _card_shift;
832 static address _field_addresses_list[];
833 static AOTRuntimeConstants _aot_runtime_constants;
834 // private constructor for unique singleton
835 AOTRuntimeConstants() { }
836 // private for use by friend class AOTCodeCache
837 static void initialize_from_runtime();
838 public:
839 #if INCLUDE_CDS
840 static bool contains(address adr) {
841 address base = (address)&_aot_runtime_constants;
842 address hi = base + sizeof(AOTRuntimeConstants);
843 return (base <= adr && adr < hi);
844 }
845 static address grain_shift_address() { return (address)&_aot_runtime_constants._grain_shift; }
846 static address card_shift_address() { return (address)&_aot_runtime_constants._card_shift; }
847 static address* field_addresses_list() {
848 return _field_addresses_list;
849 }
850 #else
851 static bool contains(address adr) { return false; }
852 static address grain_shift_address() { return nullptr; }
853 static address card_shift_address() { return nullptr; }
854 static address* field_addresses_list() { return nullptr; }
855 #endif
856 };
857
858 #endif // SHARE_CODE_AOTCODECACHE_HPP
|