1 /*
  2  * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  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_SCCACHE_HPP
 26 #define SHARE_CODE_SCCACHE_HPP
 27 
 28 /*
 29  * Startup Code Cache (SCC) collects compiled code and metadata during
 30  * an application training runs.
 31  * In following "deployment" runs this code can me loaded into
 32  * Code Cache as normal nmethods skipping JIT compilation.
 33  * In additoin special compiled code is generated with class initialization
 34  * barriers which can be called on first Java method invocation.
 35  */
 36  
 37 class AbstractCompiler;
 38 class ciConstant;
 39 class ciEnv;
 40 class ciMethod;
 41 class CodeBuffer;
 42 class CodeOffsets;
 43 class CompileTask;
 44 class DebugInformationRecorder;
 45 class Dependencies;
 46 class ExceptionTable;
 47 class ExceptionHandlerTable;
 48 class ImplicitExceptionTable;
 49 class JavaThread;
 50 class methodHandle;
 51 class Method;
 52 class OopMapSet;
 53 class OopRecorder;
 54 class outputStream;
 55 class RelocIterator;
 56 class SCCache;
 57 class StubCodeGenerator;
 58 
 59 enum class vmIntrinsicID : int;
 60 enum CompLevel : signed char;
 61 
 62 class SCConfig {
 63   uint _compressedOopShift;
 64   uint _compressedKlassShift;
 65   uint _contendedPaddingWidth;
 66   uint _objectAlignment;
 67   uint _gc;
 68   enum Flags {
 69     none                     = 0,
 70     metadataPointers         = 1,
 71     debugVM                  = 2,
 72     compressedOops           = 4,
 73     compressedClassPointers  = 8,
 74     useTLAB                  = 16,
 75     systemClassAssertions    = 32,
 76     userClassAssertions      = 64,
 77     enableContendedPadding   = 128,
 78     restrictContendedPadding = 256,
 79   };
 80   uint _flags;
 81 
 82 public:
 83   void record(bool use_meta_ptrs);
 84   bool verify(const char* cache_path) const;
 85 
 86   bool has_meta_ptrs()  const { return (_flags & metadataPointers) != 0; }
 87 };
 88 
 89 // Code Cache file header
 90 class SCCHeader : public CHeapObj<mtCode> {
 91 private:
 92   // Here should be version and other verification fields
 93   enum {
 94     SCC_VERSION = 1
 95   };
 96   uint _version;           // SCC version (should match when reading code cache)
 97   uint _jvm_version_offset;// JVM version string
 98   uint _cache_size;        // cache size in bytes
 99   uint _strings_count;
100   uint _strings_offset;    // offset to recorded C strings
101   uint _entries_count;     // number of recorded entries in cache
102   uint _entries_offset;    // offset of SCCEntry array describing entries
103   uint _preload_entries_count; // entries for pre-loading code
104   uint _preload_entries_offset;
105   SCConfig _config;
106 
107 public:
108   void init(uint jvm_version_offset, uint cache_size,
109             uint strings_count, uint strings_offset,
110             uint entries_count, uint entries_offset,
111             uint preload_entries_count, uint preload_entries_offset,
112             bool use_meta_ptrs) {
113     _version        = SCC_VERSION;
114      _jvm_version_offset = jvm_version_offset;
115     _cache_size     = cache_size;
116     _strings_count  = strings_count;
117     _strings_offset = strings_offset;
118     _entries_count  = entries_count;
119     _entries_offset = entries_offset;
120     _preload_entries_count  = preload_entries_count;
121     _preload_entries_offset = preload_entries_offset;
122 
123     _config.record(use_meta_ptrs);
124   }
125 
126   uint jvm_version_offset() const { return _jvm_version_offset; }
127 
128   uint cache_size()     const { return _cache_size; }
129   uint strings_count()  const { return _strings_count; }
130   uint strings_offset() const { return _strings_offset; }
131   uint entries_count()  const { return _entries_count; }
132   uint entries_offset() const { return _entries_offset; }
133   uint preload_entries_count()  const { return _preload_entries_count; }
134   uint preload_entries_offset() const { return _preload_entries_offset; }
135   bool has_meta_ptrs()  const { return _config.has_meta_ptrs(); }
136 
137   bool verify_config(const char* cache_path, uint load_size)  const;
138   bool verify_vm_config(const char* cache_path) const { // Called after Universe initialized
139     return _config.verify(cache_path);
140   }
141 };
142 
143 // Code Cache's entry contain information from CodeBuffer
144 class SCCEntry {
145 public:
146   enum Kind {
147     None = 0,
148     Stub = 1,
149     Blob = 2,
150     Code = 3
151   };
152 
153 private:
154   SCCEntry* _next;
155   Method*   _method;
156   Kind   _kind;        //
157   uint   _id;          // vmIntrinsic::ID for stub or name's hash for nmethod
158 
159   uint   _offset;      // Offset to entry
160   uint   _size;        // Entry size
161   uint   _name_offset; // Method's or intrinsic name
162   uint   _name_size;
163   uint   _code_offset; // Start of code in cache
164   uint   _code_size;   // Total size of all code sections
165   uint   _reloc_offset;// Relocations
166   uint   _reloc_size;  // Max size of relocations per code section
167   uint   _num_inlined_bytecodes;
168 
169   uint   _comp_level;  // compilation level
170   uint   _comp_id;     // compilation id
171   uint   _decompile;   // Decompile count for this nmethod
172   bool   _has_clinit_barriers; // Generated code has class init checks
173   bool   _for_preload; // Code can be used for preload
174   bool   _loaded;      // Code was loaded
175   bool   _not_entrant; // Deoptimized
176   bool   _load_fail;   // Failed to load due to some klass state
177   bool   _ignore_decompile; // ignore decompile counter if compilation is done
178                             // during "assembly" phase without running application
179 
180 public:
181   SCCEntry(uint offset, uint size, uint name_offset, uint name_size,
182            uint code_offset, uint code_size,
183            uint reloc_offset, uint reloc_size,
184            Kind kind, uint id, uint comp_level = 0,
185            uint comp_id = 0, uint decomp = 0,
186            bool has_clinit_barriers = false,
187            bool for_preload = false,
188            bool ignore_decompile = false) {
189     _next         = nullptr;
190     _method       = nullptr;
191     _kind         = kind;
192     _id           = id;
193 
194     _offset       = offset;
195     _size         = size;
196     _name_offset  = name_offset;
197     _name_size    = name_size;
198     _code_offset  = code_offset;
199     _code_size    = code_size;
200     _reloc_offset = reloc_offset;
201     _reloc_size   = reloc_size;
202     _num_inlined_bytecodes = 0;
203 
204     _comp_level   = comp_level;
205     _comp_id      = comp_id;
206     _decompile    = decomp;
207     _has_clinit_barriers = has_clinit_barriers;
208     _for_preload  = for_preload;
209     _loaded       = false;
210     _not_entrant  = false;
211     _load_fail    = false;
212     _ignore_decompile = ignore_decompile;
213   }
214   void* operator new(size_t x, SCCache* cache);
215   // Delete is a NOP
216   void operator delete( void *ptr ) {}
217 
218   SCCEntry* next()    const { return _next; }
219   void set_next(SCCEntry* next) { _next = next; }
220 
221   Method*   method()  const { return _method; }
222   void set_method(Method* method) { _method = method; }
223   void update_method_for_writing();
224 
225   Kind kind()         const { return _kind; }
226   uint id()           const { return _id; }
227 
228   uint offset()       const { return _offset; }
229   void set_offset(uint off) { _offset = off; }
230 
231   uint size()         const { return _size; }
232   uint name_offset()  const { return _name_offset; }
233   uint name_size()    const { return _name_size; }
234   uint code_offset()  const { return _code_offset; }
235   uint code_size()    const { return _code_size; }
236   uint reloc_offset() const { return _reloc_offset; }
237   uint reloc_size()   const { return _reloc_size; }
238   uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
239   void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; }
240 
241   uint comp_level()   const { return _comp_level; }
242   uint comp_id()      const { return _comp_id; }
243 
244   uint decompile()    const { return _decompile; }
245   bool has_clinit_barriers() const { return _has_clinit_barriers; }
246   bool for_preload()  const { return _for_preload; }
247   bool is_loaded()    const { return _loaded; }
248   void set_loaded()         { _loaded = true; }
249   bool ignore_decompile() const { return _ignore_decompile; }
250 
251   bool not_entrant()  const { return _not_entrant; }
252   void set_not_entrant()    { _not_entrant = true; }
253   void set_entrant()        { _not_entrant = false; }
254 
255   bool load_fail()  const { return _load_fail; }
256   void set_load_fail()    { _load_fail = true; }
257 
258   void print(outputStream* st) const;
259 };
260 
261 // Addresses of stubs, blobs and runtime finctions called from compiled code.
262 class SCAddressTable : public CHeapObj<mtCode> {
263 private:
264   address* _extrs_addr;
265   address* _stubs_addr;
266   address* _blobs_addr;
267   address* _C1_blobs_addr;
268   address* _C2_blobs_addr;
269   uint     _extrs_length;
270   uint     _stubs_length;
271   uint     _blobs_length;
272   uint     _C1_blobs_length;
273   uint     _C2_blobs_length;
274   uint     _final_blobs_length;
275 
276   bool _complete;
277   bool _opto_complete;
278   bool _c1_complete;
279 
280 public:
281   SCAddressTable() {
282     _extrs_addr = nullptr;
283     _stubs_addr = nullptr;
284     _blobs_addr = nullptr;
285     _complete = false;
286     _opto_complete = false;
287     _c1_complete = false;
288   }
289   ~SCAddressTable();
290   void init();
291   void init_opto();
292   void init_c1();
293   void add_C_string(const char* str);
294   int  id_for_C_string(address str);
295   address address_for_C_string(int idx);
296   int  id_for_address(address addr, RelocIterator iter, CodeBuffer* buffer);
297   address address_for_id(int id);
298   bool opto_complete() const { return _opto_complete; }
299   bool c1_complete() const { return _c1_complete; }
300 };
301 
302 struct SCCodeSection {
303 public:
304   address _origin_address;
305   uint _size;
306   uint _offset;
307 };
308 
309 enum class DataKind: int {
310   No_Data   = -1,
311   Null      = 0,
312   Klass     = 1,
313   Method    = 2,
314   String    = 3,
315   Primitive = 4, // primitive Class object
316   SysLoader = 5, // java_system_loader
317   PlaLoader = 6, // java_platform_loader
318   MethodCnts= 7,
319   Klass_Shared  = 8,
320   Method_Shared = 9,
321   String_Shared = 10,
322   MH_Oop_Shared = 11
323 };
324 
325 class SCCache;
326 
327 class SCCReader { // Concurent per compilation request
328 private:
329   const SCCache*  _cache;
330   const SCCEntry* _entry;
331   const char*     _load_buffer; // Loaded cached code buffer
332   uint  _read_position;            // Position in _load_buffer
333   uint  read_position() const { return _read_position; }
334   void  set_read_position(uint pos);
335   const char* addr(uint offset) const { return _load_buffer + offset; }
336 
337   uint _compile_id;
338   uint _comp_level;
339   uint compile_id() const { return _compile_id; }
340   uint comp_level() const { return _comp_level; }
341 
342   bool _preload;             // Preloading code before method execution
343   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
344   void set_lookup_failed()     { _lookup_failed = true; }
345   void clear_lookup_failed()   { _lookup_failed = false; }
346   bool lookup_failed()   const { return _lookup_failed; }
347 
348 public:
349   SCCReader(SCCache* cache, SCCEntry* entry, CompileTask* task);
350 
351   bool compile(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler);
352   bool compile_blob(CodeBuffer* buffer, int* pc_offset);
353 
354   Klass* read_klass(const methodHandle& comp_method, bool shared);
355   Method* read_method(const methodHandle& comp_method, bool shared);
356 
357   bool read_code(CodeBuffer* buffer, CodeBuffer* orig_buffer, uint code_offset);
358   bool read_relocations(CodeBuffer* buffer, CodeBuffer* orig_buffer, OopRecorder* oop_recorder, ciMethod* target);
359   DebugInformationRecorder* read_debug_info(OopRecorder* oop_recorder);
360   OopMapSet* read_oop_maps();
361   bool read_dependencies(Dependencies* dependencies);
362 
363   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
364   Metadata* read_metadata(const methodHandle& comp_method);
365   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
366   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
367 
368   void print_on(outputStream* st);
369 };
370 
371 class SCCache : public CHeapObj<mtCode> {
372 private:
373   SCCHeader*  _load_header;
374   const char* _cache_path;
375   char*       _load_buffer;    // Aligned buffer for loading cached code
376   char*       _store_buffer;   // Aligned buffer for storing cached code
377   char*       _C_load_buffer;  // Original unaligned buffer
378   char*       _C_store_buffer; // Original unaligned buffer
379 
380   uint        _write_position; // Position in _store_buffer
381   uint        _load_size;      // Used when reading cache
382   uint        _store_size;     // Used when writing cache
383   bool _for_read;              // Open for read
384   bool _for_write;             // Open for write
385   bool _use_meta_ptrs;         // Store metadata pointers
386   bool _for_preload;           // Code for preload
387   bool _gen_preload_code;      // Generate pre-loading code
388   bool _has_clinit_barriers;   // Code with clinit barriers
389   bool _closing;               // Closing cache file
390   bool _failed;                // Failed read/write to/from cache (cache is broken?)
391 
392   SCAddressTable* _table;
393 
394   SCCEntry* _load_entries;     // Used when reading cache
395   uint*     _search_entries;   // sorted by ID table [id, index]
396   SCCEntry* _store_entries;    // Used when writing cache
397   const char* _C_strings_buf;  // Loaded buffer for _C_strings[] table
398   uint      _store_entries_cnt;
399 
400   uint _compile_id;
401   uint _comp_level;
402   uint compile_id() const { return _compile_id; }
403   uint comp_level() const { return _comp_level; }
404 
405   static SCCache* open_for_read();
406   static SCCache* open_for_write();
407 
408   bool set_write_position(uint pos);
409   bool align_write();
410   uint write_bytes(const void* buffer, uint nbytes);
411   const char* addr(uint offset) const { return _load_buffer + offset; }
412 
413   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
414   void set_lookup_failed()     { _lookup_failed = true; }
415   void clear_lookup_failed()   { _lookup_failed = false; }
416   bool lookup_failed()   const { return _lookup_failed; }
417 
418   SCCEntry* write_nmethod(const methodHandle& method,
419                           int compile_id,
420                           int entry_bci,
421                           CodeOffsets* offsets,
422                           int orig_pc_offset,
423                           DebugInformationRecorder* recorder,
424                           Dependencies* dependencies,
425                           CodeBuffer *code_buffer,
426                           int frame_size,
427                           OopMapSet* oop_maps,
428                           ExceptionHandlerTable* handler_table,
429                           ImplicitExceptionTable* nul_chk_table,
430                           AbstractCompiler* compiler,
431                           CompLevel comp_level,
432                           bool has_clinit_barriers,
433                           bool for_preload,
434                           bool has_unsafe_access,
435                           bool has_wide_vectors,
436                           bool has_monitors,
437                           bool has_scoped_access);
438 
439   // States:
440   //   S >= 0: allow new readers, S readers are currently active
441   //   S <  0: no new readers are allowed; (-S-1) readers are currently active
442   //     (special case: S = -1 means no readers are active, and would never be active again)
443   static volatile int _nmethod_readers;
444 
445   static void wait_for_no_nmethod_readers();
446 
447   class ReadingMark {
448   private:
449     bool _failed;
450   public:
451     ReadingMark();
452     ~ReadingMark();
453     bool failed() {
454       return _failed;
455     }
456   };
457 
458 public:
459   SCCache(const char* cache_path, int fd, uint load_size);
460   ~SCCache();
461 
462   const char* cache_buffer() const { return _load_buffer; }
463   const char* cache_path()   const { return _cache_path; }
464   bool failed() const { return _failed; }
465   void set_failed()   { _failed = true; }
466 
467   uint load_size() const { return _load_size; }
468   uint write_position() const { return _write_position; }
469 
470   void load_strings();
471   int store_strings();
472 
473   static void init_table();
474   static void init_opto_table();
475   static void init_c1_table();
476   address address_for_id(int id) const { return _table->address_for_id(id); }
477 
478   bool for_read()  const { return _for_read  && !_failed; }
479   bool for_write() const { return _for_write && !_failed; }
480 
481   bool closing()          const { return _closing; }
482   bool use_meta_ptrs()    const { return _use_meta_ptrs; }
483   bool gen_preload_code() const { return _gen_preload_code; }
484 
485   void add_new_C_string(const char* str);
486 
487   SCCEntry* add_entry() {
488     _store_entries_cnt++;
489     _store_entries -= 1;
490     return _store_entries;
491   }
492   void preload_startup_code(TRAPS);
493 
494   SCCEntry* find_entry(SCCEntry::Kind kind, uint id, uint comp_level = 0, uint decomp = 0);
495   void invalidate_entry(SCCEntry* entry);
496 
497   bool finish_write();
498 
499   static bool load_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start);
500   static bool store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start);
501 
502   bool write_klass(Klass* klass);
503   bool write_method(Method* method);
504 
505   bool write_code(CodeBuffer* buffer, uint& code_size);
506   bool write_relocations(CodeBuffer* buffer, uint& reloc_size);
507   bool write_debug_info(DebugInformationRecorder* recorder);
508   bool write_oop_maps(OopMapSet* oop_maps);
509 
510   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
511   Metadata* read_metadata(const methodHandle& comp_method);
512   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
513   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
514 
515   bool write_oop(jobject& jo);
516   bool write_oops(OopRecorder* oop_recorder);
517   bool write_metadata(Metadata* m);
518   bool write_metadata(OopRecorder* oop_recorder);
519 
520   static bool load_exception_blob(CodeBuffer* buffer, int* pc_offset);
521   static bool store_exception_blob(CodeBuffer* buffer, int pc_offset);
522 
523   static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level);
524 
525   static SCCEntry* store_nmethod(const methodHandle& method,
526                      int compile_id,
527                      int entry_bci,
528                      CodeOffsets* offsets,
529                      int orig_pc_offset,
530                      DebugInformationRecorder* recorder,
531                      Dependencies* dependencies,
532                      CodeBuffer *code_buffer,
533                      int frame_size,
534                      OopMapSet* oop_maps,
535                      ExceptionHandlerTable* handler_table,
536                      ImplicitExceptionTable* nul_chk_table,
537                      AbstractCompiler* compiler,
538                      CompLevel comp_level,
539                      bool has_clinit_barriers,
540                      bool for_preload,
541                      bool has_unsafe_access,
542                      bool has_wide_vectors,
543                      bool has_monitors,
544                      bool has_scoped_access);
545 
546   static uint store_entries_cnt() {
547     if (is_on_for_write()) {
548       return cache()->_store_entries_cnt;
549     }
550     return -1;
551   }
552 
553 // Static access
554 
555 private:
556   static SCCache*  _cache;
557 
558   static bool open_cache(const char* cache_path);
559   static bool verify_vm_config() {
560     if (is_on_for_read()) {
561       return _cache->_load_header->verify_vm_config(_cache->_cache_path);
562     }
563     return true;
564   }
565 public:
566   static SCCache* cache() { return _cache; }
567   static void initialize();
568   static void init2();
569   static void close();
570   static bool is_on() { return _cache != nullptr && !_cache->closing(); }
571   static bool is_C3_on();
572   static bool is_code_load_thread_on();
573   static bool is_on_for_read()  { return is_on() && _cache->for_read(); }
574   static bool is_on_for_write() { return is_on() && _cache->for_write(); }
575   static bool gen_preload_code(ciMethod* m, int entry_bci);
576   static bool allow_const_field(ciConstant& value);
577   static void invalidate(SCCEntry* entry);
578   static bool is_loaded(SCCEntry* entry);
579   static SCCEntry* find_code_entry(const methodHandle& method, uint comp_level);
580   static void preload_code(JavaThread* thread);
581 
582   template<typename Function>
583   static void iterate(Function function) { // lambda enabled API
584     SCCache* cache = open_for_read();
585     if (cache != nullptr) {
586       ReadingMark rdmk;
587       if (rdmk.failed()) {
588         // Cache is closed, cannot touch anything.
589         return;
590       }
591 
592       uint count = cache->_load_header->entries_count();
593       uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index]
594       SCCEntry* load_entries = (SCCEntry*)(search_entries + 2 * count);
595 
596       for (uint i = 0; i < count; i++) {
597         int index = search_entries[2*i + 1];
598         SCCEntry* entry = &(load_entries[index]);
599         function(entry);
600       }
601     }
602   }
603 
604   static void add_C_string(const char* str);
605 
606   static void print_on(outputStream* st);
607   static void print_statistics_on(outputStream* st);
608   static void print_timers_on(outputStream* st);
609   static void print_unused_entries_on(outputStream* st);
610 
611   static void new_workflow_start_writing_cache() NOT_CDS_JAVA_HEAP_RETURN;
612   static void new_workflow_end_writing_cache() NOT_CDS_JAVA_HEAP_RETURN;
613   static void new_workflow_load_cache() NOT_CDS_JAVA_HEAP_RETURN;
614 };
615 
616 // code cache internal runtime constants area used by AOT code
617 class AOTRuntimeConstants {
618  friend class SCCache;
619   uint _grain_shift;
620   uint _card_shift;
621   static address _field_addresses_list[];
622   static AOTRuntimeConstants _aot_runtime_constants;
623   // private constructor for unique singleton
624   AOTRuntimeConstants() { }
625   // private for use by friend class SCCache
626   static void initialize_from_runtime();
627  public:
628   static bool contains(address adr) {
629     address base = (address)&_aot_runtime_constants;
630     address hi = base + sizeof(AOTRuntimeConstants);
631     return (base <= adr && adr < hi);
632   }
633   static address grain_shift_address() { return (address)&_aot_runtime_constants._grain_shift; }
634   static address card_shift_address() { return (address)&_aot_runtime_constants._card_shift; }
635   static address* field_addresses_list() {
636     return _field_addresses_list;
637   }
638 };
639 
640 #endif // SHARE_CODE_SCCACHE_HPP