Wed, 19 Nov 2014 15:02:01 -0800
Merge
.hgtags | file | annotate | diff | comparison | revisions | |
make/hotspot_version | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Mon Nov 17 15:51:46 2014 -0500 1.2 +++ b/.hgtags Wed Nov 19 15:02:01 2014 -0800 1.3 @@ -562,4 +562,7 @@ 1.4 6b93bf9ea3ea57ed0fe53cfedb2f9ab912c324e5 jdk8u40-b12 1.5 521e269ae1daa9df1cb0835b97aa76bdf340fcb2 hs25.40-b17 1.6 86307d47790785398d0695acc361bccaefe25f94 jdk8u40-b13 1.7 +4d5dc0d0f8799fafa1135d51d85edd4edd566501 hs25.40-b18 1.8 +b8ca8ec1daea70f7c0d519e866f9f147ec247055 jdk8u40-b14 1.9 +eb16b24e2eba9bdf04a9b377bebc2db9f713ff5e jdk8u40-b15 1.10 b95f13f05f553309cd74d6ccf8fcedb259c6716c jdk8u45-b00
2.1 --- a/make/bsd/makefiles/mapfile-vers-debug Mon Nov 17 15:51:46 2014 -0500 2.2 +++ b/make/bsd/makefiles/mapfile-vers-debug Wed Nov 19 15:02:01 2014 -0800 2.3 @@ -187,6 +187,9 @@ 2.4 _JVM_IsSupportedJNIVersion 2.5 _JVM_IsThreadAlive 2.6 _JVM_IsVMGeneratedMethodIx 2.7 + _JVM_KnownToNotExist 2.8 + _JVM_GetResourceLookupCacheURLs 2.9 + _JVM_GetResourceLookupCache 2.10 _JVM_LatestUserDefinedLoader 2.11 _JVM_Listen 2.12 _JVM_LoadClass0
3.1 --- a/make/bsd/makefiles/mapfile-vers-product Mon Nov 17 15:51:46 2014 -0500 3.2 +++ b/make/bsd/makefiles/mapfile-vers-product Wed Nov 19 15:02:01 2014 -0800 3.3 @@ -187,6 +187,9 @@ 3.4 _JVM_IsSupportedJNIVersion 3.5 _JVM_IsThreadAlive 3.6 _JVM_IsVMGeneratedMethodIx 3.7 + _JVM_KnownToNotExist 3.8 + _JVM_GetResourceLookupCacheURLs 3.9 + _JVM_GetResourceLookupCache 3.10 _JVM_LatestUserDefinedLoader 3.11 _JVM_Listen 3.12 _JVM_LoadClass0
4.1 --- a/make/linux/makefiles/mapfile-vers-debug Mon Nov 17 15:51:46 2014 -0500 4.2 +++ b/make/linux/makefiles/mapfile-vers-debug Wed Nov 19 15:02:01 2014 -0800 4.3 @@ -217,6 +217,9 @@ 4.4 JVM_RegisterSignal; 4.5 JVM_ReleaseUTF; 4.6 JVM_ResolveClass; 4.7 + JVM_KnownToNotExist; 4.8 + JVM_GetResourceLookupCacheURLs; 4.9 + JVM_GetResourceLookupCache; 4.10 JVM_ResumeThread; 4.11 JVM_Send; 4.12 JVM_SendTo;
5.1 --- a/make/linux/makefiles/mapfile-vers-product Mon Nov 17 15:51:46 2014 -0500 5.2 +++ b/make/linux/makefiles/mapfile-vers-product Wed Nov 19 15:02:01 2014 -0800 5.3 @@ -217,6 +217,9 @@ 5.4 JVM_RegisterSignal; 5.5 JVM_ReleaseUTF; 5.6 JVM_ResolveClass; 5.7 + JVM_KnownToNotExist; 5.8 + JVM_GetResourceLookupCacheURLs; 5.9 + JVM_GetResourceLookupCache; 5.10 JVM_ResumeThread; 5.11 JVM_Send; 5.12 JVM_SendTo;
6.1 --- a/make/solaris/makefiles/mapfile-vers Mon Nov 17 15:51:46 2014 -0500 6.2 +++ b/make/solaris/makefiles/mapfile-vers Wed Nov 19 15:02:01 2014 -0800 6.3 @@ -189,6 +189,9 @@ 6.4 JVM_IsSupportedJNIVersion; 6.5 JVM_IsThreadAlive; 6.6 JVM_IsVMGeneratedMethodIx; 6.7 + JVM_KnownToNotExist; 6.8 + JVM_GetResourceLookupCacheURLs; 6.9 + JVM_GetResourceLookupCache; 6.10 JVM_LatestUserDefinedLoader; 6.11 JVM_Listen; 6.12 JVM_LoadClass0;
7.1 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Nov 17 15:51:46 2014 -0500 7.2 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Nov 19 15:02:01 2014 -0800 7.3 @@ -909,7 +909,7 @@ 7.4 */ 7.5 char* hint = (char*) (Linux::initial_thread_stack_bottom() - 7.6 ((StackYellowPages + StackRedPages + 1) * page_size)); 7.7 - char* codebuf = os::reserve_memory(page_size, hint); 7.8 + char* codebuf = os::attempt_reserve_memory_at(page_size, hint); 7.9 if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) { 7.10 return; // No matter, we tried, best effort. 7.11 }
8.1 --- a/src/share/vm/classfile/classLoader.cpp Mon Nov 17 15:51:46 2014 -0500 8.2 +++ b/src/share/vm/classfile/classLoader.cpp Wed Nov 19 15:02:01 2014 -0800 8.3 @@ -610,7 +610,7 @@ 8.4 } 8.5 #endif 8.6 8.7 -void ClassLoader::setup_search_path(const char *class_path) { 8.8 +void ClassLoader::setup_search_path(const char *class_path, bool canonicalize) { 8.9 int offset = 0; 8.10 int len = (int)strlen(class_path); 8.11 int end = 0; 8.12 @@ -625,7 +625,13 @@ 8.13 char* path = NEW_RESOURCE_ARRAY(char, end - start + 1); 8.14 strncpy(path, &class_path[start], end - start); 8.15 path[end - start] = '\0'; 8.16 - update_class_path_entry_list(path, false); 8.17 + if (canonicalize) { 8.18 + char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN + 1); 8.19 + if (get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { 8.20 + path = canonical_path; 8.21 + } 8.22 + } 8.23 + update_class_path_entry_list(path, /*check_for_duplicates=*/canonicalize); 8.24 #if INCLUDE_CDS 8.25 if (DumpSharedSpaces) { 8.26 check_shared_classpath(path);
9.1 --- a/src/share/vm/classfile/classLoader.hpp Mon Nov 17 15:51:46 2014 -0500 9.2 +++ b/src/share/vm/classfile/classLoader.hpp Wed Nov 19 15:02:01 2014 -0800 9.3 @@ -129,8 +129,8 @@ 9.4 bool _has_error; 9.5 bool _throw_exception; 9.6 volatile ClassPathEntry* _resolved_entry; 9.7 + public: 9.8 ClassPathEntry* resolve_entry(TRAPS); 9.9 - public: 9.10 bool is_jar_file(); 9.11 const char* name() { return _path; } 9.12 LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception); 9.13 @@ -218,7 +218,7 @@ 9.14 static void setup_meta_index(const char* meta_index_path, const char* meta_index_dir, 9.15 int start_index); 9.16 static void setup_bootstrap_search_path(); 9.17 - static void setup_search_path(const char *class_path); 9.18 + static void setup_search_path(const char *class_path, bool canonicalize=false); 9.19 9.20 static void load_zip_library(); 9.21 static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st, 9.22 @@ -329,6 +329,10 @@ 9.23 return e; 9.24 } 9.25 9.26 + static int num_classpath_entries() { 9.27 + return _num_entries; 9.28 + } 9.29 + 9.30 #if INCLUDE_CDS 9.31 // Sharing dump and restore 9.32 static void copy_package_info_buckets(char** top, char* end);
10.1 --- a/src/share/vm/classfile/classLoaderData.cpp Mon Nov 17 15:51:46 2014 -0500 10.2 +++ b/src/share/vm/classfile/classLoaderData.cpp Wed Nov 19 15:02:01 2014 -0800 10.3 @@ -747,7 +747,7 @@ 10.4 10.5 // Move class loader data from main list to the unloaded list for unloading 10.6 // and deallocation later. 10.7 -bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) { 10.8 +bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure, bool clean_alive) { 10.9 ClassLoaderData* data = _head; 10.10 ClassLoaderData* prev = NULL; 10.11 bool seen_dead_loader = false; 10.12 @@ -756,16 +756,8 @@ 10.13 // purging and we don't want to rewalk the previously unloaded class loader data. 10.14 _saved_unloading = _unloading; 10.15 10.16 - // mark metadata seen on the stack and code cache so we can delete 10.17 - // unneeded entries. 10.18 - bool has_redefined_a_class = JvmtiExport::has_redefined_a_class(); 10.19 - MetadataOnStackMark md_on_stack; 10.20 while (data != NULL) { 10.21 if (data->is_alive(is_alive_closure)) { 10.22 - if (has_redefined_a_class) { 10.23 - data->classes_do(InstanceKlass::purge_previous_versions); 10.24 - } 10.25 - data->free_deallocate_list(); 10.26 prev = data; 10.27 data = data->next(); 10.28 continue; 10.29 @@ -787,6 +779,11 @@ 10.30 _unloading = dead; 10.31 } 10.32 10.33 + if (clean_alive) { 10.34 + // Clean previous versions and the deallocate list. 10.35 + ClassLoaderDataGraph::clean_metaspaces(); 10.36 + } 10.37 + 10.38 if (seen_dead_loader) { 10.39 post_class_unload_events(); 10.40 } 10.41 @@ -794,6 +791,26 @@ 10.42 return seen_dead_loader; 10.43 } 10.44 10.45 +void ClassLoaderDataGraph::clean_metaspaces() { 10.46 + // mark metadata seen on the stack and code cache so we can delete unneeded entries. 10.47 + bool has_redefined_a_class = JvmtiExport::has_redefined_a_class(); 10.48 + MetadataOnStackMark md_on_stack(has_redefined_a_class); 10.49 + 10.50 + if (has_redefined_a_class) { 10.51 + // purge_previous_versions also cleans weak method links. Because 10.52 + // one method's MDO can reference another method from another 10.53 + // class loader, we need to first clean weak method links for all 10.54 + // class loaders here. Below, we can then free redefined methods 10.55 + // for all class loaders. 10.56 + for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { 10.57 + data->classes_do(InstanceKlass::purge_previous_versions); 10.58 + } 10.59 + } 10.60 + 10.61 + // Need to purge the previous version before deallocating. 10.62 + free_deallocate_lists(); 10.63 +} 10.64 + 10.65 void ClassLoaderDataGraph::purge() { 10.66 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); 10.67 ClassLoaderData* list = _unloading; 10.68 @@ -821,6 +838,14 @@ 10.69 #endif 10.70 } 10.71 10.72 +void ClassLoaderDataGraph::free_deallocate_lists() { 10.73 + for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { 10.74 + // We need to keep this data until InstanceKlass::purge_previous_version has been 10.75 + // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces. 10.76 + cld->free_deallocate_list(); 10.77 + } 10.78 +} 10.79 + 10.80 // CDS support 10.81 10.82 // Global metaspaces for writing information to the shared archive. When
11.1 --- a/src/share/vm/classfile/classLoaderData.hpp Mon Nov 17 15:51:46 2014 -0500 11.2 +++ b/src/share/vm/classfile/classLoaderData.hpp Wed Nov 19 15:02:01 2014 -0800 11.3 @@ -71,6 +71,7 @@ 11.4 11.5 static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS); 11.6 static void post_class_unload_events(void); 11.7 + static void clean_metaspaces(); 11.8 public: 11.9 static ClassLoaderData* find_or_create(Handle class_loader, TRAPS); 11.10 static void purge(); 11.11 @@ -89,7 +90,7 @@ 11.12 static void classes_do(void f(Klass* const)); 11.13 static void loaded_classes_do(KlassClosure* klass_closure); 11.14 static void classes_unloading_do(void f(Klass* const)); 11.15 - static bool do_unloading(BoolObjectClosure* is_alive); 11.16 + static bool do_unloading(BoolObjectClosure* is_alive, bool clean_alive); 11.17 11.18 // CMS support. 11.19 static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); } 11.20 @@ -105,6 +106,8 @@ 11.21 } 11.22 } 11.23 11.24 + static void free_deallocate_lists(); 11.25 + 11.26 static void dump_on(outputStream * const out) PRODUCT_RETURN; 11.27 static void dump() { dump_on(tty); } 11.28 static void verify();
12.1 --- a/src/share/vm/classfile/classLoaderExt.hpp Mon Nov 17 15:51:46 2014 -0500 12.2 +++ b/src/share/vm/classfile/classLoaderExt.hpp Wed Nov 19 15:02:01 2014 -0800 12.3 @@ -64,6 +64,15 @@ 12.4 ClassLoader::add_to_list(new_entry); 12.5 } 12.6 static void setup_search_paths() {} 12.7 + 12.8 + static void init_lookup_cache(TRAPS) {} 12.9 + static void copy_lookup_cache_to_archive(char** top, char* end) {} 12.10 + static char* restore_lookup_cache_from_archive(char* buffer) {return buffer;} 12.11 + static inline bool is_lookup_cache_enabled() {return false;} 12.12 + 12.13 + static bool known_to_not_exist(JNIEnv *env, jobject loader, const char *classname, TRAPS) {return false;} 12.14 + static jobjectArray get_lookup_cache_urls(JNIEnv *env, jobject loader, TRAPS) {return NULL;} 12.15 + static jintArray get_lookup_cache(JNIEnv *env, jobject loader, const char *pkgname, TRAPS) {return NULL;} 12.16 }; 12.17 12.18 #endif // SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
13.1 --- a/src/share/vm/classfile/metadataOnStackMark.cpp Mon Nov 17 15:51:46 2014 -0500 13.2 +++ b/src/share/vm/classfile/metadataOnStackMark.cpp Wed Nov 19 15:02:01 2014 -0800 13.3 @@ -31,25 +31,23 @@ 13.4 #include "runtime/synchronizer.hpp" 13.5 #include "runtime/thread.hpp" 13.6 #include "services/threadService.hpp" 13.7 -#include "utilities/growableArray.hpp" 13.8 +#include "utilities/chunkedList.hpp" 13.9 13.10 +volatile MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL; 13.11 +volatile MetadataOnStackBuffer* MetadataOnStackMark::_free_buffers = NULL; 13.12 13.13 -// Keep track of marked on-stack metadata so it can be cleared. 13.14 -GrowableArray<Metadata*>* _marked_objects = NULL; 13.15 NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;) 13.16 13.17 // Walk metadata on the stack and mark it so that redefinition doesn't delete 13.18 // it. Class unloading also walks the previous versions and might try to 13.19 // delete it, so this class is used by class unloading also. 13.20 -MetadataOnStackMark::MetadataOnStackMark() { 13.21 +MetadataOnStackMark::MetadataOnStackMark(bool visit_code_cache) { 13.22 assert(SafepointSynchronize::is_at_safepoint(), "sanity check"); 13.23 + assert(_used_buffers == NULL, "sanity check"); 13.24 NOT_PRODUCT(_is_active = true;) 13.25 - if (_marked_objects == NULL) { 13.26 - _marked_objects = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(1000, true); 13.27 - } 13.28 13.29 Threads::metadata_do(Metadata::mark_on_stack); 13.30 - if (JvmtiExport::has_redefined_a_class()) { 13.31 + if (visit_code_cache) { 13.32 CodeCache::alive_nmethods_do(nmethod::mark_on_stack); 13.33 } 13.34 CompileBroker::mark_on_stack(); 13.35 @@ -62,15 +60,93 @@ 13.36 // Unmark everything that was marked. Can't do the same walk because 13.37 // redefine classes messes up the code cache so the set of methods 13.38 // might not be the same. 13.39 - for (int i = 0; i< _marked_objects->length(); i++) { 13.40 - _marked_objects->at(i)->set_on_stack(false); 13.41 + 13.42 + retire_buffer_for_thread(Thread::current()); 13.43 + 13.44 + MetadataOnStackBuffer* buffer = const_cast<MetadataOnStackBuffer* >(_used_buffers); 13.45 + while (buffer != NULL) { 13.46 + // Clear on stack state for all metadata. 13.47 + size_t size = buffer->size(); 13.48 + for (size_t i = 0; i < size; i++) { 13.49 + Metadata* md = buffer->at(i); 13.50 + md->set_on_stack(false); 13.51 + } 13.52 + 13.53 + MetadataOnStackBuffer* next = buffer->next_used(); 13.54 + 13.55 + // Move the buffer to the free list. 13.56 + buffer->clear(); 13.57 + buffer->set_next_used(NULL); 13.58 + buffer->set_next_free(const_cast<MetadataOnStackBuffer*>(_free_buffers)); 13.59 + _free_buffers = buffer; 13.60 + 13.61 + // Step to next used buffer. 13.62 + buffer = next; 13.63 } 13.64 - _marked_objects->clear(); // reuse growable array for next time. 13.65 + 13.66 + _used_buffers = NULL; 13.67 + 13.68 NOT_PRODUCT(_is_active = false;) 13.69 } 13.70 13.71 +void MetadataOnStackMark::retire_buffer(MetadataOnStackBuffer* buffer) { 13.72 + if (buffer == NULL) { 13.73 + return; 13.74 + } 13.75 + 13.76 + MetadataOnStackBuffer* old_head; 13.77 + 13.78 + do { 13.79 + old_head = const_cast<MetadataOnStackBuffer*>(_used_buffers); 13.80 + buffer->set_next_used(old_head); 13.81 + } while (Atomic::cmpxchg_ptr(buffer, &_used_buffers, old_head) != old_head); 13.82 +} 13.83 + 13.84 +void MetadataOnStackMark::retire_buffer_for_thread(Thread* thread) { 13.85 + retire_buffer(thread->metadata_on_stack_buffer()); 13.86 + thread->set_metadata_on_stack_buffer(NULL); 13.87 +} 13.88 + 13.89 +bool MetadataOnStackMark::has_buffer_for_thread(Thread* thread) { 13.90 + return thread->metadata_on_stack_buffer() != NULL; 13.91 +} 13.92 + 13.93 +MetadataOnStackBuffer* MetadataOnStackMark::allocate_buffer() { 13.94 + MetadataOnStackBuffer* allocated; 13.95 + MetadataOnStackBuffer* new_head; 13.96 + 13.97 + do { 13.98 + allocated = const_cast<MetadataOnStackBuffer*>(_free_buffers); 13.99 + if (allocated == NULL) { 13.100 + break; 13.101 + } 13.102 + new_head = allocated->next_free(); 13.103 + } while (Atomic::cmpxchg_ptr(new_head, &_free_buffers, allocated) != allocated); 13.104 + 13.105 + if (allocated == NULL) { 13.106 + allocated = new MetadataOnStackBuffer(); 13.107 + } 13.108 + 13.109 + assert(!allocated->is_full(), err_msg("Should not be full: " PTR_FORMAT, p2i(allocated))); 13.110 + 13.111 + return allocated; 13.112 +} 13.113 + 13.114 // Record which objects are marked so we can unmark the same objects. 13.115 -void MetadataOnStackMark::record(Metadata* m) { 13.116 +void MetadataOnStackMark::record(Metadata* m, Thread* thread) { 13.117 assert(_is_active, "metadata on stack marking is active"); 13.118 - _marked_objects->push(m); 13.119 + 13.120 + MetadataOnStackBuffer* buffer = thread->metadata_on_stack_buffer(); 13.121 + 13.122 + if (buffer != NULL && buffer->is_full()) { 13.123 + retire_buffer(buffer); 13.124 + buffer = NULL; 13.125 + } 13.126 + 13.127 + if (buffer == NULL) { 13.128 + buffer = allocate_buffer(); 13.129 + thread->set_metadata_on_stack_buffer(buffer); 13.130 + } 13.131 + 13.132 + buffer->push(m); 13.133 }
14.1 --- a/src/share/vm/classfile/metadataOnStackMark.hpp Mon Nov 17 15:51:46 2014 -0500 14.2 +++ b/src/share/vm/classfile/metadataOnStackMark.hpp Wed Nov 19 15:02:01 2014 -0800 14.3 @@ -26,9 +26,12 @@ 14.4 #define SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP 14.5 14.6 #include "memory/allocation.hpp" 14.7 +#include "utilities/chunkedList.hpp" 14.8 14.9 class Metadata; 14.10 14.11 +typedef ChunkedList<Metadata*, mtInternal> MetadataOnStackBuffer; 14.12 + 14.13 // Helper class to mark and unmark metadata used on the stack as either handles 14.14 // or executing methods, so that it can't be deleted during class redefinition 14.15 // and class unloading. 14.16 @@ -36,10 +39,20 @@ 14.17 // metadata during parsing, relocated methods, and methods in backtraces. 14.18 class MetadataOnStackMark : public StackObj { 14.19 NOT_PRODUCT(static bool _is_active;) 14.20 + 14.21 + static volatile MetadataOnStackBuffer* _used_buffers; 14.22 + static volatile MetadataOnStackBuffer* _free_buffers; 14.23 + 14.24 + static MetadataOnStackBuffer* allocate_buffer(); 14.25 + static void retire_buffer(MetadataOnStackBuffer* buffer); 14.26 + 14.27 public: 14.28 - MetadataOnStackMark(); 14.29 - ~MetadataOnStackMark(); 14.30 - static void record(Metadata* m); 14.31 + MetadataOnStackMark(bool visit_code_cache); 14.32 + ~MetadataOnStackMark(); 14.33 + 14.34 + static void record(Metadata* m, Thread* thread); 14.35 + static void retire_buffer_for_thread(Thread* thread); 14.36 + static bool has_buffer_for_thread(Thread* thread); 14.37 }; 14.38 14.39 #endif // SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
15.1 --- a/src/share/vm/classfile/systemDictionary.cpp Mon Nov 17 15:51:46 2014 -0500 15.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Wed Nov 19 15:02:01 2014 -0800 15.3 @@ -1691,9 +1691,9 @@ 15.4 15.5 // Assumes classes in the SystemDictionary are only unloaded at a safepoint 15.6 // Note: anonymous classes are not in the SD. 15.7 -bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) { 15.8 +bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive, bool clean_alive) { 15.9 // First, mark for unload all ClassLoaderData referencing a dead class loader. 15.10 - bool unloading_occurred = ClassLoaderDataGraph::do_unloading(is_alive); 15.11 + bool unloading_occurred = ClassLoaderDataGraph::do_unloading(is_alive, clean_alive); 15.12 if (unloading_occurred) { 15.13 dictionary()->do_unloading(); 15.14 constraints()->purge_loader_constraints();
16.1 --- a/src/share/vm/classfile/systemDictionary.hpp Mon Nov 17 15:51:46 2014 -0500 16.2 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Nov 19 15:02:01 2014 -0800 16.3 @@ -176,6 +176,8 @@ 16.4 do_klass(URL_klass, java_net_URL, Pre ) \ 16.5 do_klass(Jar_Manifest_klass, java_util_jar_Manifest, Pre ) \ 16.6 do_klass(sun_misc_Launcher_klass, sun_misc_Launcher, Pre ) \ 16.7 + do_klass(sun_misc_Launcher_AppClassLoader_klass, sun_misc_Launcher_AppClassLoader, Pre ) \ 16.8 + do_klass(sun_misc_Launcher_ExtClassLoader_klass, sun_misc_Launcher_ExtClassLoader, Pre ) \ 16.9 do_klass(CodeSource_klass, java_security_CodeSource, Pre ) \ 16.10 \ 16.11 /* It's NULL in non-1.4 JDKs. */ \ 16.12 @@ -340,7 +342,7 @@ 16.13 16.14 // Unload (that is, break root links to) all unmarked classes and 16.15 // loaders. Returns "true" iff something was unloaded. 16.16 - static bool do_unloading(BoolObjectClosure* is_alive); 16.17 + static bool do_unloading(BoolObjectClosure* is_alive, bool clean_alive = true); 16.18 16.19 // Used by DumpSharedSpaces only to remove classes that failed verification 16.20 static void remove_classes_in_error_state();
17.1 --- a/src/share/vm/classfile/vmSymbols.hpp Mon Nov 17 15:51:46 2014 -0500 17.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Nov 19 15:02:01 2014 -0800 17.3 @@ -117,6 +117,7 @@ 17.4 template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \ 17.5 template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \ 17.6 template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \ 17.7 + template(sun_misc_Launcher_AppClassLoader, "sun/misc/Launcher$AppClassLoader") \ 17.8 template(sun_misc_Launcher_ExtClassLoader, "sun/misc/Launcher$ExtClassLoader") \ 17.9 \ 17.10 /* Java runtime version access */ \
18.1 --- a/src/share/vm/code/nmethod.cpp Mon Nov 17 15:51:46 2014 -0500 18.2 +++ b/src/share/vm/code/nmethod.cpp Wed Nov 19 15:02:01 2014 -0800 18.3 @@ -1720,11 +1720,17 @@ 18.4 set_unload_reported(); 18.5 } 18.6 18.7 -void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) { 18.8 +void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive, bool mark_on_stack) { 18.9 if (ic->is_icholder_call()) { 18.10 // The only exception is compiledICHolder oops which may 18.11 // yet be marked below. (We check this further below). 18.12 CompiledICHolder* cichk_oop = ic->cached_icholder(); 18.13 + 18.14 + if (mark_on_stack) { 18.15 + Metadata::mark_on_stack(cichk_oop->holder_method()); 18.16 + Metadata::mark_on_stack(cichk_oop->holder_klass()); 18.17 + } 18.18 + 18.19 if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) && 18.20 cichk_oop->holder_klass()->is_loader_alive(is_alive)) { 18.21 return; 18.22 @@ -1732,6 +1738,10 @@ 18.23 } else { 18.24 Metadata* ic_oop = ic->cached_metadata(); 18.25 if (ic_oop != NULL) { 18.26 + if (mark_on_stack) { 18.27 + Metadata::mark_on_stack(ic_oop); 18.28 + } 18.29 + 18.30 if (ic_oop->is_klass()) { 18.31 if (((Klass*)ic_oop)->is_loader_alive(is_alive)) { 18.32 return; 18.33 @@ -1792,7 +1802,7 @@ 18.34 while(iter.next()) { 18.35 if (iter.type() == relocInfo::virtual_call_type) { 18.36 CompiledIC *ic = CompiledIC_at(&iter); 18.37 - clean_ic_if_metadata_is_dead(ic, is_alive); 18.38 + clean_ic_if_metadata_is_dead(ic, is_alive, false); 18.39 } 18.40 } 18.41 } 18.42 @@ -1860,6 +1870,53 @@ 18.43 return clean_if_nmethod_is_unloaded(csc, csc->destination(), is_alive, from); 18.44 } 18.45 18.46 +bool nmethod::unload_if_dead_at(RelocIterator* iter_at_oop, BoolObjectClosure *is_alive, bool unloading_occurred) { 18.47 + assert(iter_at_oop->type() == relocInfo::oop_type, "Wrong relocation type"); 18.48 + 18.49 + oop_Relocation* r = iter_at_oop->oop_reloc(); 18.50 + // Traverse those oops directly embedded in the code. 18.51 + // Other oops (oop_index>0) are seen as part of scopes_oops. 18.52 + assert(1 == (r->oop_is_immediate()) + 18.53 + (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), 18.54 + "oop must be found in exactly one place"); 18.55 + if (r->oop_is_immediate() && r->oop_value() != NULL) { 18.56 + // Unload this nmethod if the oop is dead. 18.57 + if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) { 18.58 + return true;; 18.59 + } 18.60 + } 18.61 + 18.62 + return false; 18.63 +} 18.64 + 18.65 +void nmethod::mark_metadata_on_stack_at(RelocIterator* iter_at_metadata) { 18.66 + assert(iter_at_metadata->type() == relocInfo::metadata_type, "Wrong relocation type"); 18.67 + 18.68 + metadata_Relocation* r = iter_at_metadata->metadata_reloc(); 18.69 + // In this metadata, we must only follow those metadatas directly embedded in 18.70 + // the code. Other metadatas (oop_index>0) are seen as part of 18.71 + // the metadata section below. 18.72 + assert(1 == (r->metadata_is_immediate()) + 18.73 + (r->metadata_addr() >= metadata_begin() && r->metadata_addr() < metadata_end()), 18.74 + "metadata must be found in exactly one place"); 18.75 + if (r->metadata_is_immediate() && r->metadata_value() != NULL) { 18.76 + Metadata* md = r->metadata_value(); 18.77 + if (md != _method) Metadata::mark_on_stack(md); 18.78 + } 18.79 +} 18.80 + 18.81 +void nmethod::mark_metadata_on_stack_non_relocs() { 18.82 + // Visit the metadata section 18.83 + for (Metadata** p = metadata_begin(); p < metadata_end(); p++) { 18.84 + if (*p == Universe::non_oop_word() || *p == NULL) continue; // skip non-oops 18.85 + Metadata* md = *p; 18.86 + Metadata::mark_on_stack(md); 18.87 + } 18.88 + 18.89 + // Visit metadata not embedded in the other places. 18.90 + if (_method != NULL) Metadata::mark_on_stack(_method); 18.91 +} 18.92 + 18.93 bool nmethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred) { 18.94 ResourceMark rm; 18.95 18.96 @@ -1889,6 +1946,11 @@ 18.97 unloading_occurred = true; 18.98 } 18.99 18.100 + // When class redefinition is used all metadata in the CodeCache has to be recorded, 18.101 + // so that unused "previous versions" can be purged. Since walking the CodeCache can 18.102 + // be expensive, the "mark on stack" is piggy-backed on this parallel unloading code. 18.103 + bool mark_metadata_on_stack = a_class_was_redefined; 18.104 + 18.105 // Exception cache 18.106 clean_exception_cache(is_alive); 18.107 18.108 @@ -1904,7 +1966,7 @@ 18.109 if (unloading_occurred) { 18.110 // If class unloading occurred we first iterate over all inline caches and 18.111 // clear ICs where the cached oop is referring to an unloaded klass or method. 18.112 - clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive); 18.113 + clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive, mark_metadata_on_stack); 18.114 } 18.115 18.116 postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this); 18.117 @@ -1920,24 +1982,21 @@ 18.118 18.119 case relocInfo::oop_type: 18.120 if (!is_unloaded) { 18.121 - // Unload check 18.122 - oop_Relocation* r = iter.oop_reloc(); 18.123 - // Traverse those oops directly embedded in the code. 18.124 - // Other oops (oop_index>0) are seen as part of scopes_oops. 18.125 - assert(1 == (r->oop_is_immediate()) + 18.126 - (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), 18.127 - "oop must be found in exactly one place"); 18.128 - if (r->oop_is_immediate() && r->oop_value() != NULL) { 18.129 - if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) { 18.130 - is_unloaded = true; 18.131 - } 18.132 - } 18.133 + is_unloaded = unload_if_dead_at(&iter, is_alive, unloading_occurred); 18.134 } 18.135 break; 18.136 18.137 + case relocInfo::metadata_type: 18.138 + if (mark_metadata_on_stack) { 18.139 + mark_metadata_on_stack_at(&iter); 18.140 + } 18.141 } 18.142 } 18.143 18.144 + if (mark_metadata_on_stack) { 18.145 + mark_metadata_on_stack_non_relocs(); 18.146 + } 18.147 + 18.148 if (is_unloaded) { 18.149 return postponed; 18.150 } 18.151 @@ -2085,7 +2144,7 @@ 18.152 while (iter.next()) { 18.153 if (iter.type() == relocInfo::metadata_type ) { 18.154 metadata_Relocation* r = iter.metadata_reloc(); 18.155 - // In this lmetadata, we must only follow those metadatas directly embedded in 18.156 + // In this metadata, we must only follow those metadatas directly embedded in 18.157 // the code. Other metadatas (oop_index>0) are seen as part of 18.158 // the metadata section below. 18.159 assert(1 == (r->metadata_is_immediate()) + 18.160 @@ -2119,7 +2178,7 @@ 18.161 f(md); 18.162 } 18.163 18.164 - // Call function Method*, not embedded in these other places. 18.165 + // Visit metadata not embedded in the other places. 18.166 if (_method != NULL) f(_method); 18.167 } 18.168
19.1 --- a/src/share/vm/code/nmethod.hpp Mon Nov 17 15:51:46 2014 -0500 19.2 +++ b/src/share/vm/code/nmethod.hpp Wed Nov 19 15:02:01 2014 -0800 19.3 @@ -614,9 +614,16 @@ 19.4 // The parallel versions are used by G1. 19.5 bool do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred); 19.6 void do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred); 19.7 + 19.8 + private: 19.9 // Unload a nmethod if the *root object is dead. 19.10 bool can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred); 19.11 + bool unload_if_dead_at(RelocIterator *iter_at_oop, BoolObjectClosure* is_alive, bool unloading_occurred); 19.12 19.13 + void mark_metadata_on_stack_at(RelocIterator* iter_at_metadata); 19.14 + void mark_metadata_on_stack_non_relocs(); 19.15 + 19.16 + public: 19.17 void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, 19.18 OopClosure* f); 19.19 void oops_do(OopClosure* f) { oops_do(f, false); }
20.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Nov 17 15:51:46 2014 -0500 20.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Nov 19 15:02:01 2014 -0800 20.3 @@ -23,6 +23,7 @@ 20.4 */ 20.5 20.6 #include "precompiled.hpp" 20.7 +#include "classfile/metadataOnStackMark.hpp" 20.8 #include "classfile/symbolTable.hpp" 20.9 #include "code/codeCache.hpp" 20.10 #include "gc_implementation/g1/concurrentMark.inline.hpp" 20.11 @@ -2602,17 +2603,27 @@ 20.12 G1RemarkGCTraceTime trace("Unloading", G1Log::finer()); 20.13 20.14 if (ClassUnloadingWithConcurrentMark) { 20.15 + // Cleaning of klasses depends on correct information from MetadataMarkOnStack. The CodeCache::mark_on_stack 20.16 + // part is too slow to be done serially, so it is handled during the weakRefsWorkParallelPart phase. 20.17 + // Defer the cleaning until we have complete on_stack data. 20.18 + MetadataOnStackMark md_on_stack(false /* Don't visit the code cache at this point */); 20.19 + 20.20 bool purged_classes; 20.21 20.22 { 20.23 G1RemarkGCTraceTime trace("System Dictionary Unloading", G1Log::finest()); 20.24 - purged_classes = SystemDictionary::do_unloading(&g1_is_alive); 20.25 + purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */); 20.26 } 20.27 20.28 { 20.29 G1RemarkGCTraceTime trace("Parallel Unloading", G1Log::finest()); 20.30 weakRefsWorkParallelPart(&g1_is_alive, purged_classes); 20.31 } 20.32 + 20.33 + { 20.34 + G1RemarkGCTraceTime trace("Deallocate Metadata", G1Log::finest()); 20.35 + ClassLoaderDataGraph::free_deallocate_lists(); 20.36 + } 20.37 } 20.38 20.39 if (G1StringDedup::is_enabled()) {
21.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Nov 17 15:51:46 2014 -0500 21.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Nov 19 15:02:01 2014 -0800 21.3 @@ -27,6 +27,7 @@ 21.4 #endif 21.5 21.6 #include "precompiled.hpp" 21.7 +#include "classfile/metadataOnStackMark.hpp" 21.8 #include "code/codeCache.hpp" 21.9 #include "code/icBuffer.hpp" 21.10 #include "gc_implementation/g1/bufferingOopClosure.hpp" 21.11 @@ -5133,6 +5134,10 @@ 21.12 clean_nmethod(claimed_nmethods[i]); 21.13 } 21.14 } 21.15 + 21.16 + // The nmethod cleaning helps out and does the CodeCache part of MetadataOnStackMark. 21.17 + // Need to retire the buffers now that this thread has stopped cleaning nmethods. 21.18 + MetadataOnStackMark::retire_buffer_for_thread(Thread::current()); 21.19 } 21.20 21.21 void work_second_pass(uint worker_id) { 21.22 @@ -5185,6 +5190,9 @@ 21.23 // G1 specific cleanup work that has 21.24 // been moved here to be done in parallel. 21.25 ik->clean_dependent_nmethods(); 21.26 + if (JvmtiExport::has_redefined_a_class()) { 21.27 + InstanceKlass::purge_previous_versions(ik); 21.28 + } 21.29 } 21.30 21.31 void work() { 21.32 @@ -5219,8 +5227,18 @@ 21.33 _klass_cleaning_task(is_alive) { 21.34 } 21.35 21.36 + void pre_work_verification() { 21.37 + assert(!MetadataOnStackMark::has_buffer_for_thread(Thread::current()), "Should be empty"); 21.38 + } 21.39 + 21.40 + void post_work_verification() { 21.41 + assert(!MetadataOnStackMark::has_buffer_for_thread(Thread::current()), "Should be empty"); 21.42 + } 21.43 + 21.44 // The parallel work done by all worker threads. 21.45 void work(uint worker_id) { 21.46 + pre_work_verification(); 21.47 + 21.48 // Do first pass of code cache cleaning. 21.49 _code_cache_task.work_first_pass(worker_id); 21.50 21.51 @@ -5239,6 +5257,8 @@ 21.52 21.53 // Clean all klasses that were not unloaded. 21.54 _klass_cleaning_task.work(); 21.55 + 21.56 + post_work_verification(); 21.57 } 21.58 }; 21.59
22.1 --- a/src/share/vm/memory/metadataFactory.hpp Mon Nov 17 15:51:46 2014 -0500 22.2 +++ b/src/share/vm/memory/metadataFactory.hpp Wed Nov 19 15:02:01 2014 -0800 22.3 @@ -64,6 +64,12 @@ 22.4 22.5 template <typename T> 22.6 static void free_array(ClassLoaderData* loader_data, Array<T>* data) { 22.7 + if (DumpSharedSpaces) { 22.8 + // FIXME: the freeing code is buggy, especially when PrintSharedSpaces is enabled. 22.9 + // Disable for now -- this means if you specify bad classes in your classlist you 22.10 + // may have wasted space inside the archive. 22.11 + return; 22.12 + } 22.13 if (data != NULL) { 22.14 assert(loader_data != NULL, "shouldn't pass null"); 22.15 assert(!data->is_shared(), "cannot deallocate array in shared spaces");
23.1 --- a/src/share/vm/memory/metaspaceShared.cpp Mon Nov 17 15:51:46 2014 -0500 23.2 +++ b/src/share/vm/memory/metaspaceShared.cpp Wed Nov 19 15:02:01 2014 -0800 23.3 @@ -24,6 +24,7 @@ 23.4 23.5 #include "precompiled.hpp" 23.6 #include "classfile/dictionary.hpp" 23.7 +#include "classfile/classLoaderExt.hpp" 23.8 #include "classfile/loaderConstraints.hpp" 23.9 #include "classfile/placeholders.hpp" 23.10 #include "classfile/sharedClassUtil.hpp" 23.11 @@ -39,6 +40,7 @@ 23.12 #include "runtime/signature.hpp" 23.13 #include "runtime/vm_operations.hpp" 23.14 #include "runtime/vmThread.hpp" 23.15 +#include "utilities/hashtable.hpp" 23.16 #include "utilities/hashtable.inline.hpp" 23.17 23.18 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 23.19 @@ -533,6 +535,8 @@ 23.20 ClassLoader::copy_package_info_table(&md_top, md_end); 23.21 ClassLoader::verify(); 23.22 23.23 + ClassLoaderExt::copy_lookup_cache_to_archive(&md_top, md_end); 23.24 + 23.25 // Write the other data to the output array. 23.26 WriteClosure wc(md_top, md_end); 23.27 MetaspaceShared::serialize(&wc); 23.28 @@ -745,6 +749,8 @@ 23.29 } 23.30 tty->print_cr("Loading classes to share: done."); 23.31 23.32 + ClassLoaderExt::init_lookup_cache(THREAD); 23.33 + 23.34 if (PrintSharedSpaces) { 23.35 tty->print_cr("Shared spaces: preloaded %d classes", class_count); 23.36 } 23.37 @@ -1056,6 +1062,8 @@ 23.38 buffer += sizeof(intptr_t); 23.39 buffer += len; 23.40 23.41 + buffer = ClassLoaderExt::restore_lookup_cache_from_archive(buffer); 23.42 + 23.43 intptr_t* array = (intptr_t*)buffer; 23.44 ReadClosure rc(&array); 23.45 serialize(&rc);
24.1 --- a/src/share/vm/memory/metaspaceShared.hpp Mon Nov 17 15:51:46 2014 -0500 24.2 +++ b/src/share/vm/memory/metaspaceShared.hpp Wed Nov 19 15:02:01 2014 -0800 24.3 @@ -32,9 +32,9 @@ 24.4 24.5 #define LargeSharedArchiveSize (300*M) 24.6 #define HugeSharedArchiveSize (800*M) 24.7 -#define ReadOnlyRegionPercentage 0.4 24.8 -#define ReadWriteRegionPercentage 0.55 24.9 -#define MiscDataRegionPercentage 0.03 24.10 +#define ReadOnlyRegionPercentage 0.39 24.11 +#define ReadWriteRegionPercentage 0.50 24.12 +#define MiscDataRegionPercentage 0.09 24.13 #define MiscCodeRegionPercentage 0.02 24.14 #define LargeThresholdClassCount 5000 24.15 #define HugeThresholdClassCount 40000
25.1 --- a/src/share/vm/oops/constantPool.cpp Mon Nov 17 15:51:46 2014 -0500 25.2 +++ b/src/share/vm/oops/constantPool.cpp Wed Nov 19 15:02:01 2014 -0800 25.3 @@ -1817,11 +1817,22 @@ 25.4 25.5 void ConstantPool::set_on_stack(const bool value) { 25.6 if (value) { 25.7 - _flags |= _on_stack; 25.8 + int old_flags = *const_cast<volatile int *>(&_flags); 25.9 + while ((old_flags & _on_stack) == 0) { 25.10 + int new_flags = old_flags | _on_stack; 25.11 + int result = Atomic::cmpxchg(new_flags, &_flags, old_flags); 25.12 + 25.13 + if (result == old_flags) { 25.14 + // Succeeded. 25.15 + MetadataOnStackMark::record(this, Thread::current()); 25.16 + return; 25.17 + } 25.18 + old_flags = result; 25.19 + } 25.20 } else { 25.21 + // Clearing is done single-threadedly. 25.22 _flags &= ~_on_stack; 25.23 } 25.24 - if (value) MetadataOnStackMark::record(this); 25.25 } 25.26 25.27 // JSR 292 support for patching constant pool oops after the class is linked and
26.1 --- a/src/share/vm/oops/instanceKlass.cpp Mon Nov 17 15:51:46 2014 -0500 26.2 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Nov 19 15:02:01 2014 -0800 26.3 @@ -2890,6 +2890,22 @@ 26.4 OsrList_lock->unlock(); 26.5 } 26.6 26.7 +int InstanceKlass::mark_osr_nmethods(const Method* m) { 26.8 + // This is a short non-blocking critical region, so the no safepoint check is ok. 26.9 + MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag); 26.10 + nmethod* osr = osr_nmethods_head(); 26.11 + int found = 0; 26.12 + while (osr != NULL) { 26.13 + assert(osr->is_osr_method(), "wrong kind of nmethod found in chain"); 26.14 + if (osr->method() == m) { 26.15 + osr->mark_for_deoptimization(); 26.16 + found++; 26.17 + } 26.18 + osr = osr->osr_link(); 26.19 + } 26.20 + return found; 26.21 +} 26.22 + 26.23 nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const { 26.24 // This is a short non-blocking critical region, so the no safepoint check is ok. 26.25 OsrList_lock->lock_without_safepoint_check();
27.1 --- a/src/share/vm/oops/instanceKlass.hpp Mon Nov 17 15:51:46 2014 -0500 27.2 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Nov 19 15:02:01 2014 -0800 27.3 @@ -783,6 +783,7 @@ 27.4 void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; }; 27.5 void add_osr_nmethod(nmethod* n); 27.6 void remove_osr_nmethod(nmethod* n); 27.7 + int mark_osr_nmethods(const Method* m); 27.8 nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const; 27.9 27.10 // Breakpoint support (see methods on Method* for details)
28.1 --- a/src/share/vm/oops/method.cpp Mon Nov 17 15:51:46 2014 -0500 28.2 +++ b/src/share/vm/oops/method.cpp Wed Nov 19 15:02:01 2014 -0800 28.3 @@ -1863,9 +1863,12 @@ 28.4 void Method::set_on_stack(const bool value) { 28.5 // Set both the method itself and its constant pool. The constant pool 28.6 // on stack means some method referring to it is also on the stack. 28.7 - _access_flags.set_on_stack(value); 28.8 constants()->set_on_stack(value); 28.9 - if (value) MetadataOnStackMark::record(this); 28.10 + 28.11 + bool succeeded = _access_flags.set_on_stack(value); 28.12 + if (value && succeeded) { 28.13 + MetadataOnStackMark::record(this, Thread::current()); 28.14 + } 28.15 } 28.16 28.17 // Called when the class loader is unloaded to make all methods weak.
29.1 --- a/src/share/vm/oops/method.hpp Mon Nov 17 15:51:46 2014 -0500 29.2 +++ b/src/share/vm/oops/method.hpp Wed Nov 19 15:02:01 2014 -0800 29.3 @@ -793,6 +793,10 @@ 29.4 return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL; 29.5 } 29.6 29.7 + int mark_osr_nmethods() { 29.8 + return method_holder()->mark_osr_nmethods(this); 29.9 + } 29.10 + 29.11 nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) { 29.12 return method_holder()->lookup_osr_nmethod(this, bci, level, match_level); 29.13 }
30.1 --- a/src/share/vm/opto/lcm.cpp Mon Nov 17 15:51:46 2014 -0500 30.2 +++ b/src/share/vm/opto/lcm.cpp Wed Nov 19 15:02:01 2014 -0800 30.3 @@ -484,9 +484,7 @@ 30.4 iop == Op_CreateEx || // Create-exception must start block 30.5 iop == Op_CheckCastPP 30.6 ) { 30.7 - // select the node n 30.8 - // remove n from worklist and retain the order of remaining nodes 30.9 - worklist.remove((uint)i); 30.10 + worklist.map(i,worklist.pop()); 30.11 return n; 30.12 } 30.13 30.14 @@ -572,9 +570,7 @@ 30.15 assert(idx >= 0, "index should be set"); 30.16 Node *n = worklist[(uint)idx]; // Get the winner 30.17 30.18 - // select the node n 30.19 - // remove n from worklist and retain the order of remaining nodes 30.20 - worklist.remove((uint)idx); 30.21 + worklist.map((uint)idx, worklist.pop()); // Compress worklist 30.22 return n; 30.23 } 30.24
31.1 --- a/src/share/vm/prims/jni.cpp Mon Nov 17 15:51:46 2014 -0500 31.2 +++ b/src/share/vm/prims/jni.cpp Wed Nov 19 15:02:01 2014 -0800 31.3 @@ -5080,6 +5080,7 @@ 31.4 void TestNewSize_test(); 31.5 void TestKlass_test(); 31.6 void Test_linked_list(); 31.7 +void TestChunkedList_test(); 31.8 #if INCLUDE_ALL_GCS 31.9 void TestOldFreeSpaceCalculation_test(); 31.10 void TestG1BiasedArray_test(); 31.11 @@ -5108,6 +5109,7 @@ 31.12 run_unit_test(TestNewSize_test()); 31.13 run_unit_test(TestKlass_test()); 31.14 run_unit_test(Test_linked_list()); 31.15 + run_unit_test(TestChunkedList_test()); 31.16 #if INCLUDE_VM_STRUCTS 31.17 run_unit_test(VMStructs::test()); 31.18 #endif
32.1 --- a/src/share/vm/prims/jvm.cpp Mon Nov 17 15:51:46 2014 -0500 32.2 +++ b/src/share/vm/prims/jvm.cpp Wed Nov 19 15:02:01 2014 -0800 32.3 @@ -24,6 +24,7 @@ 32.4 32.5 #include "precompiled.hpp" 32.6 #include "classfile/classLoader.hpp" 32.7 +#include "classfile/classLoaderExt.hpp" 32.8 #include "classfile/javaAssertions.hpp" 32.9 #include "classfile/javaClasses.hpp" 32.10 #include "classfile/symbolTable.hpp" 32.11 @@ -393,6 +394,14 @@ 32.12 } 32.13 } 32.14 32.15 + const char* enableSharedLookupCache = "false"; 32.16 +#if INCLUDE_CDS 32.17 + if (ClassLoaderExt::is_lookup_cache_enabled()) { 32.18 + enableSharedLookupCache = "true"; 32.19 + } 32.20 +#endif 32.21 + PUTPROP(props, "sun.cds.enableSharedLookupCache", enableSharedLookupCache); 32.22 + 32.23 return properties; 32.24 JVM_END 32.25 32.26 @@ -766,6 +775,36 @@ 32.27 JVM_END 32.28 32.29 32.30 +JVM_ENTRY(jboolean, JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname)) 32.31 + JVMWrapper("JVM_KnownToNotExist"); 32.32 +#if INCLUDE_CDS 32.33 + return ClassLoaderExt::known_to_not_exist(env, loader, classname, CHECK_(false)); 32.34 +#else 32.35 + return false; 32.36 +#endif 32.37 +JVM_END 32.38 + 32.39 + 32.40 +JVM_ENTRY(jobjectArray, JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader)) 32.41 + JVMWrapper("JVM_GetResourceLookupCacheURLs"); 32.42 +#if INCLUDE_CDS 32.43 + return ClassLoaderExt::get_lookup_cache_urls(env, loader, CHECK_NULL); 32.44 +#else 32.45 + return NULL; 32.46 +#endif 32.47 +JVM_END 32.48 + 32.49 + 32.50 +JVM_ENTRY(jintArray, JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name)) 32.51 + JVMWrapper("JVM_GetResourceLookupCache"); 32.52 +#if INCLUDE_CDS 32.53 + return ClassLoaderExt::get_lookup_cache(env, loader, resource_name, CHECK_NULL); 32.54 +#else 32.55 + return NULL; 32.56 +#endif 32.57 +JVM_END 32.58 + 32.59 + 32.60 // Returns a class loaded by the bootstrap class loader; or null 32.61 // if not found. ClassNotFoundException is not thrown. 32.62 //
33.1 --- a/src/share/vm/prims/jvm.h Mon Nov 17 15:51:46 2014 -0500 33.2 +++ b/src/share/vm/prims/jvm.h Wed Nov 19 15:02:01 2014 -0800 33.3 @@ -1548,6 +1548,31 @@ 33.4 JNIEXPORT jobjectArray JNICALL 33.5 JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values); 33.6 33.7 +/* 33.8 + * Returns true if the JVM's lookup cache indicates that this class is 33.9 + * known to NOT exist for the given loader. 33.10 + */ 33.11 +JNIEXPORT jboolean JNICALL 33.12 +JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname); 33.13 + 33.14 +/* 33.15 + * Returns an array of all URLs that are stored in the JVM's lookup cache 33.16 + * for the given loader. NULL if the lookup cache is unavailable. 33.17 + */ 33.18 +JNIEXPORT jobjectArray JNICALL 33.19 +JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader); 33.20 + 33.21 +/* 33.22 + * Returns an array of all URLs that *may* contain the resource_name for the 33.23 + * given loader. This function returns an integer array, each element 33.24 + * of which can be used to index into the array returned by 33.25 + * JVM_GetResourceLookupCacheURLs of the same loader to determine the 33.26 + * URLs. 33.27 + */ 33.28 +JNIEXPORT jintArray JNICALL 33.29 +JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name); 33.30 + 33.31 + 33.32 /* ========================================================================= 33.33 * The following defines a private JVM interface that the JDK can query 33.34 * for the JVM version and capabilities. sun.misc.Version defines
34.1 --- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Nov 17 15:51:46 2014 -0500 34.2 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Wed Nov 19 15:02:01 2014 -0800 34.3 @@ -54,6 +54,7 @@ 34.4 void JvmtiClassFileReconstituter::write_field_infos() { 34.5 HandleMark hm(thread()); 34.6 Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations(); 34.7 + Array<AnnotationArray*>* fields_type_anno = ikh()->fields_type_annotations(); 34.8 34.9 // Compute the real number of Java fields 34.10 int java_fields = ikh()->java_fields_count(); 34.11 @@ -68,6 +69,7 @@ 34.12 // int offset = ikh()->field_offset( index ); 34.13 int generic_signature_index = fs.generic_signature_index(); 34.14 AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index()); 34.15 + AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index()); 34.16 34.17 // JVMSpec| field_info { 34.18 // JVMSpec| u2 access_flags; 34.19 @@ -93,6 +95,9 @@ 34.20 if (anno != NULL) { 34.21 ++attr_count; // has RuntimeVisibleAnnotations attribute 34.22 } 34.23 + if (type_anno != NULL) { 34.24 + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute 34.25 + } 34.26 34.27 write_u2(attr_count); 34.28 34.29 @@ -110,6 +115,9 @@ 34.30 if (anno != NULL) { 34.31 write_annotations_attribute("RuntimeVisibleAnnotations", anno); 34.32 } 34.33 + if (type_anno != NULL) { 34.34 + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); 34.35 + } 34.36 } 34.37 } 34.38 34.39 @@ -550,6 +558,7 @@ 34.40 AnnotationArray* anno = method->annotations(); 34.41 AnnotationArray* param_anno = method->parameter_annotations(); 34.42 AnnotationArray* default_anno = method->annotation_default(); 34.43 + AnnotationArray* type_anno = method->type_annotations(); 34.44 34.45 // skip generated default interface methods 34.46 if (method->is_overpass()) { 34.47 @@ -585,6 +594,9 @@ 34.48 if (param_anno != NULL) { 34.49 ++attr_count; // has RuntimeVisibleParameterAnnotations attribute 34.50 } 34.51 + if (type_anno != NULL) { 34.52 + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute 34.53 + } 34.54 34.55 write_u2(attr_count); 34.56 if (const_method->code_size() > 0) { 34.57 @@ -609,6 +621,9 @@ 34.58 if (param_anno != NULL) { 34.59 write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno); 34.60 } 34.61 + if (type_anno != NULL) { 34.62 + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); 34.63 + } 34.64 } 34.65 34.66 // Write the class attributes portion of ClassFile structure 34.67 @@ -618,6 +633,7 @@ 34.68 u2 inner_classes_length = inner_classes_attribute_length(); 34.69 Symbol* generic_signature = ikh()->generic_signature(); 34.70 AnnotationArray* anno = ikh()->class_annotations(); 34.71 + AnnotationArray* type_anno = ikh()->class_type_annotations(); 34.72 34.73 int attr_count = 0; 34.74 if (generic_signature != NULL) { 34.75 @@ -635,6 +651,9 @@ 34.76 if (anno != NULL) { 34.77 ++attr_count; // has RuntimeVisibleAnnotations attribute 34.78 } 34.79 + if (type_anno != NULL) { 34.80 + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute 34.81 + } 34.82 if (cpool()->operands() != NULL) { 34.83 ++attr_count; 34.84 } 34.85 @@ -656,6 +675,9 @@ 34.86 if (anno != NULL) { 34.87 write_annotations_attribute("RuntimeVisibleAnnotations", anno); 34.88 } 34.89 + if (type_anno != NULL) { 34.90 + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); 34.91 + } 34.92 if (cpool()->operands() != NULL) { 34.93 write_bootstrapmethod_attribute(); 34.94 }
35.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Nov 17 15:51:46 2014 -0500 35.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Nov 19 15:02:01 2014 -0800 35.3 @@ -135,7 +135,7 @@ 35.4 35.5 // Mark methods seen on stack and everywhere else so old methods are not 35.6 // cleaned up if they're on the stack. 35.7 - MetadataOnStackMark md_on_stack; 35.8 + MetadataOnStackMark md_on_stack(true); 35.9 HandleMark hm(thread); // make sure any handles created are deleted 35.10 // before the stack walk again. 35.11 35.12 @@ -1569,6 +1569,29 @@ 35.13 return false; 35.14 } 35.15 35.16 + // rewrite constant pool references in the class_type_annotations: 35.17 + if (!rewrite_cp_refs_in_class_type_annotations(scratch_class, THREAD)) { 35.18 + // propagate failure back to caller 35.19 + return false; 35.20 + } 35.21 + 35.22 + // rewrite constant pool references in the fields_type_annotations: 35.23 + if (!rewrite_cp_refs_in_fields_type_annotations(scratch_class, THREAD)) { 35.24 + // propagate failure back to caller 35.25 + return false; 35.26 + } 35.27 + 35.28 + // rewrite constant pool references in the methods_type_annotations: 35.29 + if (!rewrite_cp_refs_in_methods_type_annotations(scratch_class, THREAD)) { 35.30 + // propagate failure back to caller 35.31 + return false; 35.32 + } 35.33 + 35.34 + // There can be type annotations in the Code part of a method_info attribute. 35.35 + // These annotations are not accessible, even by reflection. 35.36 + // Currently they are not even parsed by the ClassFileParser. 35.37 + // If runtime access is added they will also need to be rewritten. 35.38 + 35.39 // rewrite source file name index: 35.40 u2 source_file_name_idx = scratch_class->source_file_name_index(); 35.41 if (source_file_name_idx != 0) { 35.42 @@ -2239,6 +2262,588 @@ 35.43 } // end rewrite_cp_refs_in_methods_default_annotations() 35.44 35.45 35.46 +// Rewrite constant pool references in a class_type_annotations field. 35.47 +bool VM_RedefineClasses::rewrite_cp_refs_in_class_type_annotations( 35.48 + instanceKlassHandle scratch_class, TRAPS) { 35.49 + 35.50 + AnnotationArray* class_type_annotations = scratch_class->class_type_annotations(); 35.51 + if (class_type_annotations == NULL || class_type_annotations->length() == 0) { 35.52 + // no class_type_annotations so nothing to do 35.53 + return true; 35.54 + } 35.55 + 35.56 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.57 + ("class_type_annotations length=%d", class_type_annotations->length())); 35.58 + 35.59 + int byte_i = 0; // byte index into class_type_annotations 35.60 + return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations, 35.61 + byte_i, "ClassFile", THREAD); 35.62 +} // end rewrite_cp_refs_in_class_type_annotations() 35.63 + 35.64 + 35.65 +// Rewrite constant pool references in a fields_type_annotations field. 35.66 +bool VM_RedefineClasses::rewrite_cp_refs_in_fields_type_annotations( 35.67 + instanceKlassHandle scratch_class, TRAPS) { 35.68 + 35.69 + Array<AnnotationArray*>* fields_type_annotations = scratch_class->fields_type_annotations(); 35.70 + if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) { 35.71 + // no fields_type_annotations so nothing to do 35.72 + return true; 35.73 + } 35.74 + 35.75 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.76 + ("fields_type_annotations length=%d", fields_type_annotations->length())); 35.77 + 35.78 + for (int i = 0; i < fields_type_annotations->length(); i++) { 35.79 + AnnotationArray* field_type_annotations = fields_type_annotations->at(i); 35.80 + if (field_type_annotations == NULL || field_type_annotations->length() == 0) { 35.81 + // this field does not have any annotations so skip it 35.82 + continue; 35.83 + } 35.84 + 35.85 + int byte_i = 0; // byte index into field_type_annotations 35.86 + if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations, 35.87 + byte_i, "field_info", THREAD)) { 35.88 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.89 + ("bad field_type_annotations at %d", i)); 35.90 + // propagate failure back to caller 35.91 + return false; 35.92 + } 35.93 + } 35.94 + 35.95 + return true; 35.96 +} // end rewrite_cp_refs_in_fields_type_annotations() 35.97 + 35.98 + 35.99 +// Rewrite constant pool references in a methods_type_annotations field. 35.100 +bool VM_RedefineClasses::rewrite_cp_refs_in_methods_type_annotations( 35.101 + instanceKlassHandle scratch_class, TRAPS) { 35.102 + 35.103 + for (int i = 0; i < scratch_class->methods()->length(); i++) { 35.104 + Method* m = scratch_class->methods()->at(i); 35.105 + AnnotationArray* method_type_annotations = m->constMethod()->type_annotations(); 35.106 + 35.107 + if (method_type_annotations == NULL || method_type_annotations->length() == 0) { 35.108 + // this method does not have any annotations so skip it 35.109 + continue; 35.110 + } 35.111 + 35.112 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.113 + ("methods type_annotations length=%d", method_type_annotations->length())); 35.114 + 35.115 + int byte_i = 0; // byte index into method_type_annotations 35.116 + if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations, 35.117 + byte_i, "method_info", THREAD)) { 35.118 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.119 + ("bad method_type_annotations at %d", i)); 35.120 + // propagate failure back to caller 35.121 + return false; 35.122 + } 35.123 + } 35.124 + 35.125 + return true; 35.126 +} // end rewrite_cp_refs_in_methods_type_annotations() 35.127 + 35.128 + 35.129 +// Rewrite constant pool references in a type_annotations 35.130 +// field. This "structure" is adapted from the 35.131 +// RuntimeVisibleTypeAnnotations_attribute described in 35.132 +// section 4.7.20 of the Java SE 8 Edition of the VM spec: 35.133 +// 35.134 +// type_annotations_typeArray { 35.135 +// u2 num_annotations; 35.136 +// type_annotation annotations[num_annotations]; 35.137 +// } 35.138 +// 35.139 +bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotations_typeArray( 35.140 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, 35.141 + const char * location_mesg, TRAPS) { 35.142 + 35.143 + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { 35.144 + // not enough room for num_annotations field 35.145 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.146 + ("length() is too small for num_annotations field")); 35.147 + return false; 35.148 + } 35.149 + 35.150 + u2 num_annotations = Bytes::get_Java_u2((address) 35.151 + type_annotations_typeArray->adr_at(byte_i_ref)); 35.152 + byte_i_ref += 2; 35.153 + 35.154 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.155 + ("num_type_annotations=%d", num_annotations)); 35.156 + 35.157 + int calc_num_annotations = 0; 35.158 + for (; calc_num_annotations < num_annotations; calc_num_annotations++) { 35.159 + if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray, 35.160 + byte_i_ref, location_mesg, THREAD)) { 35.161 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.162 + ("bad type_annotation_struct at %d", calc_num_annotations)); 35.163 + // propagate failure back to caller 35.164 + return false; 35.165 + } 35.166 + } 35.167 + assert(num_annotations == calc_num_annotations, "sanity check"); 35.168 + 35.169 + if (byte_i_ref != type_annotations_typeArray->length()) { 35.170 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.171 + ("read wrong amount of bytes at end of processing " 35.172 + "type_annotations_typeArray (%d of %d bytes were read)", 35.173 + byte_i_ref, type_annotations_typeArray->length())); 35.174 + return false; 35.175 + } 35.176 + 35.177 + return true; 35.178 +} // end rewrite_cp_refs_in_type_annotations_typeArray() 35.179 + 35.180 + 35.181 +// Rewrite constant pool references in a type_annotation 35.182 +// field. This "structure" is adapted from the 35.183 +// RuntimeVisibleTypeAnnotations_attribute described in 35.184 +// section 4.7.20 of the Java SE 8 Edition of the VM spec: 35.185 +// 35.186 +// type_annotation { 35.187 +// u1 target_type; 35.188 +// union { 35.189 +// type_parameter_target; 35.190 +// supertype_target; 35.191 +// type_parameter_bound_target; 35.192 +// empty_target; 35.193 +// method_formal_parameter_target; 35.194 +// throws_target; 35.195 +// localvar_target; 35.196 +// catch_target; 35.197 +// offset_target; 35.198 +// type_argument_target; 35.199 +// } target_info; 35.200 +// type_path target_path; 35.201 +// annotation anno; 35.202 +// } 35.203 +// 35.204 +bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotation_struct( 35.205 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, 35.206 + const char * location_mesg, TRAPS) { 35.207 + 35.208 + if (!skip_type_annotation_target(type_annotations_typeArray, 35.209 + byte_i_ref, location_mesg, THREAD)) { 35.210 + return false; 35.211 + } 35.212 + 35.213 + if (!skip_type_annotation_type_path(type_annotations_typeArray, 35.214 + byte_i_ref, THREAD)) { 35.215 + return false; 35.216 + } 35.217 + 35.218 + if (!rewrite_cp_refs_in_annotation_struct(type_annotations_typeArray, 35.219 + byte_i_ref, THREAD)) { 35.220 + return false; 35.221 + } 35.222 + 35.223 + return true; 35.224 +} // end rewrite_cp_refs_in_type_annotation_struct() 35.225 + 35.226 + 35.227 +// Read, verify and skip over the target_type and target_info part 35.228 +// so that rewriting can continue in the later parts of the struct. 35.229 +// 35.230 +// u1 target_type; 35.231 +// union { 35.232 +// type_parameter_target; 35.233 +// supertype_target; 35.234 +// type_parameter_bound_target; 35.235 +// empty_target; 35.236 +// method_formal_parameter_target; 35.237 +// throws_target; 35.238 +// localvar_target; 35.239 +// catch_target; 35.240 +// offset_target; 35.241 +// type_argument_target; 35.242 +// } target_info; 35.243 +// 35.244 +bool VM_RedefineClasses::skip_type_annotation_target( 35.245 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, 35.246 + const char * location_mesg, TRAPS) { 35.247 + 35.248 + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { 35.249 + // not enough room for a target_type let alone the rest of a type_annotation 35.250 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.251 + ("length() is too small for a target_type")); 35.252 + return false; 35.253 + } 35.254 + 35.255 + u1 target_type = type_annotations_typeArray->at(byte_i_ref); 35.256 + byte_i_ref += 1; 35.257 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type)); 35.258 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg)); 35.259 + 35.260 + // Skip over target_info 35.261 + switch (target_type) { 35.262 + case 0x00: 35.263 + // kind: type parameter declaration of generic class or interface 35.264 + // location: ClassFile 35.265 + case 0x01: 35.266 + // kind: type parameter declaration of generic method or constructor 35.267 + // location: method_info 35.268 + 35.269 + { 35.270 + // struct: 35.271 + // type_parameter_target { 35.272 + // u1 type_parameter_index; 35.273 + // } 35.274 + // 35.275 + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { 35.276 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.277 + ("length() is too small for a type_parameter_target")); 35.278 + return false; 35.279 + } 35.280 + 35.281 + u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); 35.282 + byte_i_ref += 1; 35.283 + 35.284 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.285 + ("type_parameter_target: type_parameter_index=%d", 35.286 + type_parameter_index)); 35.287 + } break; 35.288 + 35.289 + case 0x10: 35.290 + // kind: type in extends clause of class or interface declaration 35.291 + // (including the direct superclass of an anonymous class declaration), 35.292 + // or in implements clause of interface declaration 35.293 + // location: ClassFile 35.294 + 35.295 + { 35.296 + // struct: 35.297 + // supertype_target { 35.298 + // u2 supertype_index; 35.299 + // } 35.300 + // 35.301 + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { 35.302 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.303 + ("length() is too small for a supertype_target")); 35.304 + return false; 35.305 + } 35.306 + 35.307 + u2 supertype_index = Bytes::get_Java_u2((address) 35.308 + type_annotations_typeArray->adr_at(byte_i_ref)); 35.309 + byte_i_ref += 2; 35.310 + 35.311 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.312 + ("supertype_target: supertype_index=%d", supertype_index)); 35.313 + } break; 35.314 + 35.315 + case 0x11: 35.316 + // kind: type in bound of type parameter declaration of generic class or interface 35.317 + // location: ClassFile 35.318 + case 0x12: 35.319 + // kind: type in bound of type parameter declaration of generic method or constructor 35.320 + // location: method_info 35.321 + 35.322 + { 35.323 + // struct: 35.324 + // type_parameter_bound_target { 35.325 + // u1 type_parameter_index; 35.326 + // u1 bound_index; 35.327 + // } 35.328 + // 35.329 + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { 35.330 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.331 + ("length() is too small for a type_parameter_bound_target")); 35.332 + return false; 35.333 + } 35.334 + 35.335 + u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); 35.336 + byte_i_ref += 1; 35.337 + u1 bound_index = type_annotations_typeArray->at(byte_i_ref); 35.338 + byte_i_ref += 1; 35.339 + 35.340 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.341 + ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d", 35.342 + type_parameter_index, bound_index)); 35.343 + } break; 35.344 + 35.345 + case 0x13: 35.346 + // kind: type in field declaration 35.347 + // location: field_info 35.348 + case 0x14: 35.349 + // kind: return type of method, or type of newly constructed object 35.350 + // location: method_info 35.351 + case 0x15: 35.352 + // kind: receiver type of method or constructor 35.353 + // location: method_info 35.354 + 35.355 + { 35.356 + // struct: 35.357 + // empty_target { 35.358 + // } 35.359 + // 35.360 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.361 + ("empty_target")); 35.362 + } break; 35.363 + 35.364 + case 0x16: 35.365 + // kind: type in formal parameter declaration of method, constructor, or lambda expression 35.366 + // location: method_info 35.367 + 35.368 + { 35.369 + // struct: 35.370 + // formal_parameter_target { 35.371 + // u1 formal_parameter_index; 35.372 + // } 35.373 + // 35.374 + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { 35.375 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.376 + ("length() is too small for a formal_parameter_target")); 35.377 + return false; 35.378 + } 35.379 + 35.380 + u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref); 35.381 + byte_i_ref += 1; 35.382 + 35.383 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.384 + ("formal_parameter_target: formal_parameter_index=%d", 35.385 + formal_parameter_index)); 35.386 + } break; 35.387 + 35.388 + case 0x17: 35.389 + // kind: type in throws clause of method or constructor 35.390 + // location: method_info 35.391 + 35.392 + { 35.393 + // struct: 35.394 + // throws_target { 35.395 + // u2 throws_type_index 35.396 + // } 35.397 + // 35.398 + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { 35.399 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.400 + ("length() is too small for a throws_target")); 35.401 + return false; 35.402 + } 35.403 + 35.404 + u2 throws_type_index = Bytes::get_Java_u2((address) 35.405 + type_annotations_typeArray->adr_at(byte_i_ref)); 35.406 + byte_i_ref += 2; 35.407 + 35.408 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.409 + ("throws_target: throws_type_index=%d", throws_type_index)); 35.410 + } break; 35.411 + 35.412 + case 0x40: 35.413 + // kind: type in local variable declaration 35.414 + // location: Code 35.415 + case 0x41: 35.416 + // kind: type in resource variable declaration 35.417 + // location: Code 35.418 + 35.419 + { 35.420 + // struct: 35.421 + // localvar_target { 35.422 + // u2 table_length; 35.423 + // struct { 35.424 + // u2 start_pc; 35.425 + // u2 length; 35.426 + // u2 index; 35.427 + // } table[table_length]; 35.428 + // } 35.429 + // 35.430 + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { 35.431 + // not enough room for a table_length let alone the rest of a localvar_target 35.432 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.433 + ("length() is too small for a localvar_target table_length")); 35.434 + return false; 35.435 + } 35.436 + 35.437 + u2 table_length = Bytes::get_Java_u2((address) 35.438 + type_annotations_typeArray->adr_at(byte_i_ref)); 35.439 + byte_i_ref += 2; 35.440 + 35.441 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.442 + ("localvar_target: table_length=%d", table_length)); 35.443 + 35.444 + int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry 35.445 + int table_size = table_length * table_struct_size; 35.446 + 35.447 + if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) { 35.448 + // not enough room for a table 35.449 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.450 + ("length() is too small for a table array of length %d", table_length)); 35.451 + return false; 35.452 + } 35.453 + 35.454 + // Skip over table 35.455 + byte_i_ref += table_size; 35.456 + } break; 35.457 + 35.458 + case 0x42: 35.459 + // kind: type in exception parameter declaration 35.460 + // location: Code 35.461 + 35.462 + { 35.463 + // struct: 35.464 + // catch_target { 35.465 + // u2 exception_table_index; 35.466 + // } 35.467 + // 35.468 + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { 35.469 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.470 + ("length() is too small for a catch_target")); 35.471 + return false; 35.472 + } 35.473 + 35.474 + u2 exception_table_index = Bytes::get_Java_u2((address) 35.475 + type_annotations_typeArray->adr_at(byte_i_ref)); 35.476 + byte_i_ref += 2; 35.477 + 35.478 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.479 + ("catch_target: exception_table_index=%d", exception_table_index)); 35.480 + } break; 35.481 + 35.482 + case 0x43: 35.483 + // kind: type in instanceof expression 35.484 + // location: Code 35.485 + case 0x44: 35.486 + // kind: type in new expression 35.487 + // location: Code 35.488 + case 0x45: 35.489 + // kind: type in method reference expression using ::new 35.490 + // location: Code 35.491 + case 0x46: 35.492 + // kind: type in method reference expression using ::Identifier 35.493 + // location: Code 35.494 + 35.495 + { 35.496 + // struct: 35.497 + // offset_target { 35.498 + // u2 offset; 35.499 + // } 35.500 + // 35.501 + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { 35.502 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.503 + ("length() is too small for a offset_target")); 35.504 + return false; 35.505 + } 35.506 + 35.507 + u2 offset = Bytes::get_Java_u2((address) 35.508 + type_annotations_typeArray->adr_at(byte_i_ref)); 35.509 + byte_i_ref += 2; 35.510 + 35.511 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.512 + ("offset_target: offset=%d", offset)); 35.513 + } break; 35.514 + 35.515 + case 0x47: 35.516 + // kind: type in cast expression 35.517 + // location: Code 35.518 + case 0x48: 35.519 + // kind: type argument for generic constructor in new expression or 35.520 + // explicit constructor invocation statement 35.521 + // location: Code 35.522 + case 0x49: 35.523 + // kind: type argument for generic method in method invocation expression 35.524 + // location: Code 35.525 + case 0x4A: 35.526 + // kind: type argument for generic constructor in method reference expression using ::new 35.527 + // location: Code 35.528 + case 0x4B: 35.529 + // kind: type argument for generic method in method reference expression using ::Identifier 35.530 + // location: Code 35.531 + 35.532 + { 35.533 + // struct: 35.534 + // type_argument_target { 35.535 + // u2 offset; 35.536 + // u1 type_argument_index; 35.537 + // } 35.538 + // 35.539 + if ((byte_i_ref + 3) > type_annotations_typeArray->length()) { 35.540 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.541 + ("length() is too small for a type_argument_target")); 35.542 + return false; 35.543 + } 35.544 + 35.545 + u2 offset = Bytes::get_Java_u2((address) 35.546 + type_annotations_typeArray->adr_at(byte_i_ref)); 35.547 + byte_i_ref += 2; 35.548 + u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); 35.549 + byte_i_ref += 1; 35.550 + 35.551 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.552 + ("type_argument_target: offset=%d, type_argument_index=%d", 35.553 + offset, type_argument_index)); 35.554 + } break; 35.555 + 35.556 + default: 35.557 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.558 + ("unknown target_type")); 35.559 +#ifdef ASSERT 35.560 + ShouldNotReachHere(); 35.561 +#endif 35.562 + return false; 35.563 + } 35.564 + 35.565 + return true; 35.566 +} // end skip_type_annotation_target() 35.567 + 35.568 + 35.569 +// Read, verify and skip over the type_path part so that rewriting 35.570 +// can continue in the later parts of the struct. 35.571 +// 35.572 +// type_path { 35.573 +// u1 path_length; 35.574 +// { 35.575 +// u1 type_path_kind; 35.576 +// u1 type_argument_index; 35.577 +// } path[path_length]; 35.578 +// } 35.579 +// 35.580 +bool VM_RedefineClasses::skip_type_annotation_type_path( 35.581 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) { 35.582 + 35.583 + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { 35.584 + // not enough room for a path_length let alone the rest of the type_path 35.585 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.586 + ("length() is too small for a type_path")); 35.587 + return false; 35.588 + } 35.589 + 35.590 + u1 path_length = type_annotations_typeArray->at(byte_i_ref); 35.591 + byte_i_ref += 1; 35.592 + 35.593 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.594 + ("type_path: path_length=%d", path_length)); 35.595 + 35.596 + int calc_path_length = 0; 35.597 + for (; calc_path_length < path_length; calc_path_length++) { 35.598 + if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) { 35.599 + // not enough room for a path 35.600 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.601 + ("length() is too small for path entry %d of %d", 35.602 + calc_path_length, path_length)); 35.603 + return false; 35.604 + } 35.605 + 35.606 + u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref); 35.607 + byte_i_ref += 1; 35.608 + u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); 35.609 + byte_i_ref += 1; 35.610 + 35.611 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.612 + ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d", 35.613 + calc_path_length, type_path_kind, type_argument_index)); 35.614 + 35.615 + if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) { 35.616 + // not enough room for a path 35.617 + RC_TRACE_WITH_THREAD(0x02000000, THREAD, 35.618 + ("inconsistent type_path values")); 35.619 + return false; 35.620 + } 35.621 + } 35.622 + assert(path_length == calc_path_length, "sanity check"); 35.623 + 35.624 + return true; 35.625 +} // end skip_type_annotation_type_path() 35.626 + 35.627 + 35.628 // Rewrite constant pool references in the method's stackmap table. 35.629 // These "structures" are adapted from the StackMapTable_attribute that 35.630 // is described in section 4.8.4 of the 6.0 version of the VM spec 35.631 @@ -3223,23 +3828,6 @@ 35.632 35.633 void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class, 35.634 instanceKlassHandle scratch_class) { 35.635 - // Since there is currently no rewriting of type annotations indexes 35.636 - // into the CP, we null out type annotations on scratch_class before 35.637 - // we swap annotations with the_class rather than facing the 35.638 - // possibility of shipping annotations with broken indexes to 35.639 - // Java-land. 35.640 - ClassLoaderData* loader_data = scratch_class->class_loader_data(); 35.641 - AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations(); 35.642 - if (new_class_type_annotations != NULL) { 35.643 - MetadataFactory::free_array<u1>(loader_data, new_class_type_annotations); 35.644 - scratch_class->annotations()->set_class_type_annotations(NULL); 35.645 - } 35.646 - Array<AnnotationArray*>* new_field_type_annotations = scratch_class->fields_type_annotations(); 35.647 - if (new_field_type_annotations != NULL) { 35.648 - Annotations::free_contents(loader_data, new_field_type_annotations); 35.649 - scratch_class->annotations()->set_fields_type_annotations(NULL); 35.650 - } 35.651 - 35.652 // Swap annotation fields values 35.653 Annotations* old_annotations = the_class->annotations(); 35.654 the_class->set_annotations(scratch_class->annotations());
36.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Mon Nov 17 15:51:46 2014 -0500 36.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Nov 19 15:02:01 2014 -0800 36.3 @@ -457,6 +457,17 @@ 36.4 instanceKlassHandle scratch_class, TRAPS); 36.5 bool rewrite_cp_refs_in_element_value( 36.6 AnnotationArray* class_annotations, int &byte_i_ref, TRAPS); 36.7 + bool rewrite_cp_refs_in_type_annotations_typeArray( 36.8 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, 36.9 + const char * location_mesg, TRAPS); 36.10 + bool rewrite_cp_refs_in_type_annotation_struct( 36.11 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, 36.12 + const char * location_mesg, TRAPS); 36.13 + bool skip_type_annotation_target( 36.14 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, 36.15 + const char * location_mesg, TRAPS); 36.16 + bool skip_type_annotation_type_path( 36.17 + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS); 36.18 bool rewrite_cp_refs_in_fields_annotations( 36.19 instanceKlassHandle scratch_class, TRAPS); 36.20 void rewrite_cp_refs_in_method(methodHandle method, 36.21 @@ -468,6 +479,12 @@ 36.22 instanceKlassHandle scratch_class, TRAPS); 36.23 bool rewrite_cp_refs_in_methods_parameter_annotations( 36.24 instanceKlassHandle scratch_class, TRAPS); 36.25 + bool rewrite_cp_refs_in_class_type_annotations( 36.26 + instanceKlassHandle scratch_class, TRAPS); 36.27 + bool rewrite_cp_refs_in_fields_type_annotations( 36.28 + instanceKlassHandle scratch_class, TRAPS); 36.29 + bool rewrite_cp_refs_in_methods_type_annotations( 36.30 + instanceKlassHandle scratch_class, TRAPS); 36.31 void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS); 36.32 void rewrite_cp_refs_in_verification_type_info( 36.33 address& stackmap_addr_ref, address stackmap_end, u2 frame_i,
37.1 --- a/src/share/vm/prims/whitebox.cpp Mon Nov 17 15:51:46 2014 -0500 37.2 +++ b/src/share/vm/prims/whitebox.cpp Wed Nov 19 15:02:01 2014 -0800 37.3 @@ -104,6 +104,28 @@ 37.4 return closure.found(); 37.5 WB_END 37.6 37.7 +WB_ENTRY(jboolean, WB_ClassKnownToNotExist(JNIEnv* env, jobject o, jobject loader, jstring name)) 37.8 + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 37.9 + const char* class_name = env->GetStringUTFChars(name, NULL); 37.10 + jboolean result = JVM_KnownToNotExist(env, loader, class_name); 37.11 + env->ReleaseStringUTFChars(name, class_name); 37.12 + return result; 37.13 +WB_END 37.14 + 37.15 +WB_ENTRY(jobjectArray, WB_GetLookupCacheURLs(JNIEnv* env, jobject o, jobject loader)) 37.16 + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 37.17 + return JVM_GetResourceLookupCacheURLs(env, loader); 37.18 +WB_END 37.19 + 37.20 +WB_ENTRY(jintArray, WB_GetLookupCacheMatches(JNIEnv* env, jobject o, jobject loader, jstring name)) 37.21 + ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 37.22 + const char* resource_name = env->GetStringUTFChars(name, NULL); 37.23 + jintArray result = JVM_GetResourceLookupCache(env, loader, resource_name); 37.24 + 37.25 + env->ReleaseStringUTFChars(name, resource_name); 37.26 + return result; 37.27 +WB_END 37.28 + 37.29 WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { 37.30 return (jlong)Arguments::max_heap_for_compressed_oops(); 37.31 } 37.32 @@ -382,19 +404,10 @@ 37.33 CHECK_JNI_EXCEPTION_(env, result); 37.34 MutexLockerEx mu(Compile_lock); 37.35 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 37.36 - nmethod* code; 37.37 if (is_osr) { 37.38 - int bci = InvocationEntryBci; 37.39 - while ((code = mh->lookup_osr_nmethod_for(bci, CompLevel_none, false)) != NULL) { 37.40 - code->mark_for_deoptimization(); 37.41 - ++result; 37.42 - bci = code->osr_entry_bci() + 1; 37.43 - } 37.44 - } else { 37.45 - code = mh->code(); 37.46 - } 37.47 - if (code != NULL) { 37.48 - code->mark_for_deoptimization(); 37.49 + result += mh->mark_osr_nmethods(); 37.50 + } else if (mh->code() != NULL) { 37.51 + mh->code()->mark_for_deoptimization(); 37.52 ++result; 37.53 } 37.54 result += CodeCache::mark_for_deoptimization(mh()); 37.55 @@ -939,6 +952,11 @@ 37.56 {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen }, 37.57 {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize }, 37.58 {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, 37.59 + {CC"classKnownToNotExist", 37.60 + CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)Z",(void*)&WB_ClassKnownToNotExist}, 37.61 + {CC"getLookupCacheURLs", CC"(Ljava/lang/ClassLoader;)[Ljava/net/URL;", (void*)&WB_GetLookupCacheURLs}, 37.62 + {CC"getLookupCacheMatches", CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)[I", 37.63 + (void*)&WB_GetLookupCacheMatches}, 37.64 {CC"parseCommandLine", 37.65 CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", 37.66 (void*) &WB_ParseCommandLine
38.1 --- a/src/share/vm/runtime/simpleThresholdPolicy.cpp Mon Nov 17 15:51:46 2014 -0500 38.2 +++ b/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Nov 19 15:02:01 2014 -0800 38.3 @@ -196,7 +196,6 @@ 38.4 // Don't trigger other compiles in testing mode 38.5 return NULL; 38.6 } 38.7 - nmethod *osr_nm = NULL; 38.8 38.9 handle_counter_overflow(method()); 38.10 if (method() != inlinee()) { 38.11 @@ -210,14 +209,16 @@ 38.12 if (bci == InvocationEntryBci) { 38.13 method_invocation_event(method, inlinee, comp_level, nm, thread); 38.14 } else { 38.15 + // method == inlinee if the event originated in the main method 38.16 method_back_branch_event(method, inlinee, bci, comp_level, nm, thread); 38.17 - // method == inlinee if the event originated in the main method 38.18 - int highest_level = inlinee->highest_osr_comp_level(); 38.19 - if (highest_level > comp_level) { 38.20 - osr_nm = inlinee->lookup_osr_nmethod_for(bci, highest_level, false); 38.21 + // Check if event led to a higher level OSR compilation 38.22 + nmethod* osr_nm = inlinee->lookup_osr_nmethod_for(bci, comp_level, false); 38.23 + if (osr_nm != NULL && osr_nm->comp_level() > comp_level) { 38.24 + // Perform OSR with new nmethod 38.25 + return osr_nm; 38.26 } 38.27 } 38.28 - return osr_nm; 38.29 + return NULL; 38.30 } 38.31 38.32 // Check if the method can be compiled, change level if necessary
39.1 --- a/src/share/vm/runtime/thread.cpp Mon Nov 17 15:51:46 2014 -0500 39.2 +++ b/src/share/vm/runtime/thread.cpp Wed Nov 19 15:02:01 2014 -0800 39.3 @@ -234,6 +234,8 @@ 39.4 // This initial value ==> never claimed. 39.5 _oops_do_parity = 0; 39.6 39.7 + _metadata_on_stack_buffer = NULL; 39.8 + 39.9 // the handle mark links itself to last_handle_mark 39.10 new HandleMark(this); 39.11
40.1 --- a/src/share/vm/runtime/thread.hpp Mon Nov 17 15:51:46 2014 -0500 40.2 +++ b/src/share/vm/runtime/thread.hpp Wed Nov 19 15:02:01 2014 -0800 40.3 @@ -42,11 +42,10 @@ 40.4 #include "runtime/threadLocalStorage.hpp" 40.5 #include "runtime/thread_ext.hpp" 40.6 #include "runtime/unhandledOops.hpp" 40.7 -#include "utilities/macros.hpp" 40.8 - 40.9 #include "trace/traceBackend.hpp" 40.10 #include "trace/traceMacros.hpp" 40.11 #include "utilities/exceptions.hpp" 40.12 +#include "utilities/macros.hpp" 40.13 #include "utilities/top.hpp" 40.14 #if INCLUDE_ALL_GCS 40.15 #include "gc_implementation/g1/dirtyCardQueue.hpp" 40.16 @@ -83,6 +82,10 @@ 40.17 class ThreadClosure; 40.18 class IdealGraphPrinter; 40.19 40.20 +class Metadata; 40.21 +template <class T, MEMFLAGS F> class ChunkedList; 40.22 +typedef ChunkedList<Metadata*, mtInternal> MetadataOnStackBuffer; 40.23 + 40.24 DEBUG_ONLY(class ResourceMark;) 40.25 40.26 class WorkerThread; 40.27 @@ -256,6 +259,9 @@ 40.28 jlong _allocated_bytes; // Cumulative number of bytes allocated on 40.29 // the Java heap 40.30 40.31 + // Thread-local buffer used by MetadataOnStackMark. 40.32 + MetadataOnStackBuffer* _metadata_on_stack_buffer; 40.33 + 40.34 TRACE_DATA _trace_data; // Thread-local data for tracing 40.35 40.36 ThreadExt _ext; 40.37 @@ -517,7 +523,10 @@ 40.38 // creation fails due to lack of memory, too many threads etc. 40.39 bool set_as_starting_thread(); 40.40 40.41 - protected: 40.42 + void set_metadata_on_stack_buffer(MetadataOnStackBuffer* buffer) { _metadata_on_stack_buffer = buffer; } 40.43 + MetadataOnStackBuffer* metadata_on_stack_buffer() const { return _metadata_on_stack_buffer; } 40.44 + 40.45 +protected: 40.46 // OS data associated with the thread 40.47 OSThread* _osthread; // Platform-specific thread information 40.48
41.1 --- a/src/share/vm/services/runtimeService.cpp Mon Nov 17 15:51:46 2014 -0500 41.2 +++ b/src/share/vm/services/runtimeService.cpp Wed Nov 19 15:02:01 2014 -0800 41.3 @@ -46,6 +46,7 @@ 41.4 PerfCounter* RuntimeService::_thread_interrupt_signaled_count = NULL; 41.5 PerfCounter* RuntimeService::_interrupted_before_count = NULL; 41.6 PerfCounter* RuntimeService::_interrupted_during_count = NULL; 41.7 +double RuntimeService::_last_safepoint_sync_time_sec = 0.0; 41.8 41.9 void RuntimeService::init() { 41.10 // Make sure the VM version is initialized 41.11 @@ -128,6 +129,7 @@ 41.12 41.13 // update the time stamp to begin recording safepoint time 41.14 _safepoint_timer.update(); 41.15 + _last_safepoint_sync_time_sec = 0.0; 41.16 if (UsePerfData) { 41.17 _total_safepoints->inc(); 41.18 if (_app_timer.is_updated()) { 41.19 @@ -140,6 +142,9 @@ 41.20 if (UsePerfData) { 41.21 _sync_time_ticks->inc(_safepoint_timer.ticks_since_update()); 41.22 } 41.23 + if (PrintGCApplicationStoppedTime) { 41.24 + _last_safepoint_sync_time_sec = last_safepoint_time_sec(); 41.25 + } 41.26 } 41.27 41.28 void RuntimeService::record_safepoint_end() { 41.29 @@ -155,8 +160,10 @@ 41.30 gclog_or_tty->date_stamp(PrintGCDateStamps); 41.31 gclog_or_tty->stamp(PrintGCTimeStamps); 41.32 gclog_or_tty->print_cr("Total time for which application threads " 41.33 - "were stopped: %3.7f seconds", 41.34 - last_safepoint_time_sec()); 41.35 + "were stopped: %3.7f seconds, " 41.36 + "Stopping threads took: %3.7f seconds", 41.37 + last_safepoint_time_sec(), 41.38 + _last_safepoint_sync_time_sec); 41.39 } 41.40 41.41 // update the time stamp to begin recording app time
42.1 --- a/src/share/vm/services/runtimeService.hpp Mon Nov 17 15:51:46 2014 -0500 42.2 +++ b/src/share/vm/services/runtimeService.hpp Wed Nov 19 15:02:01 2014 -0800 42.3 @@ -40,6 +40,7 @@ 42.4 42.5 static TimeStamp _safepoint_timer; 42.6 static TimeStamp _app_timer; 42.7 + static double _last_safepoint_sync_time_sec; 42.8 42.9 public: 42.10 static void init();
43.1 --- a/src/share/vm/utilities/accessFlags.cpp Mon Nov 17 15:51:46 2014 -0500 43.2 +++ b/src/share/vm/utilities/accessFlags.cpp Wed Nov 19 15:02:01 2014 -0800 43.3 @@ -62,6 +62,21 @@ 43.4 } while(f != old_flags); 43.5 } 43.6 43.7 +// Returns true iff this thread succeeded setting the bit. 43.8 +bool AccessFlags::atomic_set_one_bit(jint bit) { 43.9 + // Atomically update the flags with the bit given 43.10 + jint old_flags, new_flags, f; 43.11 + bool is_setting_bit = false; 43.12 + do { 43.13 + old_flags = _flags; 43.14 + new_flags = old_flags | bit; 43.15 + is_setting_bit = old_flags != new_flags; 43.16 + f = Atomic::cmpxchg(new_flags, &_flags, old_flags); 43.17 + } while(f != old_flags); 43.18 + 43.19 + return is_setting_bit; 43.20 +} 43.21 + 43.22 #if !defined(PRODUCT) || INCLUDE_JVMTI 43.23 43.24 void AccessFlags::print_on(outputStream* st) const {
44.1 --- a/src/share/vm/utilities/accessFlags.hpp Mon Nov 17 15:51:46 2014 -0500 44.2 +++ b/src/share/vm/utilities/accessFlags.hpp Wed Nov 19 15:02:01 2014 -0800 44.3 @@ -170,6 +170,7 @@ 44.4 44.5 // Atomic update of flags 44.6 void atomic_set_bits(jint bits); 44.7 + bool atomic_set_one_bit(jint bit); 44.8 void atomic_clear_bits(jint bits); 44.9 44.10 private: 44.11 @@ -230,12 +231,13 @@ 44.12 atomic_set_bits(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE); 44.13 } 44.14 44.15 - void set_on_stack(const bool value) 44.16 + bool set_on_stack(const bool value) 44.17 { 44.18 if (value) { 44.19 - atomic_set_bits(JVM_ACC_ON_STACK); 44.20 + return atomic_set_one_bit(JVM_ACC_ON_STACK); 44.21 } else { 44.22 atomic_clear_bits(JVM_ACC_ON_STACK); 44.23 + return true; // Ignored 44.24 } 44.25 } 44.26 // Conversion
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/src/share/vm/utilities/chunkedList.cpp Wed Nov 19 15:02:01 2014 -0800 45.3 @@ -0,0 +1,109 @@ 45.4 +/* 45.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 45.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 45.7 + * 45.8 + * This code is free software; you can redistribute it and/or modify it 45.9 + * under the terms of the GNU General Public License version 2 only, as 45.10 + * published by the Free Software Foundation. 45.11 + * 45.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 45.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 45.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 45.15 + * version 2 for more details (a copy is included in the LICENSE file that 45.16 + * accompanied this code). 45.17 + * 45.18 + * You should have received a copy of the GNU General Public License version 45.19 + * 2 along with this work; if not, write to the Free Software Foundation, 45.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 45.21 + * 45.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 45.23 + * or visit www.oracle.com if you need additional information or have any 45.24 + * questions. 45.25 + * 45.26 + */ 45.27 + 45.28 +#include "precompiled.hpp" 45.29 +#include "utilities/chunkedList.hpp" 45.30 +#include "utilities/debug.hpp" 45.31 + 45.32 +/////////////// Unit tests /////////////// 45.33 + 45.34 +#ifndef PRODUCT 45.35 + 45.36 +template <typename T> 45.37 +class TestChunkedList { 45.38 + typedef ChunkedList<T, mtOther> ChunkedListT; 45.39 + 45.40 + public: 45.41 + static void testEmpty() { 45.42 + ChunkedListT buffer; 45.43 + assert(buffer.size() == 0, "assert"); 45.44 + } 45.45 + 45.46 + static void testFull() { 45.47 + ChunkedListT buffer; 45.48 + for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { 45.49 + buffer.push((T)i); 45.50 + } 45.51 + assert(buffer.size() == ChunkedListT::BufferSize, "assert"); 45.52 + assert(buffer.is_full(), "assert"); 45.53 + } 45.54 + 45.55 + static void testSize() { 45.56 + ChunkedListT buffer; 45.57 + for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { 45.58 + assert(buffer.size() == i, "assert"); 45.59 + buffer.push((T)i); 45.60 + assert(buffer.size() == i + 1, "assert"); 45.61 + } 45.62 + } 45.63 + 45.64 + static void testClear() { 45.65 + ChunkedListT buffer; 45.66 + 45.67 + buffer.clear(); 45.68 + assert(buffer.size() == 0, "assert"); 45.69 + 45.70 + for (uintptr_t i = 0; i < ChunkedListT::BufferSize / 2; i++) { 45.71 + buffer.push((T)i); 45.72 + } 45.73 + buffer.clear(); 45.74 + assert(buffer.size() == 0, "assert"); 45.75 + 45.76 + for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { 45.77 + buffer.push((T)i); 45.78 + } 45.79 + buffer.clear(); 45.80 + assert(buffer.size() == 0, "assert"); 45.81 + } 45.82 + 45.83 + static void testAt() { 45.84 + ChunkedListT buffer; 45.85 + 45.86 + for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { 45.87 + buffer.push((T)i); 45.88 + assert(buffer.at(i) == (T)i, "assert"); 45.89 + } 45.90 + 45.91 + for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) { 45.92 + assert(buffer.at(i) == (T)i, "assert"); 45.93 + } 45.94 + } 45.95 + 45.96 + static void test() { 45.97 + testEmpty(); 45.98 + testFull(); 45.99 + testSize(); 45.100 + testClear(); 45.101 + testAt(); 45.102 + } 45.103 +}; 45.104 + 45.105 +class Metadata; 45.106 + 45.107 +void TestChunkedList_test() { 45.108 + TestChunkedList<Metadata*>::test(); 45.109 + TestChunkedList<size_t>::test(); 45.110 +} 45.111 + 45.112 +#endif
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/src/share/vm/utilities/chunkedList.hpp Wed Nov 19 15:02:01 2014 -0800 46.3 @@ -0,0 +1,81 @@ 46.4 +/* 46.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 46.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 46.7 + * 46.8 + * This code is free software; you can redistribute it and/or modify it 46.9 + * under the terms of the GNU General Public License version 2 only, as 46.10 + * published by the Free Software Foundation. 46.11 + * 46.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 46.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 46.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 46.15 + * version 2 for more details (a copy is included in the LICENSE file that 46.16 + * accompanied this code). 46.17 + * 46.18 + * You should have received a copy of the GNU General Public License version 46.19 + * 2 along with this work; if not, write to the Free Software Foundation, 46.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 46.21 + * 46.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 46.23 + * or visit www.oracle.com if you need additional information or have any 46.24 + * questions. 46.25 + * 46.26 + */ 46.27 + 46.28 +#ifndef SHARE_VM_UTILITIES_CHUNKED_LIST_HPP 46.29 +#define SHARE_VM_UTILITIES_CHUNKED_LIST_HPP 46.30 + 46.31 +#include "memory/allocation.hpp" 46.32 +#include "utilities/debug.hpp" 46.33 + 46.34 +template <class T, MEMFLAGS F> class ChunkedList : public CHeapObj<F> { 46.35 + template <class U> friend class TestChunkedList; 46.36 + 46.37 + static const size_t BufferSize = 64; 46.38 + 46.39 + T _values[BufferSize]; 46.40 + T* _top; 46.41 + 46.42 + ChunkedList<T, F>* _next_used; 46.43 + ChunkedList<T, F>* _next_free; 46.44 + 46.45 + T const * end() const { 46.46 + return &_values[BufferSize]; 46.47 + } 46.48 + 46.49 + public: 46.50 + ChunkedList<T, F>() : _top(_values), _next_used(NULL), _next_free(NULL) {} 46.51 + 46.52 + bool is_full() const { 46.53 + return _top == end(); 46.54 + } 46.55 + 46.56 + void clear() { 46.57 + _top = _values; 46.58 + // Don't clear the next pointers since that would interfere 46.59 + // with other threads trying to iterate through the lists. 46.60 + } 46.61 + 46.62 + void push(T m) { 46.63 + assert(!is_full(), "Buffer is full"); 46.64 + *_top = m; 46.65 + _top++; 46.66 + } 46.67 + 46.68 + void set_next_used(ChunkedList<T, F>* buffer) { _next_used = buffer; } 46.69 + void set_next_free(ChunkedList<T, F>* buffer) { _next_free = buffer; } 46.70 + 46.71 + ChunkedList<T, F>* next_used() const { return _next_used; } 46.72 + ChunkedList<T, F>* next_free() const { return _next_free; } 46.73 + 46.74 + size_t size() const { 46.75 + return pointer_delta(_top, _values, sizeof(T)); 46.76 + } 46.77 + 46.78 + T at(size_t i) { 46.79 + assert(i < size(), err_msg("IOOBE i: " SIZE_FORMAT " size(): " SIZE_FORMAT, i, size())); 46.80 + return _values[i]; 46.81 + } 46.82 +}; 46.83 + 46.84 +#endif // SHARE_VM_UTILITIES_CHUNKED_LIST_HPP
47.1 --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java Mon Nov 17 15:51:46 2014 -0500 47.2 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java Wed Nov 19 15:02:01 2014 -0800 47.3 @@ -72,9 +72,9 @@ 47.4 /** Flag for verbose output, true if {@code -Dverbose} specified */ 47.5 protected static final boolean IS_VERBOSE 47.6 = System.getProperty("verbose") != null; 47.7 - /** count of invocation to triger compilation */ 47.8 + /** invocation count to trigger compilation */ 47.9 protected static final int THRESHOLD; 47.10 - /** count of invocation to triger OSR compilation */ 47.11 + /** invocation count to trigger OSR compilation */ 47.12 protected static final long BACKEDGE_THRESHOLD; 47.13 /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ 47.14 protected static final String MODE = System.getProperty("java.vm.info"); 47.15 @@ -206,7 +206,6 @@ 47.16 * is compiled, or if {@linkplain #method} has zero 47.17 * compilation level. 47.18 */ 47.19 - 47.20 protected final void checkNotCompiled(int compLevel) { 47.21 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 47.22 throw new RuntimeException(method + " must not be in queue"); 47.23 @@ -227,20 +226,30 @@ 47.24 * compilation level. 47.25 */ 47.26 protected final void checkNotCompiled() { 47.27 + checkNotCompiled(true); 47.28 + checkNotCompiled(false); 47.29 + } 47.30 + 47.31 + /** 47.32 + * Checks, that {@linkplain #method} is not (OSR-)compiled. 47.33 + * 47.34 + * @param isOsr Check for OSR compilation if true 47.35 + * @throws RuntimeException if {@linkplain #method} is in compiler queue or 47.36 + * is compiled, or if {@linkplain #method} has zero 47.37 + * compilation level. 47.38 + */ 47.39 + protected final void checkNotCompiled(boolean isOsr) { 47.40 + waitBackgroundCompilation(); 47.41 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 47.42 throw new RuntimeException(method + " must not be in queue"); 47.43 } 47.44 - if (WHITE_BOX.isMethodCompiled(method, false)) { 47.45 - throw new RuntimeException(method + " must be not compiled"); 47.46 + if (WHITE_BOX.isMethodCompiled(method, isOsr)) { 47.47 + throw new RuntimeException(method + " must not be " + 47.48 + (isOsr ? "osr_" : "") + "compiled"); 47.49 } 47.50 - if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) { 47.51 - throw new RuntimeException(method + " comp_level must be == 0"); 47.52 - } 47.53 - if (WHITE_BOX.isMethodCompiled(method, true)) { 47.54 - throw new RuntimeException(method + " must be not osr_compiled"); 47.55 - } 47.56 - if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { 47.57 - throw new RuntimeException(method + " osr_comp_level must be == 0"); 47.58 + if (WHITE_BOX.getMethodCompilationLevel(method, isOsr) != 0) { 47.59 + throw new RuntimeException(method + (isOsr ? " osr_" : " ") + 47.60 + "comp_level must be == 0"); 47.61 } 47.62 } 47.63 47.64 @@ -306,12 +315,21 @@ 47.65 * Waits for completion of background compilation of {@linkplain #method}. 47.66 */ 47.67 protected final void waitBackgroundCompilation() { 47.68 + waitBackgroundCompilation(method); 47.69 + } 47.70 + 47.71 + /** 47.72 + * Waits for completion of background compilation of the given executable. 47.73 + * 47.74 + * @param executable Executable 47.75 + */ 47.76 + protected static final void waitBackgroundCompilation(Executable executable) { 47.77 if (!BACKGROUND_COMPILATION) { 47.78 return; 47.79 } 47.80 final Object obj = new Object(); 47.81 for (int i = 0; i < 10 47.82 - && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) { 47.83 + && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) { 47.84 synchronized (obj) { 47.85 try { 47.86 obj.wait(1000); 47.87 @@ -425,14 +443,14 @@ 47.88 /** constructor test case */ 47.89 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), 47.90 /** method test case */ 47.91 - METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), 47.92 + METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), 47.93 /** static method test case */ 47.94 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), 47.95 /** OSR constructor test case */ 47.96 OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, 47.97 Helper.OSR_CONSTRUCTOR_CALLABLE, true), 47.98 /** OSR method test case */ 47.99 - OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), 47.100 + OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), 47.101 /** OSR static method test case */ 47.102 OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); 47.103 47.104 @@ -494,7 +512,7 @@ 47.105 = new Callable<Integer>() { 47.106 @Override 47.107 public Integer call() throws Exception { 47.108 - return new Helper(null).hashCode(); 47.109 + return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode(); 47.110 } 47.111 }; 47.112 47.113 @@ -504,7 +522,7 @@ 47.114 47.115 @Override 47.116 public Integer call() throws Exception { 47.117 - return helper.osrMethod(); 47.118 + return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); 47.119 } 47.120 }; 47.121 47.122 @@ -512,7 +530,7 @@ 47.123 = new Callable<Integer>() { 47.124 @Override 47.125 public Integer call() throws Exception { 47.126 - return osrStaticMethod(); 47.127 + return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); 47.128 } 47.129 }; 47.130 47.131 @@ -532,25 +550,24 @@ 47.132 } 47.133 try { 47.134 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( 47.135 - Object.class); 47.136 + Object.class, long.class); 47.137 } catch (NoSuchMethodException | SecurityException e) { 47.138 throw new RuntimeException( 47.139 - "exception on getting method Helper.<init>(Object)", e); 47.140 + "exception on getting method Helper.<init>(Object, long)", e); 47.141 } 47.142 METHOD = getMethod("method"); 47.143 STATIC = getMethod("staticMethod"); 47.144 - OSR_METHOD = getMethod("osrMethod"); 47.145 - OSR_STATIC = getMethod("osrStaticMethod"); 47.146 + OSR_METHOD = getMethod("osrMethod", long.class); 47.147 + OSR_STATIC = getMethod("osrStaticMethod", long.class); 47.148 } 47.149 47.150 - private static Method getMethod(String name) { 47.151 + private static Method getMethod(String name, Class<?>... parameterTypes) { 47.152 try { 47.153 - return Helper.class.getDeclaredMethod(name); 47.154 + return Helper.class.getDeclaredMethod(name, parameterTypes); 47.155 } catch (NoSuchMethodException | SecurityException e) { 47.156 throw new RuntimeException( 47.157 "exception on getting method Helper." + name, e); 47.158 } 47.159 - 47.160 } 47.161 47.162 private static int staticMethod() { 47.163 @@ -561,17 +578,84 @@ 47.164 return 42; 47.165 } 47.166 47.167 - private static int osrStaticMethod() { 47.168 + /** 47.169 + * Deoptimizes all non-osr versions of the given executable after 47.170 + * compilation finished. 47.171 + * 47.172 + * @param e Executable 47.173 + * @throws Exception 47.174 + */ 47.175 + private static void waitAndDeoptimize(Executable e) { 47.176 + CompilerWhiteBoxTest.waitBackgroundCompilation(e); 47.177 + if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) { 47.178 + throw new RuntimeException(e + " must not be in queue"); 47.179 + } 47.180 + // Deoptimize non-osr versions of executable 47.181 + WhiteBox.getWhiteBox().deoptimizeMethod(e, false); 47.182 + } 47.183 + 47.184 + /** 47.185 + * Executes the method multiple times to make sure we have 47.186 + * enough profiling information before triggering an OSR 47.187 + * compilation. Otherwise the C2 compiler may add uncommon traps. 47.188 + * 47.189 + * @param m Method to be executed 47.190 + * @return Number of times the method was executed 47.191 + * @throws Exception 47.192 + */ 47.193 + private static int warmup(Method m) throws Exception { 47.194 + waitAndDeoptimize(m); 47.195 + Helper helper = new Helper(); 47.196 int result = 0; 47.197 - for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { 47.198 + for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) { 47.199 + result += (int)m.invoke(helper, 1); 47.200 + } 47.201 + // Wait to make sure OSR compilation is not blocked by 47.202 + // non-OSR compilation in the compile queue 47.203 + CompilerWhiteBoxTest.waitBackgroundCompilation(m); 47.204 + return result; 47.205 + } 47.206 + 47.207 + /** 47.208 + * Executes the constructor multiple times to make sure we 47.209 + * have enough profiling information before triggering an OSR 47.210 + * compilation. Otherwise the C2 compiler may add uncommon traps. 47.211 + * 47.212 + * @param c Constructor to be executed 47.213 + * @return Number of times the constructor was executed 47.214 + * @throws Exception 47.215 + */ 47.216 + private static int warmup(Constructor c) throws Exception { 47.217 + waitAndDeoptimize(c); 47.218 + int result = 0; 47.219 + for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) { 47.220 + result += c.newInstance(null, 1).hashCode(); 47.221 + } 47.222 + // Wait to make sure OSR compilation is not blocked by 47.223 + // non-OSR compilation in the compile queue 47.224 + CompilerWhiteBoxTest.waitBackgroundCompilation(c); 47.225 + return result; 47.226 + } 47.227 + 47.228 + private static int osrStaticMethod(long limit) throws Exception { 47.229 + int result = 0; 47.230 + if (limit != 1) { 47.231 + result = warmup(OSR_STATIC); 47.232 + } 47.233 + // Trigger osr compilation 47.234 + for (long i = 0; i < limit; ++i) { 47.235 result += staticMethod(); 47.236 } 47.237 return result; 47.238 } 47.239 47.240 - private int osrMethod() { 47.241 + private int osrMethod(long limit) throws Exception { 47.242 int result = 0; 47.243 - for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { 47.244 + if (limit != 1) { 47.245 + result = warmup(OSR_METHOD); 47.246 + } 47.247 + // Trigger osr compilation 47.248 + for (long i = 0; i < limit; ++i) { 47.249 result += method(); 47.250 } 47.251 return result; 47.252 @@ -585,9 +669,13 @@ 47.253 } 47.254 47.255 // for OSR constructor test case 47.256 - private Helper(Object o) { 47.257 + private Helper(Object o, long limit) throws Exception { 47.258 int result = 0; 47.259 - for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { 47.260 + if (limit != 1) { 47.261 + result = warmup(OSR_CONSTRUCTOR); 47.262 + } 47.263 + // Trigger osr compilation 47.264 + for (long i = 0; i < limit; ++i) { 47.265 result += method(); 47.266 } 47.267 x = result;
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java Wed Nov 19 15:02:01 2014 -0800 48.3 @@ -0,0 +1,95 @@ 48.4 +/* 48.5 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 48.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 48.7 + * 48.8 + * This code is free software; you can redistribute it and/or modify it 48.9 + * under the terms of the GNU General Public License version 2 only, as 48.10 + * published by the Free Software Foundation. 48.11 + * 48.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 48.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 48.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 48.15 + * version 2 for more details (a copy is included in the LICENSE file that 48.16 + * accompanied this code). 48.17 + * 48.18 + * You should have received a copy of the GNU General Public License version 48.19 + * 2 along with this work; if not, write to the Free Software Foundation, 48.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 48.21 + * 48.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 48.23 + * or visit www.oracle.com if you need additional information or have any 48.24 + * questions. 48.25 + */ 48.26 + 48.27 +import sun.hotspot.WhiteBox; 48.28 +import java.lang.reflect.Executable; 48.29 +import java.lang.reflect.Method; 48.30 + 48.31 +/* 48.32 + * @test DeoptimizeMultipleOSRTest 48.33 + * @bug 8061817 48.34 + * @library /testlibrary /testlibrary/whitebox 48.35 + * @build DeoptimizeMultipleOSRTest 48.36 + * @run main ClassFileInstaller sun.hotspot.WhiteBox 48.37 + * sun.hotspot.WhiteBox$WhiteBoxPermission 48.38 + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,DeoptimizeMultipleOSRTest::triggerOSR DeoptimizeMultipleOSRTest 48.39 + * @summary testing of WB::deoptimizeMethod() 48.40 + */ 48.41 +public class DeoptimizeMultipleOSRTest { 48.42 + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 48.43 + private static final long BACKEDGE_THRESHOLD = 150000; 48.44 + private Method method; 48.45 + private int counter = 0; 48.46 + 48.47 + public static void main(String[] args) throws Exception { 48.48 + DeoptimizeMultipleOSRTest test = new DeoptimizeMultipleOSRTest(); 48.49 + test.test(); 48.50 + } 48.51 + 48.52 + /** 48.53 + * Triggers two different OSR compilations for the same method and 48.54 + * checks if WhiteBox.deoptimizeMethod() deoptimizes both. 48.55 + * 48.56 + * @throws Exception 48.57 + */ 48.58 + public void test() throws Exception { 48.59 + method = DeoptimizeMultipleOSRTest.class.getDeclaredMethod("triggerOSR", boolean.class, long.class); 48.60 + // Trigger two OSR compiled versions 48.61 + triggerOSR(true, BACKEDGE_THRESHOLD); 48.62 + triggerOSR(false, BACKEDGE_THRESHOLD); 48.63 + // Wait for compilation 48.64 + CompilerWhiteBoxTest.waitBackgroundCompilation(method); 48.65 + // Deoptimize 48.66 + WHITE_BOX.deoptimizeMethod(method, true); 48.67 + if (WHITE_BOX.isMethodCompiled(method, true)) { 48.68 + throw new AssertionError("Not all OSR compiled versions were deoptimized"); 48.69 + } 48.70 + } 48.71 + 48.72 + /** 48.73 + * Triggers OSR compilations by executing loops. 48.74 + * 48.75 + * @param first Determines which loop to execute 48.76 + * @param limit The number of loop iterations 48.77 + */ 48.78 + public void triggerOSR(boolean first, long limit) { 48.79 + if (limit != 1) { 48.80 + // Warmup method to avoid uncommon traps 48.81 + for (int i = 0; i < limit; ++i) { 48.82 + triggerOSR(first, 1); 48.83 + } 48.84 + CompilerWhiteBoxTest.waitBackgroundCompilation(method); 48.85 + } 48.86 + if (first) { 48.87 + // Trigger OSR compilation 1 48.88 + for (int i = 0; i < limit; ++i) { 48.89 + counter++; 48.90 + } 48.91 + } else { 48.92 + // Trigger OSR compilation 2 48.93 + for (int i = 0; i < limit; ++i) { 48.94 + counter++; 48.95 + } 48.96 + } 48.97 + } 48.98 +}
49.1 --- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java Mon Nov 17 15:51:46 2014 -0500 49.2 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java Wed Nov 19 15:02:01 2014 -0800 49.3 @@ -131,14 +131,15 @@ 49.4 throw new RuntimeException(method 49.5 + " is not compilable after clearMethodState()"); 49.6 } 49.7 - 49.8 + // Make method not (OSR-)compilable (depending on testCase.isOsr()) 49.9 makeNotCompilable(); 49.10 if (isCompilable()) { 49.11 throw new RuntimeException(method + " must be not compilable"); 49.12 } 49.13 - 49.14 + // Try to (OSR-)compile method 49.15 compile(); 49.16 - checkNotCompiled(); 49.17 + // Method should not be (OSR-)compiled 49.18 + checkNotCompiled(testCase.isOsr()); 49.19 if (isCompilable()) { 49.20 throw new RuntimeException(method + " must be not compilable"); 49.21 }
50.1 --- a/test/gc/g1/TestHumongousShrinkHeap.java Mon Nov 17 15:51:46 2014 -0500 50.2 +++ b/test/gc/g1/TestHumongousShrinkHeap.java Wed Nov 19 15:02:01 2014 -0800 50.3 @@ -24,9 +24,12 @@ 50.4 /** 50.5 * @test TestHumongousShrinkHeap 50.6 * @bug 8036025 8056043 50.7 - * @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects 50.8 + * @summary Verify that heap shrinks after GC in the presence of fragmentation 50.9 + * due to humongous objects 50.10 * @library /testlibrary 50.11 - * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=12 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc TestHumongousShrinkHeap 50.12 + * @run main/othervm -XX:-ExplicitGCInvokesConcurrent -XX:MinHeapFreeRatio=10 50.13 + * -XX:MaxHeapFreeRatio=12 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc 50.14 + * TestHumongousShrinkHeap 50.15 */ 50.16 50.17 import java.lang.management.ManagementFactory;
51.1 --- a/test/gc/g1/TestShrinkAuxiliaryData.java Mon Nov 17 15:51:46 2014 -0500 51.2 +++ b/test/gc/g1/TestShrinkAuxiliaryData.java Wed Nov 19 15:02:01 2014 -0800 51.3 @@ -45,6 +45,7 @@ 51.4 "-XX:MaxHeapFreeRatio=11", 51.5 "-XX:+UseG1GC", 51.6 "-XX:G1HeapRegionSize=1m", 51.7 + "-XX:-ExplicitGCInvokesConcurrent", 51.8 "-XX:+PrintGCDetails" 51.9 }; 51.10
52.1 --- a/test/gc/g1/TestShrinkDefragmentedHeap.java Mon Nov 17 15:51:46 2014 -0500 52.2 +++ b/test/gc/g1/TestShrinkDefragmentedHeap.java Wed Nov 19 15:02:01 2014 -0800 52.3 @@ -59,6 +59,7 @@ 52.4 "-XX:MaxHeapFreeRatio=11", 52.5 "-XX:+UseG1GC", 52.6 "-XX:G1HeapRegionSize=" + REGION_SIZE, 52.7 + "-XX:-ExplicitGCInvokesConcurrent", 52.8 "-verbose:gc", 52.9 GCTest.class.getName() 52.10 );
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/test/runtime/RedefineTests/RedefineAnnotations.java Wed Nov 19 15:02:01 2014 -0800 53.3 @@ -0,0 +1,410 @@ 53.4 +/* 53.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 53.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 53.7 + * 53.8 + * This code is free software; you can redistribute it and/or modify it 53.9 + * under the terms of the GNU General Public License version 2 only, as 53.10 + * published by the Free Software Foundation. 53.11 + * 53.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 53.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 53.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 53.15 + * version 2 for more details (a copy is included in the LICENSE file that 53.16 + * accompanied this code). 53.17 + * 53.18 + * You should have received a copy of the GNU General Public License version 53.19 + * 2 along with this work; if not, write to the Free Software Foundation, 53.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 53.21 + * 53.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 53.23 + * or visit www.oracle.com if you need additional information or have any 53.24 + * questions. 53.25 + */ 53.26 + 53.27 +/* 53.28 + * @test 53.29 + * @library /testlibrary 53.30 + * @summary Test that type annotations are retained after a retransform 53.31 + * @run main RedefineAnnotations buildagent 53.32 + * @run main/othervm -javaagent:redefineagent.jar RedefineAnnotations 53.33 + */ 53.34 + 53.35 +import static com.oracle.java.testlibrary.Asserts.assertTrue; 53.36 +import java.io.FileNotFoundException; 53.37 +import java.io.PrintWriter; 53.38 +import java.lang.NoSuchFieldException; 53.39 +import java.lang.NoSuchMethodException; 53.40 +import java.lang.RuntimeException; 53.41 +import java.lang.annotation.Annotation; 53.42 +import java.lang.annotation.ElementType; 53.43 +import java.lang.annotation.Retention; 53.44 +import java.lang.annotation.RetentionPolicy; 53.45 +import java.lang.annotation.Target; 53.46 +import java.lang.instrument.ClassFileTransformer; 53.47 +import java.lang.instrument.IllegalClassFormatException; 53.48 +import java.lang.instrument.Instrumentation; 53.49 +import java.lang.instrument.UnmodifiableClassException; 53.50 +import java.lang.reflect.AnnotatedArrayType; 53.51 +import java.lang.reflect.AnnotatedParameterizedType; 53.52 +import java.lang.reflect.AnnotatedType; 53.53 +import java.lang.reflect.AnnotatedWildcardType; 53.54 +import java.lang.reflect.Executable; 53.55 +import java.lang.reflect.TypeVariable; 53.56 +import java.security.ProtectionDomain; 53.57 +import java.util.Arrays; 53.58 +import java.util.LinkedList; 53.59 +import java.util.List; 53.60 +import java.util.Map; 53.61 +import jdk.internal.org.objectweb.asm.ClassReader; 53.62 +import jdk.internal.org.objectweb.asm.ClassVisitor; 53.63 +import jdk.internal.org.objectweb.asm.ClassWriter; 53.64 +import jdk.internal.org.objectweb.asm.FieldVisitor; 53.65 +import static jdk.internal.org.objectweb.asm.Opcodes.ASM5; 53.66 + 53.67 +@Retention(RetentionPolicy.RUNTIME) 53.68 +@Target(ElementType.TYPE_USE) 53.69 +@interface TestAnn { 53.70 + String site(); 53.71 +} 53.72 + 53.73 +public class RedefineAnnotations { 53.74 + static Instrumentation inst; 53.75 + public static void premain(String agentArgs, Instrumentation inst) { 53.76 + RedefineAnnotations.inst = inst; 53.77 + } 53.78 + 53.79 + static class Transformer implements ClassFileTransformer { 53.80 + 53.81 + public byte[] asm(ClassLoader loader, String className, 53.82 + Class<?> classBeingRedefined, 53.83 + ProtectionDomain protectionDomain, byte[] classfileBuffer) 53.84 + throws IllegalClassFormatException { 53.85 + 53.86 + ClassWriter cw = new ClassWriter(0); 53.87 + ClassVisitor cv = new ReAddDummyFieldsClassVisitor(ASM5, cw) { }; 53.88 + ClassReader cr = new ClassReader(classfileBuffer); 53.89 + cr.accept(cv, 0); 53.90 + return cw.toByteArray(); 53.91 + } 53.92 + 53.93 + public class ReAddDummyFieldsClassVisitor extends ClassVisitor { 53.94 + 53.95 + LinkedList<F> fields = new LinkedList<>(); 53.96 + 53.97 + public ReAddDummyFieldsClassVisitor(int api, ClassVisitor cv) { 53.98 + super(api, cv); 53.99 + } 53.100 + 53.101 + @Override public FieldVisitor visitField(int access, String name, 53.102 + String desc, String signature, Object value) { 53.103 + if (name.startsWith("dummy")) { 53.104 + // Remove dummy field 53.105 + fields.addLast(new F(access, name, desc, signature, value)); 53.106 + return null; 53.107 + } 53.108 + return cv.visitField(access, name, desc, signature, value); 53.109 + } 53.110 + 53.111 + @Override public void visitEnd() { 53.112 + F f; 53.113 + while ((f = fields.pollFirst()) != null) { 53.114 + // Re-add dummy fields 53.115 + cv.visitField(f.access, f.name, f.desc, f.signature, f.value); 53.116 + } 53.117 + } 53.118 + 53.119 + private class F { 53.120 + private int access; 53.121 + private String name; 53.122 + private String desc; 53.123 + private String signature; 53.124 + private Object value; 53.125 + F(int access, String name, String desc, String signature, Object value) { 53.126 + this.access = access; 53.127 + this.name = name; 53.128 + this.desc = desc; 53.129 + this.signature = signature; 53.130 + this.value = value; 53.131 + } 53.132 + } 53.133 + } 53.134 + 53.135 + @Override public byte[] transform(ClassLoader loader, String className, 53.136 + Class<?> classBeingRedefined, 53.137 + ProtectionDomain protectionDomain, byte[] classfileBuffer) 53.138 + throws IllegalClassFormatException { 53.139 + 53.140 + if (className.contains("TypeAnnotatedTestClass")) { 53.141 + try { 53.142 + // Here we remove and re-add the dummy fields. This shuffles the constant pool 53.143 + return asm(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); 53.144 + } catch (Throwable e) { 53.145 + // The retransform native code that called this method does not propagate 53.146 + // exceptions. Instead of getting an uninformative generic error, catch 53.147 + // problems here and print it, then exit. 53.148 + e.printStackTrace(); 53.149 + System.exit(1); 53.150 + } 53.151 + } 53.152 + return null; 53.153 + } 53.154 + } 53.155 + 53.156 + private static void buildAgent() { 53.157 + try { 53.158 + ClassFileInstaller.main("RedefineAnnotations"); 53.159 + } catch (Exception e) { 53.160 + throw new RuntimeException("Could not write agent classfile", e); 53.161 + } 53.162 + 53.163 + try { 53.164 + PrintWriter pw = new PrintWriter("MANIFEST.MF"); 53.165 + pw.println("Premain-Class: RedefineAnnotations"); 53.166 + pw.println("Agent-Class: RedefineAnnotations"); 53.167 + pw.println("Can-Retransform-Classes: true"); 53.168 + pw.close(); 53.169 + } catch (FileNotFoundException e) { 53.170 + throw new RuntimeException("Could not write manifest file for the agent", e); 53.171 + } 53.172 + 53.173 + sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar"); 53.174 + if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "RedefineAnnotations.class" })) { 53.175 + throw new RuntimeException("Could not write the agent jar file"); 53.176 + } 53.177 + } 53.178 + 53.179 + public static void main(String argv[]) throws NoSuchFieldException, NoSuchMethodException { 53.180 + if (argv.length == 1 && argv[0].equals("buildagent")) { 53.181 + buildAgent(); 53.182 + return; 53.183 + } 53.184 + 53.185 + if (inst == null) { 53.186 + throw new RuntimeException("Instrumentation object was null"); 53.187 + } 53.188 + 53.189 + RedefineAnnotations test = new RedefineAnnotations(); 53.190 + test.testTransformAndVerify(); 53.191 + } 53.192 + 53.193 + // Class type annotations 53.194 + private Annotation classTypeParameterTA; 53.195 + private Annotation extendsTA; 53.196 + private Annotation implementsTA; 53.197 + 53.198 + // Field type annotations 53.199 + private Annotation fieldTA; 53.200 + private Annotation innerTA; 53.201 + private Annotation[] arrayTA = new Annotation[4]; 53.202 + private Annotation[] mapTA = new Annotation[5]; 53.203 + 53.204 + // Method type annotations 53.205 + private Annotation returnTA, methodTypeParameterTA, formalParameterTA, throwsTA; 53.206 + 53.207 + private void testTransformAndVerify() 53.208 + throws NoSuchFieldException, NoSuchMethodException { 53.209 + 53.210 + Class<TypeAnnotatedTestClass> c = TypeAnnotatedTestClass.class; 53.211 + Class<?> myClass = c; 53.212 + 53.213 + /* 53.214 + * Verify that the expected annotations are where they should be before transform. 53.215 + */ 53.216 + verifyClassTypeAnnotations(c); 53.217 + verifyFieldTypeAnnotations(c); 53.218 + verifyMethodTypeAnnotations(c); 53.219 + 53.220 + try { 53.221 + inst.addTransformer(new Transformer(), true); 53.222 + inst.retransformClasses(myClass); 53.223 + } catch (UnmodifiableClassException e) { 53.224 + throw new RuntimeException(e); 53.225 + } 53.226 + 53.227 + /* 53.228 + * Verify that the expected annotations are where they should be after transform. 53.229 + * Also verify that before and after are equal. 53.230 + */ 53.231 + verifyClassTypeAnnotations(c); 53.232 + verifyFieldTypeAnnotations(c); 53.233 + verifyMethodTypeAnnotations(c); 53.234 + } 53.235 + 53.236 + private void verifyClassTypeAnnotations(Class c) { 53.237 + Annotation anno; 53.238 + 53.239 + anno = c.getTypeParameters()[0].getAnnotations()[0]; 53.240 + verifyTestAnn(classTypeParameterTA, anno, "classTypeParameter"); 53.241 + classTypeParameterTA = anno; 53.242 + 53.243 + anno = c.getAnnotatedSuperclass().getAnnotations()[0]; 53.244 + verifyTestAnn(extendsTA, anno, "extends"); 53.245 + extendsTA = anno; 53.246 + 53.247 + anno = c.getAnnotatedInterfaces()[0].getAnnotations()[0]; 53.248 + verifyTestAnn(implementsTA, anno, "implements"); 53.249 + implementsTA = anno; 53.250 + } 53.251 + 53.252 + private void verifyFieldTypeAnnotations(Class c) 53.253 + throws NoSuchFieldException, NoSuchMethodException { 53.254 + 53.255 + verifyBasicFieldTypeAnnotations(c); 53.256 + verifyInnerFieldTypeAnnotations(c); 53.257 + verifyArrayFieldTypeAnnotations(c); 53.258 + verifyMapFieldTypeAnnotations(c); 53.259 + } 53.260 + 53.261 + private void verifyBasicFieldTypeAnnotations(Class c) 53.262 + throws NoSuchFieldException, NoSuchMethodException { 53.263 + 53.264 + Annotation anno = c.getDeclaredField("typeAnnotatedBoolean").getAnnotatedType().getAnnotations()[0]; 53.265 + verifyTestAnn(fieldTA, anno, "field"); 53.266 + fieldTA = anno; 53.267 + } 53.268 + 53.269 + private void verifyInnerFieldTypeAnnotations(Class c) 53.270 + throws NoSuchFieldException, NoSuchMethodException { 53.271 + 53.272 + AnnotatedType at = c.getDeclaredField("typeAnnotatedInner").getAnnotatedType(); 53.273 + Annotation anno = at.getAnnotations()[0]; 53.274 + verifyTestAnn(innerTA, anno, "inner"); 53.275 + innerTA = anno; 53.276 + } 53.277 + 53.278 + private void verifyArrayFieldTypeAnnotations(Class c) 53.279 + throws NoSuchFieldException, NoSuchMethodException { 53.280 + 53.281 + Annotation anno; 53.282 + AnnotatedType at; 53.283 + 53.284 + at = c.getDeclaredField("typeAnnotatedArray").getAnnotatedType(); 53.285 + anno = at.getAnnotations()[0]; 53.286 + verifyTestAnn(arrayTA[0], anno, "array1"); 53.287 + arrayTA[0] = anno; 53.288 + 53.289 + for (int i = 1; i <= 3; i++) { 53.290 + at = ((AnnotatedArrayType) at).getAnnotatedGenericComponentType(); 53.291 + anno = at.getAnnotations()[0]; 53.292 + verifyTestAnn(arrayTA[i], anno, "array" + (i + 1)); 53.293 + arrayTA[i] = anno; 53.294 + } 53.295 + } 53.296 + 53.297 + private void verifyMapFieldTypeAnnotations(Class c) 53.298 + throws NoSuchFieldException, NoSuchMethodException { 53.299 + 53.300 + Annotation anno; 53.301 + AnnotatedType atBase; 53.302 + AnnotatedType atParameter; 53.303 + atBase = c.getDeclaredField("typeAnnotatedMap").getAnnotatedType(); 53.304 + 53.305 + anno = atBase.getAnnotations()[0]; 53.306 + verifyTestAnn(mapTA[0], anno, "map1"); 53.307 + mapTA[0] = anno; 53.308 + 53.309 + atParameter = 53.310 + ((AnnotatedParameterizedType) atBase). 53.311 + getAnnotatedActualTypeArguments()[0]; 53.312 + anno = ((AnnotatedWildcardType) atParameter).getAnnotations()[0]; 53.313 + verifyTestAnn(mapTA[1], anno, "map2"); 53.314 + mapTA[1] = anno; 53.315 + 53.316 + anno = 53.317 + ((AnnotatedWildcardType) atParameter). 53.318 + getAnnotatedUpperBounds()[0].getAnnotations()[0]; 53.319 + verifyTestAnn(mapTA[2], anno, "map3"); 53.320 + mapTA[2] = anno; 53.321 + 53.322 + atParameter = 53.323 + ((AnnotatedParameterizedType) atBase). 53.324 + getAnnotatedActualTypeArguments()[1]; 53.325 + anno = ((AnnotatedParameterizedType) atParameter).getAnnotations()[0]; 53.326 + verifyTestAnn(mapTA[3], anno, "map4"); 53.327 + mapTA[3] = anno; 53.328 + 53.329 + anno = 53.330 + ((AnnotatedParameterizedType) atParameter). 53.331 + getAnnotatedActualTypeArguments()[0].getAnnotations()[0]; 53.332 + verifyTestAnn(mapTA[4], anno, "map5"); 53.333 + mapTA[4] = anno; 53.334 + } 53.335 + 53.336 + private void verifyMethodTypeAnnotations(Class c) 53.337 + throws NoSuchFieldException, NoSuchMethodException { 53.338 + Annotation anno; 53.339 + Executable typeAnnotatedMethod = 53.340 + c.getDeclaredMethod("typeAnnotatedMethod", TypeAnnotatedTestClass.class); 53.341 + 53.342 + anno = typeAnnotatedMethod.getAnnotatedReturnType().getAnnotations()[0]; 53.343 + verifyTestAnn(returnTA, anno, "return"); 53.344 + returnTA = anno; 53.345 + 53.346 + anno = typeAnnotatedMethod.getTypeParameters()[0].getAnnotations()[0]; 53.347 + verifyTestAnn(methodTypeParameterTA, anno, "methodTypeParameter"); 53.348 + methodTypeParameterTA = anno; 53.349 + 53.350 + anno = typeAnnotatedMethod.getAnnotatedParameterTypes()[0].getAnnotations()[0]; 53.351 + verifyTestAnn(formalParameterTA, anno, "formalParameter"); 53.352 + formalParameterTA = anno; 53.353 + 53.354 + anno = typeAnnotatedMethod.getAnnotatedExceptionTypes()[0].getAnnotations()[0]; 53.355 + verifyTestAnn(throwsTA, anno, "throws"); 53.356 + throwsTA = anno; 53.357 + } 53.358 + 53.359 + private static void verifyTestAnn(Annotation verifyAgainst, Annotation anno, String expectedSite) { 53.360 + verifyTestAnnSite(anno, expectedSite); 53.361 + 53.362 + // When called before transform verifyAgainst will be null, when called 53.363 + // after transform it will be the annotation from before the transform 53.364 + if (verifyAgainst != null) { 53.365 + assertTrue(anno.equals(verifyAgainst), 53.366 + "Annotations do not match before and after." + 53.367 + " Before: \"" + verifyAgainst + "\", After: \"" + anno + "\""); 53.368 + } 53.369 + } 53.370 + 53.371 + private static void verifyTestAnnSite(Annotation testAnn, String expectedSite) { 53.372 + String expectedAnn = "@TestAnn(site=" + expectedSite + ")"; 53.373 + assertTrue(testAnn.toString().equals(expectedAnn), 53.374 + "Expected \"" + expectedAnn + "\", got \"" + testAnn + "\""); 53.375 + } 53.376 + 53.377 + public static class TypeAnnotatedTestClass <@TestAnn(site="classTypeParameter") S,T> 53.378 + extends @TestAnn(site="extends") Thread 53.379 + implements @TestAnn(site="implements") Runnable { 53.380 + 53.381 + public @TestAnn(site="field") boolean typeAnnotatedBoolean; 53.382 + 53.383 + public 53.384 + RedefineAnnotations. 53.385 + @TestAnn(site="inner") TypeAnnotatedTestClass 53.386 + typeAnnotatedInner; 53.387 + 53.388 + public 53.389 + @TestAnn(site="array4") boolean 53.390 + @TestAnn(site="array1") [] 53.391 + @TestAnn(site="array2") [] 53.392 + @TestAnn(site="array3") [] 53.393 + typeAnnotatedArray; 53.394 + 53.395 + public @TestAnn(site="map1") Map 53.396 + <@TestAnn(site="map2") ? extends @TestAnn(site="map3") String, 53.397 + @TestAnn(site="map4") List<@TestAnn(site="map5") Object>> typeAnnotatedMap; 53.398 + 53.399 + public int dummy1; 53.400 + public int dummy2; 53.401 + public int dummy3; 53.402 + 53.403 + @TestAnn(site="return") <@TestAnn(site="methodTypeParameter") U,V> Class 53.404 + typeAnnotatedMethod(@TestAnn(site="formalParameter") TypeAnnotatedTestClass arg) 53.405 + throws @TestAnn(site="throws") ClassNotFoundException { 53.406 + 53.407 + @TestAnn(site="local_variable_type") int foo = 0; 53.408 + throw new ClassNotFoundException(); 53.409 + } 53.410 + 53.411 + public void run() {} 53.412 + } 53.413 +}
54.1 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Mon Nov 17 15:51:46 2014 -0500 54.2 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Nov 19 15:02:01 2014 -0800 54.3 @@ -30,6 +30,7 @@ 54.4 import java.util.function.Function; 54.5 import java.util.stream.Stream; 54.6 import java.security.BasicPermission; 54.7 +import java.net.URL; 54.8 54.9 import sun.hotspot.parser.DiagnosticCommand; 54.10 54.11 @@ -84,6 +85,11 @@ 54.12 } 54.13 private native boolean isClassAlive0(String name); 54.14 54.15 + // Resource/Class Lookup Cache 54.16 + public native boolean classKnownToNotExist(ClassLoader loader, String name); 54.17 + public native URL[] getLookupCacheURLs(ClassLoader loader); 54.18 + public native int[] getLookupCacheMatches(ClassLoader loader, String name); 54.19 + 54.20 // G1 54.21 public native boolean g1InConcurrentMark(); 54.22 public native boolean g1IsHumongous(Object o);