Wed, 25 Sep 2013 13:03:21 -0400
Merge
1.1 --- a/agent/src/os/linux/ps_core.c Fri Sep 20 11:17:04 2013 -0700 1.2 +++ b/agent/src/os/linux/ps_core.c Wed Sep 25 13:03:21 2013 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -698,29 +698,58 @@ 1.11 1.12 // read segments of a shared object 1.13 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) { 1.14 - int i = 0; 1.15 - ELF_PHDR* phbuf; 1.16 - ELF_PHDR* lib_php = NULL; 1.17 + int i = 0; 1.18 + ELF_PHDR* phbuf; 1.19 + ELF_PHDR* lib_php = NULL; 1.20 1.21 - if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) 1.22 - return false; 1.23 + int page_size=sysconf(_SC_PAGE_SIZE); 1.24 1.25 - // we want to process only PT_LOAD segments that are not writable. 1.26 - // i.e., text segments. The read/write/exec (data) segments would 1.27 - // have been already added from core file segments. 1.28 - for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) { 1.29 - if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { 1.30 - if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL) 1.31 - goto err; 1.32 + if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) { 1.33 + return false; 1.34 + } 1.35 + 1.36 + // we want to process only PT_LOAD segments that are not writable. 1.37 + // i.e., text segments. The read/write/exec (data) segments would 1.38 + // have been already added from core file segments. 1.39 + for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) { 1.40 + if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { 1.41 + 1.42 + uintptr_t target_vaddr = lib_php->p_vaddr + lib_base; 1.43 + map_info *existing_map = core_lookup(ph, target_vaddr); 1.44 + 1.45 + if (existing_map == NULL){ 1.46 + if (add_map_info(ph, lib_fd, lib_php->p_offset, 1.47 + target_vaddr, lib_php->p_filesz) == NULL) { 1.48 + goto err; 1.49 + } 1.50 + } else { 1.51 + if ((existing_map->memsz != page_size) && 1.52 + (existing_map->fd != lib_fd) && 1.53 + (existing_map->memsz != lib_php->p_filesz)){ 1.54 + 1.55 + print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)", 1.56 + target_vaddr, lib_php->p_filesz, lib_php->p_flags); 1.57 + goto err; 1.58 + } 1.59 + 1.60 + /* replace PT_LOAD segment with library segment */ 1.61 + print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n", 1.62 + existing_map->memsz, lib_php->p_filesz); 1.63 + 1.64 + existing_map->fd = lib_fd; 1.65 + existing_map->offset = lib_php->p_offset; 1.66 + existing_map->memsz = lib_php->p_filesz; 1.67 } 1.68 - lib_php++; 1.69 - } 1.70 + } 1.71 1.72 - free(phbuf); 1.73 - return true; 1.74 + lib_php++; 1.75 + } 1.76 + 1.77 + free(phbuf); 1.78 + return true; 1.79 err: 1.80 - free(phbuf); 1.81 - return false; 1.82 + free(phbuf); 1.83 + return false; 1.84 } 1.85 1.86 // process segments from interpreter (ld.so or ld-linux.so)
2.1 --- a/src/share/vm/classfile/javaClasses.cpp Fri Sep 20 11:17:04 2013 -0700 2.2 +++ b/src/share/vm/classfile/javaClasses.cpp Wed Sep 25 13:03:21 2013 -0400 2.3 @@ -438,6 +438,29 @@ 2.4 return true; 2.5 } 2.6 2.7 +bool java_lang_String::equals(oop str1, oop str2) { 2.8 + assert(str1->klass() == SystemDictionary::String_klass(), 2.9 + "must be java String"); 2.10 + assert(str2->klass() == SystemDictionary::String_klass(), 2.11 + "must be java String"); 2.12 + typeArrayOop value1 = java_lang_String::value(str1); 2.13 + int offset1 = java_lang_String::offset(str1); 2.14 + int length1 = java_lang_String::length(str1); 2.15 + typeArrayOop value2 = java_lang_String::value(str2); 2.16 + int offset2 = java_lang_String::offset(str2); 2.17 + int length2 = java_lang_String::length(str2); 2.18 + 2.19 + if (length1 != length2) { 2.20 + return false; 2.21 + } 2.22 + for (int i = 0; i < length1; i++) { 2.23 + if (value1->char_at(i + offset1) != value2->char_at(i + offset2)) { 2.24 + return false; 2.25 + } 2.26 + } 2.27 + return true; 2.28 +} 2.29 + 2.30 void java_lang_String::print(Handle java_string, outputStream* st) { 2.31 oop obj = java_string(); 2.32 assert(obj->klass() == SystemDictionary::String_klass(), "must be java_string");
3.1 --- a/src/share/vm/classfile/javaClasses.hpp Fri Sep 20 11:17:04 2013 -0700 3.2 +++ b/src/share/vm/classfile/javaClasses.hpp Wed Sep 25 13:03:21 2013 -0400 3.3 @@ -182,6 +182,7 @@ 3.4 static unsigned int hash_string(oop java_string); 3.5 3.6 static bool equals(oop java_string, jchar* chars, int len); 3.7 + static bool equals(oop str1, oop str2); 3.8 3.9 // Conversion between '.' and '/' formats 3.10 static Handle externalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '/', '.', THREAD); }
4.1 --- a/src/share/vm/classfile/symbolTable.cpp Fri Sep 20 11:17:04 2013 -0700 4.2 +++ b/src/share/vm/classfile/symbolTable.cpp Wed Sep 25 13:03:21 2013 -0400 4.3 @@ -807,6 +807,8 @@ 4.4 } 4.5 } 4.6 4.7 +// This verification is part of Universe::verify() and needs to be quick. 4.8 +// See StringTable::verify_and_compare() below for exhaustive verification. 4.9 void StringTable::verify() { 4.10 for (int i = 0; i < the_table()->table_size(); ++i) { 4.11 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i); 4.12 @@ -825,6 +827,162 @@ 4.13 the_table()->dump_table(st, "StringTable"); 4.14 } 4.15 4.16 +StringTable::VerifyRetTypes StringTable::compare_entries( 4.17 + int bkt1, int e_cnt1, 4.18 + HashtableEntry<oop, mtSymbol>* e_ptr1, 4.19 + int bkt2, int e_cnt2, 4.20 + HashtableEntry<oop, mtSymbol>* e_ptr2) { 4.21 + // These entries are sanity checked by verify_and_compare_entries() 4.22 + // before this function is called. 4.23 + oop str1 = e_ptr1->literal(); 4.24 + oop str2 = e_ptr2->literal(); 4.25 + 4.26 + if (str1 == str2) { 4.27 + tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " 4.28 + "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", 4.29 + str1, bkt1, e_cnt1, bkt2, e_cnt2); 4.30 + return _verify_fail_continue; 4.31 + } 4.32 + 4.33 + if (java_lang_String::equals(str1, str2)) { 4.34 + tty->print_cr("ERROR: identical String values in entry @ " 4.35 + "bucket[%d][%d] and entry @ bucket[%d][%d]", 4.36 + bkt1, e_cnt1, bkt2, e_cnt2); 4.37 + return _verify_fail_continue; 4.38 + } 4.39 + 4.40 + return _verify_pass; 4.41 +} 4.42 + 4.43 +StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt, 4.44 + HashtableEntry<oop, mtSymbol>* e_ptr, 4.45 + StringTable::VerifyMesgModes mesg_mode) { 4.46 + 4.47 + VerifyRetTypes ret = _verify_pass; // be optimistic 4.48 + 4.49 + oop str = e_ptr->literal(); 4.50 + if (str == NULL) { 4.51 + if (mesg_mode == _verify_with_mesgs) { 4.52 + tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt, 4.53 + e_cnt); 4.54 + } 4.55 + // NULL oop means no more verifications are possible 4.56 + return _verify_fail_done; 4.57 + } 4.58 + 4.59 + if (str->klass() != SystemDictionary::String_klass()) { 4.60 + if (mesg_mode == _verify_with_mesgs) { 4.61 + tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]", 4.62 + bkt, e_cnt); 4.63 + } 4.64 + // not a String means no more verifications are possible 4.65 + return _verify_fail_done; 4.66 + } 4.67 + 4.68 + unsigned int h = java_lang_String::hash_string(str); 4.69 + if (e_ptr->hash() != h) { 4.70 + if (mesg_mode == _verify_with_mesgs) { 4.71 + tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " 4.72 + "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h); 4.73 + } 4.74 + ret = _verify_fail_continue; 4.75 + } 4.76 + 4.77 + if (the_table()->hash_to_index(h) != bkt) { 4.78 + if (mesg_mode == _verify_with_mesgs) { 4.79 + tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], " 4.80 + "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h, 4.81 + the_table()->hash_to_index(h)); 4.82 + } 4.83 + ret = _verify_fail_continue; 4.84 + } 4.85 + 4.86 + return ret; 4.87 +} 4.88 + 4.89 +// See StringTable::verify() above for the quick verification that is 4.90 +// part of Universe::verify(). This verification is exhaustive and 4.91 +// reports on every issue that is found. StringTable::verify() only 4.92 +// reports on the first issue that is found. 4.93 +// 4.94 +// StringTable::verify_entry() checks: 4.95 +// - oop value != NULL (same as verify()) 4.96 +// - oop value is a String 4.97 +// - hash(String) == hash in entry (same as verify()) 4.98 +// - index for hash == index of entry (same as verify()) 4.99 +// 4.100 +// StringTable::compare_entries() checks: 4.101 +// - oops are unique across all entries 4.102 +// - String values are unique across all entries 4.103 +// 4.104 +int StringTable::verify_and_compare_entries() { 4.105 + assert(StringTable_lock->is_locked(), "sanity check"); 4.106 + 4.107 + int fail_cnt = 0; 4.108 + 4.109 + // first, verify all the entries individually: 4.110 + for (int bkt = 0; bkt < the_table()->table_size(); bkt++) { 4.111 + HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt); 4.112 + for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) { 4.113 + VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs); 4.114 + if (ret != _verify_pass) { 4.115 + fail_cnt++; 4.116 + } 4.117 + } 4.118 + } 4.119 + 4.120 + // Optimization: if the above check did not find any failures, then 4.121 + // the comparison loop below does not need to call verify_entry() 4.122 + // before calling compare_entries(). If there were failures, then we 4.123 + // have to call verify_entry() to see if the entry can be passed to 4.124 + // compare_entries() safely. When we call verify_entry() in the loop 4.125 + // below, we do so quietly to void duplicate messages and we don't 4.126 + // increment fail_cnt because the failures have already been counted. 4.127 + bool need_entry_verify = (fail_cnt != 0); 4.128 + 4.129 + // second, verify all entries relative to each other: 4.130 + for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) { 4.131 + HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1); 4.132 + for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) { 4.133 + if (need_entry_verify) { 4.134 + VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1, 4.135 + _verify_quietly); 4.136 + if (ret == _verify_fail_done) { 4.137 + // cannot use the current entry to compare against other entries 4.138 + continue; 4.139 + } 4.140 + } 4.141 + 4.142 + for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) { 4.143 + HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2); 4.144 + int e_cnt2; 4.145 + for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) { 4.146 + if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) { 4.147 + // skip the entries up to and including the one that 4.148 + // we're comparing against 4.149 + continue; 4.150 + } 4.151 + 4.152 + if (need_entry_verify) { 4.153 + VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2, 4.154 + _verify_quietly); 4.155 + if (ret == _verify_fail_done) { 4.156 + // cannot compare against this entry 4.157 + continue; 4.158 + } 4.159 + } 4.160 + 4.161 + // compare two entries, report and count any failures: 4.162 + if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2) 4.163 + != _verify_pass) { 4.164 + fail_cnt++; 4.165 + } 4.166 + } 4.167 + } 4.168 + } 4.169 + } 4.170 + return fail_cnt; 4.171 +} 4.172 4.173 // Create a new table and using alternate hash code, populate the new table 4.174 // with the existing strings. Set flag to use the alternate hash code afterwards.
5.1 --- a/src/share/vm/classfile/symbolTable.hpp Fri Sep 20 11:17:04 2013 -0700 5.2 +++ b/src/share/vm/classfile/symbolTable.hpp Wed Sep 25 13:03:21 2013 -0400 5.3 @@ -311,6 +311,26 @@ 5.4 static void verify(); 5.5 static void dump(outputStream* st); 5.6 5.7 + enum VerifyMesgModes { 5.8 + _verify_quietly = 0, 5.9 + _verify_with_mesgs = 1 5.10 + }; 5.11 + 5.12 + enum VerifyRetTypes { 5.13 + _verify_pass = 0, 5.14 + _verify_fail_continue = 1, 5.15 + _verify_fail_done = 2 5.16 + }; 5.17 + 5.18 + static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, 5.19 + HashtableEntry<oop, mtSymbol>* e_ptr1, 5.20 + int bkt2, int e_cnt2, 5.21 + HashtableEntry<oop, mtSymbol>* e_ptr2); 5.22 + static VerifyRetTypes verify_entry(int bkt, int e_cnt, 5.23 + HashtableEntry<oop, mtSymbol>* e_ptr, 5.24 + VerifyMesgModes mesg_mode); 5.25 + static int verify_and_compare_entries(); 5.26 + 5.27 // Sharing 5.28 static void copy_buckets(char** top, char*end) { 5.29 the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end);
6.1 --- a/src/share/vm/memory/metaspaceShared.cpp Fri Sep 20 11:17:04 2013 -0700 6.2 +++ b/src/share/vm/memory/metaspaceShared.cpp Wed Sep 25 13:03:21 2013 -0400 6.3 @@ -103,9 +103,10 @@ 6.4 if (k->oop_is_instance()) { 6.5 InstanceKlass* ik = InstanceKlass::cast(k); 6.6 for (int i = 0; i < ik->methods()->length(); i++) { 6.7 - ResourceMark rm; 6.8 Method* m = ik->methods()->at(i); 6.9 - (new Fingerprinter(m))->fingerprint(); 6.10 + Fingerprinter fp(m); 6.11 + // The side effect of this call sets method's fingerprint field. 6.12 + fp.fingerprint(); 6.13 } 6.14 } 6.15 }
7.1 --- a/src/share/vm/oops/constantPool.cpp Fri Sep 20 11:17:04 2013 -0700 7.2 +++ b/src/share/vm/oops/constantPool.cpp Wed Sep 25 13:03:21 2013 -0400 7.3 @@ -108,16 +108,16 @@ 7.4 void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data, 7.5 intStack reference_map, 7.6 int constant_pool_map_length, 7.7 - TRAPS) { 7.8 + TRAPS) { 7.9 // Initialized the resolved object cache. 7.10 int map_length = reference_map.length(); 7.11 if (map_length > 0) { 7.12 // Only need mapping back to constant pool entries. The map isn't used for 7.13 - // invokedynamic resolved_reference entries. The constant pool cache index 7.14 - // has the mapping back to both the constant pool and to the resolved 7.15 - // reference index. 7.16 + // invokedynamic resolved_reference entries. For invokedynamic entries, 7.17 + // the constant pool cache index has the mapping back to both the constant 7.18 + // pool and to the resolved reference index. 7.19 if (constant_pool_map_length > 0) { 7.20 - Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, map_length, CHECK); 7.21 + Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, constant_pool_map_length, CHECK); 7.22 7.23 for (int i = 0; i < constant_pool_map_length; i++) { 7.24 int x = reference_map.at(i); 7.25 @@ -182,16 +182,9 @@ 7.26 7.27 int ConstantPool::cp_to_object_index(int cp_index) { 7.28 // this is harder don't do this so much. 7.29 - for (int i = 0; i< reference_map()->length(); i++) { 7.30 - if (reference_map()->at(i) == cp_index) return i; 7.31 - // Zero entry is divider between constant pool indices for strings, 7.32 - // method handles and method types. After that the index is a constant 7.33 - // pool cache index for invokedynamic. Stop when zero (which can never 7.34 - // be a constant pool index) 7.35 - if (reference_map()->at(i) == 0) break; 7.36 - } 7.37 - // We might not find the index. 7.38 - return _no_index_sentinel; 7.39 + int i = reference_map()->find(cp_index); 7.40 + // We might not find the index for jsr292 call. 7.41 + return (i < 0) ? _no_index_sentinel : i; 7.42 } 7.43 7.44 Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 7.45 @@ -840,8 +833,7 @@ 7.46 // If the string has already been interned, this entry will be non-null 7.47 oop str = this_oop->resolved_references()->obj_at(obj_index); 7.48 if (str != NULL) return str; 7.49 - 7.50 - Symbol* sym = this_oop->unresolved_string_at(which); 7.51 + Symbol* sym = this_oop->unresolved_string_at(which); 7.52 str = StringTable::intern(sym, CHECK_(NULL)); 7.53 this_oop->string_at_put(which, obj_index, str); 7.54 assert(java_lang_String::is_instance(str), "must be string"); 7.55 @@ -1619,9 +1611,11 @@ 7.56 case JVM_CONSTANT_UnresolvedClassInError: 7.57 case JVM_CONSTANT_StringIndex: 7.58 case JVM_CONSTANT_MethodType: 7.59 + case JVM_CONSTANT_MethodTypeInError: 7.60 return 3; 7.61 7.62 case JVM_CONSTANT_MethodHandle: 7.63 + case JVM_CONSTANT_MethodHandleInError: 7.64 return 4; //tag, ref_kind, ref_index 7.65 7.66 case JVM_CONSTANT_Integer: 7.67 @@ -1802,8 +1796,8 @@ 7.68 case JVM_CONSTANT_MethodHandle: 7.69 case JVM_CONSTANT_MethodHandleInError: { 7.70 *bytes = JVM_CONSTANT_MethodHandle; 7.71 - int kind = method_handle_ref_kind_at(idx); 7.72 - idx1 = method_handle_index_at(idx); 7.73 + int kind = method_handle_ref_kind_at_error_ok(idx); 7.74 + idx1 = method_handle_index_at_error_ok(idx); 7.75 *(bytes+1) = (unsigned char) kind; 7.76 Bytes::put_Java_u2((address) (bytes+2), idx1); 7.77 DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); 7.78 @@ -1812,7 +1806,7 @@ 7.79 case JVM_CONSTANT_MethodType: 7.80 case JVM_CONSTANT_MethodTypeInError: { 7.81 *bytes = JVM_CONSTANT_MethodType; 7.82 - idx1 = method_type_index_at(idx); 7.83 + idx1 = method_type_index_at_error_ok(idx); 7.84 Bytes::put_Java_u2((address) (bytes+1), idx1); 7.85 DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); 7.86 break; 7.87 @@ -2000,12 +1994,12 @@ 7.88 break; 7.89 case JVM_CONSTANT_MethodHandle : 7.90 case JVM_CONSTANT_MethodHandleInError : 7.91 - st->print("ref_kind=%d", method_handle_ref_kind_at(index)); 7.92 - st->print(" ref_index=%d", method_handle_index_at(index)); 7.93 + st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index)); 7.94 + st->print(" ref_index=%d", method_handle_index_at_error_ok(index)); 7.95 break; 7.96 case JVM_CONSTANT_MethodType : 7.97 case JVM_CONSTANT_MethodTypeInError : 7.98 - st->print("signature_index=%d", method_type_index_at(index)); 7.99 + st->print("signature_index=%d", method_type_index_at_error_ok(index)); 7.100 break; 7.101 case JVM_CONSTANT_InvokeDynamic : 7.102 {
8.1 --- a/src/share/vm/oops/constantPool.hpp Fri Sep 20 11:17:04 2013 -0700 8.2 +++ b/src/share/vm/oops/constantPool.hpp Wed Sep 25 13:03:21 2013 -0400 8.3 @@ -231,7 +231,6 @@ 8.4 static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); } 8.5 static int pool_holder_offset_in_bytes() { return offset_of(ConstantPool, _pool_holder); } 8.6 static int resolved_references_offset_in_bytes() { return offset_of(ConstantPool, _resolved_references); } 8.7 - static int reference_map_offset_in_bytes() { return offset_of(ConstantPool, _reference_map); } 8.8 8.9 // Storing constants 8.10 8.11 @@ -475,18 +474,42 @@ 8.12 return *int_at_addr(which); 8.13 } 8.14 8.15 - int method_handle_ref_kind_at(int which) { 8.16 - assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); 8.17 + private: 8.18 + int method_handle_ref_kind_at(int which, bool error_ok) { 8.19 + assert(tag_at(which).is_method_handle() || 8.20 + (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool"); 8.21 return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits 8.22 } 8.23 - int method_handle_index_at(int which) { 8.24 - assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); 8.25 + int method_handle_index_at(int which, bool error_ok) { 8.26 + assert(tag_at(which).is_method_handle() || 8.27 + (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool"); 8.28 return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits 8.29 } 8.30 - int method_type_index_at(int which) { 8.31 - assert(tag_at(which).is_method_type(), "Corrupted constant pool"); 8.32 + int method_type_index_at(int which, bool error_ok) { 8.33 + assert(tag_at(which).is_method_type() || 8.34 + (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool"); 8.35 return *int_at_addr(which); 8.36 } 8.37 + public: 8.38 + int method_handle_ref_kind_at(int which) { 8.39 + return method_handle_ref_kind_at(which, false); 8.40 + } 8.41 + int method_handle_ref_kind_at_error_ok(int which) { 8.42 + return method_handle_ref_kind_at(which, true); 8.43 + } 8.44 + int method_handle_index_at(int which) { 8.45 + return method_handle_index_at(which, false); 8.46 + } 8.47 + int method_handle_index_at_error_ok(int which) { 8.48 + return method_handle_index_at(which, true); 8.49 + } 8.50 + int method_type_index_at(int which) { 8.51 + return method_type_index_at(which, false); 8.52 + } 8.53 + int method_type_index_at_error_ok(int which) { 8.54 + return method_type_index_at(which, true); 8.55 + } 8.56 + 8.57 // Derived queries: 8.58 Symbol* method_handle_name_ref_at(int which) { 8.59 int member = method_handle_index_at(which);
9.1 --- a/src/share/vm/oops/instanceKlass.cpp Fri Sep 20 11:17:04 2013 -0700 9.2 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Sep 25 13:03:21 2013 -0400 9.3 @@ -2769,24 +2769,17 @@ 9.4 st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr(); 9.5 st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); 9.6 { 9.7 - ResourceMark rm; 9.8 - // PreviousVersionInfo objects returned via PreviousVersionWalker 9.9 - // contain a GrowableArray of handles. We have to clean up the 9.10 - // GrowableArray _after_ the PreviousVersionWalker destructor 9.11 - // has destroyed the handles. 9.12 - { 9.13 - bool have_pv = false; 9.14 - PreviousVersionWalker pvw((InstanceKlass*)this); 9.15 - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); 9.16 - pv_info != NULL; pv_info = pvw.next_previous_version()) { 9.17 - if (!have_pv) 9.18 - st->print(BULLET"previous version: "); 9.19 - have_pv = true; 9.20 - pv_info->prev_constant_pool_handle()()->print_value_on(st); 9.21 - } 9.22 - if (have_pv) st->cr(); 9.23 - } // pvw is cleaned up 9.24 - } // rm is cleaned up 9.25 + bool have_pv = false; 9.26 + PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this); 9.27 + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); 9.28 + pv_node != NULL; pv_node = pvw.next_previous_version()) { 9.29 + if (!have_pv) 9.30 + st->print(BULLET"previous version: "); 9.31 + have_pv = true; 9.32 + pv_node->prev_constant_pool()->print_value_on(st); 9.33 + } 9.34 + if (have_pv) st->cr(); 9.35 + } // pvw is cleaned up 9.36 9.37 if (generic_signature() != NULL) { 9.38 st->print(BULLET"generic signature: "); 9.39 @@ -3317,34 +3310,34 @@ 9.40 Array<Method*>* old_methods = ikh->methods(); 9.41 9.42 if (cp_ref->on_stack()) { 9.43 - PreviousVersionNode * pv_node = NULL; 9.44 - if (emcp_method_count == 0) { 9.45 + PreviousVersionNode * pv_node = NULL; 9.46 + if (emcp_method_count == 0) { 9.47 // non-shared ConstantPool gets a reference 9.48 - pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), NULL); 9.49 - RC_TRACE(0x00000400, 9.50 - ("add: all methods are obsolete; flushing any EMCP refs")); 9.51 - } else { 9.52 - int local_count = 0; 9.53 + pv_node = new PreviousVersionNode(cp_ref, NULL); 9.54 + RC_TRACE(0x00000400, 9.55 + ("add: all methods are obsolete; flushing any EMCP refs")); 9.56 + } else { 9.57 + int local_count = 0; 9.58 GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass) 9.59 - GrowableArray<Method*>(emcp_method_count, true); 9.60 - for (int i = 0; i < old_methods->length(); i++) { 9.61 - if (emcp_methods->at(i)) { 9.62 - // this old method is EMCP. Save it only if it's on the stack 9.63 - Method* old_method = old_methods->at(i); 9.64 - if (old_method->on_stack()) { 9.65 - method_refs->append(old_method); 9.66 + GrowableArray<Method*>(emcp_method_count, true); 9.67 + for (int i = 0; i < old_methods->length(); i++) { 9.68 + if (emcp_methods->at(i)) { 9.69 + // this old method is EMCP. Save it only if it's on the stack 9.70 + Method* old_method = old_methods->at(i); 9.71 + if (old_method->on_stack()) { 9.72 + method_refs->append(old_method); 9.73 + } 9.74 + if (++local_count >= emcp_method_count) { 9.75 + // no more EMCP methods so bail out now 9.76 + break; 9.77 } 9.78 - if (++local_count >= emcp_method_count) { 9.79 - // no more EMCP methods so bail out now 9.80 - break; 9.81 } 9.82 } 9.83 - } 9.84 // non-shared ConstantPool gets a reference 9.85 - pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), method_refs); 9.86 + pv_node = new PreviousVersionNode(cp_ref, method_refs); 9.87 } 9.88 // append new previous version. 9.89 - _previous_versions->append(pv_node); 9.90 + _previous_versions->append(pv_node); 9.91 } 9.92 9.93 // Since the caller is the VMThread and we are at a safepoint, this 9.94 @@ -3445,6 +3438,8 @@ 9.95 return m; 9.96 } 9.97 } 9.98 + // None found, return null for the caller to handle. 9.99 + return NULL; 9.100 } 9.101 return m; 9.102 } 9.103 @@ -3461,10 +3456,9 @@ 9.104 // Construct a PreviousVersionNode entry for the array hung off 9.105 // the InstanceKlass. 9.106 PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, 9.107 - bool prev_cp_is_weak, GrowableArray<Method*>* prev_EMCP_methods) { 9.108 + GrowableArray<Method*>* prev_EMCP_methods) { 9.109 9.110 _prev_constant_pool = prev_constant_pool; 9.111 - _prev_cp_is_weak = prev_cp_is_weak; 9.112 _prev_EMCP_methods = prev_EMCP_methods; 9.113 } 9.114 9.115 @@ -3480,99 +3474,38 @@ 9.116 } 9.117 } 9.118 9.119 - 9.120 -// Construct a PreviousVersionInfo entry 9.121 -PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { 9.122 - _prev_constant_pool_handle = constantPoolHandle(); // NULL handle 9.123 - _prev_EMCP_method_handles = NULL; 9.124 - 9.125 - ConstantPool* cp = pv_node->prev_constant_pool(); 9.126 - assert(cp != NULL, "constant pool ref was unexpectedly cleared"); 9.127 - if (cp == NULL) { 9.128 - return; // robustness 9.129 - } 9.130 - 9.131 - // make the ConstantPool* safe to return 9.132 - _prev_constant_pool_handle = constantPoolHandle(cp); 9.133 - 9.134 - GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods(); 9.135 - if (method_refs == NULL) { 9.136 - // the InstanceKlass did not have any EMCP methods 9.137 - return; 9.138 - } 9.139 - 9.140 - _prev_EMCP_method_handles = new GrowableArray<methodHandle>(10); 9.141 - 9.142 - int n_methods = method_refs->length(); 9.143 - for (int i = 0; i < n_methods; i++) { 9.144 - Method* method = method_refs->at(i); 9.145 - assert (method != NULL, "method has been cleared"); 9.146 - if (method == NULL) { 9.147 - continue; // robustness 9.148 - } 9.149 - // make the Method* safe to return 9.150 - _prev_EMCP_method_handles->append(methodHandle(method)); 9.151 - } 9.152 -} 9.153 - 9.154 - 9.155 -// Destroy a PreviousVersionInfo 9.156 -PreviousVersionInfo::~PreviousVersionInfo() { 9.157 - // Since _prev_EMCP_method_handles is not C-heap allocated, we 9.158 - // don't have to delete it. 9.159 -} 9.160 - 9.161 - 9.162 // Construct a helper for walking the previous versions array 9.163 -PreviousVersionWalker::PreviousVersionWalker(InstanceKlass *ik) { 9.164 +PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) { 9.165 + _thread = thread; 9.166 _previous_versions = ik->previous_versions(); 9.167 _current_index = 0; 9.168 - // _hm needs no initialization 9.169 _current_p = NULL; 9.170 -} 9.171 - 9.172 - 9.173 -// Destroy a PreviousVersionWalker 9.174 -PreviousVersionWalker::~PreviousVersionWalker() { 9.175 - // Delete the current info just in case the caller didn't walk to 9.176 - // the end of the previous versions list. No harm if _current_p is 9.177 - // already NULL. 9.178 - delete _current_p; 9.179 - 9.180 - // When _hm is destroyed, all the Handles returned in 9.181 - // PreviousVersionInfo objects will be destroyed. 9.182 - // Also, after this destructor is finished it will be 9.183 - // safe to delete the GrowableArray allocated in the 9.184 - // PreviousVersionInfo objects. 9.185 + _current_constant_pool_handle = constantPoolHandle(thread, ik->constants()); 9.186 } 9.187 9.188 9.189 // Return the interesting information for the next previous version 9.190 // of the klass. Returns NULL if there are no more previous versions. 9.191 -PreviousVersionInfo* PreviousVersionWalker::next_previous_version() { 9.192 +PreviousVersionNode* PreviousVersionWalker::next_previous_version() { 9.193 if (_previous_versions == NULL) { 9.194 // no previous versions so nothing to return 9.195 return NULL; 9.196 } 9.197 9.198 - delete _current_p; // cleanup the previous info for the caller 9.199 - _current_p = NULL; // reset to NULL so we don't delete same object twice 9.200 + _current_p = NULL; // reset to NULL 9.201 + _current_constant_pool_handle = NULL; 9.202 9.203 int length = _previous_versions->length(); 9.204 9.205 while (_current_index < length) { 9.206 PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); 9.207 - PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass) 9.208 - PreviousVersionInfo(pv_node); 9.209 - 9.210 - constantPoolHandle cp_h = pv_info->prev_constant_pool_handle(); 9.211 - assert (!cp_h.is_null(), "null cp found in previous version"); 9.212 - 9.213 - // The caller will need to delete pv_info when they are done with it. 9.214 - _current_p = pv_info; 9.215 - return pv_info; 9.216 + 9.217 + // Save a handle to the constant pool for this previous version, 9.218 + // which keeps all the methods from being deallocated. 9.219 + _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool()); 9.220 + _current_p = pv_node; 9.221 + return pv_node; 9.222 } 9.223 9.224 - // all of the underlying nodes' info has been deleted 9.225 return NULL; 9.226 } // end next_previous_version()
10.1 --- a/src/share/vm/oops/instanceKlass.hpp Fri Sep 20 11:17:04 2013 -0700 10.2 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Sep 25 13:03:21 2013 -0400 10.3 @@ -1126,21 +1126,11 @@ 10.4 10.5 10.6 // A collection point for interesting information about the previous 10.7 -// version(s) of an InstanceKlass. This class uses weak references to 10.8 -// the information so that the information may be collected as needed 10.9 -// by the system. If the information is shared, then a regular 10.10 -// reference must be used because a weak reference would be seen as 10.11 -// collectible. A GrowableArray of PreviousVersionNodes is attached 10.12 -// to the InstanceKlass as needed. See PreviousVersionWalker below. 10.13 +// version(s) of an InstanceKlass. A GrowableArray of PreviousVersionNodes 10.14 +// is attached to the InstanceKlass as needed. See PreviousVersionWalker below. 10.15 class PreviousVersionNode : public CHeapObj<mtClass> { 10.16 private: 10.17 - // A shared ConstantPool is never collected so we'll always have 10.18 - // a reference to it so we can update items in the cache. We'll 10.19 - // have a weak reference to a non-shared ConstantPool until all 10.20 - // of the methods (EMCP or obsolete) have been collected; the 10.21 - // non-shared ConstantPool becomes collectible at that point. 10.22 - ConstantPool* _prev_constant_pool; // regular or weak reference 10.23 - bool _prev_cp_is_weak; // true if not a shared ConstantPool 10.24 + ConstantPool* _prev_constant_pool; 10.25 10.26 // If the previous version of the InstanceKlass doesn't have any 10.27 // EMCP methods, then _prev_EMCP_methods will be NULL. If all the 10.28 @@ -1149,8 +1139,8 @@ 10.29 GrowableArray<Method*>* _prev_EMCP_methods; 10.30 10.31 public: 10.32 - PreviousVersionNode(ConstantPool* prev_constant_pool, bool prev_cp_is_weak, 10.33 - GrowableArray<Method*>* prev_EMCP_methods); 10.34 + PreviousVersionNode(ConstantPool* prev_constant_pool, 10.35 + GrowableArray<Method*>* prev_EMCP_methods); 10.36 ~PreviousVersionNode(); 10.37 ConstantPool* prev_constant_pool() const { 10.38 return _prev_constant_pool; 10.39 @@ -1161,59 +1151,26 @@ 10.40 }; 10.41 10.42 10.43 -// A Handle-ized version of PreviousVersionNode. 10.44 -class PreviousVersionInfo : public ResourceObj { 10.45 - private: 10.46 - constantPoolHandle _prev_constant_pool_handle; 10.47 - // If the previous version of the InstanceKlass doesn't have any 10.48 - // EMCP methods, then _prev_EMCP_methods will be NULL. Since the 10.49 - // methods cannot be collected while we hold a handle, 10.50 - // _prev_EMCP_methods should never have a length of zero. 10.51 - GrowableArray<methodHandle>* _prev_EMCP_method_handles; 10.52 - 10.53 -public: 10.54 - PreviousVersionInfo(PreviousVersionNode *pv_node); 10.55 - ~PreviousVersionInfo(); 10.56 - constantPoolHandle prev_constant_pool_handle() const { 10.57 - return _prev_constant_pool_handle; 10.58 - } 10.59 - GrowableArray<methodHandle>* prev_EMCP_method_handles() const { 10.60 - return _prev_EMCP_method_handles; 10.61 - } 10.62 -}; 10.63 - 10.64 - 10.65 -// Helper object for walking previous versions. This helper cleans up 10.66 -// the Handles that it allocates when the helper object is destroyed. 10.67 -// The PreviousVersionInfo object returned by next_previous_version() 10.68 -// is only valid until a subsequent call to next_previous_version() or 10.69 -// the helper object is destroyed. 10.70 +// Helper object for walking previous versions. 10.71 class PreviousVersionWalker : public StackObj { 10.72 private: 10.73 + Thread* _thread; 10.74 GrowableArray<PreviousVersionNode *>* _previous_versions; 10.75 int _current_index; 10.76 - // Fields for cleaning up when we are done walking the previous versions: 10.77 - // A HandleMark for the PreviousVersionInfo handles: 10.78 - HandleMark _hm; 10.79 10.80 - // It would be nice to have a ResourceMark field in this helper also, 10.81 - // but the ResourceMark code says to be careful to delete handles held 10.82 - // in GrowableArrays _before_ deleting the GrowableArray. Since we 10.83 - // can't guarantee the order in which the fields are destroyed, we 10.84 - // have to let the creator of the PreviousVersionWalker object do 10.85 - // the right thing. Also, adding a ResourceMark here causes an 10.86 - // include loop. 10.87 + // A pointer to the current node object so we can handle the deletes. 10.88 + PreviousVersionNode* _current_p; 10.89 10.90 - // A pointer to the current info object so we can handle the deletes. 10.91 - PreviousVersionInfo * _current_p; 10.92 + // The constant pool handle keeps all the methods in this class from being 10.93 + // deallocated from the metaspace during class unloading. 10.94 + constantPoolHandle _current_constant_pool_handle; 10.95 10.96 public: 10.97 - PreviousVersionWalker(InstanceKlass *ik); 10.98 - ~PreviousVersionWalker(); 10.99 + PreviousVersionWalker(Thread* thread, InstanceKlass *ik); 10.100 10.101 // Return the interesting information for the next previous version 10.102 // of the klass. Returns NULL if there are no more previous versions. 10.103 - PreviousVersionInfo* next_previous_version(); 10.104 + PreviousVersionNode* next_previous_version(); 10.105 }; 10.106 10.107
11.1 --- a/src/share/vm/prims/jvm.cpp Fri Sep 20 11:17:04 2013 -0700 11.2 +++ b/src/share/vm/prims/jvm.cpp Wed Sep 25 13:03:21 2013 -0400 11.3 @@ -1835,16 +1835,27 @@ 11.4 } 11.5 JVM_END 11.6 11.7 -JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) 11.8 -{ 11.9 - JVMWrapper("JVM_GetClassDeclaredMethods"); 11.10 +static bool select_method(methodHandle method, bool want_constructor) { 11.11 + if (want_constructor) { 11.12 + return (method->is_initializer() && !method->is_static()); 11.13 + } else { 11.14 + return (!method->is_initializer() && !method->is_overpass()); 11.15 + } 11.16 +} 11.17 + 11.18 +static jobjectArray get_class_declared_methods_helper( 11.19 + JNIEnv *env, 11.20 + jclass ofClass, jboolean publicOnly, 11.21 + bool want_constructor, 11.22 + Klass* klass, TRAPS) { 11.23 + 11.24 JvmtiVMObjectAllocEventCollector oam; 11.25 11.26 // Exclude primitive types and array types 11.27 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) 11.28 || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { 11.29 // Return empty array 11.30 - oop res = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), 0, CHECK_NULL); 11.31 + oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL); 11.32 return (jobjectArray) JNIHandles::make_local(env, res); 11.33 } 11.34 11.35 @@ -1855,87 +1866,67 @@ 11.36 11.37 Array<Method*>* methods = k->methods(); 11.38 int methods_length = methods->length(); 11.39 + 11.40 + // Save original method_idnum in case of redefinition, which can change 11.41 + // the idnum of obsolete methods. The new method will have the same idnum 11.42 + // but if we refresh the methods array, the counts will be wrong. 11.43 + ResourceMark rm(THREAD); 11.44 + GrowableArray<int>* idnums = new GrowableArray<int>(methods_length); 11.45 int num_methods = 0; 11.46 11.47 - int i; 11.48 - for (i = 0; i < methods_length; i++) { 11.49 + for (int i = 0; i < methods_length; i++) { 11.50 methodHandle method(THREAD, methods->at(i)); 11.51 - if (!method->is_initializer() && !method->is_overpass()) { 11.52 + if (select_method(method, want_constructor)) { 11.53 if (!publicOnly || method->is_public()) { 11.54 + idnums->push(method->method_idnum()); 11.55 ++num_methods; 11.56 } 11.57 } 11.58 } 11.59 11.60 // Allocate result 11.61 - objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), num_methods, CHECK_NULL); 11.62 + objArrayOop r = oopFactory::new_objArray(klass, num_methods, CHECK_NULL); 11.63 objArrayHandle result (THREAD, r); 11.64 11.65 - int out_idx = 0; 11.66 - for (i = 0; i < methods_length; i++) { 11.67 - methodHandle method(THREAD, methods->at(i)); 11.68 - if (!method->is_initializer() && !method->is_overpass()) { 11.69 - if (!publicOnly || method->is_public()) { 11.70 - oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); 11.71 - result->obj_at_put(out_idx, m); 11.72 - ++out_idx; 11.73 + // Now just put the methods that we selected above, but go by their idnum 11.74 + // in case of redefinition. The methods can be redefined at any safepoint, 11.75 + // so above when allocating the oop array and below when creating reflect 11.76 + // objects. 11.77 + for (int i = 0; i < num_methods; i++) { 11.78 + methodHandle method(THREAD, k->method_with_idnum(idnums->at(i))); 11.79 + if (method.is_null()) { 11.80 + // Method may have been deleted and seems this API can handle null 11.81 + // Otherwise should probably put a method that throws NSME 11.82 + result->obj_at_put(i, NULL); 11.83 + } else { 11.84 + oop m; 11.85 + if (want_constructor) { 11.86 + m = Reflection::new_constructor(method, CHECK_NULL); 11.87 + } else { 11.88 + m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); 11.89 } 11.90 + result->obj_at_put(i, m); 11.91 } 11.92 } 11.93 - assert(out_idx == num_methods, "just checking"); 11.94 + 11.95 return (jobjectArray) JNIHandles::make_local(env, result()); 11.96 } 11.97 + 11.98 +JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) 11.99 +{ 11.100 + JVMWrapper("JVM_GetClassDeclaredMethods"); 11.101 + return get_class_declared_methods_helper(env, ofClass, publicOnly, 11.102 + /*want_constructor*/ false, 11.103 + SystemDictionary::reflect_Method_klass(), THREAD); 11.104 +} 11.105 JVM_END 11.106 11.107 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)) 11.108 { 11.109 JVMWrapper("JVM_GetClassDeclaredConstructors"); 11.110 - JvmtiVMObjectAllocEventCollector oam; 11.111 - 11.112 - // Exclude primitive types and array types 11.113 - if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) 11.114 - || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { 11.115 - // Return empty array 11.116 - oop res = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0 , CHECK_NULL); 11.117 - return (jobjectArray) JNIHandles::make_local(env, res); 11.118 - } 11.119 - 11.120 - instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); 11.121 - 11.122 - // Ensure class is linked 11.123 - k->link_class(CHECK_NULL); 11.124 - 11.125 - Array<Method*>* methods = k->methods(); 11.126 - int methods_length = methods->length(); 11.127 - int num_constructors = 0; 11.128 - 11.129 - int i; 11.130 - for (i = 0; i < methods_length; i++) { 11.131 - methodHandle method(THREAD, methods->at(i)); 11.132 - if (method->is_initializer() && !method->is_static()) { 11.133 - if (!publicOnly || method->is_public()) { 11.134 - ++num_constructors; 11.135 - } 11.136 - } 11.137 - } 11.138 - 11.139 - // Allocate result 11.140 - objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), num_constructors, CHECK_NULL); 11.141 - objArrayHandle result(THREAD, r); 11.142 - 11.143 - int out_idx = 0; 11.144 - for (i = 0; i < methods_length; i++) { 11.145 - methodHandle method(THREAD, methods->at(i)); 11.146 - if (method->is_initializer() && !method->is_static()) { 11.147 - if (!publicOnly || method->is_public()) { 11.148 - oop m = Reflection::new_constructor(method, CHECK_NULL); 11.149 - result->obj_at_put(out_idx, m); 11.150 - ++out_idx; 11.151 - } 11.152 - } 11.153 - } 11.154 - assert(out_idx == num_constructors, "just checking"); 11.155 - return (jobjectArray) JNIHandles::make_local(env, result()); 11.156 + return get_class_declared_methods_helper(env, ofClass, publicOnly, 11.157 + /*want_constructor*/ true, 11.158 + SystemDictionary::reflect_Constructor_klass(), THREAD); 11.159 } 11.160 JVM_END 11.161
12.1 --- a/src/share/vm/prims/jvmtiEnvBase.hpp Fri Sep 20 11:17:04 2013 -0700 12.2 +++ b/src/share/vm/prims/jvmtiEnvBase.hpp Wed Sep 25 13:03:21 2013 -0400 12.3 @@ -406,7 +406,11 @@ 12.4 VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; } 12.5 jvmtiError result() { return _result; } 12.6 void doit() { 12.7 - _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); 12.8 + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; 12.9 + if (Threads::includes(_java_thread) && !_java_thread->is_exiting() && 12.10 + _java_thread->threadObj() != NULL) { 12.11 + _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); 12.12 + } 12.13 } 12.14 }; 12.15
13.1 --- a/src/share/vm/prims/jvmtiImpl.cpp Fri Sep 20 11:17:04 2013 -0700 13.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp Wed Sep 25 13:03:21 2013 -0400 13.3 @@ -273,59 +273,49 @@ 13.4 13.5 // add/remove breakpoint to/from versions of the method that 13.6 // are EMCP. Directly or transitively obsolete methods are 13.7 - // not saved in the PreviousVersionInfo. 13.8 + // not saved in the PreviousVersionNodes. 13.9 Thread *thread = Thread::current(); 13.10 instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); 13.11 Symbol* m_name = _method->name(); 13.12 Symbol* m_signature = _method->signature(); 13.13 13.14 - { 13.15 - ResourceMark rm(thread); 13.16 - // PreviousVersionInfo objects returned via PreviousVersionWalker 13.17 - // contain a GrowableArray of handles. We have to clean up the 13.18 - // GrowableArray _after_ the PreviousVersionWalker destructor 13.19 - // has destroyed the handles. 13.20 - { 13.21 - // search previous versions if they exist 13.22 - PreviousVersionWalker pvw((InstanceKlass *)ikh()); 13.23 - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); 13.24 - pv_info != NULL; pv_info = pvw.next_previous_version()) { 13.25 - GrowableArray<methodHandle>* methods = 13.26 - pv_info->prev_EMCP_method_handles(); 13.27 + // search previous versions if they exist 13.28 + PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh()); 13.29 + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); 13.30 + pv_node != NULL; pv_node = pvw.next_previous_version()) { 13.31 + GrowableArray<Method*>* methods = pv_node->prev_EMCP_methods(); 13.32 13.33 - if (methods == NULL) { 13.34 - // We have run into a PreviousVersion generation where 13.35 - // all methods were made obsolete during that generation's 13.36 - // RedefineClasses() operation. At the time of that 13.37 - // operation, all EMCP methods were flushed so we don't 13.38 - // have to go back any further. 13.39 - // 13.40 - // A NULL methods array is different than an empty methods 13.41 - // array. We cannot infer any optimizations about older 13.42 - // generations from an empty methods array for the current 13.43 - // generation. 13.44 - break; 13.45 - } 13.46 + if (methods == NULL) { 13.47 + // We have run into a PreviousVersion generation where 13.48 + // all methods were made obsolete during that generation's 13.49 + // RedefineClasses() operation. At the time of that 13.50 + // operation, all EMCP methods were flushed so we don't 13.51 + // have to go back any further. 13.52 + // 13.53 + // A NULL methods array is different than an empty methods 13.54 + // array. We cannot infer any optimizations about older 13.55 + // generations from an empty methods array for the current 13.56 + // generation. 13.57 + break; 13.58 + } 13.59 13.60 - for (int i = methods->length() - 1; i >= 0; i--) { 13.61 - methodHandle method = methods->at(i); 13.62 - // obsolete methods that are running are not deleted from 13.63 - // previous version array, but they are skipped here. 13.64 - if (!method->is_obsolete() && 13.65 - method->name() == m_name && 13.66 - method->signature() == m_signature) { 13.67 - RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", 13.68 - meth_act == &Method::set_breakpoint ? "sett" : "clear", 13.69 - method->name()->as_C_string(), 13.70 - method->signature()->as_C_string())); 13.71 + for (int i = methods->length() - 1; i >= 0; i--) { 13.72 + Method* method = methods->at(i); 13.73 + // obsolete methods that are running are not deleted from 13.74 + // previous version array, but they are skipped here. 13.75 + if (!method->is_obsolete() && 13.76 + method->name() == m_name && 13.77 + method->signature() == m_signature) { 13.78 + RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", 13.79 + meth_act == &Method::set_breakpoint ? "sett" : "clear", 13.80 + method->name()->as_C_string(), 13.81 + method->signature()->as_C_string())); 13.82 13.83 - ((Method*)method()->*meth_act)(_bci); 13.84 - break; 13.85 - } 13.86 - } 13.87 + (method->*meth_act)(_bci); 13.88 + break; 13.89 } 13.90 - } // pvw is cleaned up 13.91 - } // rm is cleaned up 13.92 + } 13.93 + } 13.94 } 13.95 13.96 void JvmtiBreakpoint::set() {
14.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Sep 20 11:17:04 2013 -0700 14.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Sep 25 13:03:21 2013 -0400 14.3 @@ -2807,28 +2807,20 @@ 14.4 &trace_name_printed); 14.5 } 14.6 } 14.7 - { 14.8 - ResourceMark rm(_thread); 14.9 - // PreviousVersionInfo objects returned via PreviousVersionWalker 14.10 - // contain a GrowableArray of handles. We have to clean up the 14.11 - // GrowableArray _after_ the PreviousVersionWalker destructor 14.12 - // has destroyed the handles. 14.13 - { 14.14 - // the previous versions' constant pool caches may need adjustment 14.15 - PreviousVersionWalker pvw(ik); 14.16 - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); 14.17 - pv_info != NULL; pv_info = pvw.next_previous_version()) { 14.18 - other_cp = pv_info->prev_constant_pool_handle(); 14.19 - cp_cache = other_cp->cache(); 14.20 - if (cp_cache != NULL) { 14.21 - cp_cache->adjust_method_entries(_matching_old_methods, 14.22 - _matching_new_methods, 14.23 - _matching_methods_length, 14.24 - &trace_name_printed); 14.25 - } 14.26 - } 14.27 - } // pvw is cleaned up 14.28 - } // rm is cleaned up 14.29 + 14.30 + // the previous versions' constant pool caches may need adjustment 14.31 + PreviousVersionWalker pvw(_thread, ik); 14.32 + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); 14.33 + pv_node != NULL; pv_node = pvw.next_previous_version()) { 14.34 + other_cp = pv_node->prev_constant_pool(); 14.35 + cp_cache = other_cp->cache(); 14.36 + if (cp_cache != NULL) { 14.37 + cp_cache->adjust_method_entries(_matching_old_methods, 14.38 + _matching_new_methods, 14.39 + _matching_methods_length, 14.40 + &trace_name_printed); 14.41 + } 14.42 + } 14.43 } 14.44 } 14.45 14.46 @@ -2942,10 +2934,9 @@ 14.47 // obsolete methods need a unique idnum 14.48 u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum(); 14.49 if (num != ConstMethod::UNSET_IDNUM) { 14.50 -// u2 old_num = old_method->method_idnum(); 14.51 old_method->set_method_idnum(num); 14.52 -// TO DO: attach obsolete annotations to obsolete method's new idnum 14.53 } 14.54 + 14.55 // With tracing we try not to "yack" too much. The position of 14.56 // this trace assumes there are fewer obsolete methods than 14.57 // EMCP methods.
15.1 --- a/src/share/vm/runtime/arguments.cpp Fri Sep 20 11:17:04 2013 -0700 15.2 +++ b/src/share/vm/runtime/arguments.cpp Wed Sep 25 13:03:21 2013 -0400 15.3 @@ -1100,6 +1100,7 @@ 15.4 } 15.5 } 15.6 15.7 +#if defined(COMPILER2) || defined(_LP64) || !INCLUDE_CDS 15.8 // Conflict: required to use shared spaces (-Xshare:on), but 15.9 // incompatible command line options were chosen. 15.10 15.11 @@ -1112,6 +1113,7 @@ 15.12 FLAG_SET_DEFAULT(UseSharedSpaces, false); 15.13 } 15.14 } 15.15 +#endif 15.16 15.17 void Arguments::set_tiered_flags() { 15.18 // With tiered, set default policy to AdvancedThresholdPolicy, which is 3. 15.19 @@ -1520,16 +1522,18 @@ 15.20 FLAG_SET_ERGO(bool, UseParallelGC, true); 15.21 } 15.22 } 15.23 - // Shared spaces work fine with other GCs but causes bytecode rewriting 15.24 - // to be disabled, which hurts interpreter performance and decreases 15.25 - // server performance. On server class machines, keep the default 15.26 - // off unless it is asked for. Future work: either add bytecode rewriting 15.27 - // at link time, or rewrite bytecodes in non-shared methods. 15.28 - if (!DumpSharedSpaces && !RequireSharedSpaces && 15.29 - (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) { 15.30 - no_shared_spaces(); 15.31 - } 15.32 } 15.33 +#ifdef COMPILER2 15.34 + // Shared spaces work fine with other GCs but causes bytecode rewriting 15.35 + // to be disabled, which hurts interpreter performance and decreases 15.36 + // server performance. When -server is specified, keep the default off 15.37 + // unless it is asked for. Future work: either add bytecode rewriting 15.38 + // at link time, or rewrite bytecodes in non-shared methods. 15.39 + if (!DumpSharedSpaces && !RequireSharedSpaces && 15.40 + (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) { 15.41 + no_shared_spaces(); 15.42 + } 15.43 +#endif 15.44 15.45 set_conservative_max_heap_alignment(); 15.46 15.47 @@ -2439,21 +2443,6 @@ 15.48 return result; 15.49 } 15.50 15.51 - if (AggressiveOpts) { 15.52 - // Insert alt-rt.jar between user-specified bootclasspath 15.53 - // prefix and the default bootclasspath. os::set_boot_path() 15.54 - // uses meta_index_dir as the default bootclasspath directory. 15.55 - const char* altclasses_jar = "alt-rt.jar"; 15.56 - size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 + 15.57 - strlen(altclasses_jar); 15.58 - char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len, mtInternal); 15.59 - strcpy(altclasses_path, get_meta_index_dir()); 15.60 - strcat(altclasses_path, altclasses_jar); 15.61 - scp.add_suffix_to_prefix(altclasses_path); 15.62 - scp_assembly_required = true; 15.63 - FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal); 15.64 - } 15.65 - 15.66 // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) 15.67 result = parse_java_options_environment_variable(&scp, &scp_assembly_required); 15.68 if (result != JNI_OK) {
16.1 --- a/src/share/vm/runtime/globals.hpp Fri Sep 20 11:17:04 2013 -0700 16.2 +++ b/src/share/vm/runtime/globals.hpp Wed Sep 25 13:03:21 2013 -0400 16.3 @@ -2526,6 +2526,9 @@ 16.4 product(bool, PrintStringTableStatistics, false, \ 16.5 "print statistics about the StringTable and SymbolTable") \ 16.6 \ 16.7 + diagnostic(bool, VerifyStringTableAtExit, false, \ 16.8 + "verify StringTable contents at exit") \ 16.9 + \ 16.10 notproduct(bool, PrintSymbolTableSizeHistogram, false, \ 16.11 "print histogram of the symbol table") \ 16.12 \
17.1 --- a/src/share/vm/runtime/handles.hpp Fri Sep 20 11:17:04 2013 -0700 17.2 +++ b/src/share/vm/runtime/handles.hpp Wed Sep 25 13:03:21 2013 -0400 17.3 @@ -136,7 +136,7 @@ 17.4 // Specific Handles for different oop types 17.5 #define DEF_METADATA_HANDLE(name, type) \ 17.6 class name##Handle; \ 17.7 - class name##Handle { \ 17.8 + class name##Handle : public StackObj { \ 17.9 type* _value; \ 17.10 Thread* _thread; \ 17.11 protected: \ 17.12 @@ -175,7 +175,7 @@ 17.13 // Writing this class explicitly, since DEF_METADATA_HANDLE(klass) doesn't 17.14 // provide the necessary Klass* <-> Klass* conversions. This Klass 17.15 // could be removed when we don't have the Klass* typedef anymore. 17.16 -class KlassHandle { 17.17 +class KlassHandle : public StackObj { 17.18 Klass* _value; 17.19 protected: 17.20 Klass* obj() const { return _value; }
18.1 --- a/src/share/vm/runtime/handles.inline.hpp Fri Sep 20 11:17:04 2013 -0700 18.2 +++ b/src/share/vm/runtime/handles.inline.hpp Wed Sep 25 13:03:21 2013 -0400 18.3 @@ -79,6 +79,7 @@ 18.4 } else { \ 18.5 _thread = Thread::current(); \ 18.6 } \ 18.7 + assert (_thread->is_in_stack((address)this), "not on stack?"); \ 18.8 _thread->metadata_handles()->push((Metadata*)_value); \ 18.9 } else { \ 18.10 _thread = NULL; \ 18.11 @@ -95,6 +96,7 @@ 18.12 } else { \ 18.13 _thread = Thread::current(); \ 18.14 } \ 18.15 + assert (_thread->is_in_stack((address)this), "not on stack?"); \ 18.16 _thread->metadata_handles()->push((Metadata*)_value); \ 18.17 } else { \ 18.18 _thread = NULL; \
19.1 --- a/src/share/vm/runtime/java.cpp Fri Sep 20 11:17:04 2013 -0700 19.2 +++ b/src/share/vm/runtime/java.cpp Wed Sep 25 13:03:21 2013 -0400 19.3 @@ -544,6 +544,19 @@ 19.4 // it will run into trouble when system destroys static variables. 19.5 MemTracker::shutdown(MemTracker::NMT_normal); 19.6 19.7 + if (VerifyStringTableAtExit) { 19.8 + int fail_cnt = 0; 19.9 + { 19.10 + MutexLocker ml(StringTable_lock); 19.11 + fail_cnt = StringTable::verify_and_compare_entries(); 19.12 + } 19.13 + 19.14 + if (fail_cnt != 0) { 19.15 + tty->print_cr("ERROR: fail_cnt=%d", fail_cnt); 19.16 + guarantee(fail_cnt == 0, "unexpected StringTable verification failures"); 19.17 + } 19.18 + } 19.19 + 19.20 #undef BEFORE_EXIT_NOT_RUN 19.21 #undef BEFORE_EXIT_RUNNING 19.22 #undef BEFORE_EXIT_DONE
20.1 --- a/src/share/vm/services/attachListener.cpp Fri Sep 20 11:17:04 2013 -0700 20.2 +++ b/src/share/vm/services/attachListener.cpp Wed Sep 25 13:03:21 2013 -0400 20.3 @@ -470,7 +470,17 @@ 20.4 vmSymbols::threadgroup_string_void_signature(), 20.5 thread_group, 20.6 string, 20.7 - CHECK); 20.8 + THREAD); 20.9 + 20.10 + if (HAS_PENDING_EXCEPTION) { 20.11 + tty->print_cr("Exception in VM (AttachListener::init) : "); 20.12 + java_lang_Throwable::print(PENDING_EXCEPTION, tty); 20.13 + tty->cr(); 20.14 + 20.15 + CLEAR_PENDING_EXCEPTION; 20.16 + 20.17 + return; 20.18 + } 20.19 20.20 KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass()); 20.21 JavaCalls::call_special(&result, 20.22 @@ -479,7 +489,17 @@ 20.23 vmSymbols::add_method_name(), 20.24 vmSymbols::thread_void_signature(), 20.25 thread_oop, // ARG 1 20.26 - CHECK); 20.27 + THREAD); 20.28 + 20.29 + if (HAS_PENDING_EXCEPTION) { 20.30 + tty->print_cr("Exception in VM (AttachListener::init) : "); 20.31 + java_lang_Throwable::print(PENDING_EXCEPTION, tty); 20.32 + tty->cr(); 20.33 + 20.34 + CLEAR_PENDING_EXCEPTION; 20.35 + 20.36 + return; 20.37 + } 20.38 20.39 { MutexLocker mu(Threads_lock); 20.40 JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry);
21.1 --- a/src/share/vm/services/diagnosticArgument.cpp Fri Sep 20 11:17:04 2013 -0700 21.2 +++ b/src/share/vm/services/diagnosticArgument.cpp Wed Sep 25 13:03:21 2013 -0400 21.3 @@ -61,7 +61,7 @@ 21.4 } 21.5 21.6 void GenDCmdArgument::to_string(char* c, char* buf, size_t len) { 21.7 - jio_snprintf(buf, len, "%s", c); 21.8 + jio_snprintf(buf, len, "%s", (c != NULL) ? c : ""); 21.9 } 21.10 21.11 void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) {
22.1 --- a/test/runtime/CDSCompressedKPtrs/XShareAuto.java Fri Sep 20 11:17:04 2013 -0700 22.2 +++ b/test/runtime/CDSCompressedKPtrs/XShareAuto.java Wed Sep 25 13:03:21 2013 -0400 22.3 @@ -33,16 +33,9 @@ 22.4 22.5 public class XShareAuto { 22.6 public static void main(String[] args) throws Exception { 22.7 - if (!Platform.is64bit()) { 22.8 - System.out.println("ObjectAlignmentInBytes for CDS is only " + 22.9 - "supported on 64bit platforms; this plaform is " + 22.10 - System.getProperty("sun.arch.data.model")); 22.11 - System.out.println("Skipping the test"); 22.12 - return; 22.13 - } 22.14 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 22.15 - "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", 22.16 - "-Xshare:dump"); 22.17 + "-server", "-XX:+UnlockDiagnosticVMOptions", 22.18 + "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); 22.19 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 22.20 output.shouldContain("Loading classes to share"); 22.21 output.shouldHaveExitValue(0);