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