From d19aa4e217e0d4bdf0f9f63cb3a256fb8e754db2 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 3 Dec 2009 14:20:22 -0800 Subject: [PATCH 1/9] 6892265: System.arraycopy unable to reference elements beyond Integer.MAX_VALUE bytes Use size_t type cast to widen int values in typeArrayKlass::copy_array(). Reviewed-by: never, jcoomes --- hotspot/src/share/vm/oops/typeArrayKlass.cpp | 12 ++-- hotspot/test/compiler/6892265/Test.java | 65 ++++++++++++++++++++ 2 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 hotspot/test/compiler/6892265/Test.java diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.cpp b/hotspot/src/share/vm/oops/typeArrayKlass.cpp index 68d67f1ccf6..b9ccd0cbc29 100644 --- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp +++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp @@ -123,16 +123,16 @@ void typeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) { THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); } + // Check zero copy + if (length == 0) + return; // This is an attempt to make the copy_array fast. - // NB: memmove takes care of overlapping memory segments. - // Potential problem: memmove is not guaranteed to be word atomic - // Revisit in Merlin int l2es = log2_element_size(); int ihs = array_header_in_bytes() / wordSize; - char* src = (char*) ((oop*)s + ihs) + (src_pos << l2es); - char* dst = (char*) ((oop*)d + ihs) + (dst_pos << l2es); - memmove(dst, src, length << l2es); + char* src = (char*) ((oop*)s + ihs) + ((size_t)src_pos << l2es); + char* dst = (char*) ((oop*)d + ihs) + ((size_t)dst_pos << l2es); + Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es); } diff --git a/hotspot/test/compiler/6892265/Test.java b/hotspot/test/compiler/6892265/Test.java new file mode 100644 index 00000000000..1b5d6daa9e1 --- /dev/null +++ b/hotspot/test/compiler/6892265/Test.java @@ -0,0 +1,65 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/** + * @test + * @bug 6892265 + * @summary System.arraycopy unable to reference elements beyond Integer.MAX_VALUE bytes + * + * @run main/othervm Test + */ + +public class Test { + static final int NCOPY = 1; + static final int OVERFLOW = 1; + static int[] src2 = new int[NCOPY]; + static int[] dst2; + + static void test() { + int N; + int SIZE; + + N = Integer.MAX_VALUE/4 + OVERFLOW; + System.arraycopy(src2, 0, dst2, N, NCOPY); + System.arraycopy(dst2, N, src2, 0, NCOPY); + } + + public static void main(String[] args) { + try { + dst2 = new int[NCOPY + Integer.MAX_VALUE/4 + OVERFLOW]; + } catch (OutOfMemoryError e) { + System.exit(95); // Not enough memory + } + System.out.println("warmup"); + for (int i=0; i <11000; i++) { + test(); + } + System.out.println("start"); + for (int i=0; i <1000; i++) { + test(); + } + System.out.println("finish"); + } + +} From 8101e71766a29f7bce1eb3757450bf832f927382 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Tue, 19 Jan 2010 16:03:09 -0500 Subject: [PATCH 2/9] 6626217: Fixed loader constraint array handling Loader constraints track array elements, not arrays themselves. Reviewed-by: dcubed, kevinw --- hotspot/src/share/vm/ci/ciEnv.cpp | 24 ---------- .../share/vm/classfile/loaderConstraints.cpp | 27 ----------- .../share/vm/classfile/loaderConstraints.hpp | 3 -- .../share/vm/classfile/systemDictionary.cpp | 45 +++++++++++++------ 4 files changed, 31 insertions(+), 68 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index b0a17b35c2e..d358e65d07f 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -375,30 +375,6 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, return get_object(found_klass)->as_klass(); } - // If we fail to find an array klass, look again for its element type. - // The element type may be available either locally or via constraints. - // In either case, if we can find the element type in the system dictionary, - // we must build an array type around it. The CI requires array klasses - // to be loaded if their element klasses are loaded, except when memory - // is exhausted. - if (sym->byte_at(0) == '[' && - (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { - // We have an unloaded array. - // Build it on the fly if the element class exists. - symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1, - sym->utf8_length()-1, - KILL_COMPILE_ON_FATAL_(fail_type)); - // Get element ciKlass recursively. - ciKlass* elem_klass = - get_klass_by_name_impl(accessing_klass, - get_object(elem_sym)->as_symbol(), - require_local); - if (elem_klass != NULL && elem_klass->is_loaded()) { - // Now make an array for it - return ciObjArrayKlass::make_impl(elem_klass); - } - } - if (require_local) return NULL; // Not yet loaded into the VM, or not governed by loader constraints. // Make a CI representative for it. diff --git a/hotspot/src/share/vm/classfile/loaderConstraints.cpp b/hotspot/src/share/vm/classfile/loaderConstraints.cpp index daaaa327556..906418f1983 100644 --- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp +++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp @@ -334,33 +334,6 @@ klassOop LoaderConstraintTable::find_constrained_klass(symbolHandle name, return NULL; } - -klassOop LoaderConstraintTable::find_constrained_elem_klass(symbolHandle name, - symbolHandle elem_name, - Handle loader, - TRAPS) { - LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); - if (p != NULL) { - assert(p->klass() == NULL, "Expecting null array klass"); - - // The array name has a constraint, but it will not have a class. Check - // each loader for an associated elem - for (int i = 0; i < p->num_loaders(); i++) { - Handle no_protection_domain; - - klassOop k = SystemDictionary::find(elem_name, p->loader(i), no_protection_domain, THREAD); - if (k != NULL) { - // Return the first elem klass found. - return k; - } - } - } - - // No constraints, or else no klass loaded yet. - return NULL; -} - - void LoaderConstraintTable::ensure_loader_constraint_capacity( LoaderConstraintEntry *p, int nfree) { diff --git a/hotspot/src/share/vm/classfile/loaderConstraints.hpp b/hotspot/src/share/vm/classfile/loaderConstraints.hpp index 6928180d22a..f72f0ed6651 100644 --- a/hotspot/src/share/vm/classfile/loaderConstraints.hpp +++ b/hotspot/src/share/vm/classfile/loaderConstraints.hpp @@ -66,9 +66,6 @@ public: // bool is_method, TRAPS) klassOop find_constrained_klass(symbolHandle name, Handle loader); - klassOop find_constrained_elem_klass(symbolHandle name, symbolHandle elem_name, - Handle loader, TRAPS); - // Class loader constraints diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 5598c9fcfb3..ef5368d6126 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -2164,9 +2164,8 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass( // a loader constraint that would require this loader to return the // klass that is already loaded. if (FieldType::is_array(class_name())) { - // Array classes are hard because their klassOops are not kept in the - // constraint table. The array klass may be constrained, but the elem class - // may not be. + // For array classes, their klassOops are not kept in the + // constraint table. The element klassOops are. jint dimension; symbolOop object_key; BasicType t = FieldType::get_array_info(class_name(), &dimension, @@ -2176,8 +2175,9 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass( } else { symbolHandle elem_name(THREAD, object_key); MutexLocker mu(SystemDictionary_lock, THREAD); - klass = constraints()->find_constrained_elem_klass(class_name, elem_name, class_loader, THREAD); + klass = constraints()->find_constrained_klass(elem_name, class_loader); } + // If element class already loaded, allocate array klass if (klass != NULL) { klass = Klass::cast(klass)->array_klass_or_null(dimension); } @@ -2195,22 +2195,38 @@ bool SystemDictionary::add_loader_constraint(symbolHandle class_name, Handle class_loader1, Handle class_loader2, Thread* THREAD) { - unsigned int d_hash1 = dictionary()->compute_hash(class_name, class_loader1); + symbolHandle constraint_name; + if (!FieldType::is_array(class_name())) { + constraint_name = class_name; + } else { + // For array classes, their klassOops are not kept in the + // constraint table. The element classes are. + jint dimension; + symbolOop object_key; + BasicType t = FieldType::get_array_info(class_name(), &dimension, + &object_key, CHECK_(false)); + // primitive types always pass + if (t != T_OBJECT) { + return true; + } else { + constraint_name = symbolHandle(THREAD, object_key); + } + } + unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1); int d_index1 = dictionary()->hash_to_index(d_hash1); - unsigned int d_hash2 = dictionary()->compute_hash(class_name, class_loader2); + unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, class_loader2); int d_index2 = dictionary()->hash_to_index(d_hash2); - { - MutexLocker mu_s(SystemDictionary_lock, THREAD); + MutexLocker mu_s(SystemDictionary_lock, THREAD); - // Better never do a GC while we're holding these oops - No_Safepoint_Verifier nosafepoint; + // Better never do a GC while we're holding these oops + No_Safepoint_Verifier nosafepoint; - klassOop klass1 = find_class(d_index1, d_hash1, class_name, class_loader1); - klassOop klass2 = find_class(d_index2, d_hash2, class_name, class_loader2); - return constraints()->add_entry(class_name, klass1, class_loader1, - klass2, class_loader2); + klassOop klass1 = find_class(d_index1, d_hash1, constraint_name, class_loader1); + klassOop klass2 = find_class(d_index2, d_hash2, constraint_name, class_loader2); + return constraints()->add_entry(constraint_name, klass1, class_loader1, + klass2, class_loader2); } } @@ -2287,6 +2303,7 @@ symbolOop SystemDictionary::find_resolution_error(constantPoolHandle pool, int w // Returns the name of the type that failed a loader constraint check, or // NULL if no constraint failed. The returned C string needs cleaning up // with a ResourceMark in the caller. No exception except OOME is thrown. +// Arrays are not added to the loader constraint table, their elements are. char* SystemDictionary::check_signature_loaders(symbolHandle signature, Handle loader1, Handle loader2, bool is_method, TRAPS) { From 0ebcf0d492571bd2ee2dee35d930170a11a35847 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 21 Jan 2010 10:07:59 -0800 Subject: [PATCH 3/9] 6894807: No ClassCastException for HashAttributeSet constructors if run with -Xcomp Return interface klass type if it is exact. Reviewed-by: never --- hotspot/src/share/vm/opto/cfgnode.cpp | 1 + hotspot/src/share/vm/opto/type.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index b1da1c716d9..383f4f8c989 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -956,6 +956,7 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const { } if( jtkp && ttkp ) { if( jtkp->is_loaded() && jtkp->klass()->is_interface() && + !jtkp->klass_is_exact() && // Keep exact interface klass (6894807) ttkp->is_loaded() && !ttkp->klass()->is_interface() ) { assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) || ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), ""); diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index c22d1e8f6b0..30883d37dc3 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -2545,12 +2545,15 @@ const Type *TypeOopPtr::filter( const Type *kills ) const { ftip->is_loaded() && ftip->klass()->is_interface() && ktip->is_loaded() && !ktip->klass()->is_interface()) { // Happens in a CTW of rt.jar, 320-341, no extra flags + assert(!ftip->klass_is_exact(), "interface could not be exact"); return ktip->cast_to_ptr_type(ftip->ptr()); } + // Interface klass type could be exact in opposite to interface type, + // return it here instead of incorrect Constant ptr J/L/Object (6894807). if (ftkp != NULL && ktkp != NULL && ftkp->is_loaded() && ftkp->klass()->is_interface() && + !ftkp->klass_is_exact() && // Keep exact interface klass ktkp->is_loaded() && !ktkp->klass()->is_interface()) { - // Happens in a CTW of rt.jar, 320-341, no extra flags return ktkp->cast_to_ptr_type(ftkp->ptr()); } From a4d7c77789ad1e0b327d9863c229d8f82ee1c038 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 12 Mar 2010 15:22:50 -0800 Subject: [PATCH 4/9] 6934712: run langtools jtreg tests from top level test/Makefile Reviewed-by: ohair --- test/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Makefile b/test/Makefile index bf9a4a1daf0..0888529a92b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -49,7 +49,7 @@ fi endef # Test target list for langtools repository -LANGTOOLS_TEST_LIST = langtools_all +LANGTOOLS_TEST_LIST = langtools_jtreg # Test target list for jdk repository JDK_TEST_LIST = \ @@ -74,7 +74,7 @@ all: $(JDK_TEST_LIST) $(LANGTOOLS_TEST_LIST) # Test targets $(LANGTOOLS_TEST_LIST): - @$(call SUBDIR_TEST, $(LANGTOOLS_DIR), all) + @$(call SUBDIR_TEST, $(LANGTOOLS_DIR), $(subst langtools_,,$@)) $(JDK_TEST_LIST): @$(call SUBDIR_TEST, $(JDK_DIR), $@) From c21467f5549f69b5bc4067b624dd7de900017458 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Fri, 12 Mar 2010 17:44:50 -0800 Subject: [PATCH 5/9] 6934759: Add langtools testing to jprt control builds Reviewed-by: jjg --- make/jprt.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/jprt.properties b/make/jprt.properties index f08ea270041..54d64ae3b6a 100644 --- a/make/jprt.properties +++ b/make/jprt.properties @@ -62,6 +62,7 @@ jprt.test.targets= \ # Test targets in test/Makefile jprt.make.rule.test.targets= \ + *-product-*-langtools_jtreg, \ *-product-*-jdk_beans1, \ *-product-*-jdk_beans2, \ *-product-*-jdk_beans3, \ @@ -84,7 +85,6 @@ jprt.make.rule.test.targets= \ *-product-*-jdk_util # Not Ready Yet: -# *-product-*-langtools_all # *-product-*-jdk_awt # *-product-*-jdk_rmi # *-product-*-jdk_swing From d8ec45338281f546ce845d87e0782eb53f6912e4 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Mon, 15 Mar 2010 15:51:36 -0400 Subject: [PATCH 6/9] 6932480: Fix crash in CompilerThread/Parser. Unloaded array klass? Restore code deleted in 6626217 Reviewed-by: asaha, kevinw --- hotspot/src/share/vm/ci/ciEnv.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index d358e65d07f..7ac5b275dae 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -370,6 +370,30 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, KILL_COMPILE_ON_FATAL_(fail_type)); } + // If we fail to find an array klass, look again for its element type. + // The element type may be available either locally or via constraints. + // In either case, if we can find the element type in the system dictionary, + // we must build an array type around it. The CI requires array klasses + // to be loaded if their element klasses are loaded, except when memory + // is exhausted. + if (sym->byte_at(0) == '[' && + (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { + // We have an unloaded array. + // Build it on the fly if the element class exists. + symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1, + sym->utf8_length()-1, + KILL_COMPILE_ON_FATAL_(fail_type)); + // Get element ciKlass recursively. + ciKlass* elem_klass = + get_klass_by_name_impl(accessing_klass, + get_object(elem_sym)->as_symbol(), + require_local); + if (elem_klass != NULL && elem_klass->is_loaded()) { + // Now make an array for it + return ciObjArrayKlass::make_impl(elem_klass); + } + } + if (found_klass != NULL) { // Found it. Build a CI handle. return get_object(found_klass)->as_klass(); From 235a0d94bdc997dc9ecfdf73ca3a4553253bbe3f Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Fri, 19 Mar 2010 18:17:49 -0700 Subject: [PATCH 7/9] 6936788: Minor adjustment to top repo test/Makefile, missing non-zero exit case Reviewed-by: jjg --- test/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Makefile b/test/Makefile index 0888529a92b..00e532eda8f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -42,6 +42,7 @@ if [ -d $1 ] ; then \ $(MAKE) -C $1/test $2 ; \ else \ echo "ERROR: File does not exist: $1/test/Makefile"; \ + exit 1; \ fi; \ else \ echo "WARNING: No testing done, directory does not exist: $1"; \ From 27f4cf5d08e8bc8e63663a6f64ca1e08c800361f Mon Sep 17 00:00:00 2001 From: Michael Wilkerson Date: Thu, 8 Apr 2010 17:02:36 -0700 Subject: [PATCH 8/9] Added tag jdk7-b88 for changeset 9c9bfe8f3a47 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 5dae6b2da6d..4713fd46342 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -62,3 +62,4 @@ e1176f86805fe07fd9fb9da065dc51b47712ce76 jdk7-b82 cf26288a114be67c39f2758959ce50b60f5ae330 jdk7-b85 433a60a9c0bf1b26ee7e65cebaa89c541f497aed jdk7-b86 6b1069f53fbc30663ccef49d78c31bb7d6967bde jdk7-b87 +82135c848d5fcddb065e98ae77b81077c858f593 jdk7-b88 From 9e32cd0837817ac975b494b70eae7f69b71944e8 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson Date: Thu, 8 Apr 2010 17:02:41 -0700 Subject: [PATCH 9/9] Added tag jdk7-b88 for changeset 0c79cc0b79fd --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index df06313deca..76dc8e725d3 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -86,3 +86,4 @@ ffc8d176b84bcfb5ac21302b4feb3b0c0d69b97c jdk7-b84 bf823ef06b4f211e66988d76a2e2669be5c0820e jdk7-b86 07226e9eab8f74b37346b32715f829a2ef2c3188 hs18-b01 e7e7e36ccdb5d56edd47e5744351202d38f3b7ad jdk7-b87 +4b60f23c42231f7ecd62ad1fcb6a9ca26fa57d1b jdk7-b88