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 #include "precompiled.hpp" 25 26 #include "aot/aotCodeHeap.hpp" 27 #include "aot/aotLoader.inline.hpp" 28 #include "jvmci/jvmciRuntime.hpp" 29 #include "oops/method.hpp" 30 #include "prims/jvm.h" 31 #include "runtime/os.hpp" 32 #include "runtime/timerTrace.hpp" 33 34 GrowableArray<AOTCodeHeap*>* AOTLoader::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTCodeHeap*> (2, true); 35 GrowableArray<AOTLib*>* AOTLoader::_libraries = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTLib*> (2, true); 36 37 // Iterate over all AOT CodeHeaps 38 #define FOR_ALL_AOT_HEAPS(heap) for (GrowableArrayIterator<AOTCodeHeap*> heap = heaps()->begin(); heap != heaps()->end(); ++heap) 39 // Iterate over all AOT Libraries 40 #define FOR_ALL_AOT_LIBRARIES(lib) for (GrowableArrayIterator<AOTLib*> lib = libraries()->begin(); lib != libraries()->end(); ++lib) 41 42 void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) { 43 if (UseAOT) { 44 FOR_ALL_AOT_HEAPS(heap) { 45 (*heap)->load_klass_data(ik, thread); 46 } 47 } 48 } 49 50 uint64_t AOTLoader::get_saved_fingerprint(InstanceKlass* ik) { 51 FOR_ALL_AOT_HEAPS(heap) { 52 AOTKlassData* klass_data = (*heap)->find_klass(ik); 53 if (klass_data != NULL) { 54 return klass_data->_fingerprint; 55 } 56 } 57 return 0; 58 } 59 60 bool AOTLoader::find_klass(InstanceKlass* ik) { 61 FOR_ALL_AOT_HEAPS(heap) { 62 if ((*heap)->find_klass(ik) != NULL) { 63 return true; 64 } 65 } 66 return false; 67 } 68 69 bool AOTLoader::contains(address p) { 70 FOR_ALL_AOT_HEAPS(heap) { 71 if ((*heap)->contains(p)) { 72 return true; 73 } 74 } 75 return false; 76 } 77 78 void AOTLoader::oops_do(OopClosure* f) { 79 if (UseAOT) { 80 FOR_ALL_AOT_HEAPS(heap) { 81 (*heap)->oops_do(f); 82 } 83 } 84 } 85 86 void AOTLoader::metadata_do(void f(Metadata*)) { 87 if (UseAOT) { 88 FOR_ALL_AOT_HEAPS(heap) { 89 (*heap)->metadata_do(f); 90 } 91 } 92 } 93 94 // Flushing and deoptimization in case of evolution 95 void AOTLoader::flush_evol_dependents_on(InstanceKlass* dependee) { 96 // make non entrant and mark for deoptimization 97 FOR_ALL_AOT_HEAPS(heap) { 98 (*heap)->flush_evol_dependents_on(dependee); 99 } 100 Deoptimization::deoptimize_dependents(); 101 } 102 103 /** 104 * List of core modules for which we search for shared libraries. 105 */ 106 static const char* modules[] = { 107 "java.base", 108 "java.logging", 109 "jdk.compiler", 110 "jdk.scripting.nashorn", 111 "jdk.internal.vm.ci", 112 "jdk.internal.vm.compiler" 113 }; 114 115 void AOTLoader::initialize() { 116 TraceTime timer("AOT initialization", TRACETIME_LOG(Info, aot, startuptime)); 117 118 if (FLAG_IS_DEFAULT(UseAOT) && AOTLibrary != NULL) { 119 // Don't need to set UseAOT on command line when AOTLibrary is specified 120 FLAG_SET_DEFAULT(UseAOT, true); 121 } 122 if (UseAOT) { 123 // EagerInitialization is not compatible with AOT 124 if (EagerInitialization) { 125 if (PrintAOT) { 126 warning("EagerInitialization is not compatible with AOT (switching AOT off)"); 127 } 128 FLAG_SET_DEFAULT(UseAOT, false); 129 return; 130 } 131 132 // -Xint is not compatible with AOT 133 if (Arguments::is_interpreter_only()) { 134 if (PrintAOT) { 135 warning("-Xint is not compatible with AOT (switching AOT off)"); 136 } 137 FLAG_SET_DEFAULT(UseAOT, false); 138 return; 139 } 140 141 const char* home = Arguments::get_java_home(); 142 const char* file_separator = os::file_separator(); 143 144 for (int i = 0; i < (int) (sizeof(modules) / sizeof(const char*)); i++) { 145 char library[JVM_MAXPATHLEN]; 146 jio_snprintf(library, sizeof(library), "%s%slib%slib%s%s%s%s", home, file_separator, file_separator, modules[i], UseCompressedOops ? "-coop" : "", UseG1GC ? "" : "-nong1", os::dll_file_extension()); 147 load_library(library, false); 148 } 149 150 // Scan the AOTLibrary option. 151 if (AOTLibrary != NULL) { 152 const int len = (int)strlen(AOTLibrary); 153 char* cp = NEW_C_HEAP_ARRAY(char, len+1, mtCode); 154 if (cp != NULL) { // No memory? 155 memcpy(cp, AOTLibrary, len); 156 cp[len] = '\0'; 157 char* end = cp + len; 158 while (cp < end) { 159 const char* name = cp; 160 while ((*cp) != '\0' && (*cp) != '\n' && (*cp) != ',' && (*cp) != ':' && (*cp) != ';') cp++; 161 cp[0] = '\0'; // Terminate name 162 cp++; 163 load_library(name, true); 164 } 165 } 166 } 167 } 168 } 169 170 void AOTLoader::universe_init() { 171 if (UseAOT && libraries_count() > 0) { 172 // Shifts are static values which initialized by 0 until java heap initialization. 173 // AOT libs are loaded before heap initialized so shift values are not set. 174 // It is okay since ObjectAlignmentInBytes flag which defines shifts value is set before AOT libs are loaded. 175 // Set shifts value based on first AOT library config. 176 if (UseCompressedOops && AOTLib::narrow_oop_shift_initialized()) { 177 int oop_shift = Universe::narrow_oop_shift(); 178 if (oop_shift == 0) { 179 Universe::set_narrow_oop_shift(AOTLib::narrow_oop_shift()); 180 } else { 181 FOR_ALL_AOT_LIBRARIES(lib) { 182 (*lib)->verify_flag(AOTLib::narrow_oop_shift(), oop_shift, "Universe::narrow_oop_shift"); 183 } 184 } 185 if (UseCompressedClassPointers) { // It is set only if UseCompressedOops is set 186 int klass_shift = Universe::narrow_klass_shift(); 187 if (klass_shift == 0) { 188 Universe::set_narrow_klass_shift(AOTLib::narrow_klass_shift()); 189 } else { 190 FOR_ALL_AOT_LIBRARIES(lib) { 191 (*lib)->verify_flag(AOTLib::narrow_klass_shift(), klass_shift, "Universe::narrow_klass_shift"); 192 } 193 } 194 } 195 } 196 // Create heaps for all the libraries 197 FOR_ALL_AOT_LIBRARIES(lib) { 198 if ((*lib)->is_valid()) { 199 AOTCodeHeap* heap = new AOTCodeHeap(*lib); 200 { 201 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 202 add_heap(heap); 203 CodeCache::add_heap(heap); 204 } 205 } 206 } 207 } 208 if (heaps_count() == 0) { 209 if (FLAG_IS_DEFAULT(UseAOT)) { 210 FLAG_SET_DEFAULT(UseAOT, false); 211 } 212 } 213 } 214 215 void AOTLoader::set_narrow_klass_shift() { 216 // This method could be called from Metaspace::set_narrow_klass_base_and_shift(). 217 // In case it is not called (during dump CDS, for example) the corresponding code in 218 // AOTLoader::universe_init(), which is called later, will set the shift value. 219 if (UseAOT && libraries_count() > 0 && 220 UseCompressedOops && AOTLib::narrow_oop_shift_initialized() && 221 UseCompressedClassPointers) { 222 int klass_shift = Universe::narrow_klass_shift(); 223 if (klass_shift == 0) { 224 Universe::set_narrow_klass_shift(AOTLib::narrow_klass_shift()); 225 } else { 226 FOR_ALL_AOT_LIBRARIES(lib) { 227 (*lib)->verify_flag(AOTLib::narrow_klass_shift(), klass_shift, "Universe::narrow_klass_shift"); 228 } 229 } 230 } 231 } 232 233 void AOTLoader::load_library(const char* name, bool exit_on_error) { 234 char ebuf[1024]; 235 void* handle = os::dll_load(name, ebuf, sizeof ebuf); 236 if (handle == NULL) { 237 if (exit_on_error) { 238 tty->print_cr("error opening file: %s", ebuf); 239 vm_exit(1); 240 } 241 return; 242 } 243 const int dso_id = libraries_count() + 1; 244 AOTLib* lib = new AOTLib(handle, name, dso_id); 245 if (!lib->is_valid()) { 246 delete lib; 247 os::dll_unload(handle); 248 return; 249 } 250 add_library(lib); 251 } 252 253 #ifndef PRODUCT 254 void AOTLoader::print_statistics() { 255 { ttyLocker ttyl; 256 tty->print_cr("--- AOT Statistics ---"); 257 tty->print_cr("AOT libraries loaded: %d", heaps_count()); 258 AOTCodeHeap::print_statistics(); 259 } 260 } 261 #endif