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