1 /*
  2  * Copyright (c) 2023, 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     useEmptySlotsInSupers    = 512
 80   };
 81   uint _flags;
 82 
 83 public:
 84   void record(bool use_meta_ptrs);
 85   bool verify(const char* cache_path) const;
 86 
 87   bool has_meta_ptrs()  const { return (_flags & metadataPointers) != 0; }
 88 };
 89 
 90 // Code Cache file header
 91 class SCCHeader : public CHeapObj<mtCode> {
 92 private:
 93   // Here should be version and other verification fields
 94   enum {
 95     SCC_VERSION = 1
 96   };
 97   uint _version;           // SCC version (should match when reading code cache)
 98   uint _jvm_version_offset;// JVM version string
 99   uint _cache_size;        // cache size in bytes
100   uint _strings_count;
101   uint _strings_offset;    // offset to recorded C strings
102   uint _entries_count;     // number of recorded entries in cache
103   uint _entries_offset;    // offset of SCCEntry array describing entries
104   uint _preload_entries_count; // entries for pre-loading code
105   uint _preload_entries_offset;
106   SCConfig _config;
107 
108 public:
109   void init(uint jvm_version_offset, uint cache_size,
110             uint strings_count, uint strings_offset,
111             uint entries_count, uint entries_offset,
112             uint preload_entries_count, uint preload_entries_offset,
113             bool use_meta_ptrs) {
114     _version        = SCC_VERSION;
115      _jvm_version_offset = jvm_version_offset;
116     _cache_size     = cache_size;
117     _strings_count  = strings_count;
118     _strings_offset = strings_offset;
119     _entries_count  = entries_count;
120     _entries_offset = entries_offset;
121     _preload_entries_count  = preload_entries_count;
122     _preload_entries_offset = preload_entries_offset;
123 
124     _config.record(use_meta_ptrs);
125   }
126 
127   uint jvm_version_offset() const { return _jvm_version_offset; }
128 
129   uint cache_size()     const { return _cache_size; }
130   uint strings_count()  const { return _strings_count; }
131   uint strings_offset() const { return _strings_offset; }
132   uint entries_count()  const { return _entries_count; }
133   uint entries_offset() const { return _entries_offset; }
134   uint preload_entries_count()  const { return _preload_entries_count; }
135   uint preload_entries_offset() const { return _preload_entries_offset; }
136   bool has_meta_ptrs()  const { return _config.has_meta_ptrs(); }
137 
138   bool verify_config(const char* cache_path, uint load_size)  const;
139   bool verify_vm_config(const char* cache_path) const { // Called after Universe initialized
140     return _config.verify(cache_path);
141   }
142 };
143 
144 // Code Cache's entry contain information from CodeBuffer
145 class SCCEntry {
146 public:
147   enum Kind {
148     None = 0,
149     Stub = 1,
150     Blob = 2,
151     Code = 3
152   };
153 
154 private:
155   SCCEntry* _next;
156   Method*   _method;
157   Kind   _kind;        //
158   uint   _id;          // vmIntrinsic::ID for stub or name's hash for nmethod
159 
160   uint   _offset;      // Offset to entry
161   uint   _size;        // Entry size
162   uint   _name_offset; // Method's or intrinsic name
163   uint   _name_size;
164   uint   _code_offset; // Start of code in cache
165   uint   _code_size;   // Total size of all code sections
166   uint   _reloc_offset;// Relocations
167   uint   _reloc_size;  // Max size of relocations per code section
168   uint   _num_inlined_bytecodes;
169 
170   uint   _comp_level;  // compilation level
171   uint   _comp_id;     // compilation id
172   uint   _decompile;   // Decompile count for this nmethod
173   bool   _has_clinit_barriers; // Generated code has class init checks
174   bool   _for_preload; // Code can be used for preload
175   bool   _loaded;      // Code was loaded
176   bool   _not_entrant; // Deoptimized
177   bool   _load_fail;   // Failed to load due to some klass state
178 
179 public:
180   SCCEntry(uint offset, uint size, uint name_offset, uint name_size,
181            uint code_offset, uint code_size,
182            uint reloc_offset, uint reloc_size,
183            Kind kind, uint id, uint comp_level = 0,
184            uint comp_id = 0, uint decomp = 0,
185            bool has_clinit_barriers = false,
186            bool for_preload = false) {
187     _next         = nullptr;
188     _method       = nullptr;
189     _kind         = kind;
190     _id           = id;
191 
192     _offset       = offset;
193     _size         = size;
194     _name_offset  = name_offset;
195     _name_size    = name_size;
196     _code_offset  = code_offset;
197     _code_size    = code_size;
198     _reloc_offset = reloc_offset;
199     _reloc_size   = reloc_size;
200     _num_inlined_bytecodes = 0;
201 
202     _comp_level   = comp_level;
203     _comp_id      = comp_id;
204     _decompile    = decomp;
205     _has_clinit_barriers = has_clinit_barriers;
206     _for_preload  = for_preload;
207     _loaded       = false;
208     _not_entrant  = false;
209     _load_fail    = false;
210   }
211   void* operator new(size_t x, SCCache* cache);
212   // Delete is a NOP
213   void operator delete( void *ptr ) {}
214 
215   SCCEntry* next()    const { return _next; }
216   void set_next(SCCEntry* next) { _next = next; }
217 
218   Method*   method()  const { return _method; }
219   void set_method(Method* method) { _method = method; }
220   void update_method_for_writing();
221 
222   Kind kind()         const { return _kind; }
223   uint id()           const { return _id; }
224 
225   uint offset()       const { return _offset; }
226   void set_offset(uint off) { _offset = off; }
227 
228   uint size()         const { return _size; }
229   uint name_offset()  const { return _name_offset; }
230   uint name_size()    const { return _name_size; }
231   uint code_offset()  const { return _code_offset; }
232   uint code_size()    const { return _code_size; }
233   uint reloc_offset() const { return _reloc_offset; }
234   uint reloc_size()   const { return _reloc_size; }
235   uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
236   void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; }
237 
238   uint comp_level()   const { return _comp_level; }
239   uint comp_id()      const { return _comp_id; }
240 
241   uint decompile()    const { return _decompile; }
242   bool has_clinit_barriers() const { return _has_clinit_barriers; }
243   bool for_preload()  const { return _for_preload; }
244   bool is_loaded()    const { return _loaded; }
245   void set_loaded()         { _loaded = true; }
246 
247   bool not_entrant()  const { return _not_entrant; }
248   void set_not_entrant()    { _not_entrant = true; }
249   void set_entrant()        { _not_entrant = false; }
250 
251   bool load_fail()  const { return _load_fail; }
252   void set_load_fail()    { _load_fail = true; }
253 
254   void print(outputStream* st) const;
255 };
256 
257 // Addresses of stubs, blobs and runtime finctions called from compiled code.
258 class SCAddressTable : public CHeapObj<mtCode> {
259 private:
260   address* _extrs_addr;
261   address* _stubs_addr;
262   address* _blobs_addr;
263   address* _C1_blobs_addr;
264   address* _C2_blobs_addr;
265   uint     _extrs_length;
266   uint     _stubs_length;
267   uint     _blobs_length;
268   uint     _C1_blobs_length;
269   uint     _C2_blobs_length;
270   uint     _final_blobs_length;
271 
272   bool _complete;
273   bool _opto_complete;
274   bool _c1_complete;
275 
276 public:
277   SCAddressTable() {
278     _extrs_addr = nullptr;
279     _stubs_addr = nullptr;
280     _blobs_addr = nullptr;
281     _complete = false;
282     _opto_complete = false;
283     _c1_complete = false;
284   }
285   ~SCAddressTable();
286   void init();
287   void init_opto();
288   void init_c1();
289   void add_C_string(const char* str);
290   int  id_for_C_string(address str);
291   address address_for_C_string(int idx);
292   int  id_for_address(address addr, RelocIterator iter, CodeBuffer* buffer);
293   address address_for_id(int id);
294   bool opto_complete() const { return _opto_complete; }
295   bool c1_complete() const { return _c1_complete; }
296 };
297 
298 struct SCCodeSection {
299 public:
300   address _origin_address;
301   uint _size;
302   uint _offset;
303 };
304 
305 enum class DataKind: int {
306   No_Data   = -1,
307   Null      = 0,
308   Klass     = 1,
309   Method    = 2,
310   String    = 3,
311   Primitive = 4, // primitive Class object
312   SysLoader = 5, // java_system_loader
313   PlaLoader = 6, // java_platform_loader
314   MethodCnts= 7,
315   Klass_Shared  = 8,
316   Method_Shared = 9,
317   String_Shared = 10,
318   MH_Oop_Shared = 11
319 };
320 
321 class SCCache;
322 
323 class SCCReader { // Concurent per compilation request
324 private:
325   const SCCache*  _cache;
326   const SCCEntry* _entry;
327   const char*     _load_buffer; // Loaded cached code buffer
328   uint  _read_position;            // Position in _load_buffer
329   uint  read_position() const { return _read_position; }
330   void  set_read_position(uint pos);
331   const char* addr(uint offset) const { return _load_buffer + offset; }
332 
333   uint _compile_id;
334   uint _comp_level;
335   uint compile_id() const { return _compile_id; }
336   uint comp_level() const { return _comp_level; }
337 
338   bool _preload;             // Preloading code before method execution
339   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
340   void set_lookup_failed()     { _lookup_failed = true; }
341   void clear_lookup_failed()   { _lookup_failed = false; }
342   bool lookup_failed()   const { return _lookup_failed; }
343 
344 public:
345   SCCReader(SCCache* cache, SCCEntry* entry, CompileTask* task);
346 
347   bool compile(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler);
348   bool compile_blob(CodeBuffer* buffer, int* pc_offset);
349 
350   Klass* read_klass(const methodHandle& comp_method, bool shared);
351   Method* read_method(const methodHandle& comp_method, bool shared);
352 
353   bool read_code(CodeBuffer* buffer, CodeBuffer* orig_buffer, uint code_offset);
354   bool read_relocations(CodeBuffer* buffer, CodeBuffer* orig_buffer, OopRecorder* oop_recorder, ciMethod* target);
355   DebugInformationRecorder* read_debug_info(OopRecorder* oop_recorder);
356   OopMapSet* read_oop_maps();
357   bool read_dependencies(Dependencies* dependencies);
358 
359   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
360   Metadata* read_metadata(const methodHandle& comp_method);
361   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
362   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
363 
364   void print_on(outputStream* st);
365 };
366 
367 class SCCache : public CHeapObj<mtCode> {
368 private:
369   SCCHeader*  _load_header;
370   const char* _cache_path;
371   char*       _load_buffer;    // Aligned buffer for loading cached code
372   char*       _store_buffer;   // Aligned buffer for storing cached code
373   char*       _C_load_buffer;  // Original unaligned buffer
374   char*       _C_store_buffer; // Original unaligned buffer
375 
376   uint        _write_position; // Position in _store_buffer
377   uint        _load_size;      // Used when reading cache
378   uint        _store_size;     // Used when writing cache
379   bool _for_read;              // Open for read
380   bool _for_write;             // Open for write
381   bool _use_meta_ptrs;         // Store metadata pointers
382   bool _for_preload;           // Code for preload
383   bool _gen_preload_code;      // Generate pre-loading code
384   bool _has_clinit_barriers;   // Code with clinit barriers
385   bool _closing;               // Closing cache file
386   bool _failed;                // Failed read/write to/from cache (cache is broken?)
387 
388   SCAddressTable* _table;
389 
390   SCCEntry* _load_entries;     // Used when reading cache
391   uint*     _search_entries;   // sorted by ID table [id, index]
392   SCCEntry* _store_entries;    // Used when writing cache
393   const char* _C_strings_buf;  // Loaded buffer for _C_strings[] table
394   uint      _store_entries_cnt;
395 
396   uint _compile_id;
397   uint _comp_level;
398   uint compile_id() const { return _compile_id; }
399   uint comp_level() const { return _comp_level; }
400 
401   static SCCache* open_for_read();
402   static SCCache* open_for_write();
403 
404   bool set_write_position(uint pos);
405   bool align_write();
406   uint write_bytes(const void* buffer, uint nbytes);
407   const char* addr(uint offset) const { return _load_buffer + offset; }
408 
409   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
410   void set_lookup_failed()     { _lookup_failed = true; }
411   void clear_lookup_failed()   { _lookup_failed = false; }
412   bool lookup_failed()   const { return _lookup_failed; }
413 
414 public:
415   SCCache(const char* cache_path, int fd, uint load_size);
416   ~SCCache();
417 
418   const char* cache_buffer() const { return _load_buffer; }
419   const char* cache_path()   const { return _cache_path; }
420   bool failed() const { return _failed; }
421   void set_failed()   { _failed = true; }
422 
423   uint load_size() const { return _load_size; }
424   uint write_position() const { return _write_position; }
425 
426   void load_strings();
427   int store_strings();
428 
429   static void init_table();
430   static void init_opto_table();
431   static void init_c1_table();
432   address address_for_id(int id) const { return _table->address_for_id(id); }
433 
434   bool for_read()  const { return _for_read  && !_failed; }
435   bool for_write() const { return _for_write && !_failed; }
436 
437   bool closing()          const { return _closing; }
438   bool use_meta_ptrs()    const { return _use_meta_ptrs; }
439   bool gen_preload_code() const { return _gen_preload_code; }
440 
441   void add_new_C_string(const char* str);
442 
443   SCCEntry* add_entry() {
444     _store_entries_cnt++;
445     _store_entries -= 1;
446     return _store_entries;
447   }
448   void preload_startup_code(TRAPS);
449 
450   SCCEntry* find_entry(SCCEntry::Kind kind, uint id, uint comp_level = 0, uint decomp = 0);
451   void invalidate_entry(SCCEntry* entry);
452 
453   bool finish_write();
454 
455   static bool load_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start);
456   static bool store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start);
457 
458   bool write_klass(Klass* klass);
459   bool write_method(Method* method);
460 
461   bool write_code(CodeBuffer* buffer, uint& code_size);
462   bool write_relocations(CodeBuffer* buffer, uint& reloc_size);
463   bool write_debug_info(DebugInformationRecorder* recorder);
464   bool write_oop_maps(OopMapSet* oop_maps);
465 
466   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
467   Metadata* read_metadata(const methodHandle& comp_method);
468   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
469   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
470 
471   bool write_oop(jobject& jo);
472   bool write_oops(OopRecorder* oop_recorder);
473   bool write_metadata(Metadata* m);
474   bool write_metadata(OopRecorder* oop_recorder);
475 
476   static bool load_exception_blob(CodeBuffer* buffer, int* pc_offset);
477   static bool store_exception_blob(CodeBuffer* buffer, int pc_offset);
478 
479   static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level);
480 
481   static SCCEntry* store_nmethod(const methodHandle& method,
482                      int compile_id,
483                      int entry_bci,
484                      CodeOffsets* offsets,
485                      int orig_pc_offset,
486                      DebugInformationRecorder* recorder,
487                      Dependencies* dependencies,
488                      CodeBuffer *code_buffer,
489                      int frame_size,
490                      OopMapSet* oop_maps,
491                      ExceptionHandlerTable* handler_table,
492                      ImplicitExceptionTable* nul_chk_table,
493                      AbstractCompiler* compiler,
494                      CompLevel comp_level,
495                      bool has_clinit_barriers,
496                      bool for_preload,
497                      bool has_unsafe_access,
498                      bool has_wide_vectors,
499                      bool has_monitors);
500 
501 // Static access
502 
503 private:
504   static SCCache*  _cache;
505 
506   static bool open_cache(const char* cache_path);
507   static bool verify_vm_config() {
508     if (is_on_for_read()) {
509       return _cache->_load_header->verify_vm_config(_cache->_cache_path);
510     }
511     return true;
512   }
513 public:
514   static SCCache* cache() { return _cache; }
515   static void initialize();
516   static void init2();
517   static void close();
518   static bool is_on() { return _cache != nullptr && !_cache->closing(); }
519   static bool is_C3_on();
520   static bool is_code_load_thread_on();
521   static bool is_on_for_read()  { return is_on() && _cache->for_read(); }
522   static bool is_on_for_write() { return is_on() && _cache->for_write(); }
523   static bool gen_preload_code(ciMethod* m, int entry_bci);
524   static bool allow_const_field(ciConstant& value);
525   static void invalidate(SCCEntry* entry);
526   static bool is_loaded(SCCEntry* entry);
527   static SCCEntry* find_code_entry(const methodHandle& method, uint comp_level);
528   static void preload_code(JavaThread* thread);
529 
530   static void add_C_string(const char* str);
531 
532   static void print_on(outputStream* st);
533   static void print_statistics_on(outputStream* st);
534   static void print_timers_on(outputStream* st);
535 
536   static void new_workflow_start_writing_cache();
537   static void new_workflow_end_writing_cache();
538   static void new_workflow_load_cache();
539 };
540 
541 #endif // SHARE_CODE_SCCACHE_HPP