1 /*
   2  * Copyright (c) 2016, 2017, 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 #ifndef SHARE_VM_AOT_AOTCODEHEAP_HPP
  25 #define SHARE_VM_AOT_AOTCODEHEAP_HPP
  26 
  27 #include "aot/aotCompiledMethod.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "metaprogramming/integralConstant.hpp"
  30 #include "metaprogramming/isRegisteredEnum.hpp"
  31 #include "oops/metadata.hpp"
  32 #include "oops/method.hpp"
  33 
  34 enum CodeState {
  35   not_set = 0, // _aot fields is not set yet
  36   in_use  = 1, // _aot field is set to corresponding AOTCompiledMethod
  37   invalid = 2  // AOT code is invalidated because dependencies failed
  38 };
  39 
  40 template<> struct IsRegisteredEnum<CodeState> : public TrueType {};
  41 
  42 typedef struct {
  43   AOTCompiledMethod* _aot;
  44   CodeState _state; // State change cases: not_set->in_use, not_set->invalid
  45 } CodeToAMethod;
  46 
  47 class ClassLoaderData;
  48 
  49 class AOTClass {
  50 public:
  51   ClassLoaderData* _classloader;
  52 };
  53 
  54 typedef struct {
  55   int _name_offset;
  56   int _code_offset;
  57   int _meta_offset;
  58   int _metadata_got_offset;
  59   int _metadata_got_size;
  60   int _code_id;
  61 } AOTMethodOffsets;
  62 
  63 typedef struct {
  64   const char* _name;
  65   address     _code;
  66   aot_metadata* _meta;
  67   jlong*      _state_adr;
  68   address     _metadata_table;
  69   int         _metadata_size;
  70 } AOTMethodData;
  71 
  72 typedef struct {
  73   int _got_index;
  74   int _class_id;
  75   int _compiled_methods_offset;
  76   int _dependent_methods_offset;
  77   uint64_t _fingerprint;
  78 } AOTKlassData;
  79 
  80 typedef struct {
  81   int _version;
  82   int _class_count;
  83   int _method_count;
  84   int _metaspace_got_size;
  85   int _metadata_got_size;
  86   int _oop_got_size;
  87   int _jvm_version_offset;
  88 
  89   enum {
  90     AOT_SHARED_VERSION = 1
  91   };
  92 } AOTHeader;
  93 
  94 typedef struct {
  95   enum { CONFIG_SIZE = 7 * jintSize + 11 };
  96   // 7 int values
  97   int _config_size;
  98   int _narrowOopShift;
  99   int _narrowKlassShift;
 100   int _contendedPaddingWidth;
 101   int _fieldsAllocationStyle;
 102   int _objectAlignment;
 103   int _codeSegmentSize;
 104   // byte[11] array map to boolean values here
 105   bool _debug_VM;
 106   bool _useCompressedOops;
 107   bool _useCompressedClassPointers;
 108   bool _compactFields;
 109   bool _useG1GC;
 110   bool _useTLAB;
 111   bool _useBiasedLocking;
 112   bool _tieredAOT;
 113   bool _enableContended;
 114   bool _restrictContended;
 115   bool _omitAssertions;
 116 } AOTConfiguration;
 117 
 118 class AOTLib : public CHeapObj<mtCode> {
 119   static bool _narrow_oop_shift_initialized;
 120   static int _narrow_oop_shift;
 121   static int _narrow_klass_shift;
 122 
 123   bool _valid;
 124   void* _dl_handle;
 125   const int _dso_id;
 126   const char* _name;
 127   // VM configuration during AOT compilation
 128   AOTConfiguration* _config;
 129   AOTHeader* _header;
 130 
 131   void handle_config_error(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
 132 public:
 133   AOTLib(void* handle, const char* name, int dso_id);
 134   virtual ~AOTLib();
 135   static int  narrow_oop_shift() { return _narrow_oop_shift; }
 136   static int  narrow_klass_shift() { return _narrow_klass_shift; }
 137   static bool narrow_oop_shift_initialized() { return _narrow_oop_shift_initialized; }
 138 
 139   bool is_valid() const {
 140     return _valid;
 141   }
 142   const char* name() const {
 143     return _name;
 144   }
 145   void* dl_handle() const {
 146     return _dl_handle;
 147   }
 148   int id() const {
 149     return _dso_id;
 150   }
 151   AOTHeader* header() const {
 152     return _header;
 153   }
 154   AOTConfiguration* config() const {
 155     return _config;
 156   }
 157   void verify_config();
 158   void verify_flag(bool aot_flag, bool flag, const char* name);
 159   void verify_flag(int  aot_flag, int  flag, const char* name);
 160 
 161   address load_symbol(const char *name);
 162 };
 163 
 164 
 165 class AOTCodeHeap : public CodeHeap {
 166   AOTLib* _lib;
 167   int _aot_id;
 168 
 169   int _class_count;
 170   int _method_count;
 171   AOTClass* _classes;
 172   CodeToAMethod* _code_to_aot;
 173 
 174   address _code_space;
 175   address _code_segments;
 176   jlong*  _method_state;
 177 
 178 
 179   // Collect metaspace info: names -> address in .got section
 180   const char* _metaspace_names;
 181   address _method_metadata;
 182 
 183   address _methods_offsets;
 184   address _klasses_offsets;
 185   address _dependencies;
 186 
 187   Metadata** _metaspace_got;
 188   Metadata** _metadata_got;
 189   oop*    _oop_got;
 190 
 191   int _metaspace_got_size;
 192   int _metadata_got_size;
 193   int _oop_got_size;
 194 
 195   // Collect stubs info
 196   int* _stubs_offsets;
 197 
 198   bool _lib_symbols_initialized;
 199 
 200   void adjust_boundaries(AOTCompiledMethod* method) {
 201     char* low = (char*)method->code_begin();
 202     if (low < low_boundary()) {
 203       _memory.set_low_boundary(low);
 204       _memory.set_low(low);
 205     }
 206     char* high = (char *)method->code_end();
 207     if (high > high_boundary()) {
 208       _memory.set_high_boundary(high);
 209       _memory.set_high(high);
 210     }
 211     assert(_method_count > 0, "methods count should be set already");
 212   }
 213 
 214   void register_stubs();
 215 
 216   void link_shared_runtime_symbols();
 217   void link_stub_routines_symbols();
 218   void link_os_symbols();
 219   void link_graal_runtime_symbols();
 220 
 221   void link_global_lib_symbols();
 222   void link_primitive_array_klasses();
 223   void publish_aot(const methodHandle& mh, AOTMethodData* method_data, int code_id);
 224 
 225 
 226   AOTCompiledMethod* next_in_use_at(int index) const;
 227 
 228   // Find klass in SystemDictionary for aot metadata.
 229   static Klass* lookup_klass(const char* name, int len, const Method* method, Thread* THREAD);
 230 public:
 231   AOTCodeHeap(AOTLib* lib);
 232   virtual ~AOTCodeHeap();
 233 
 234   AOTCompiledMethod* find_aot(address p) const;
 235 
 236   virtual void* find_start(void* p)     const;
 237   virtual CodeBlob* find_blob_unsafe(void* start) const;
 238   virtual void* first() const;
 239   virtual void* next(void *p) const;
 240 
 241   AOTKlassData* find_klass(InstanceKlass* ik);
 242   bool load_klass_data(InstanceKlass* ik, Thread* thread);
 243   Klass* get_klass_from_got(const char* klass_name, int klass_len, const Method* method);
 244   void sweep_dependent_methods(AOTKlassData* klass_data);
 245   bool is_dependent_method(Klass* dependee, AOTCompiledMethod* aot);
 246 
 247   const char* get_name_at(int offset) {
 248     return _metaspace_names + offset;
 249   }
 250 
 251   void oops_do(OopClosure* f);
 252   void metadata_do(void f(Metadata*));
 253   void got_metadata_do(void f(Metadata*));
 254 
 255 #ifdef ASSERT
 256   bool got_contains(Metadata **p) {
 257     return (p >= &_metadata_got[0] && p < &_metadata_got[_metadata_got_size]) ||
 258            (p >= &_metaspace_got[0] && p < &_metaspace_got[_metaspace_got_size]);
 259   }
 260 #endif
 261 
 262   int dso_id() const { return _lib->id(); }
 263   int aot_id() const { return _aot_id; }
 264 
 265   int method_count() { return _method_count; }
 266 
 267   AOTCompiledMethod* get_code_desc_at_index(int index) {
 268     if (index < _method_count && _code_to_aot[index]._state == in_use) {
 269         AOTCompiledMethod* m = _code_to_aot[index]._aot;
 270         assert(m != NULL, "AOT method should be set");
 271         if (!m->is_runtime_stub()) {
 272           return m;
 273         }
 274     }
 275     return NULL;
 276   }
 277 
 278   static Method* find_method(Klass* klass, Thread* thread, const char* method_name);
 279 
 280   void cleanup_inline_caches();
 281 
 282   DEBUG_ONLY( int verify_icholder_relocations(); )
 283 
 284   void flush_evol_dependents_on(InstanceKlass* dependee);
 285 
 286   void alive_methods_do(void f(CompiledMethod* nm));
 287 
 288 #ifndef PRODUCT
 289   static int klasses_seen;
 290   static int aot_klasses_found;
 291   static int aot_klasses_fp_miss;
 292   static int aot_klasses_cl_miss;
 293   static int aot_methods_found;
 294 
 295   static void print_statistics();
 296 #endif
 297 };
 298 
 299 #endif // SHARE_VM_AOT_AOTCODEHEAP_HPP