Mercurial > hg > truffle
comparison src/share/vm/classfile/classLoader.cpp @ 12355:cefad50507d8
Merge with hs25-b53
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Fri, 11 Oct 2013 10:38:03 +0200 |
parents | 3cce976666d9 3a4e6c929bf3 |
children | d8041d695d19 |
comparison
equal
deleted
inserted
replaced
12058:ccb4f2af2319 | 12355:cefad50507d8 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
195 _dir = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass); | 195 _dir = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass); |
196 strcpy(_dir, dir); | 196 strcpy(_dir, dir); |
197 } | 197 } |
198 | 198 |
199 | 199 |
200 ClassFileStream* ClassPathDirEntry::open_stream(const char* name) { | 200 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) { |
201 // construct full path name | 201 // construct full path name |
202 char path[JVM_MAXPATHLEN]; | 202 char path[JVM_MAXPATHLEN]; |
203 if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) { | 203 if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) { |
204 return NULL; | 204 return NULL; |
205 } | 205 } |
238 (*ZipClose)(_zip); | 238 (*ZipClose)(_zip); |
239 } | 239 } |
240 FREE_C_HEAP_ARRAY(char, _zip_name, mtClass); | 240 FREE_C_HEAP_ARRAY(char, _zip_name, mtClass); |
241 } | 241 } |
242 | 242 |
243 ClassFileStream* ClassPathZipEntry::open_stream(const char* name) { | 243 ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) { |
244 // enable call to C land | 244 // enable call to C land |
245 JavaThread* thread = JavaThread::current(); | 245 JavaThread* thread = JavaThread::current(); |
246 ThreadToNativeFromVM ttn(thread); | 246 ThreadToNativeFromVM ttn(thread); |
247 // check whether zip archive contains name | 247 // check whether zip archive contains name |
248 jint filesize, name_len; | 248 jint filesize, name_len; |
282 if (ze == NULL) break; | 282 if (ze == NULL) break; |
283 (*f)(ze->name, context); | 283 (*f)(ze->name, context); |
284 } | 284 } |
285 } | 285 } |
286 | 286 |
287 LazyClassPathEntry::LazyClassPathEntry(char* path, struct stat st) : ClassPathEntry() { | 287 LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() { |
288 _path = strdup(path); | 288 _path = strdup(path); |
289 _st = st; | 289 _st = *st; |
290 _meta_index = NULL; | 290 _meta_index = NULL; |
291 _resolved_entry = NULL; | 291 _resolved_entry = NULL; |
292 _has_error = false; | |
292 } | 293 } |
293 | 294 |
294 bool LazyClassPathEntry::is_jar_file() { | 295 bool LazyClassPathEntry::is_jar_file() { |
295 return ((_st.st_mode & S_IFREG) == S_IFREG); | 296 return ((_st.st_mode & S_IFREG) == S_IFREG); |
296 } | 297 } |
297 | 298 |
298 ClassPathEntry* LazyClassPathEntry::resolve_entry() { | 299 ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) { |
299 if (_resolved_entry != NULL) { | 300 if (_resolved_entry != NULL) { |
300 return (ClassPathEntry*) _resolved_entry; | 301 return (ClassPathEntry*) _resolved_entry; |
301 } | 302 } |
302 ClassPathEntry* new_entry = NULL; | 303 ClassPathEntry* new_entry = NULL; |
303 ClassLoader::create_class_path_entry(_path, _st, &new_entry, false); | 304 new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL); |
304 assert(new_entry != NULL, "earlier code should have caught this"); | |
305 { | 305 { |
306 ThreadCritical tc; | 306 ThreadCritical tc; |
307 if (_resolved_entry == NULL) { | 307 if (_resolved_entry == NULL) { |
308 _resolved_entry = new_entry; | 308 _resolved_entry = new_entry; |
309 return new_entry; | 309 return new_entry; |
312 assert(_resolved_entry != NULL, "bug in MT-safe resolution logic"); | 312 assert(_resolved_entry != NULL, "bug in MT-safe resolution logic"); |
313 delete new_entry; | 313 delete new_entry; |
314 return (ClassPathEntry*) _resolved_entry; | 314 return (ClassPathEntry*) _resolved_entry; |
315 } | 315 } |
316 | 316 |
317 ClassFileStream* LazyClassPathEntry::open_stream(const char* name) { | 317 ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) { |
318 if (_meta_index != NULL && | 318 if (_meta_index != NULL && |
319 !_meta_index->may_contain(name)) { | 319 !_meta_index->may_contain(name)) { |
320 return NULL; | 320 return NULL; |
321 } | 321 } |
322 return resolve_entry()->open_stream(name); | 322 if (_has_error) { |
323 return NULL; | |
324 } | |
325 ClassPathEntry* cpe = resolve_entry(THREAD); | |
326 if (cpe == NULL) { | |
327 _has_error = true; | |
328 return NULL; | |
329 } else { | |
330 return cpe->open_stream(name, THREAD); | |
331 } | |
323 } | 332 } |
324 | 333 |
325 bool LazyClassPathEntry::is_lazy() { | 334 bool LazyClassPathEntry::is_lazy() { |
326 return true; | 335 return true; |
327 } | 336 } |
463 end++; | 472 end++; |
464 } | 473 } |
465 } | 474 } |
466 } | 475 } |
467 | 476 |
468 void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy) { | 477 ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) { |
469 JavaThread* thread = JavaThread::current(); | 478 JavaThread* thread = JavaThread::current(); |
470 if (lazy) { | 479 if (lazy) { |
471 *new_entry = new LazyClassPathEntry(path, st); | 480 return new LazyClassPathEntry(path, st); |
472 return; | 481 } |
473 } | 482 ClassPathEntry* new_entry = NULL; |
474 if ((st.st_mode & S_IFREG) == S_IFREG) { | 483 if ((st->st_mode & S_IFREG) == S_IFREG) { |
475 // Regular file, should be a zip file | 484 // Regular file, should be a zip file |
476 // Canonicalized filename | 485 // Canonicalized filename |
477 char canonical_path[JVM_MAXPATHLEN]; | 486 char canonical_path[JVM_MAXPATHLEN]; |
478 if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { | 487 if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { |
479 // This matches the classic VM | 488 // This matches the classic VM |
480 EXCEPTION_MARK; | 489 THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL); |
481 THROW_MSG(vmSymbols::java_io_IOException(), "Bad pathname"); | |
482 } | 490 } |
483 char* error_msg = NULL; | 491 char* error_msg = NULL; |
484 jzfile* zip; | 492 jzfile* zip; |
485 { | 493 { |
486 // enable call to C land | 494 // enable call to C land |
487 ThreadToNativeFromVM ttn(thread); | 495 ThreadToNativeFromVM ttn(thread); |
488 HandleMark hm(thread); | 496 HandleMark hm(thread); |
489 zip = (*ZipOpen)(canonical_path, &error_msg); | 497 zip = (*ZipOpen)(canonical_path, &error_msg); |
490 } | 498 } |
491 if (zip != NULL && error_msg == NULL) { | 499 if (zip != NULL && error_msg == NULL) { |
492 *new_entry = new ClassPathZipEntry(zip, path); | 500 new_entry = new ClassPathZipEntry(zip, path); |
493 if (TraceClassLoading) { | 501 if (TraceClassLoading) { |
494 tty->print_cr("[Opened %s]", path); | 502 tty->print_cr("[Opened %s]", path); |
495 } | 503 } |
496 } else { | 504 } else { |
497 ResourceMark rm(thread); | 505 ResourceMark rm(thread); |
502 } else { | 510 } else { |
503 int len = (int)(strlen(path) + strlen(error_msg) + 128); | 511 int len = (int)(strlen(path) + strlen(error_msg) + 128); |
504 msg = NEW_RESOURCE_ARRAY(char, len); ; | 512 msg = NEW_RESOURCE_ARRAY(char, len); ; |
505 jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path); | 513 jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path); |
506 } | 514 } |
507 EXCEPTION_MARK; | 515 THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL); |
508 THROW_MSG(vmSymbols::java_lang_ClassNotFoundException(), msg); | |
509 } | 516 } |
510 } else { | 517 } else { |
511 // Directory | 518 // Directory |
512 *new_entry = new ClassPathDirEntry(path); | 519 new_entry = new ClassPathDirEntry(path); |
513 if (TraceClassLoading) { | 520 if (TraceClassLoading) { |
514 tty->print_cr("[Path %s]", path); | 521 tty->print_cr("[Path %s]", path); |
515 } | 522 } |
516 } | 523 } |
524 return new_entry; | |
517 } | 525 } |
518 | 526 |
519 | 527 |
520 // Create a class path zip entry for a given path (return NULL if not found | 528 // Create a class path zip entry for a given path (return NULL if not found |
521 // or zip/JAR file cannot be opened) | 529 // or zip/JAR file cannot be opened) |
570 _last_entry = new_entry; | 578 _last_entry = new_entry; |
571 } | 579 } |
572 } | 580 } |
573 } | 581 } |
574 | 582 |
575 void ClassLoader::update_class_path_entry_list(const char *path, | 583 void ClassLoader::update_class_path_entry_list(char *path, |
576 bool check_for_duplicates) { | 584 bool check_for_duplicates) { |
577 struct stat st; | 585 struct stat st; |
578 if (os::stat((char *)path, &st) == 0) { | 586 if (os::stat(path, &st) == 0) { |
579 // File or directory found | 587 // File or directory found |
580 ClassPathEntry* new_entry = NULL; | 588 ClassPathEntry* new_entry = NULL; |
581 create_class_path_entry((char *)path, st, &new_entry, LazyBootClassLoader); | 589 Thread* THREAD = Thread::current(); |
590 new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK); | |
582 // The kernel VM adds dynamically to the end of the classloader path and | 591 // The kernel VM adds dynamically to the end of the classloader path and |
583 // doesn't reorder the bootclasspath which would break java.lang.Package | 592 // doesn't reorder the bootclasspath which would break java.lang.Package |
584 // (see PackageInfo). | 593 // (see PackageInfo). |
585 // Add new entry to linked list | 594 // Add new entry to linked list |
586 if (!check_for_duplicates || !contains_entry(new_entry)) { | 595 if (!check_for_duplicates || !contains_entry(new_entry)) { |
895 PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(), | 904 PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(), |
896 ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(), | 905 ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(), |
897 PerfClassTraceTime::CLASS_LOAD); | 906 PerfClassTraceTime::CLASS_LOAD); |
898 ClassPathEntry* e = _first_entry; | 907 ClassPathEntry* e = _first_entry; |
899 while (e != NULL) { | 908 while (e != NULL) { |
900 stream = e->open_stream(name); | 909 stream = e->open_stream(name, CHECK_NULL); |
901 if (stream != NULL) { | 910 if (stream != NULL) { |
902 break; | 911 break; |
903 } | 912 } |
904 e = e->next(); | 913 e = e->next(); |
905 ++classpath_index; | 914 ++classpath_index; |
1255 // only used for debugging. | 1264 // only used for debugging. |
1256 return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0); | 1265 return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0); |
1257 } | 1266 } |
1258 | 1267 |
1259 void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) { | 1268 void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) { |
1260 resolve_entry()->compile_the_world(loader, CHECK); | 1269 ClassPathEntry* cpe = resolve_entry(THREAD); |
1270 if (cpe != NULL) { | |
1271 cpe->compile_the_world(loader, CHECK); | |
1272 } | |
1261 } | 1273 } |
1262 | 1274 |
1263 bool LazyClassPathEntry::is_rt_jar() { | 1275 bool LazyClassPathEntry::is_rt_jar() { |
1264 return resolve_entry()->is_rt_jar(); | 1276 Thread* THREAD = Thread::current(); |
1277 ClassPathEntry* cpe = resolve_entry(THREAD); | |
1278 return (cpe != NULL) ? cpe->is_jar_file() : false; | |
1265 } | 1279 } |
1266 | 1280 |
1267 void ClassLoader::compile_the_world() { | 1281 void ClassLoader::compile_the_world() { |
1268 EXCEPTION_MARK; | 1282 EXCEPTION_MARK; |
1269 HandleMark hm(THREAD); | 1283 HandleMark hm(THREAD); |
1301 if (HAS_PENDING_EXCEPTION && | 1315 if (HAS_PENDING_EXCEPTION && |
1302 !PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) { | 1316 !PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) { |
1303 CLEAR_PENDING_EXCEPTION; | 1317 CLEAR_PENDING_EXCEPTION; |
1304 } | 1318 } |
1305 // The CHECK at the caller will propagate the exception out | 1319 // The CHECK at the caller will propagate the exception out |
1320 } | |
1321 | |
1322 /** | |
1323 * Returns if the given method should be compiled when doing compile-the-world. | |
1324 * | |
1325 * TODO: This should be a private method in a CompileTheWorld class. | |
1326 */ | |
1327 static bool can_be_compiled(methodHandle m, int comp_level) { | |
1328 assert(CompileTheWorld, "must be"); | |
1329 | |
1330 // It's not valid to compile a native wrapper for MethodHandle methods | |
1331 // that take a MemberName appendix since the bytecode signature is not | |
1332 // correct. | |
1333 vmIntrinsics::ID iid = m->intrinsic_id(); | |
1334 if (MethodHandles::is_signature_polymorphic(iid) && MethodHandles::has_member_arg(iid)) { | |
1335 return false; | |
1336 } | |
1337 | |
1338 return CompilationPolicy::can_be_compiled(m, comp_level); | |
1306 } | 1339 } |
1307 | 1340 |
1308 void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { | 1341 void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { |
1309 int len = (int)strlen(name); | 1342 int len = (int)strlen(name); |
1310 if (len > 6 && strcmp(".class", name + len - 6) == 0) { | 1343 if (len > 6 && strcmp(".class", name + len - 6) == 0) { |
1346 // Preload all classes to get around uncommon traps | 1379 // Preload all classes to get around uncommon traps |
1347 // Iterate over all methods in class | 1380 // Iterate over all methods in class |
1348 int comp_level = CompilationPolicy::policy()->initial_compile_level(); | 1381 int comp_level = CompilationPolicy::policy()->initial_compile_level(); |
1349 for (int n = 0; n < k->methods()->length(); n++) { | 1382 for (int n = 0; n < k->methods()->length(); n++) { |
1350 methodHandle m (THREAD, k->methods()->at(n)); | 1383 methodHandle m (THREAD, k->methods()->at(n)); |
1351 if (CompilationPolicy::can_be_compiled(m, comp_level)) { | 1384 if (can_be_compiled(m, comp_level)) { |
1352 | |
1353 if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) { | 1385 if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) { |
1354 // Give sweeper a chance to keep up with CTW | 1386 // Give sweeper a chance to keep up with CTW |
1355 VM_ForceSafepoint op; | 1387 VM_ForceSafepoint op; |
1356 VMThread::execute(&op); | 1388 VMThread::execute(&op); |
1357 _codecache_sweep_counter = 0; | 1389 _codecache_sweep_counter = 0; |
1359 // Force compilation | 1391 // Force compilation |
1360 CompileBroker::compile_method(m, InvocationEntryBci, comp_level, | 1392 CompileBroker::compile_method(m, InvocationEntryBci, comp_level, |
1361 methodHandle(), 0, "CTW", THREAD); | 1393 methodHandle(), 0, "CTW", THREAD); |
1362 if (HAS_PENDING_EXCEPTION) { | 1394 if (HAS_PENDING_EXCEPTION) { |
1363 clear_pending_exception_if_not_oom(CHECK); | 1395 clear_pending_exception_if_not_oom(CHECK); |
1364 tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string()); | 1396 tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); |
1365 } else { | 1397 } else { |
1366 _compile_the_world_method_counter++; | 1398 _compile_the_world_method_counter++; |
1367 } | 1399 } |
1368 if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) { | 1400 if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) { |
1369 // Clobber the first compile and force second tier compilation | 1401 // Clobber the first compile and force second tier compilation |
1375 } | 1407 } |
1376 CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization, | 1408 CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization, |
1377 methodHandle(), 0, "CTW", THREAD); | 1409 methodHandle(), 0, "CTW", THREAD); |
1378 if (HAS_PENDING_EXCEPTION) { | 1410 if (HAS_PENDING_EXCEPTION) { |
1379 clear_pending_exception_if_not_oom(CHECK); | 1411 clear_pending_exception_if_not_oom(CHECK); |
1380 tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string()); | 1412 tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); |
1381 } else { | 1413 } else { |
1382 _compile_the_world_method_counter++; | 1414 _compile_the_world_method_counter++; |
1383 } | 1415 } |
1384 } | 1416 } |
1417 } else { | |
1418 tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); | |
1385 } | 1419 } |
1386 | 1420 |
1387 nmethod* nm = m->code(); | 1421 nmethod* nm = m->code(); |
1388 if (nm != NULL) { | 1422 if (nm != NULL) { |
1389 // Throw out the code so that the code cache doesn't fill up | 1423 // Throw out the code so that the code cache doesn't fill up |