OpenJDK / jdk / jdk
changeset 40653:bf64831e7e73
Merge
author | iveresov |
---|---|
date | Fri, 19 Aug 2016 18:48:25 -0700 |
parents | 9e6d111b4089 0e8df237a83e |
children | d4f8e348420a e15f80121414 |
files | jdk/src/java.base/share/classes/java/lang/reflect/AbstractClassLoaderValue.java jdk/src/java.base/share/classes/java/lang/reflect/ClassLoaderValue.java jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java jdk/test/java/lang/reflect/ClassLoaderValue/Driver.java jdk/test/java/lang/reflect/ClassLoaderValue/java.base/java/lang/reflect/ClassLoaderValueTest.java langtools/make/intellij/runConfigurations/jtreg__debug_.xml langtools/make/intellij/runConfigurations/jtreg__run_.xml langtools/make/intellij/utils/jtreg-live-templates.xml langtools/test/jdk/javadoc/tool/sourceOnly/p/NonSource.class langtools/test/tools/javac/defaultMethods/static/StaticInvoke.java langtools/test/tools/javac/defaultMethods/static/StaticInvoke6.out langtools/test/tools/javac/defaultMethods/static/StaticInvoke7.out langtools/test/tools/javac/generics/diamond/neg/Neg09.java langtools/test/tools/javac/generics/diamond/neg/Neg09.out |
diffstat | 710 files changed, 22619 insertions(+), 12191 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Fri Aug 19 14:33:52 2016 -0700 +++ b/.hgtags Fri Aug 19 18:48:25 2016 -0700 @@ -374,3 +374,4 @@ e8373543a3f0f60589b7d72b1f9b172721124caf jdk-9+129 e613affb88d178dc7c589f1679db113d589bddb4 jdk-9+130 4d2a15091124488080d65848b704e25599b2aaeb jdk-9+131 +2e83d21d78cd9c1d52e6cd2599e9c8aa36ea1f52 jdk-9+132
--- a/.hgtags-top-repo Fri Aug 19 14:33:52 2016 -0700 +++ b/.hgtags-top-repo Fri Aug 19 18:48:25 2016 -0700 @@ -374,3 +374,4 @@ f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129 d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130 8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131 +a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
--- a/common/autoconf/spec.gmk.in Fri Aug 19 14:33:52 2016 -0700 +++ b/common/autoconf/spec.gmk.in Fri Aug 19 18:48:25 2016 -0700 @@ -251,8 +251,6 @@ # Legacy support USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@ -MACOSX_UNIVERSAL=@MACOSX_UNIVERSAL@ - # JDK_OUTPUTDIR specifies where a working jvm is built. # You can run $(JDK_OUTPUTDIR)/bin/java # Though the layout of the contents of $(JDK_OUTPUTDIR) is not
--- a/corba/.hgtags Fri Aug 19 14:33:52 2016 -0700 +++ b/corba/.hgtags Fri Aug 19 18:48:25 2016 -0700 @@ -374,3 +374,4 @@ c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129 77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130 f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131 +1ab4b9399c4cba584f66c1c088188f2f565fbf9c jdk-9+132
--- a/corba/src/java.corba/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/corba/src/java.corba/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Java binding of the OMG CORBA APIs, and the RMI-IIOP API. + */ module java.corba { requires public java.desktop; requires public java.rmi;
--- a/hotspot/.hgtags Fri Aug 19 14:33:52 2016 -0700 +++ b/hotspot/.hgtags Fri Aug 19 18:48:25 2016 -0700 @@ -534,3 +534,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129 7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130 943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131 +713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
--- a/hotspot/src/share/vm/prims/jvmti.xml Fri Aug 19 14:33:52 2016 -0700 +++ b/hotspot/src/share/vm/prims/jvmti.xml Fri Aug 19 18:48:25 2016 -0700 @@ -7152,15 +7152,19 @@ returns <code>JNI_FALSE</code>) the class can be neither redefined nor retransformed. <p/> - Primitive classes (for example, <code>java.lang.Integer.TYPE</code>) - and array classes are never modifiable. + Primitive classes (for example, <code>java.lang.Integer.TYPE</code>), + array classes, and some implementation defined classes are never modifiable. <p/> </description> <origin>new</origin> <capabilities> <capability id="can_redefine_any_class"> - If possessed then all classes (except primitive and array classes) - are modifiable. + If possessed then all classes (except primitive, array, and some implementation defined + classes) are modifiable (redefine or retransform). + </capability> + <capability id="can_retransform_any_class"> + If possessed then all classes (except primitive, array, and some implementation defined + classes) are modifiable with <functionlink id="RetransformClasses"/>. </capability> <capability id="can_redefine_classes"> No effect on the result of the function. @@ -9900,7 +9904,7 @@ </capabilityfield> <capabilityfield id="can_redefine_any_class"> <description> - Can modify (retransform or redefine) any non-primitive non-array class. + Can modify (retransform or redefine) any modifiable class. See <functionlink id="IsModifiableClass"/>. </description> </capabilityfield> @@ -10024,7 +10028,8 @@ </capabilityfield> <capabilityfield id="can_retransform_any_class" since="1.1"> <description> - <functionlink id="RetransformClasses"/> can be called on any class + <functionlink id="RetransformClasses"/> can be called on any modifiable class. + See <functionlink id="IsModifiableClass"/>. (<fieldlink id="can_retransform_classes" struct="jvmtiCapabilities"/> must also be set) </description> @@ -12494,8 +12499,8 @@ Otherwise, this event may be sent before the VM is initialized (the start <functionlink id="GetPhase">phase</functionlink>). Some classes might not be compatible - with the function (eg. ROMized classes) and this event will not be - generated for these classes. + with the function (eg. ROMized classes or implementation defined classes) and this event will + not be generated for these classes. <p/> The agent must allocate the space for the modified class file data buffer @@ -14498,6 +14503,10 @@ - Add new capability can_generate_early_class_hook_events - Add new function GetNamedModule </change> + <change date="16 August 2016" version="9.0.0"> + Clarified can_redefine_any_classes, can_retransform_any_classes and IsModifiableClass API to + disallow some implementation defined classes. + </change> </changehistory> </specification>
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Fri Aug 19 14:33:52 2016 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Fri Aug 19 18:48:25 2016 -0700 @@ -283,7 +283,7 @@ return JVMTI_ERROR_INVALID_CLASS; } - if (java_lang_Class::is_primitive(k_mirror)) { + if (!VM_RedefineClasses::is_modifiable_class(k_mirror)) { return JVMTI_ERROR_UNMODIFIABLE_CLASS; } @@ -294,9 +294,6 @@ if (status & (JVMTI_CLASS_STATUS_ERROR)) { return JVMTI_ERROR_INVALID_CLASS; } - if (status & (JVMTI_CLASS_STATUS_ARRAY)) { - return JVMTI_ERROR_UNMODIFIABLE_CLASS; - } instanceKlassHandle ikh(current_thread, k_oop); if (ikh->get_cached_class_file_bytes() == NULL) {
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Aug 19 14:33:52 2016 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Aug 19 18:48:25 2016 -0700 @@ -130,7 +130,7 @@ } oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); - // classes for primitives and arrays cannot be redefined + // classes for primitives and arrays and vm anonymous classes cannot be redefined // check here so following code can assume these classes are InstanceKlass if (!is_modifiable_class(mirror)) { _res = JVMTI_ERROR_UNMODIFIABLE_CLASS; @@ -250,9 +250,14 @@ if (java_lang_Class::is_primitive(klass_mirror)) { return false; } - Klass* the_class_oop = java_lang_Class::as_Klass(klass_mirror); + Klass* k = java_lang_Class::as_Klass(klass_mirror); // classes for arrays cannot be redefined - if (the_class_oop == NULL || !the_class_oop->is_instance_klass()) { + if (k == NULL || !k->is_instance_klass()) { + return false; + } + + // Cannot redefine or retransform an anonymous class. + if (InstanceKlass::cast(k)->is_anonymous()) { return false; } return true;
--- a/hotspot/src/share/vm/utilities/bitMap.cpp Fri Aug 19 14:33:52 2016 -0700 +++ b/hotspot/src/share/vm/utilities/bitMap.cpp Fri Aug 19 18:48:25 2016 -0700 @@ -376,77 +376,99 @@ par_put_range_within_word(bit_index(end_full_word), end, value); } +inline bm_word_t tail_mask(idx_t tail_bits) { + assert(tail_bits != 0, "precondition"); // Works, but shouldn't be called. + assert(tail_bits < (idx_t)BitsPerWord, "precondition"); + return (bm_word_t(1) << tail_bits) - 1; +} + +// Get the low tail_bits of value, which is the last partial word of a map. +inline bm_word_t tail_of_map(bm_word_t value, idx_t tail_bits) { + return value & tail_mask(tail_bits); +} + +// Compute the new last word of a map with a non-aligned length. +// new_value has the new trailing bits of the map in the low tail_bits. +// old_value is the last word of the map, including bits beyond the end. +// Returns old_value with the low tail_bits replaced by the corresponding +// bits in new_value. +inline bm_word_t merge_tail_of_map(bm_word_t new_value, + bm_word_t old_value, + idx_t tail_bits) { + bm_word_t mask = tail_mask(tail_bits); + return (new_value & mask) | (old_value & ~mask); +} + bool BitMap::contains(const BitMap& other) const { assert(size() == other.size(), "must have same size"); const bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size_in_words(); index++) { - bm_word_t word_union = dest_map[index] | other_map[index]; - // If this has more bits set than dest_map[index], then other is not a - // subset. - if (word_union != dest_map[index]) return false; + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + // false if other bitmap has bits set which are clear in this bitmap. + if ((~dest_map[index] & other_map[index]) != 0) return false; } - return true; + idx_t rest = bit_in_word(size()); + // true unless there is a partial-word tail in which the other + // bitmap has bits set which are clear in this bitmap. + return (rest == 0) || tail_of_map(~dest_map[limit] & other_map[limit], rest) == 0; } bool BitMap::intersects(const BitMap& other) const { assert(size() == other.size(), "must have same size"); const bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size_in_words(); index++) { + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { if ((dest_map[index] & other_map[index]) != 0) return true; } - // Otherwise, no intersection. - return false; + idx_t rest = bit_in_word(size()); + // false unless there is a partial-word tail with non-empty intersection. + return (rest > 0) && tail_of_map(dest_map[limit] & other_map[limit], rest) != 0; } void BitMap::set_union(const BitMap& other) { assert(size() == other.size(), "must have same size"); bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size_in_words(); index++) { - dest_map[index] = dest_map[index] | other_map[index]; + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + dest_map[index] |= other_map[index]; + } + idx_t rest = bit_in_word(size()); + if (rest > 0) { + bm_word_t orig = dest_map[limit]; + dest_map[limit] = merge_tail_of_map(orig | other_map[limit], orig, rest); } } - void BitMap::set_difference(const BitMap& other) { assert(size() == other.size(), "must have same size"); bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size_in_words(); index++) { - dest_map[index] = dest_map[index] & ~(other_map[index]); + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + dest_map[index] &= ~other_map[index]; + } + idx_t rest = bit_in_word(size()); + if (rest > 0) { + bm_word_t orig = dest_map[limit]; + dest_map[limit] = merge_tail_of_map(orig & ~other_map[limit], orig, rest); } } - void BitMap::set_intersection(const BitMap& other) { assert(size() == other.size(), "must have same size"); bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size; index++) { - dest_map[index] = dest_map[index] & other_map[index]; + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + dest_map[index] &= other_map[index]; } -} - - -void BitMap::set_intersection_at_offset(const BitMap& other, idx_t offset) { - assert(other.size() >= offset, "offset not in range"); - assert(other.size() - offset >= size(), "other not large enough"); - // XXX Ideally, we would remove this restriction. - guarantee((offset % (sizeof(bm_word_t) * BitsPerByte)) == 0, - "Only handle aligned cases so far."); - bm_word_t* dest_map = map(); - const bm_word_t* other_map = other.map(); - idx_t offset_word_ind = word_index(offset); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size; index++) { - dest_map[index] = dest_map[index] & other_map[offset_word_ind + index]; + idx_t rest = bit_in_word(size()); + if (rest > 0) { + bm_word_t orig = dest_map[limit]; + dest_map[limit] = merge_tail_of_map(orig & other_map[limit], orig, rest); } } @@ -455,88 +477,111 @@ bool changed = false; bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size; index++) { - idx_t temp = dest_map[index] | other_map[index]; - changed = changed || (temp != dest_map[index]); + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + bm_word_t orig = dest_map[index]; + bm_word_t temp = orig | other_map[index]; + changed = changed || (temp != orig); dest_map[index] = temp; } + idx_t rest = bit_in_word(size()); + if (rest > 0) { + bm_word_t orig = dest_map[limit]; + bm_word_t temp = merge_tail_of_map(orig | other_map[limit], orig, rest); + changed = changed || (temp != orig); + dest_map[limit] = temp; + } return changed; } - bool BitMap::set_difference_with_result(const BitMap& other) { assert(size() == other.size(), "must have same size"); bool changed = false; bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size; index++) { - bm_word_t temp = dest_map[index] & ~(other_map[index]); - changed = changed || (temp != dest_map[index]); + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + bm_word_t orig = dest_map[index]; + bm_word_t temp = orig & ~other_map[index]; + changed = changed || (temp != orig); dest_map[index] = temp; } + idx_t rest = bit_in_word(size()); + if (rest > 0) { + bm_word_t orig = dest_map[limit]; + bm_word_t temp = merge_tail_of_map(orig & ~other_map[limit], orig, rest); + changed = changed || (temp != orig); + dest_map[limit] = temp; + } return changed; } - bool BitMap::set_intersection_with_result(const BitMap& other) { assert(size() == other.size(), "must have same size"); bool changed = false; bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size; index++) { + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { bm_word_t orig = dest_map[index]; bm_word_t temp = orig & other_map[index]; changed = changed || (temp != orig); - dest_map[index] = temp; + dest_map[index] = temp; + } + idx_t rest = bit_in_word(size()); + if (rest > 0) { + bm_word_t orig = dest_map[limit]; + bm_word_t temp = merge_tail_of_map(orig & other_map[limit], orig, rest); + changed = changed || (temp != orig); + dest_map[limit] = temp; } return changed; } - void BitMap::set_from(const BitMap& other) { assert(size() == other.size(), "must have same size"); bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size; index++) { - dest_map[index] = other_map[index]; + idx_t copy_words = word_index(size()); + Copy::disjoint_words((HeapWord*)other_map, (HeapWord*)dest_map, copy_words); + idx_t rest = bit_in_word(size()); + if (rest > 0) { + dest_map[copy_words] = merge_tail_of_map(other_map[copy_words], + dest_map[copy_words], + rest); } } - -bool BitMap::is_same(const BitMap& other) { +bool BitMap::is_same(const BitMap& other) const { assert(size() == other.size(), "must have same size"); - bm_word_t* dest_map = map(); + const bm_word_t* dest_map = map(); const bm_word_t* other_map = other.map(); - idx_t size = size_in_words(); - for (idx_t index = 0; index < size; index++) { + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { if (dest_map[index] != other_map[index]) return false; } - return true; + idx_t rest = bit_in_word(size()); + return (rest == 0) || (tail_of_map(dest_map[limit] ^ other_map[limit], rest) == 0); } bool BitMap::is_full() const { - const bm_word_t* word = map(); - idx_t rest = size(); - for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) { - if (*word != ~(bm_word_t)0) return false; - word++; + const bm_word_t* words = map(); + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + if (~words[index] != 0) return false; } - return rest == 0 || (*word | ~right_n_bits((int)rest)) == ~(bm_word_t)0; + idx_t rest = bit_in_word(size()); + return (rest == 0) || (tail_of_map(~words[limit], rest) == 0); } - bool BitMap::is_empty() const { - const bm_word_t* word = map(); - idx_t rest = size(); - for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) { - if (*word != 0) return false; - word++; + const bm_word_t* words = map(); + idx_t limit = word_index(size()); + for (idx_t index = 0; index < limit; ++index) { + if (words[index] != 0) return false; } - return rest == 0 || (*word & right_n_bits((int)rest)) == 0; + idx_t rest = bit_in_word(size()); + return (rest == 0) || (tail_of_map(words[limit], rest) == 0); } void BitMap::clear_large() {
--- a/hotspot/src/share/vm/utilities/bitMap.hpp Fri Aug 19 14:33:52 2016 -0700 +++ b/hotspot/src/share/vm/utilities/bitMap.hpp Fri Aug 19 18:48:25 2016 -0700 @@ -284,18 +284,9 @@ bool set_difference_with_result(const BitMap& bits); bool set_intersection_with_result(const BitMap& bits); - // Requires the submap of "bits" starting at offset to be at least as - // large as "this". Modifies "this" to be the intersection of its - // current contents and the submap of "bits" starting at "offset" of the - // same length as "this." - // (For expedience, currently requires the offset to be aligned to the - // bitsize of a uintptr_t. This should go away in the future though it - // will probably remain a good case to optimize.) - void set_intersection_at_offset(const BitMap& bits, idx_t offset); - void set_from(const BitMap& bits); - bool is_same(const BitMap& bits); + bool is_same(const BitMap& bits) const; // Test if all bits are set or cleared bool is_full() const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/native/utilities/test_bitMap_setops.cpp Fri Aug 19 18:48:25 2016 -0700 @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "utilities/bitMap.inline.hpp" +#include "utilities/copy.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" +#include <stdlib.h> +#include "unittest.hpp" + +typedef BitMap::idx_t idx_t; +typedef BitMap::bm_word_t bm_word_t; + +class BitMapMemory { +private: + idx_t _words; + bm_word_t* _memory; + +public: + BitMapMemory(idx_t bits) : + _words(BitMap::calc_size_in_words(bits)), + _memory(static_cast<bm_word_t*>(malloc(_words * sizeof(bm_word_t)))) + { } + + ~BitMapMemory() { + free(_memory); + } + + BitMapView make_view(idx_t bits, bm_word_t value) { + vmassert(BitMap::calc_size_in_words(bits) <= _words, "invalid request"); + STATIC_ASSERT(sizeof(bm_word_t) == sizeof(HeapWord)); + Copy::fill_to_aligned_words((HeapWord*)_memory, _words, value); + return BitMapView(_memory, bits); + } + + bm_word_t* memory() { return _memory; } +}; + +const idx_t aligned_size = 4 * BitsPerWord; +const idx_t unaligned_size = aligned_size - (BitsPerWord / 2); + +static bm_word_t make_even_bits() { + bm_word_t result = 1; + while (true) { + bm_word_t next = (result << 2) | 1; + if (next == result) { + return result; + } + result = next; + } +} + +const bm_word_t even_bits = make_even_bits(); +const bm_word_t odd_bits = ~even_bits; +const bm_word_t one_bits = ~bm_word_t(0); +const bm_word_t zero_bits = 0; + +// Scoped set a clear bit and restore to clear. +class WithBitSet { +private: + BitMap& _bm; + idx_t _index; + +public: + WithBitSet(BitMap& bm, idx_t index) : _bm(bm), _index(index) { + // Failure may indicate test bug; can't use ASSERT_xxx in constructor. + EXPECT_FALSE(_bm.at(_index)); + bm.set_bit(_index); + } + + ~WithBitSet() { + _bm.clear_bit(_index); + } +}; + +// Scoped clear a set bit and restore to set. +class WithBitClear { +private: + BitMap& _bm; + idx_t _index; + +public: + WithBitClear(BitMap& bm, idx_t index) : _bm(bm), _index(index) { + // Failure may indicate test bug; can't use ASSERT_xxx in constructor. + EXPECT_TRUE(_bm.at(_index)); + bm.clear_bit(_index); + } + + ~WithBitClear() { + _bm.set_bit(_index); + } +}; + +////////////////////////////////////////////////////////////////////////////// +// bool is_same(const BitMap& bits); + +TEST(BitMap, is_same__aligned) { + BitMapMemory mx(aligned_size); + BitMapMemory my(aligned_size); + + BitMapView x = mx.make_view(aligned_size, even_bits); + BitMapView y = my.make_view(aligned_size, even_bits); + EXPECT_TRUE(x.is_same(y)); + + WithBitClear wbc(x, aligned_size / 2); + EXPECT_FALSE(x.is_same(y)); +} + +TEST(BitMap, is_same__unaligned) { + BitMapMemory mx(aligned_size); + BitMapMemory my(aligned_size); + + BitMapView x = mx.make_view(unaligned_size, even_bits); + BitMapView y = my.make_view(unaligned_size, even_bits); + + // Check that a difference beyond the end of x/y doesn't count. + { + BitMapView aligned = BitMapView(mx.memory(), aligned_size); + const idx_t index = aligned_size - 2; + STATIC_ASSERT(unaligned_size <= index); + + WithBitClear wbc(aligned, index); + EXPECT_TRUE(x.is_same(y)); + } + + // Check that a difference in the final partial word does count. + { + idx_t index = unaligned_size - 2; + ASSERT_LE(BitMap::word_align_down(unaligned_size), index); + + WithBitClear wbc(y, index); + EXPECT_FALSE(x.is_same(y)); + } +} + +////////////////////////////////////////////////////////////////////////////// +// bool is_full(); +// bool is_empty(); + +TEST(BitMap, is_full_or_empty__aligned) { + BitMapMemory mx(aligned_size); + + { + BitMapView x = mx.make_view(aligned_size, even_bits); + EXPECT_FALSE(x.is_full()); + EXPECT_FALSE(x.is_empty()); + } + + { + BitMapView x = mx.make_view(aligned_size, zero_bits); + EXPECT_FALSE(x.is_full()); + EXPECT_TRUE(x.is_empty()); + } + + { + BitMapView x = mx.make_view(aligned_size, one_bits); + EXPECT_TRUE(x.is_full()); + EXPECT_FALSE(x.is_empty()); + } +} + +TEST(BitMap, is_full__unaligned) { + BitMapMemory mx(aligned_size); + + BitMapView x = mx.make_view(unaligned_size, one_bits); + EXPECT_TRUE(x.is_full()); + + // Check that a missing bit beyond the end doesn't count. + { + idx_t index = aligned_size - 1; + BitMapView aligned = BitMapView(mx.memory(), aligned_size); + + WithBitClear wcb(aligned, index); + EXPECT_FALSE(aligned.is_full()); + EXPECT_TRUE(x.is_full()); + } + + // Check that a missing bit in the final partial word does count. + { + WithBitClear wcb(x, unaligned_size - 1); + EXPECT_FALSE(x.is_full()); + } +} + +TEST(BitMap, is_empty__unaligned) { + BitMapMemory mx(aligned_size); + + BitMapView x = mx.make_view(unaligned_size, zero_bits); + EXPECT_TRUE(x.is_empty()); + + // Check that a set bit beyond the end doesn't count. + { + idx_t index = aligned_size - 1; + BitMapView aligned = BitMapView(mx.memory(), aligned_size); + + WithBitSet wbs(aligned, index); + EXPECT_FALSE(aligned.is_empty()); + EXPECT_TRUE(x.is_empty()); + } + + // Check that a set bit in the final partial word does count. + { + WithBitSet wbs(x, unaligned_size - 1); + EXPECT_FALSE(x.is_empty()); + } +} + +////////////////////////////////////////////////////////////////////////////// +// bool contains(const BitMap& bits); + +TEST(BitMap, contains__aligned) { + BitMapMemory mx(aligned_size); + BitMapMemory my(aligned_size); + + BitMapView x = mx.make_view(aligned_size, even_bits); + BitMapView y = my.make_view(aligned_size, even_bits); + EXPECT_TRUE(x.contains(y)); + + WithBitClear wbc(x, aligned_size / 2); + EXPECT_FALSE(x.contains(y)); +} + +TEST(BitMap, contains__unaligned) { + BitMapMemory mx(aligned_size); + BitMapMemory my(aligned_size); + + BitMapView x = mx.make_view(unaligned_size, even_bits); + BitMapView y = my.make_view(unaligned_size, even_bits); + + // Check that a missing bit beyond the end of x doesn't count. + { + BitMapView aligned = BitMapView(mx.memory(), aligned_size); + const idx_t index = aligned_size - 2; + STATIC_ASSERT(unaligned_size <= index); + + WithBitClear wbc(aligned, index); + EXPECT_TRUE(x.contains(y)); + } + + // Check that a missing bit in the final partial word does count. + { + idx_t index = unaligned_size - 2; + ASSERT_LE(BitMap::word_align_down(unaligned_size), index); + + WithBitClear wbc(x, index); + EXPECT_FALSE(x.contains(y)); + } +} + +////////////////////////////////////////////////////////////////////////////// +// bool intersects(const BitMap& bits); + +TEST(BitMap, intersects__aligned) { + BitMapMemory mx(aligned_size); + BitMapMemory my(aligned_size); + + BitMapView x = mx.make_view(aligned_size, even_bits); + BitMapView y = my.make_view(aligned_size, zero_bits); + EXPECT_FALSE(x.intersects(y)); + + ASSERT_TRUE(x.at(aligned_size / 2)); + WithBitSet wbs(y, aligned_size / 2); + EXPECT_TRUE(x.intersects(y)); +} + +TEST(BitMap, intersects__unaligned) { + BitMapMemory mx(aligned_size); + BitMapMemory my(aligned_size); + + BitMapView x = mx.make_view(unaligned_size, even_bits); + BitMapView y = my.make_view(unaligned_size, zero_bits); + EXPECT_FALSE(x.intersects(y)); + + // Check that adding a bit beyond the end of y doesn't count. + { + BitMapView aligned_x = BitMapView(mx.memory(), aligned_size); + BitMapView aligned_y = BitMapView(my.memory(), aligned_size); + const idx_t index = aligned_size - 2; + STATIC_ASSERT(unaligned_size <= index); + ASSERT_TRUE(aligned_x.at(index)); + + WithBitSet wbs(aligned_y, index); + EXPECT_FALSE(x.intersects(y)); + } + + // Check that adding a bit in the final partial word does count. + { + idx_t index = unaligned_size - 2; + ASSERT_LE(BitMap::word_align_down(unaligned_size), index); + ASSERT_TRUE(x.at(index)); + + WithBitSet wbs(y, index); + EXPECT_TRUE(x.intersects(y)); + } +} + +////////////////////////////////////////////////////////////////////////////// +// void set_from(const BitMap& bits); +// void set_union(const BitMap& bits); +// void set_difference(const BitMap& bits); +// void set_intersection(const BitMap& bits); +// +// bool set_union_with_result(const BitMap& bits); +// bool set_difference_with_result(const BitMap& bits); +// bool set_intersection_with_result(const BitMap& bits); + +static void check_tail_unmodified(BitMapMemory& mem, + idx_t bits, + bm_word_t fill_word) { + if (!BitMap::is_word_aligned(bits)) { + idx_t last_word_bit_index = BitMap::word_align_down(bits); + idx_t last_word_index = BitMap::calc_size_in_words(last_word_bit_index); + bm_word_t last_word = mem.memory()[last_word_index]; + idx_t shift = bits - last_word_bit_index; + EXPECT_EQ(fill_word >> shift, last_word >> shift); + } +} + +static void check_mod_setop(void (BitMap::*f)(const BitMap&), + idx_t bits, + bm_word_t wx, + bm_word_t wy, + bm_word_t wexp) { + BitMapMemory mx(bits); + BitMapMemory my(bits); + BitMapMemory mexp(bits); + + BitMapView x = mx.make_view(bits, wx); + BitMapView y = my.make_view(bits, wy); + BitMapView exp = mexp.make_view(bits, wexp); + + (x.*f)(y); + + EXPECT_TRUE(exp.is_same(x)); + check_tail_unmodified(mx, bits, wx); +} + +static void check_mod_setop_with_result(bool (BitMap::*f)(const BitMap&), + idx_t bits, + bm_word_t wx, + bm_word_t wy, + bm_word_t wexp) { + BitMapMemory mx(bits); + BitMapMemory my(bits); + BitMapMemory mexp(bits); + + BitMapView x = mx.make_view(bits, wx); + BitMapView y = my.make_view(bits, wy); + BitMapView exp = mexp.make_view(bits, wexp); + + bool value = (x.*f)(y); + EXPECT_EQ(value, wx != wexp); + + EXPECT_TRUE(exp.is_same(x)); + check_tail_unmodified(mx, bits, wx); +} + +#define CHECK_MOD_SETOP_AUX(checker, name, x, y, exp) \ + TEST(BitMap, name ## __ ## x ## _ ## y) { \ + checker(&BitMap::name, aligned_size, \ + x ## _bits, y ## _bits, exp ## _bits); \ + checker(&BitMap::name, unaligned_size, \ + x ## _bits, y ## _bits, exp ## _bits); \ + } + +#define CHECK_MOD_SETOP(name, x, y, exp) \ + CHECK_MOD_SETOP_AUX(check_mod_setop, name, x, y, exp) + +#define CHECK_MOD_SETOP_WITH_RESULT(name, x, y, exp) \ + CHECK_MOD_SETOP_AUX(check_mod_setop_with_result, name, x, y, exp) + +#define CHECK_MOD_SETOPS(name, x, y, exp) \ + CHECK_MOD_SETOP(name, x, y, exp) \ + CHECK_MOD_SETOP_WITH_RESULT(name ## _with_result, x, y, exp) + +CHECK_MOD_SETOP(set_from, even, even, even) +CHECK_MOD_SETOP(set_from, even, odd, odd) +CHECK_MOD_SETOP(set_from, even, one, one) +CHECK_MOD_SETOP(set_from, even, zero, zero) + +CHECK_MOD_SETOPS(set_union, even, even, even) +CHECK_MOD_SETOPS(set_union, even, odd, one) +CHECK_MOD_SETOPS(set_union, even, one, one) +CHECK_MOD_SETOPS(set_union, even, zero, even) + +CHECK_MOD_SETOPS(set_difference, even, even, zero) +CHECK_MOD_SETOPS(set_difference, even, odd, even) +CHECK_MOD_SETOPS(set_difference, even, one, zero) +CHECK_MOD_SETOPS(set_difference, even, zero, even) + +CHECK_MOD_SETOPS(set_intersection, even, even, even) +CHECK_MOD_SETOPS(set_intersection, even, odd, zero) +CHECK_MOD_SETOPS(set_intersection, even, one, even) +CHECK_MOD_SETOPS(set_intersection, even, zero, zero) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/RedefineTests/ModifyAnonymous.java Fri Aug 19 18:48:25 2016 -0700 @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @library /test/lib + * @summary Test that retransforming and redefining anonymous classes gets UnmodifiableClassException + * @modules java.base/jdk.internal.misc + * @modules java.instrument + * jdk.jartool/sun.tools.jar + * @run main ModifyAnonymous buildagent + * @run main/othervm -javaagent:redefineagent.jar ModifyAnonymous + */ + +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.lang.NoSuchFieldException; +import java.lang.NoSuchMethodException; +import java.lang.RuntimeException; +import java.lang.instrument.ClassDefinition; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.security.ProtectionDomain; +import jdk.test.lib.*; + +public class ModifyAnonymous { + + public static class LambdaTransformer implements ClassFileTransformer { + @Override + public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) + throws IllegalClassFormatException { + return null; + } + } + + static Instrumentation inst = null; + static volatile boolean done = false; + + public static void premain(String args, Instrumentation instrumentation) { + + inst = instrumentation; + System.out.println("javaagent in da house!"); + instrumentation.addTransformer(new LambdaTransformer()); + } + + private static void buildAgent() { + try { + ClassFileInstaller.main("ModifyAnonymous"); + } catch (Exception e) { + throw new RuntimeException("Could not write agent classfile", e); + } + + try { + PrintWriter pw = new PrintWriter("MANIFEST.MF"); + pw.println("Premain-Class: ModifyAnonymous"); + pw.println("Agent-Class: ModifyAnonymous"); + pw.println("Can-Retransform-Classes: true"); + pw.println("Can-Redefine-Classes: true"); + pw.close(); + } catch (FileNotFoundException e) { + throw new RuntimeException("Could not write manifest file for the agent", e); + } + + sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar"); + if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "ModifyAnonymous.class" })) { + throw new RuntimeException("Could not write the agent jar file"); + } + } + + public static class InstanceMethodCallSiteApp { + + public static void test() throws InterruptedException { + for (int i = 0; i < 2; i++) { + InstanceMethodCallSiteApp app = new InstanceMethodCallSiteApp(); + Runnable r = app::doWork; // this creates an anonymous class + while (!done) { + r.run(); + Thread.sleep(10); + } + } + } + + public void doWork() { + System.out.print("."); + } + } + + static void runTest() { + while (!done) { + Class[] allLoadedClasses = inst.getAllLoadedClasses(); + for (Class clazz : allLoadedClasses) { + final String name = clazz.getName(); + if (name.contains("$$Lambda$") && name.contains("App")) { + if (inst.isModifiableClass(clazz)) { + throw new RuntimeException ("Class should not be modifiable"); + } + // Try to modify them anyway. + try { + System.out.println("retransform called for " + name); + inst.retransformClasses(clazz); + } catch(java.lang.instrument.UnmodifiableClassException t) { + System.out.println("PASSED: expecting UnmodifiableClassException"); + t.printStackTrace(); + } + try { + System.out.println("redefine called for " + name); + String newclass = "class Dummy {}"; + byte[] bytecode = InMemoryJavaCompiler.compile("Dummy", newclass); + ClassDefinition cld = new ClassDefinition(clazz, bytecode); + inst.redefineClasses(new ClassDefinition[] { cld }); + } catch(java.lang.instrument.UnmodifiableClassException t) { + System.out.println("PASSED: expecting UnmodifiableClassException"); + t.printStackTrace(); + } catch(java.lang.ClassNotFoundException e) { + throw new RuntimeException ("ClassNotFoundException thrown"); + } + done = true; + } + } + } + } + + public static void main(String argv[]) throws InterruptedException, RuntimeException { + if (argv.length == 1 && argv[0].equals("buildagent")) { + buildAgent(); + return; + } + + if (inst == null) { + throw new RuntimeException("Instrumentation object was null"); + } + + new Thread() { + public void run() { + runTest(); + } + }.start(); + + // Test that NCDFE is not thrown for anonymous class: + // ModifyAnonymous$InstanceMethodCallSiteApp$$Lambda$18 + try { + ModifyAnonymous test = new ModifyAnonymous(); + InstanceMethodCallSiteApp.test(); + } catch (NoClassDefFoundError e) { + throw new RuntimeException("FAILED: NoClassDefFoundError thrown for " + e.getMessage()); + } + System.out.println("PASSED: NoClassDefFound error not thrown"); + } +}
--- a/jaxp/.hgtags Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/.hgtags Fri Aug 19 18:48:25 2016 -0700 @@ -374,3 +374,4 @@ 74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129 e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130 874082a9b565a7092a40bfa934a6e3e3c3455a60 jdk-9+131 +907445d85e680ea410fe2c83c0ec64b5508e4f3e jdk-9+132
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java Fri Aug 19 18:48:25 2016 -0700 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: XSLTErrorResources.java,v 1.2.4.1 2005/09/13 09:55:37 pvedula Exp $ - */ package com.sun.org.apache.xalan.internal.res; import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Fri Aug 19 18:48:25 2016 -0700 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: ErrorMessages.java,v 1.2.4.1 2005/09/15 09:59:41 pvedula Exp $ - */ package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java Fri Aug 19 18:48:25 2016 -0700 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: ErrorMessages.java,v 1.2.4.1 2005/09/14 05:06:42 pvedula Exp $ - */ package com.sun.org.apache.xalan.internal.xsltc.runtime;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AbortException.java Fri Aug 19 18:48:25 2016 -0700 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xerces.internal.dom; + +public class AbortException extends RuntimeException { + + private static final long serialVersionUID = 2608302175475740417L; + + /** + * Constructor AbortException + */ + public AbortException() { super(null, null, false, false); } +}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java Fri Aug 19 18:48:25 2016 -0700 @@ -26,6 +26,7 @@ import java.io.StringReader; import java.util.Vector; +import com.sun.org.apache.xerces.internal.dom.AbortException; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.RevalidationHandler; import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar; @@ -157,11 +158,6 @@ // attribute value normalization final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0); - /** - * If the user stops the process, this exception will be thrown. - */ - public static final RuntimeException abort = new RuntimeException(); - //DTD validator private XMLDTDValidator fDTDValidator; @@ -242,11 +238,8 @@ XMLGrammarDescription.XML_SCHEMA, fValidationHandler); fValidationHandler = null; } - } - catch (RuntimeException e) { - if( e==abort ) - return; // processing aborted by the user - throw e; // otherwise re-throw. + } catch (AbortException e) { + return; } } @@ -1371,10 +1364,10 @@ error.fRelatedData = locator.fRelatedNode; if(!errorHandler.handleError(error)) - throw abort; + throw new AbortException(); } if( severity==DOMError.SEVERITY_FATAL_ERROR ) - throw abort; + throw new AbortException(); } protected final void updateQName (Node node, QName qname){ @@ -2043,5 +2036,4 @@ return null; } - } // DOMNormalizer class
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages.properties Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages.properties Fri Aug 19 18:48:25 2016 -0700 @@ -2,8 +2,6 @@ # DOM implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: DOMMessages.properties,v 1.2 2005-08-16 22:51:51 jeffsuttor Exp $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DatatypeMessages.properties Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DatatypeMessages.properties Fri Aug 19 18:48:25 2016 -0700 @@ -1,8 +1,6 @@ # This file stores localized messages for the Xerces JAXP Datatype API implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: DatatypeMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/JAXPValidationMessages.properties Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/JAXPValidationMessages.properties Fri Aug 19 18:48:25 2016 -0700 @@ -1,8 +1,6 @@ # This file stores localized messages for the Xerces JAXP Validation API implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: JAXPValidationMessages.properties 3021 2011-03-01 00:12:28Z joehw $ # Messages for message reporting BadMessageKey = The error message corresponding to the message key can not be found.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/SAXMessages.properties Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/SAXMessages.properties Fri Aug 19 18:48:25 2016 -0700 @@ -2,8 +2,6 @@ # SAX implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: SAXMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Fri Aug 19 18:48:25 2016 -0700 @@ -1,7 +1,5 @@ # This file contains error and warning messages related to XML Schema # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: XMLSchemaMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSerializerMessages.properties Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSerializerMessages.properties Fri Aug 19 18:48:25 2016 -0700 @@ -4,8 +4,6 @@ # # As usual with properties files, the messages are arranged in # key/value tuples. -# -# @version $Id: XMLSerializerMessages.properties 3021 2011-03-01 00:12:28Z joehw $ BadMessageKey = The error message corresponding to the message key can not be found. FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XPointerMessages.properties Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XPointerMessages.properties Fri Aug 19 18:48:25 2016 -0700 @@ -1,8 +1,6 @@ # This file stores localized messages for the Xerces XPointer implementation. # # The messages are arranged in key and value tuples in a ListResourceBundle. -# -# @version $Id: XPointerMessages.properties 3021 2011-03-01 00:12:28Z joehw $ # Messages for message reporting BadMessageKey = The error message corresponding to the message key can not be found. @@ -24,4 +22,4 @@ InvalidElementSchemeXPointer = InvalidElementSchemeXPointer: The Element Scheme XPointer expression ''{0}'' is invalid. XPointerElementSchemeProcessingError = XPointerElementSchemeProcessingError: An error occurred while processing the XPointer element() Scheme expression. InvalidNCNameInElementSchemeData = InvalidNCNameInElementSchemeData: The element() Scheme contains a ShortHand Pointer ''{0}'' with an invalid NCName. -InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''. \ No newline at end of file +InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources.java Fri Aug 19 18:48:25 2016 -0700 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: XMLErrorResources.java,v 1.2.4.1 2005/09/15 07:45:37 suresh_emailid Exp $ - */ package com.sun.org.apache.xml.internal.res;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java Fri Aug 19 18:48:25 2016 -0700 @@ -28,6 +28,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; +import com.sun.org.apache.xerces.internal.dom.AbortException; import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl; import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl; @@ -501,11 +502,9 @@ } catch (LSException lse) { // Rethrow LSException. throw lse; + } catch (AbortException e) { + return null; } catch (RuntimeException e) { - if (e == DOMNormalizer.abort) { - // stopped at user request - return null; - } throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); } catch (IOException ioe) { // REVISIT: A generic IOException doesn't provide enough information @@ -733,11 +732,9 @@ } catch (LSException lse) { // Rethrow LSException. throw lse; + } catch (AbortException e) { + return false; } catch (RuntimeException e) { - if (e == DOMNormalizer.abort) { - // stopped at user request - return false; - } throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); } catch (Exception e) { if (ser.fDOMErrorHandler != null) { @@ -833,11 +830,9 @@ } catch (LSException lse) { // Rethrow LSException. throw lse; + } catch (AbortException e) { + return false; } catch (RuntimeException e) { - if (e == DOMNormalizer.abort) { - // stopped at user request - return false; - } throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); } catch (Exception e) { if (ser.fDOMErrorHandler != null) {
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages.java Fri Aug 19 18:48:25 2016 -0700 @@ -19,9 +19,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: SerializerMessages.java,v 1.1.4.1 2005/09/08 11:03:11 suresh_emailid Exp $ - */ package com.sun.org.apache.xml.internal.serializer.utils; import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java Fri Aug 19 18:48:25 2016 -0700 @@ -28,6 +28,7 @@ import com.sun.org.apache.xalan.internal.res.XSLMessages; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xml.internal.dtm.DTM; +import com.sun.org.apache.xpath.internal.axes.LocPathIterator; import com.sun.org.apache.xpath.internal.objects.XObject; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; import java.io.IOException; @@ -73,6 +74,12 @@ XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath) throws javax.xml.transform.TransformerException { com.sun.org.apache.xpath.internal.XPathContext xpathSupport; + if (contextItem == null && xpath.getExpression() instanceof LocPathIterator) { + // the operation must have no dependency on the context that is null + throw new TransformerException(XSLMessages.createXPATHMessage( + XPATHErrorResources.ER_CONTEXT_CAN_NOT_BE_NULL, + new Object[] {})); + } if (functionResolver != null) { JAXPExtensionsProvider jep = new JAXPExtensionsProvider( functionResolver, featureSecureProcessing, featureManager);
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Fri Aug 19 18:48:25 2016 -0700 @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: XPATHErrorResources.java,v 1.2.4.1 2005/09/15 01:29:15 jeffsuttor Exp $ - */ package com.sun.org.apache.xpath.internal.res; import java.util.ListResourceBundle; @@ -93,6 +90,7 @@ public static final String ER_CURRENT_TAKES_NO_ARGS = "ER_CURRENT_TAKES_NO_ARGS"; public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED"; + public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL"; public static final String ER_CONTEXT_HAS_NO_OWNERDOC = "ER_CONTEXT_HAS_NO_OWNERDOC"; public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS = @@ -368,6 +366,9 @@ { ER_DOCUMENT_REPLACED, "document() function implementation has been replaced by com.sun.org.apache.xalan.internal.xslt.FuncDocument!"}, + { ER_CONTEXT_CAN_NOT_BE_NULL, + "The context can not be null when the operation is context-dependent."}, + { ER_CONTEXT_HAS_NO_OWNERDOC, "context does not have an owner document!"},
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. 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 @@ -34,18 +34,20 @@ * * <a name="XPath-evaluation"></a> * <table border="1" cellpadding="2"> - * <thead> - * <tr> - * <th colspan="2">Evaluation of XPath Expressions.</th> - * </tr> - * </thead> - * <tr> - * <td>context</td> - * <td> - * If a request is made to evaluate the expression in the absence - * of a context item, an empty document node will be used for the context. - * For the purposes of evaluating XPath expressions, a DocumentFragment - * is treated like a Document node. + * <thead> + * <tr> + * <th colspan="2">Evaluation of XPath Expressions.</th> + * </tr> + * </thead> + * <tr> + * <td>context</td> + * <td> + * The type of the context is implementation-dependent. If the value is + * null, the operation must have no dependency on the context, otherwise + * an XPathExpressionException will be thrown. + * + * For the purposes of evaluating XPath expressions, a DocumentFragment + * is treated like a Document node. * </td> * </tr> * <tr>
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. 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 @@ -33,19 +33,20 @@ * * <a name="XPathExpression-evaluation"></a> * <table border="1" cellpadding="2"> - * <thead> - * <tr> - * <th colspan="2">Evaluation of XPath Expressions.</th> - * </tr> - * </thead> - * <tbody> - * <tr> - * <td>context</td> - * <td> - * If a request is made to evaluate the expression in the absence - * of a context item, an empty document node will be used for the context. - * For the purposes of evaluating XPath expressions, a DocumentFragment - * is treated like a Document node. + * <thead> + * <tr> + * <th colspan="2">Evaluation of XPath Expressions.</th> + * </tr> + * </thead> + * <tr> + * <td>context</td> + * <td> + * The type of the context is implementation-dependent. If the value is + * null, the operation must have no dependency on the context, otherwise + * an XPathExpressionException will be thrown. + * + * For the purposes of evaluating XPath expressions, a DocumentFragment + * is treated like a Document node. * </td> * </tr> * <tr>
--- a/jaxp/src/java.xml/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/src/java.xml/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,10 @@ * questions. */ +/** + * Defines the Java API for XML Processing (JAXP), the Streaming API for XML (StAX), + * the Simple API for XML (SAX), and the W3C Document Object Model (DOM) API. + */ module java.xml { exports javax.xml; exports javax.xml.catalog;
--- a/jaxp/test/javax/xml/jaxp/unittest/xpath/XPathTest.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxp/test/javax/xml/jaxp/unittest/xpath/XPathTest.java Fri Aug 19 18:48:25 2016 -0700 @@ -24,11 +24,17 @@ package xpath; import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; - +import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; /* * @test @@ -36,19 +42,105 @@ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @run testng/othervm -DrunSecMngr=true xpath.XPathTest * @run testng/othervm xpath.XPathTest - * @summary Test XPath.getNamespaceContext() is supported. + * @summary Test XPath functions. See details for each test. */ @Listeners({jaxp.library.BasePolicy.class}) public class XPathTest { + /* + @bug 6211561 + * Verifies the specification for XPath and XPathExpression: + * If a null value is provided for item (the context), + * the expression must have no dependency on the context. + */ + @Test(dataProvider = "noContextDependency") + public void testNoContextDependency1(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluate(expression, item, XPathConstants.STRING); + } + + @Test(dataProvider = "noContextDependency") + public void testNoContextDependency2(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluateExpression(expression, item, String.class); + } + + /* + @bug 6211561 + * Verifies the specification for XPath and XPathExpression: + * If a null value is provided for item (the context) that the operation + * depends on, XPathExpressionException will be thrown + */ + @Test(dataProvider = "hasContextDependency", expectedExceptions = XPathExpressionException.class) + public void testHasContextDependency1(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluate(expression, item, XPathConstants.STRING); + } + + @Test(dataProvider = "hasContextDependency", expectedExceptions = XPathExpressionException.class) + public void testHasContextDependency2(String expression, Object item) throws XPathExpressionException { + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.evaluateExpression(expression, item, String.class); + } + + /* + @bug 6376058 + Verifies that XPath.getNamespaceContext() is supported. + */ @Test public void testNamespaceContext() { - XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); + NamespaceContext namespaceContext = xPath.getNamespaceContext(); + } - NamespaceContext namespaceContext = xPath.getNamespaceContext(); + /* + * DataProvider: the expression has no dependency on the context + */ + @DataProvider(name = "noContextDependency") + public Object[][] getExpressionContext() throws Exception { + return new Object[][]{ + {"1+1", (Node)null}, + {"5 mod 2", (Node)null}, + {"8 div 2", (Node)null}, + {"/node", getEmptyDocument()} + }; + } + /* + * DataProvider: the expression has dependency on the context, but the context + * is null. + */ + @DataProvider(name = "hasContextDependency") + public Object[][] getExpressionContext1() throws Exception { + return new Object[][]{ + {"/node", (Node)null}, + {"//@lang", (Node)null}, + {"bookstore//book", (Node)null}, + {"/bookstore/book[last()]", (Node)null}, + {"//title[@lang='en']", (Node)null}, + {"/bookstore/book[price>9.99]", (Node)null}, + {"/bookstore/book[price>8.99 and price<9.99]", (Node)null}, + {"/bookstore/*", (Node)null}, + {"//title[@*]", (Node)null}, + {"//title | //price", (Node)null}, + {"//book/title | //book/price", (Node)null}, + {"/bookstore/book/title | //price", (Node)null}, + {"child::book", (Node)null}, + {"child::text()", (Node)null}, + {"child::*/child::price", (Node)null} + }; + } + + /** + * Returns an empty {@link org.w3c.dom.Document}. + * @return a DOM Document, null in case of Exception + */ + public Document getEmptyDocument() { + try { + return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + return null; + } } } -
--- a/jaxws/.hgtags Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxws/.hgtags Fri Aug 19 18:48:25 2016 -0700 @@ -377,3 +377,4 @@ 46a02f57218e4a8c334dbccf656fb048f823f163 jdk-9+129 39c6293131d91aec7f2f5120395e070a937b8858 jdk-9+130 783e7e2c587f2c7e1b9998a46d90ec196ab2a195 jdk-9+131 +9fff2477a4cadf2a9618a76f1f4fe0f20bb5ff3b jdk-9+132
--- a/jaxws/src/java.activation/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxws/src/java.activation/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the JavaBeans Activation Framework (JAF) API. + */ module java.activation { requires public java.datatransfer; // dependence on java.beans.Beans to be eliminated
--- a/jaxws/src/java.annotations.common/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxws/src/java.annotations.common/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,10 @@ * questions. */ +/** + * Defines a subset of the Common Annotations API to support programs running + * on the Java SE Platform. + */ module java.annotations.common { exports javax.annotation; }
--- a/jaxws/src/java.xml.bind/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxws/src/java.xml.bind/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,9 @@ * questions. */ +/** + * Defines the Java Architecture for XML Binding (JAXB) API. + */ module java.xml.bind { requires public java.activation; requires public java.xml;
--- a/jaxws/src/java.xml.ws/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jaxws/src/java.xml.ws/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,10 @@ * questions. */ +/** + * Defines the Java API for XML-Based Web Services (JAX-WS), and + * the Web Services Metadata API. + */ module java.xml.ws { requires public java.activation; requires public java.xml;
--- a/jdk/.hgtags Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/.hgtags Fri Aug 19 18:48:25 2016 -0700 @@ -374,3 +374,4 @@ 47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129 6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130 8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131 +d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
--- a/jdk/make/copy/Copy-java.base.gmk Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/make/copy/Copy-java.base.gmk Fri Aug 19 18:48:25 2016 -0700 @@ -183,7 +183,7 @@ DEF_POLICY_SRC_LIST := $(DEF_POLICY_SRC) -ifeq ($(OPENJDK_TARGET_OS), windows) +ifneq ($(filter $(OPENJDK_TARGET_OS), windows solaris), ) DEF_POLICY_SRC_LIST += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/lib/security/default.policy endif
--- a/jdk/src/java.base/macosx/classes/apple/security/AppleProvider.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/macosx/classes/apple/security/AppleProvider.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. 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 @@ -26,6 +26,7 @@ package apple.security; import java.security.*; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * The Apple Security Provider. @@ -74,7 +75,7 @@ public AppleProvider() { /* We are the Apple provider */ - super("Apple", 9.0d, info); + super("Apple", PROVIDER_VER, info); final Provider p = this; AccessController.doPrivileged(new PrivilegedAction<Void>() {
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. 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 @@ -107,7 +107,12 @@ throw new InvalidKeySpecException("Key length is negative"); } try { - this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance()); + this.prf = Mac.getInstance(prfAlgo); + // SunPKCS11 requires a non-empty PBE password + if (passwdBytes.length == 0 && + this.prf.getProvider().getName().startsWith("SunPKCS11")) { + this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance()); + } } catch (NoSuchAlgorithmException nsae) { // not gonna happen; re-throw just in case InvalidKeySpecException ike = new InvalidKeySpecException();
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. 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 @@ -28,6 +28,7 @@ import java.security.AccessController; import java.security.Provider; import java.security.SecureRandom; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** @@ -104,7 +105,7 @@ public SunJCE() { /* We are the "SunJCE" provider */ - super("SunJCE", 9.0d, info); + super("SunJCE", PROVIDER_VER, info); final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" + "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
--- a/jdk/src/java.base/share/classes/java/io/BufferedReader.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/BufferedReader.java Fri Aug 19 18:48:25 2016 -0700 @@ -560,7 +560,7 @@ * @since 1.8 */ public Stream<String> lines() { - Iterator<String> iter = new Iterator<String>() { + Iterator<String> iter = new Iterator<>() { String nextLine = null; @Override
--- a/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java Fri Aug 19 18:48:25 2016 -0700 @@ -187,7 +187,7 @@ * @return the current contents of this output stream, as a byte array. * @see java.io.ByteArrayOutputStream#size() */ - public synchronized byte toByteArray()[] { + public synchronized byte[] toByteArray() { return Arrays.copyOf(buf, count); }
--- a/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java Fri Aug 19 18:48:25 2016 -0700 @@ -165,7 +165,7 @@ * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -173,7 +173,7 @@ * @since 1.5 */ public CharArrayWriter append(CharSequence csq) { - String s = (csq == null ? "null" : csq.toString()); + String s = String.valueOf(csq); write(s, 0, s.length()); return this; } @@ -193,7 +193,7 @@ * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -212,9 +212,8 @@ * @since 1.5 */ public CharArrayWriter append(CharSequence csq, int start, int end) { - String s = (csq == null ? "null" : csq).subSequence(start, end).toString(); - write(s, 0, s.length()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /** @@ -251,7 +250,7 @@ * * @return an array of chars copied from the input data. */ - public char toCharArray()[] { + public char[] toCharArray() { synchronized (lock) { return Arrays.copyOf(buf, count); }
--- a/jdk/src/java.base/share/classes/java/io/FileSystem.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/FileSystem.java Fri Aug 19 18:48:25 2016 -0700 @@ -228,13 +228,8 @@ static boolean useCanonPrefixCache = true; private static boolean getBooleanProperty(String prop, boolean defaultVal) { - String val = System.getProperty(prop); - if (val == null) return defaultVal; - if (val.equalsIgnoreCase("true")) { - return true; - } else { - return false; - } + return Boolean.parseBoolean(System.getProperty(prop, + String.valueOf(defaultVal))); } static {
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Fri Aug 19 18:48:25 2016 -0700 @@ -1265,22 +1265,21 @@ WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); Boolean result = Caches.subclassAudits.get(key); if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); + result = auditSubclass(cl); Caches.subclassAudits.putIfAbsent(key, result); } - if (result.booleanValue()) { - return; + if (!result) { + sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } /** * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. + * override security-sensitive non-final methods. Returns TRUE if subclass + * is "safe", FALSE otherwise. */ - private static boolean auditSubclass(final Class<?> subcl) { - Boolean result = AccessController.doPrivileged( + private static Boolean auditSubclass(Class<?> subcl) { + return AccessController.doPrivileged( new PrivilegedAction<>() { public Boolean run() { for (Class<?> cl = subcl; @@ -1303,7 +1302,6 @@ } } ); - return result.booleanValue(); } /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java Fri Aug 19 18:48:25 2016 -0700 @@ -1050,22 +1050,21 @@ WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); Boolean result = Caches.subclassAudits.get(key); if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); + result = auditSubclass(cl); Caches.subclassAudits.putIfAbsent(key, result); } - if (result.booleanValue()) { - return; + if (!result) { + sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } /** * Performs reflective checks on given subclass to verify that it doesn't - * override security-sensitive non-final methods. Returns true if subclass - * is "safe", false otherwise. + * override security-sensitive non-final methods. Returns TRUE if subclass + * is "safe", FALSE otherwise. */ - private static boolean auditSubclass(final Class<?> subcl) { - Boolean result = AccessController.doPrivileged( + private static Boolean auditSubclass(Class<?> subcl) { + return AccessController.doPrivileged( new PrivilegedAction<>() { public Boolean run() { for (Class<?> cl = subcl; @@ -1088,7 +1087,6 @@ } } ); - return result.booleanValue(); } /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Fri Aug 19 18:48:25 2016 -0700 @@ -1509,11 +1509,9 @@ private static String getPackageName(Class<?> cl) { String s = cl.getName(); int i = s.lastIndexOf('['); - if (i >= 0) { - s = s.substring(i + 2); - } - i = s.lastIndexOf('.'); - return (i >= 0) ? s.substring(0, i) : ""; + i = (i < 0) ? 0 : i + 2; + int j = s.lastIndexOf('.'); + return (i < j) ? s.substring(i, j) : ""; } /** @@ -1535,14 +1533,14 @@ private static String getMethodSignature(Class<?>[] paramTypes, Class<?> retType) { - StringBuilder sbuf = new StringBuilder(); - sbuf.append('('); + StringBuilder sb = new StringBuilder(); + sb.append('('); for (int i = 0; i < paramTypes.length; i++) { - appendClassSignature(sbuf, paramTypes[i]); + appendClassSignature(sb, paramTypes[i]); } - sbuf.append(')'); - appendClassSignature(sbuf, retType); - return sbuf.toString(); + sb.append(')'); + appendClassSignature(sb, retType); + return sb.toString(); } /**
--- a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java Fri Aug 19 18:48:25 2016 -0700 @@ -233,22 +233,16 @@ @Override public Writer append(CharSequence csq, int start, int end) throws IOException { - if (csq == null) { - write("null".subSequence(start, end).toString()); - return this; - } else { - return append(csq.subSequence(start, end)); - } + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } @Override public Writer append(CharSequence csq) throws IOException { - if (csq == null) { - se.write("null"); - } else if (csq instanceof CharBuffer) { + if (csq instanceof CharBuffer) { se.write((CharBuffer) csq); } else { - se.write(csq.toString()); + se.write(String.valueOf(csq)); } return this; }
--- a/jdk/src/java.base/share/classes/java/io/PrintStream.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/PrintStream.java Fri Aug 19 18:48:25 2016 -0700 @@ -568,7 +568,7 @@ * @param b The {@code boolean} to be printed */ public void print(boolean b) { - write(b ? "true" : "false"); + write(String.valueOf(b)); } /** @@ -663,10 +663,7 @@ * @param s The {@code String} to be printed */ public void print(String s) { - if (s == null) { - s = "null"; - } - write(s); + write(String.valueOf(s)); } /** @@ -1068,10 +1065,7 @@ * @since 1.5 */ public PrintStream append(CharSequence csq) { - if (csq == null) - print("null"); - else - print(csq.toString()); + print(String.valueOf(csq)); return this; } @@ -1111,9 +1105,8 @@ * @since 1.5 */ public PrintStream append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/io/PrintWriter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/PrintWriter.java Fri Aug 19 18:48:25 2016 -0700 @@ -504,7 +504,7 @@ * @param b The {@code boolean} to be printed */ public void print(boolean b) { - write(b ? "true" : "false"); + write(String.valueOf(b)); } /** @@ -599,10 +599,7 @@ * @param s The {@code String} to be printed */ public void print(String s) { - if (s == null) { - s = "null"; - } - write(s); + write(String.valueOf(s)); } /** @@ -1005,10 +1002,7 @@ * @since 1.5 */ public PrintWriter append(CharSequence csq) { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -1047,9 +1041,8 @@ * @since 1.5 */ public PrintWriter append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java Fri Aug 19 18:48:25 2016 -0700 @@ -65,12 +65,7 @@ */ public SequenceInputStream(Enumeration<? extends InputStream> e) { this.e = e; - try { - nextStream(); - } catch (IOException ex) { - // This should never happen - throw new Error("panic"); - } + peekNextStream(); } /** @@ -86,16 +81,10 @@ */ public SequenceInputStream(InputStream s1, InputStream s2) { Vector<InputStream> v = new Vector<>(2); - v.addElement(s1); v.addElement(s2); e = v.elements(); - try { - nextStream(); - } catch (IOException ex) { - // This should never happen - throw new Error("panic"); - } + peekNextStream(); } /** @@ -105,14 +94,17 @@ if (in != null) { in.close(); } + peekNextStream(); + } + private void peekNextStream() { if (e.hasMoreElements()) { in = (InputStream) e.nextElement(); if (in == null) throw new NullPointerException(); + } else { + in = null; } - else in = null; - } /**
--- a/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java Fri Aug 19 18:48:25 2016 -0700 @@ -108,6 +108,7 @@ * <code>-1</code> if there is no more data because the end of * the stream has been reached. */ + @SuppressWarnings("deprecation") public synchronized int read(byte b[], int off, int len) { if (b == null) { throw new NullPointerException(); @@ -126,12 +127,8 @@ if (len <= 0) { return 0; } - String s = buffer; - int cnt = len; - while (--cnt >= 0) { - b[off++] = (byte)s.charAt(pos++); - } - + buffer.getBytes(pos, pos + len, b, off); + pos += len; return len; }
--- a/jdk/src/java.base/share/classes/java/io/StringReader.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/StringReader.java Fri Aug 19 18:48:25 2016 -0700 @@ -142,8 +142,8 @@ */ public boolean ready() throws IOException { synchronized (lock) { - ensureOpen(); - return true; + ensureOpen(); + return true; } }
--- a/jdk/src/java.base/share/classes/java/io/StringWriter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/StringWriter.java Fri Aug 19 18:48:25 2016 -0700 @@ -139,7 +139,7 @@ * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -147,10 +147,7 @@ * @since 1.5 */ public StringWriter append(CharSequence csq) { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -170,7 +167,7 @@ * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -189,9 +186,8 @@ * @since 1.5 */ public StringWriter append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/io/Writer.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/io/Writer.java Fri Aug 19 18:48:25 2016 -0700 @@ -221,7 +221,7 @@ * * @param csq * The character sequence to append. If {@code csq} is - * {@code null}, then the four characters "{@code null}" are + * {@code null}, then the four characters {@code "null"} are * appended to this writer. * * @return This writer @@ -232,10 +232,7 @@ * @since 1.5 */ public Writer append(CharSequence csq) throws IOException { - if (csq == null) - write("null"); - else - write(csq.toString()); + write(String.valueOf(csq)); return this; } @@ -256,7 +253,7 @@ * The character sequence from which a subsequence will be * appended. If {@code csq} is {@code null}, then characters * will be appended as if {@code csq} contained the four - * characters "{@code null}". + * characters {@code "null"}. * * @param start * The index of the first character in the subsequence @@ -278,9 +275,8 @@ * @since 1.5 */ public Writer append(CharSequence csq, int start, int end) throws IOException { - CharSequence cs = (csq == null ? "null" : csq); - write(cs.subSequence(start, end).toString()); - return this; + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); } /**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Fri Aug 19 18:48:25 2016 -0700 @@ -36,7 +36,6 @@ import java.lang.invoke.LambdaForm.NamedFunction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Function; @@ -308,7 +307,7 @@ /*non-public*/ char fieldTypeChar(int i) { return typeChars.charAt(i); } - Object fieldSignature() { + String fieldSignature() { return typeChars; } public Class<? extends BoundMethodHandle> fieldHolder() {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java Fri Aug 19 18:48:25 2016 -0700 @@ -27,6 +27,7 @@ import java.util.Arrays; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleStatics.*; /** @@ -96,14 +97,8 @@ int whichCache, Object constraint, NamedFunction getTargetFn) { - String debugString; - switch(whichCache) { - case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; - case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; - default: debugString = "MH.reinvoke"; break; - } // No pre-action needed. - return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null); + return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null); } /** Create a LF which simply reinvokes a target of the given basic type. */ static LambdaForm makeReinvokerForm(MethodHandle target, @@ -114,6 +109,10 @@ NamedFunction getTargetFn, NamedFunction preActionFn) { MethodType mtype = target.type().basicType(); + Kind kind = whichKind(whichCache); + if (debugString == null) { + debugString = kind.defaultLambdaName; + } boolean customized = (whichCache < 0 || mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); boolean hasPreAction = (preActionFn != null); @@ -145,13 +144,21 @@ targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); } - form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline); + form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind); if (!customized) { form = mtype.form().setCachedLambdaForm(whichCache, form); } return form; } + private static Kind whichKind(int whichCache) { + switch(whichCache) { + case MethodTypeForm.LF_REBIND: return BOUND_REINVOKER; + case MethodTypeForm.LF_DELEGATE: return DELEGATE; + default: return REINVOKER; + } + } + static final NamedFunction NF_getTarget; static { try { @@ -160,5 +167,13 @@ } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } + // The Holder class will contain pre-generated DelegatingMethodHandles resolved + // speculatively using MemberName.getFactory().resolveOrNull. However, that + // doesn't initialize the class, which subtly breaks inlining etc. By forcing + // initialization of the Holder class we avoid these issues. + UNSAFE.ensureClassInitialized(Holder.class); } + + /* Placeholder class for DelegatingMethodHandles generated ahead of time */ + final class Holder {} }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Aug 19 18:48:25 2016 -0700 @@ -38,6 +38,7 @@ import java.util.Objects; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.UNSAFE; import static java.lang.invoke.MethodHandleStatics.newInternalError; @@ -189,14 +190,15 @@ static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) { boolean needsInit = (which == LF_INVSTATIC_INIT); boolean doesAlloc = (which == LF_NEWINVSPECIAL); - String linkerName, lambdaName; + String linkerName; + LambdaForm.Kind kind; switch (which) { - case LF_INVVIRTUAL: linkerName = "linkToVirtual"; lambdaName = "DMH.invokeVirtual"; break; - case LF_INVSTATIC: linkerName = "linkToStatic"; lambdaName = "DMH.invokeStatic"; break; - case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; lambdaName = "DMH.invokeStaticInit"; break; - case LF_INVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.invokeSpecial"; break; - case LF_INVINTERFACE: linkerName = "linkToInterface"; lambdaName = "DMH.invokeInterface"; break; - case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.newInvokeSpecial"; break; + case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break; + case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break; + case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC_INIT; break; + case LF_INVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_INVOKE_SPECIAL; break; + case LF_INVINTERFACE: linkerName = "linkToInterface"; kind = DIRECT_INVOKE_INTERFACE; break; + case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_NEW_INVOKE_SPECIAL; break; default: throw new InternalError("which="+which); } @@ -240,11 +242,11 @@ result = NEW_OBJ; } names[LINKER_CALL] = new Name(linker, outArgs); - lambdaName += "_" + shortenSignature(basicTypeSignature(mtype)); - LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result); + String lambdaName = kind.defaultLambdaName + "_" + shortenSignature(basicTypeSignature(mtype)); + LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result, kind); // This is a tricky bit of code. Don't send it through the LF interpreter. - lform.compileToBytecode(Holder.class); + lform.compileToBytecode(); return lform; } @@ -705,7 +707,7 @@ } static { - // The DMH class will contain pre-generated DirectMethodHandles resolved + // The Holder class will contain pre-generated DirectMethodHandles resolved // speculatively using MemberName.getFactory().resolveOrNull. However, that // doesn't initialize the class, which subtly breaks inlining etc. By forcing // initialization of the Holder class we avoid these issues. @@ -713,5 +715,5 @@ } /* Placeholder class for DirectMethodHandles generated ahead of time */ - private final class Holder {} + final class Holder {} }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java Fri Aug 19 18:48:25 2016 -0700 @@ -29,21 +29,82 @@ import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; +import java.util.ArrayList; +import java.util.HashSet; + /** * Helper class to assist the GenerateJLIClassesPlugin to get access to * generate classes ahead of time. */ class GenerateJLIClassesHelper { - static byte[] generateDMHClassBytes(String className, + static byte[] generateBasicFormsClassBytes(String className) { + ArrayList<LambdaForm> forms = new ArrayList<>(); + ArrayList<String> names = new ArrayList<>(); + HashSet<String> dedupSet = new HashSet<>(); + for (LambdaForm.BasicType type : LambdaForm.BasicType.values()) { + LambdaForm zero = LambdaForm.zeroForm(type); + String name = zero.kind.defaultLambdaName + + "_" + zero.returnType().basicTypeChar(); + if (dedupSet.add(name)) { + names.add(name); + forms.add(zero); + } + + LambdaForm identity = LambdaForm.identityForm(type); + name = identity.kind.defaultLambdaName + + "_" + identity.returnType().basicTypeChar(); + if (dedupSet.add(name)) { + names.add(name); + forms.add(identity); + } + } + return generateCodeBytesForLFs(className, + names.toArray(new String[0]), + forms.toArray(new LambdaForm[0])); + } + + static byte[] generateDirectMethodHandleHolderClassBytes(String className, MethodType[] methodTypes, int[] types) { LambdaForm[] forms = new LambdaForm[methodTypes.length]; + String[] names = new String[methodTypes.length]; for (int i = 0; i < forms.length; i++) { forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i], types[i]); - methodTypes[i] = forms[i].methodType(); + names[i] = forms[i].kind.defaultLambdaName; } - return generateCodeBytesForLFs(className, forms, methodTypes); + return generateCodeBytesForLFs(className, names, forms); + } + + static byte[] generateDelegatingMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes) { + + HashSet<MethodType> dedupSet = new HashSet<>(); + ArrayList<LambdaForm> forms = new ArrayList<>(); + ArrayList<String> names = new ArrayList<>(); + for (int i = 0; i < methodTypes.length; i++) { + // generate methods representing the DelegatingMethodHandle + if (dedupSet.add(methodTypes[i])) { + // reinvokers are variant with the associated SpeciesData + // and shape of the target LF, but we can easily pregenerate + // the basic reinvokers associated with Species_L. Ultimately we + // may want to consider pregenerating more of these, which will + // require an even more complex naming scheme + LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]); + forms.add(reinvoker); + String speciesSig = BoundMethodHandle + .speciesData(reinvoker).fieldSignature(); + assert(speciesSig.equals("L")); + names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig); + + LambdaForm delegate = makeDelegateFor(methodTypes[i]); + forms.add(delegate); + names.add(delegate.kind.defaultLambdaName); + } + } + return generateCodeBytesForLFs(className, + names.toArray(new String[0]), + forms.toArray(new LambdaForm[0])); } /* @@ -51,22 +112,45 @@ * a class with a specified name. */ private static byte[] generateCodeBytesForLFs(String className, - LambdaForm[] forms, MethodType[] types) { - assert(forms.length == types.length); + String[] names, LambdaForm[] forms) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null); cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null); + for (int i = 0; i < forms.length; i++) { - InvokerBytecodeGenerator g - = new InvokerBytecodeGenerator(className, forms[i], types[i]); - g.setClassWriter(cw); - g.addMethod(); + addMethod(className, names[i], forms[i], + forms[i].methodType(), cw); } return cw.toByteArray(); } + private static void addMethod(String className, String methodName, LambdaForm form, + MethodType type, ClassWriter cw) { + InvokerBytecodeGenerator g + = new InvokerBytecodeGenerator(className, methodName, form, type); + g.setClassWriter(cw); + g.addMethod(); + } + + private static LambdaForm makeReinvokerFor(MethodType type) { + MethodHandle emptyHandle = MethodHandles.empty(type); + return DelegatingMethodHandle.makeReinvokerForm(emptyHandle, + MethodTypeForm.LF_REBIND, + BoundMethodHandle.speciesData_L(), + BoundMethodHandle.speciesData_L().getterFunction(0)); + } + + private static LambdaForm makeDelegateFor(MethodType type) { + MethodHandle handle = MethodHandles.empty(type); + return DelegatingMethodHandle.makeReinvokerForm( + handle, + MethodTypeForm.LF_DELEGATE, + DelegatingMethodHandle.class, + DelegatingMethodHandle.NF_getTarget); + } + static Map.Entry<String, byte[]> generateConcreteBMHClassBytes( final String types) { for (char c : types.toCharArray()) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Aug 19 18:48:25 2016 -0700 @@ -46,6 +46,7 @@ import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.BasicType.*; +import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.*; @@ -125,9 +126,15 @@ } /** For generating customized code for a single LambdaForm. */ - InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { + private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { + this(className, form.debugName, form, invokerType); + } + + /** For generating customized code for a single LambdaForm. */ + InvokerBytecodeGenerator(String className, String invokerName, + LambdaForm form, MethodType invokerType) { this(form, form.names.length, - className, form.debugName, invokerType); + className, invokerName, invokerType); // Create an array to map name indexes to locals indexes. Name[] names = form.names; for (int i = 0, index = 0; i < localsMap.length; i++) { @@ -597,10 +604,47 @@ return c.getName().replace('.', '/'); } + private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) { + MemberName member = new MemberName(holder, name, type, REF_invokeStatic); + MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder); + + return resolvedMember; + } + + private static MemberName lookupPregenerated(LambdaForm form) { + if (form.customized != null) { + // No pre-generated version for customized LF + return null; + } + MethodType invokerType = form.methodType(); + String name = form.kind.methodName; + switch (form.kind) { + case BOUND_REINVOKER: { + name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature(); + return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + } + case DELEGATE: return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + case ZERO: // fall-through + case IDENTITY: { + name = name + "_" + form.returnType().basicTypeChar(); + return resolveFrom(name, invokerType, LambdaForm.Holder.class); + } + case DIRECT_INVOKE_INTERFACE: // fall-through + case DIRECT_INVOKE_SPECIAL: // fall-through + case DIRECT_INVOKE_STATIC: // fall-through + case DIRECT_INVOKE_STATIC_INIT: // fall-through + case DIRECT_INVOKE_VIRTUAL: return resolveFrom(name, invokerType, DirectMethodHandle.Holder.class); + } + return null; + } + /** * Generate customized bytecode for a given LambdaForm. */ static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { + MemberName pregenerated = lookupPregenerated(form); + if (pregenerated != null) return pregenerated; // pre-generated bytecode + InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); return g.loadMethod(g.generateCustomizedCodeBytes()); }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Fri Aug 19 18:48:25 2016 -0700 @@ -41,6 +41,7 @@ import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; import static java.lang.invoke.MethodHandleStatics.*; +import java.util.Objects; /** * The symbolic, non-executable form of a method handle's invocation semantics. @@ -127,6 +128,7 @@ final MethodHandle customized; @Stable final Name[] names; final String debugName; + final Kind kind; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; @@ -266,12 +268,48 @@ } } + enum Kind { + GENERIC(""), + ZERO("zero"), + IDENTITY("identity"), + BOUND_REINVOKER("BMH.reinvoke"), + REINVOKER("MH.reinvoke"), + DELEGATE("MH.delegate"), + DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"), + DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"), + DIRECT_INVOKE_STATIC("DMH.invokeStatic"), + DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"), + DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"), + DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"); + + final String defaultLambdaName; + final String methodName; + + private Kind(String defaultLambdaName) { + this.defaultLambdaName = defaultLambdaName; + int p = defaultLambdaName.indexOf('.'); + if (p > -1) { + this.methodName = defaultLambdaName.substring(p + 1); + } else { + this.methodName = defaultLambdaName; + } + } + } + LambdaForm(String debugName, int arity, Name[] names, int result) { - this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null); + this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, Kind kind) { + this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, kind); } LambdaForm(String debugName, int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) { + this(debugName, arity, names, result, forceInline, customized, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); @@ -279,6 +317,7 @@ this.debugName = fixDebugName(debugName); this.forceInline = forceInline; this.customized = customized; + this.kind = kind; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. @@ -288,11 +327,15 @@ } LambdaForm(String debugName, int arity, Name[] names) { - this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null); + this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); } LambdaForm(String debugName, int arity, Name[] names, boolean forceInline) { - this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null); + this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, boolean forceInline, Kind kind) { + this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind); } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { @@ -325,6 +368,7 @@ this.debugName = "LF.zero"; this.forceInline = true; this.customized = null; + this.kind = Kind.GENERIC; assert(nameRefsAreLegal()); assert(isEmpty()); String sig = null; @@ -395,7 +439,7 @@ /** Customize LambdaForm for a particular MethodHandle */ LambdaForm customize(MethodHandle mh) { - LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh); + LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh, kind); if (COMPILE_THRESHOLD >= 0 && isCompiled) { // If shared LambdaForm has been compiled, compile customized version as well. customForm.compileToBytecode(); @@ -773,28 +817,6 @@ } } - /** - * Generate optimizable bytecode for this form after first looking for a - * pregenerated version in a specified class. - */ - void compileToBytecode(Class<?> lookupClass) { - if (vmentry != null && isCompiled) { - return; // already compiled somehow - } - MethodType invokerType = methodType(); - assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType)); - int dot = debugName.indexOf('.'); - String methodName = (dot > 0) ? debugName.substring(dot + 1) : debugName; - MemberName member = new MemberName(lookupClass, methodName, invokerType, REF_invokeStatic); - MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, lookupClass); - if (resolvedMember != null) { - vmentry = resolvedMember; - isCompiled = true; - } else { - compileToBytecode(); - } - } - private static void computeInitialPreparedForms() { // Find all predefined invokers and associate them with canonical empty lambda forms. for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) { @@ -1828,7 +1850,7 @@ // bootstrap dependency on this method in case we're interpreting LFs if (isVoid) { Name[] idNames = new Name[] { argument(0, L_TYPE) }; - idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT); + idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT, Kind.IDENTITY); idForm.compileToBytecode(); idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm)); @@ -1836,15 +1858,17 @@ zeFun = idFun; } else { Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) }; - idForm = new LambdaForm(idMem.getName(), 2, idNames, 1); + idForm = new LambdaForm(idMem.getName(), 2, idNames, 1, Kind.IDENTITY); idForm.compileToBytecode(); - idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm)); + idFun = new NamedFunction(idMem, MethodHandleImpl.makeIntrinsic( + idMem.getInvocationType(), idForm, MethodHandleImpl.Intrinsic.IDENTITY)); Object zeValue = Wrapper.forBasicType(btChar).zero(); Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) }; - zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1); + zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1, Kind.ZERO); zeForm.compileToBytecode(); - zeFun = new NamedFunction(zeMem, SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm)); + zeFun = new NamedFunction(zeMem, MethodHandleImpl.makeIntrinsic( + zeMem.getInvocationType(), zeForm, MethodHandleImpl.Intrinsic.ZERO)); } LF_zero[ord] = zeForm; @@ -1901,8 +1925,17 @@ if (USE_PREDEFINED_INTERPRET_METHODS) computeInitialPreparedForms(); NamedFunction.initializeInvokers(); + + // The Holder class will contain pre-generated forms resolved + // using MemberName.getFactory(). However, that doesn't initialize the + // class, which subtly breaks inlining etc. By forcing + // initialization of the Holder class we avoid these issues. + UNSAFE.ensureClassInitialized(Holder.class); } + /* Placeholder class for zero and identity forms generated ahead of time */ + final class Holder {} + // The following hack is necessary in order to suppress TRACE_INTERPRETER // during execution of the static initializes of this class. // Turning on TRACE_INTERPRETER too early will cause
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Aug 19 18:48:25 2016 -0700 @@ -1718,10 +1718,19 @@ } @Override - public byte[] generateDMHClassBytes(String className, - MethodType[] methodTypes, int[] types) { + public byte[] generateDirectMethodHandleHolderClassBytes( + String className, MethodType[] methodTypes, int[] types) { return GenerateJLIClassesHelper - .generateDMHClassBytes(className, methodTypes, types); + .generateDirectMethodHandleHolderClassBytes( + className, methodTypes, types); + } + + @Override + public byte[] generateDelegatingMethodHandleHolderClassBytes( + String className, MethodType[] methodTypes) { + return GenerateJLIClassesHelper + .generateDelegatingMethodHandleHolderClassBytes( + className, methodTypes); } @Override @@ -1730,6 +1739,12 @@ return GenerateJLIClassesHelper .generateConcreteBMHClassBytes(types); } + + @Override + public byte[] generateBasicFormsClassBytes(final String className) { + return GenerateJLIClassesHelper + .generateBasicFormsClassBytes(className); + } }); } @@ -1925,7 +1940,7 @@ * @return whether the counter has reached the limit. */ static boolean countedLoopPredicate(int counter, int limit) { - return counter <= limit; + return counter < limit; } /**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Aug 19 18:48:25 2016 -0700 @@ -4583,7 +4583,8 @@ * // assume MH_decrement is a handle to x-1 of type int * MethodHandle[] * indexVar = {start, MH_increment}, // i = start; i = i+1 - * loopLimit = {end, null, MH_lessThan, returnVar }, // i<end + * loopLimit = {end, null, + * filterArgument(MH_lessThan, 0, MH_decrement), returnVar}, // i-1<end * bodyClause = {init, * filterArgument(dropArguments(body, 1, int.class), 0, MH_decrement}; // v = body(i-1, v) * return loop(indexVar, loopLimit, bodyClause); @@ -4619,12 +4620,12 @@ MethodHandle actualBody = body == null ? dropArguments(defaultResultHandle, 0, int.class) : body; MethodHandle returnVar = dropArguments(defaultResultHandle, 0, int.class, int.class); MethodHandle actualEnd = end == null ? constant(int.class, 0) : end; + MethodHandle decr = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter); MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)}; MethodHandle[] loopLimit = {actualEnd, null, - MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar}; - MethodHandle[] bodyClause = {actualInit, - filterArgument(dropArguments(actualBody, 1, int.class), 0, - MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))}; + filterArgument(MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), 0, decr), + returnVar}; + MethodHandle[] bodyClause = {actualInit, filterArgument(dropArguments(actualBody, 1, int.class), 0, decr)}; return loop(indexVar, loopLimit, bodyClause); }
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AbstractClassLoaderValue.java Fri Aug 19 14:33:52 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.lang.reflect; - -import jdk.internal.loader.BootLoader; -import jdk.internal.misc.JavaLangAccess; -import jdk.internal.misc.SharedSecrets; - -import java.util.Iterator; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiFunction; -import java.util.function.Supplier; - -/** - * AbstractClassLoaderValue is a superclass of root-{@link ClassLoaderValue} - * and {@link Sub sub}-ClassLoaderValue. - * - * @param <CLV> the type of concrete ClassLoaderValue (this type) - * @param <V> the type of values associated with ClassLoaderValue - */ -abstract class AbstractClassLoaderValue<CLV extends AbstractClassLoaderValue<CLV, V>, V> { - - /** - * Sole constructor. - */ - AbstractClassLoaderValue() {} - - /** - * Returns the key component of this ClassLoaderValue. The key component of - * the root-{@link ClassLoaderValue} is the ClassLoaderValue itself, - * while the key component of a {@link #sub(Object) sub}-ClassLoaderValue - * is what was given to construct it. - * - * @return the key component of this ClassLoaderValue. - */ - public abstract Object key(); - - /** - * Constructs new sub-ClassLoaderValue of this ClassLoaderValue with given - * key component. - * - * @param key the key component of the sub-ClassLoaderValue. - * @param <K> the type of the key component. - * @return a sub-ClassLoaderValue of this ClassLoaderValue for given key - */ - public <K> Sub<K> sub(K key) { - return new Sub<>(key); - } - - /** - * Returns {@code true} if this ClassLoaderValue is equal to given {@code clv} - * or if this ClassLoaderValue was derived from given {@code clv} by a chain - * of {@link #sub(Object)} invocations. - * - * @param clv the ClassLoaderValue to test this against - * @return if this ClassLoaderValue is equal to given {@code clv} or - * its descendant - */ - public abstract boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv); - - /** - * Returns the value associated with this ClassLoaderValue and given ClassLoader - * or {@code null} if there is none. - * - * @param cl the ClassLoader for the associated value - * @return the value associated with this ClassLoaderValue and given ClassLoader - * or {@code null} if there is none. - */ - public V get(ClassLoader cl) { - Object val = AbstractClassLoaderValue.<CLV>map(cl).get(this); - try { - return extractValue(val); - } catch (Memoizer.RecursiveInvocationException e) { - // propagate recursive get() for the same key that is just - // being calculated in computeIfAbsent() - throw e; - } catch (Throwable t) { - // don't propagate exceptions thrown from Memoizer - pretend - // that there was no entry - // (computeIfAbsent invocation will try to remove it anyway) - return null; - } - } - - /** - * Associates given value {@code v} with this ClassLoaderValue and given - * ClassLoader and returns {@code null} if there was no previously associated - * value or does nothing and returns previously associated value if there - * was one. - * - * @param cl the ClassLoader for the associated value - * @param v the value to associate - * @return previously associated value or null if there was none - */ - public V putIfAbsent(ClassLoader cl, V v) { - ConcurrentHashMap<CLV, Object> map = map(cl); - @SuppressWarnings("unchecked") - CLV clv = (CLV) this; - while (true) { - try { - Object val = map.putIfAbsent(clv, v); - return extractValue(val); - } catch (Memoizer.RecursiveInvocationException e) { - // propagate RecursiveInvocationException for the same key that - // is just being calculated in computeIfAbsent - throw e; - } catch (Throwable t) { - // don't propagate exceptions thrown from foreign Memoizer - - // pretend that there was no entry and retry - // (foreign computeIfAbsent invocation will try to remove it anyway) - } - // TODO: - // Thread.onSpinLoop(); // when available - } - } - - /** - * Removes the value associated with this ClassLoaderValue and given - * ClassLoader if the associated value is equal to given value {@code v} and - * returns {@code true} or does nothing and returns {@code false} if there is - * no currently associated value or it is not equal to given value {@code v}. - * - * @param cl the ClassLoader for the associated value - * @param v the value to compare with currently associated value - * @return {@code true} if the association was removed or {@code false} if not - */ - public boolean remove(ClassLoader cl, Object v) { - return AbstractClassLoaderValue.<CLV>map(cl).remove(this, v); - } - - /** - * Returns the value associated with this ClassLoaderValue and given - * ClassLoader if there is one or computes the value by invoking given - * {@code mappingFunction}, associates it and returns it. - * <p> - * Computation and association of the computed value is performed atomically - * by the 1st thread that requests a particular association while holding a - * lock associated with this ClassLoaderValue and given ClassLoader. - * Nested calls from the {@code mappingFunction} to {@link #get}, - * {@link #putIfAbsent} or {@link #computeIfAbsent} for the same association - * are not allowed and throw {@link IllegalStateException}. Nested call to - * {@link #remove} for the same association is allowed but will always return - * {@code false} regardless of passed-in comparison value. Nested calls for - * other association(s) are allowed, but care should be taken to avoid - * deadlocks. When two threads perform nested computations of the overlapping - * set of associations they should always request them in the same order. - * - * @param cl the ClassLoader for the associated value - * @param mappingFunction the function to compute the value - * @return the value associated with this ClassLoaderValue and given - * ClassLoader. - * @throws IllegalStateException if a direct or indirect invocation from - * within given {@code mappingFunction} that - * computes the value of a particular association - * to {@link #get}, {@link #putIfAbsent} or - * {@link #computeIfAbsent} - * for the same association is attempted. - */ - public V computeIfAbsent(ClassLoader cl, - BiFunction< - ? super ClassLoader, - ? super CLV, - ? extends V - > mappingFunction) throws IllegalStateException { - ConcurrentHashMap<CLV, Object> map = map(cl); - @SuppressWarnings("unchecked") - CLV clv = (CLV) this; - Memoizer<CLV, V> mv = null; - while (true) { - Object val = (mv == null) ? map.get(clv) : map.putIfAbsent(clv, mv); - if (val == null) { - if (mv == null) { - // create Memoizer lazily when 1st needed and restart loop - mv = new Memoizer<>(cl, clv, mappingFunction); - continue; - } - // mv != null, therefore sv == null was a result of successful - // putIfAbsent - try { - // trigger Memoizer to compute the value - V v = mv.get(); - // attempt to replace our Memoizer with the value - map.replace(clv, mv, v); - // return computed value - return v; - } catch (Throwable t) { - // our Memoizer has thrown, attempt to remove it - map.remove(clv, mv); - // propagate exception because it's from our Memoizer - throw t; - } - } else { - try { - return extractValue(val); - } catch (Memoizer.RecursiveInvocationException e) { - // propagate recursive attempts to calculate the same - // value as being calculated at the moment - throw e; - } catch (Throwable t) { - // don't propagate exceptions thrown from foreign Memoizer - - // pretend that there was no entry and retry - // (foreign computeIfAbsent invocation will try to remove it anyway) - } - } - // TODO: - // Thread.onSpinLoop(); // when available - } - } - - /** - * Removes all values associated with given ClassLoader {@code cl} and - * {@link #isEqualOrDescendantOf(AbstractClassLoaderValue) this or descendants} - * of this ClassLoaderValue. - * This is not an atomic operation. Other threads may see some associations - * be already removed and others still present while this method is executing. - * <p> - * The sole intention of this method is to cleanup after a unit test that - * tests ClassLoaderValue directly. It is not intended for use in - * actual algorithms. - * - * @param cl the associated ClassLoader of the values to be removed - */ - public void removeAll(ClassLoader cl) { - ConcurrentHashMap<CLV, Object> map = map(cl); - for (Iterator<CLV> i = map.keySet().iterator(); i.hasNext(); ) { - if (i.next().isEqualOrDescendantOf(this)) { - i.remove(); - } - } - } - - private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); - - /** - * @return a ConcurrentHashMap for given ClassLoader - */ - @SuppressWarnings("unchecked") - private static <CLV extends AbstractClassLoaderValue<CLV, ?>> - ConcurrentHashMap<CLV, Object> map(ClassLoader cl) { - return (ConcurrentHashMap<CLV, Object>) - (cl == null ? BootLoader.getClassLoaderValueMap() - : JLA.createOrGetClassLoaderValueMap(cl)); - } - - /** - * @return value extracted from the {@link Memoizer} if given - * {@code memoizerOrValue} parameter is a {@code Memoizer} or - * just return given parameter. - */ - @SuppressWarnings("unchecked") - private V extractValue(Object memoizerOrValue) { - if (memoizerOrValue instanceof Memoizer) { - return ((Memoizer<?, V>) memoizerOrValue).get(); - } else { - return (V) memoizerOrValue; - } - } - - /** - * A memoized supplier that invokes given {@code mappingFunction} just once - * and remembers the result or thrown exception for subsequent calls. - * If given mappingFunction returns null, it is converted to NullPointerException, - * thrown from the Memoizer's {@link #get()} method and remembered. - * If the Memoizer is invoked recursively from the given {@code mappingFunction}, - * {@link RecursiveInvocationException} is thrown, but it is not remembered. - * The in-flight call to the {@link #get()} can still complete successfully if - * such exception is handled by the mappingFunction. - */ - private static final class Memoizer<CLV extends AbstractClassLoaderValue<CLV, V>, V> - implements Supplier<V> { - - private final ClassLoader cl; - private final CLV clv; - private final BiFunction<? super ClassLoader, ? super CLV, ? extends V> - mappingFunction; - - private volatile V v; - private volatile Throwable t; - private boolean inCall; - - Memoizer(ClassLoader cl, - CLV clv, - BiFunction<? super ClassLoader, ? super CLV, ? extends V> - mappingFunction - ) { - this.cl = cl; - this.clv = clv; - this.mappingFunction = mappingFunction; - } - - @Override - public V get() throws RecursiveInvocationException { - V v = this.v; - if (v != null) return v; - Throwable t = this.t; - if (t == null) { - synchronized (this) { - if ((v = this.v) == null && (t = this.t) == null) { - if (inCall) { - throw new RecursiveInvocationException(); - } - inCall = true; - try { - this.v = v = Objects.requireNonNull( - mappingFunction.apply(cl, clv)); - } catch (Throwable x) { - this.t = t = x; - } finally { - inCall = false; - } - } - } - } - if (v != null) return v; - if (t instanceof Error) { - throw (Error) t; - } else if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } else { - throw new UndeclaredThrowableException(t); - } - } - - static class RecursiveInvocationException extends IllegalStateException { - private static final long serialVersionUID = 1L; - - RecursiveInvocationException() { - super("Recursive call"); - } - } - } - - /** - * sub-ClassLoaderValue is an inner class of {@link AbstractClassLoaderValue} - * and also a subclass of it. It can therefore be instantiated as an inner - * class of either an instance of root-{@link ClassLoaderValue} or another - * instance of itself. This enables composing type-safe compound keys of - * arbitrary length: - * <pre>{@code - * ClassLoaderValue<V> clv = new ClassLoaderValue<>(); - * ClassLoaderValue<V>.Sub<K1>.Sub<K2>.Sub<K3> clv_k123 = - * clv.sub(k1).sub(k2).sub(k3); - * }</pre> - * From which individual components are accessible in a type-safe way: - * <pre>{@code - * K1 k1 = clv_k123.parent().parent().key(); - * K2 k2 = clv_k123.parent().key(); - * K3 k3 = clv_k123.key(); - * }</pre> - * This allows specifying non-capturing lambdas for the mapping function of - * {@link #computeIfAbsent(ClassLoader, BiFunction)} operation that can - * access individual key components from passed-in - * sub-[sub-...]ClassLoaderValue instance in a type-safe way. - * - * @param <K> the type of {@link #key()} component contained in the - * sub-ClassLoaderValue. - */ - final class Sub<K> extends AbstractClassLoaderValue<Sub<K>, V> { - - private final K key; - - Sub(K key) { - this.key = key; - } - - /** - * @return the parent ClassLoaderValue this sub-ClassLoaderValue - * has been {@link #sub(Object) derived} from. - */ - public AbstractClassLoaderValue<CLV, V> parent() { - return AbstractClassLoaderValue.this; - } - - /** - * @return the key component of this sub-ClassLoaderValue. - */ - @Override - public K key() { - return key; - } - - /** - * sub-ClassLoaderValue is a descendant of given {@code clv} if it is - * either equal to it or if its {@link #parent() parent} is a - * descendant of given {@code clv}. - */ - @Override - public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { - return equals(Objects.requireNonNull(clv)) || - parent().isEqualOrDescendantOf(clv); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Sub)) return false; - @SuppressWarnings("unchecked") - Sub<?> that = (Sub<?>) o; - return this.parent().equals(that.parent()) && - Objects.equals(this.key, that.key); - } - - @Override - public int hashCode() { - return 31 * parent().hashCode() + - Objects.hashCode(key); - } - } -}
--- a/jdk/src/java.base/share/classes/java/lang/reflect/ClassLoaderValue.java Fri Aug 19 14:33:52 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.lang.reflect; - -import java.util.Objects; -import java.util.function.BiFunction; - -/** - * root-ClassLoaderValue. Each instance defines a separate namespace for - * associated values. - * <p> - * ClassLoaderValue allows associating a - * {@link #computeIfAbsent(ClassLoader, BiFunction) computed} non-null value with - * a {@code (ClassLoader, keys...)} tuple. The associated value, as well as the - * keys are strongly reachable from the associated ClassLoader so care should be - * taken to use such keys and values that only reference types resolvable from - * the associated ClassLoader. Failing that, ClassLoader leaks are inevitable. - * <p> - * Example usage: - * <pre>{@code - * // create a root instance which represents a namespace and declares the type of - * // associated values (Class instances in this example) - * static final ClassLoaderValue<Class<?>> proxyClasses = new ClassLoaderValue<>(); - * - * // create a compound key composed of a Module and a list of interfaces - * Module module = ...; - * List<Class<?>> interfaces = ...; - * ClassLoaderValue<Class<?>>.Sub<Module>.Sub<List<Class<?>>> key = - * proxyClasses.sub(module).sub(interfaces); - * - * // use the compound key together with ClassLoader to lazily associate - * // the value with tuple (loader, module, interfaces) and return it - * ClassLoader loader = ...; - * Class<?> proxyClass = key.computeIfAbsent(loader, (ld, ky) -> { - * List<Class<?>> intfcs = ky.key(); - * Module m = ky.parent().key(); - * Class<?> clazz = defineProxyClass(ld, m, intfcs); - * return clazz; - * }); - * }</pre> - * <p> - * {@code classLoaderValue.<operation>(classLoader, ...)} represents an operation - * to {@link #get}, {@link #putIfAbsent}, {@link #computeIfAbsent} or {@link #remove} - * a value associated with a (classLoader, classLoaderValue) tuple. ClassLoader - * instances and root-{@link ClassLoaderValue} instances are compared using - * identity equality while {@link Sub sub}-ClassLoaderValue instances define - * {@link #equals(Object) equality} in terms of equality of its - * {@link Sub#parent() parent} ClassLoaderValue and its - * {@link #key() key} component. - * - * @param <V> the type of value(s) associated with the root-ClassLoaderValue and - * all its {@link #sub(Object) descendants}. - * @author Peter Levart - * @since 9 - */ -final class ClassLoaderValue<V> - extends AbstractClassLoaderValue<ClassLoaderValue<V>, V> { - - /** - * Constructs new root-ClassLoaderValue representing its own namespace. - */ - public ClassLoaderValue() {} - - /** - * @return the key component of this root-ClassLoaderValue (itself). - */ - @Override - public ClassLoaderValue<V> key() { - return this; - } - - /** - * root-ClassLoaderValue can only be equal to itself and has no predecessors. - */ - @Override - public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { - return equals(Objects.requireNonNull(clv)); - } -}
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Fri Aug 19 18:48:25 2016 -0700 @@ -29,11 +29,9 @@ import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collections; -import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.IdentityHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -49,6 +47,7 @@ import jdk.internal.misc.VM; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.loader.ClassLoaderValue; import sun.reflect.misc.ReflectUtil; import sun.security.action.GetPropertyAction; import sun.security.util.SecurityConstants;
--- a/jdk/src/java.base/share/classes/java/security/AuthProvider.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/security/AuthProvider.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. 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 @@ -50,9 +50,24 @@ * @param name the provider name. * @param version the provider version number. * @param info a description of the provider and its services. + * @deprecated use {@link #AuthProvider(String, String, String)} instead. */ + @Deprecated(since="9") protected AuthProvider(String name, double version, String info) { - super(name, version, info); + super(name, Double.toString(version), info); + } + + /** + * Constructs a provider with the specified name, version string, + * and information. + * + * @param name the provider name. + * @param versionStr the provider version string. + * @param info a description of the provider and its services. + * @since 9 + */ + protected AuthProvider(String name, String versionStr, String info) { + super(name, versionStr, info); } /**
--- a/jdk/src/java.base/share/classes/java/security/Provider.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/security/Provider.java Fri Aug 19 18:48:25 2016 -0700 @@ -67,14 +67,14 @@ * <tr><td>{@code Provider.id name}</td> * <td>{@code String.valueOf(provider.getName())}</td> * <tr><td>{@code Provider.id version}</td> - * <td>{@code String.valueOf(provider.getVersion())}</td> + * <td>{@code String.valueOf(provider.getVersionStr())}</td> * <tr><td>{@code Provider.id info}</td> <td>{@code String.valueOf(provider.getInfo())}</td> * <tr><td>{@code Provider.id className}</td> * <td>{@code provider.getClass().getName()}</td> * </table> * - * <p>Each provider has a name and a version number. A provider normally + * <p>Each provider has a name and a version string. A provider normally * identifies itself with a file named {@code java.security.Provider} * in the resource directory {@code META-INF/services}. * Security providers are looked up via the {@link ServiceLoader} mechanism @@ -102,11 +102,10 @@ public abstract class Provider extends Properties { // Declare serialVersionUID to be compatible with JDK1.1 - static final long serialVersionUID = -4298000515446427739L; + private static final long serialVersionUID = -4298000515446427739L; private static final sun.security.util.Debug debug = - sun.security.util.Debug.getInstance - ("provider", "Provider"); + sun.security.util.Debug.getInstance("provider", "Provider"); /** * The provider name. @@ -129,6 +128,12 @@ */ private double version; + /** + * The provider version string. + * + * @serial + */ + private String versionStr; private transient Set<Map.Entry<Object,Object>> entrySet = null; private transient int entrySetCallCount = 0; @@ -174,19 +179,83 @@ } } + private static double parseVersionStr(String s) { + try { + int firstDotIdx = s.indexOf('.'); + int nextDotIdx = s.indexOf('.', firstDotIdx + 1); + if (nextDotIdx != -1) { + s = s.substring(0, nextDotIdx); + } + int endIdx = s.indexOf('-'); + if (endIdx > 0) { + s = s.substring(0, endIdx); + } + endIdx = s.indexOf('+'); + if (endIdx > 0) { + s = s.substring(0, endIdx); + } + return Double.parseDouble(s); + } catch (NullPointerException | NumberFormatException e) { + return 0d; + } + } + /** * Constructs a provider with the specified name, version number, - * and information. + * and information. Calling this constructor is equivalent to call the + * {@link #Provider(String, String, String)} with {@code name} + * name, {@code Double.toString(version)}, and {@code info}. * * @param name the provider name. * * @param version the provider version number. * * @param info a description of the provider and its services. + * + * @deprecated use {@link #Provider(String, String, String)} instead. */ + @Deprecated(since="9") protected Provider(String name, double version, String info) { this.name = name; this.version = version; + this.versionStr = Double.toString(version); + this.info = info; + putId(); + initialized = true; + } + + /** + * Constructs a provider with the specified name, version string, + * and information. + * + * <p>The version string contains a version number optionally followed + * by other information separated by one of the characters of '+', '-'. + * + * The format for the version number is: + * + * <blockquote><pre> + * ^[0-9]+(\.[0-9]+)* + * </pre></blockquote> + * + * <p>In order to return the version number in a double, when there are + * more than two components (separated by '.' as defined above), only + * the first two components are retained. The resulting string is then + * passed to {@link Double#valueOf(String)} to generate version number, + * i.e. {@link #getVersion}. + * <p>If the conversion failed, value 0 will be used. + * + * @param name the provider name. + * + * @param versionStr the provider version string. + * + * @param info a description of the provider and its services. + * + * @since 9 + */ + protected Provider(String name, String versionStr, String info) { + this.name = name; + this.versionStr = versionStr; + this.version = parseVersionStr(versionStr); this.info = info; putId(); initialized = true; @@ -250,12 +319,26 @@ * Returns the version number for this provider. * * @return the version number for this provider. + * + * @deprecated use {@link #getVersionStr} instead. */ + @Deprecated(since="9") public double getVersion() { return version; } /** + * Returns the version string for this provider. + * + * @return the version string for this provider. + * + * @since 9 + */ + public String getVersionStr() { + return versionStr; + } + + /** * Returns a human-readable description of the provider and its * services. This may return an HTML page, with relevant links. * @@ -266,14 +349,14 @@ } /** - * Returns a string with the name and the version number + * Returns a string with the name and the version string * of this provider. * - * @return the string with the name and the version number + * @return the string with the name and the version string * for this provider. */ public String toString() { - return name + " version " + version; + return name + " version " + versionStr; } /* @@ -601,7 +684,7 @@ public synchronized Object compute(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("Compute " + name + " provider property " + key); @@ -632,7 +715,7 @@ public synchronized Object computeIfAbsent(Object key, Function<? super Object, ? extends Object> mappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("ComputeIfAbsent " + name + " provider property " + @@ -662,7 +745,7 @@ public synchronized Object computeIfPresent(Object key, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("ComputeIfPresent " + name + " provider property " + @@ -695,7 +778,7 @@ public synchronized Object merge(Object key, Object value, BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); - check("removeProviderProperty" + name); + check("removeProviderProperty." + name); if (debug != null) { debug.println("Merge " + name + " provider property " + key); @@ -787,11 +870,21 @@ private void putId() { // note: name and info may be null super.put("Provider.id name", String.valueOf(name)); - super.put("Provider.id version", String.valueOf(version)); + super.put("Provider.id version", String.valueOf(versionStr)); super.put("Provider.id info", String.valueOf(info)); super.put("Provider.id className", this.getClass().getName()); } + /** + * Reads the {@code ObjectInputStream} for the default serializable fields. + * If the serialized field {@code versionStr} is found in the STREAM FIELDS, + * its String value will be used to populate both the version string and + * version number. If {@code versionStr} is not found, but {@code version} + * is, then its double value will be used to populate both fields. + * + * @param in the {@code ObjectInputStream} to read + * @serial + */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { Map<Object,Object> copy = new HashMap<>(); @@ -800,6 +893,13 @@ } defaults = null; in.defaultReadObject(); + if (this.versionStr == null) { + // set versionStr based on version when not found in serialized bytes + this.versionStr = Double.toString(this.version); + } else { + // otherwise, set version based on versionStr + this.version = parseVersionStr(this.versionStr); + } implClear(); initialized = true; putAll(copy); @@ -904,8 +1004,8 @@ if (!checkLegacy(key)) { return null; } - legacyStrings.computeIfAbsent((String) key, - (Function<? super String, ? extends String>) remappingFunction); + legacyStrings.compute((String) key, + (BiFunction<? super String,? super String, ? extends String>) remappingFunction); } return super.compute(key, remappingFunction); } @@ -1913,7 +2013,5 @@ return provider.getName() + ": " + type + "." + algorithm + " -> " + className + aString + attrs + "\r\n"; } - } - }
--- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java Fri Aug 19 18:48:25 2016 -0700 @@ -399,7 +399,10 @@ * Calendar Elements in the Unicode Locale Data Markup Language * (LDML) specification</a> for more details. * - * @return the month strings. + * @return the month strings. Use + * {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, + * etc. to index the result array. */ public String[] getMonths() { return Arrays.copyOf(months, months.length); @@ -407,7 +410,9 @@ /** * Sets month strings. For example: "January", "February", etc. - * @param newMonths the new month strings. + * @param newMonths the new month strings. The array should + * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc. */ public void setMonths(String[] newMonths) { months = Arrays.copyOf(newMonths, newMonths.length); @@ -427,7 +432,10 @@ * Calendar Elements in the Unicode Locale Data Markup Language * (LDML) specification</a> for more details. * - * @return the short month strings. + * @return the short month strings. Use + * {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, + * etc. to index the result array. */ public String[] getShortMonths() { return Arrays.copyOf(shortMonths, shortMonths.length); @@ -435,7 +443,9 @@ /** * Sets short month strings. For example: "Jan", "Feb", etc. - * @param newShortMonths the new short month strings. + * @param newShortMonths the new short month strings. The array should + * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY}, + * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc. */ public void setShortMonths(String[] newShortMonths) { shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length); @@ -444,8 +454,10 @@ /** * Gets weekday strings. For example: "Sunday", "Monday", etc. - * @return the weekday strings. Use <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. to index the result array. + * @return the weekday strings. Use + * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index + * the result array. */ public String[] getWeekdays() { return Arrays.copyOf(weekdays, weekdays.length); @@ -454,8 +466,8 @@ /** * Sets weekday strings. For example: "Sunday", "Monday", etc. * @param newWeekdays the new weekday strings. The array should - * be indexed by <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. + * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. */ public void setWeekdays(String[] newWeekdays) { weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length); @@ -464,8 +476,10 @@ /** * Gets short weekday strings. For example: "Sun", "Mon", etc. - * @return the short weekday strings. Use <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. to index the result array. + * @return the short weekday strings. Use + * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index + * the result array. */ public String[] getShortWeekdays() { return Arrays.copyOf(shortWeekdays, shortWeekdays.length); @@ -474,8 +488,8 @@ /** * Sets short weekday strings. For example: "Sun", "Mon", etc. * @param newShortWeekdays the new short weekday strings. The array should - * be indexed by <code>Calendar.SUNDAY</code>, - * <code>Calendar.MONDAY</code>, etc. + * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY}, + * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. */ public void setShortWeekdays(String[] newShortWeekdays) { shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length);
--- a/jdk/src/java.base/share/classes/java/util/Date.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/util/Date.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2016, Oracle and/or its affiliates. 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 @@ -952,6 +952,9 @@ * without affecting its internal state. */ static final long getMillisOf(Date date) { + if (date.getClass() != Date.class) { + return date.getTime(); + } if (date.cdate == null || date.cdate.isNormalized()) { return date.fastTime; }
--- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Fri Aug 19 18:48:25 2016 -0700 @@ -295,7 +295,13 @@ public static <T> Collector<T, ?, Set<T>> toSet() { return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add, - (left, right) -> { left.addAll(right); return left; }, + (left, right) -> { + if (left.size() < right.size()) { + right.addAll(left); return right; + } else { + left.addAll(right); return left; + } + }, CH_UNORDERED_ID); }
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java Fri Aug 19 18:48:25 2016 -0700 @@ -861,6 +861,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites might be useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -880,6 +887,13 @@ * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -896,6 +910,14 @@ * fail. Following a successful call to this method, only suites * listed in the {@code suites} parameter are enabled for use. * <P> + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + * <P> * See {@link #getEnabledCipherSuites()} for more information * on why a specific cipher suite may never be used on a engine. *
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. 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 @@ -108,7 +108,12 @@ * <p> * Calling this constructor is equivalent to calling the no-args * constructor followed by - * {@code setCipherSuites(cipherSuites);}. + * {@code setCipherSuites(cipherSuites);}. Note that the + * standard list of cipher suite names may be found in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) */ @@ -123,6 +128,12 @@ * Calling this constructor is equivalent to calling the no-args * constructor followed by * {@code setCipherSuites(cipherSuites); setProtocols(protocols);}. + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) * @param protocols the array of protocols (or null) @@ -139,6 +150,13 @@ /** * Returns a copy of the array of ciphersuites or null if none * have been set. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return a copy of the array of ciphersuites or null if none * have been set. @@ -150,7 +168,13 @@ /** * Sets the array of ciphersuites. * - * @param cipherSuites the array of ciphersuites (or null) + * @param cipherSuites the array of ciphersuites (or null). Note that the + * standard list of cipher suite names may be found in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. */ public void setCipherSuites(String[] cipherSuites) { this.cipherSuites = clone(cipherSuites);
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java Fri Aug 19 18:48:25 2016 -0700 @@ -195,6 +195,13 @@ * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suites enabled * @see #getSupportedCipherSuites() @@ -215,6 +222,14 @@ * in this ServerSocket's authentication context will not be used * in any case, even if they are enabled. * <P> + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + * <P> * <code>SSLSocket</code>s returned from <code>accept()</code> * inherit this setting. * @@ -236,6 +251,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites()
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. 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 @@ -123,6 +123,13 @@ * will use one of these cipher suites. The minimum quality of service * for these defaults requires confidentiality protection and server * authentication (that is, no anonymous cipher suites). + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -137,6 +144,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getDefaultCipherSuites()
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java Fri Aug 19 18:48:25 2016 -0700 @@ -265,6 +265,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites might be useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -284,6 +291,13 @@ * or the requisite certificates (and private keys) for the suite are * not available, or an anonymous suite is enabled but authentication * is required. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -300,6 +314,14 @@ * fail. Following a successful call to this method, only suites * listed in the <code>suites</code> parameter are enabled for use. * <P> + * Note that the standard list of cipher suite names may be found in the + * <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation. Providers + * may support cipher suite names not found in this list or might not + * use the recommended name for a certain cipher suite. + * <P> * See {@link #getEnabledCipherSuites()} for more information * on why a specific ciphersuite may never be used on a connection. *
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. 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 @@ -148,6 +148,13 @@ * will use one of these cipher suites. The minimum quality of service * for these defaults requires confidentiality protection and server * authentication (that is, no anonymous cipher suites). + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -160,6 +167,13 @@ * be enabled by default, since this list may include cipher suites which * do not meet quality of service requirements for those defaults. Such * cipher suites are useful in specialized applications. + * <P> + * The returned array includes cipher suites from the list of standard + * cipher suite names in the <a href= + * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites"> + * JSSE Cipher Suite Names</a> section of the Java Cryptography + * Architecture Standard Algorithm Name Documentation, and may also + * include other cipher suites that the provider supports. * * @see #getDefaultCipherSuites() * @return an array of cipher suite names
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtfsviewer.js Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtfsviewer.js Fri Aug 19 18:48:25 2016 -0700 @@ -53,6 +53,7 @@ var Files = Java.type("java.nio.file.Files"); var System = Java.type("java.lang.System"); var URI = Java.type("java.net.URI"); +var Collections = Java.type("java.util.Collections"); // JavaFX classes used var StackPane = Java.type("javafx.scene.layout.StackPane"); @@ -100,7 +101,7 @@ print("did you miss specifying jrt-fs.jar with -cp option?"); usage(); } - return FileSystems.newFileSystem(uri, null, cls.classLoader); + return FileSystems.newFileSystem(uri, Collections.emptyMap(), cls.classLoader); } }
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtls.js Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/jrtls.js Fri Aug 19 18:48:25 2016 -0700 @@ -34,7 +34,6 @@ * but also compiled and delivered as part of the jrtfs.jar to support access * to the jimage file provided by the shipped JDK by tools running on JDK 8. */ - */ // classes used var Files = Java.type("java.nio.file.Files");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/AbstractClassLoaderValue.java Fri Aug 19 18:48:25 2016 -0700 @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.loader; + +import jdk.internal.misc.JavaLangAccess; +import jdk.internal.misc.SharedSecrets; + +import java.lang.reflect.UndeclaredThrowableException; +import java.util.Iterator; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiFunction; +import java.util.function.Supplier; + +/** + * AbstractClassLoaderValue is a superclass of root-{@link ClassLoaderValue} + * and {@link Sub sub}-ClassLoaderValue. + * + * @param <CLV> the type of concrete ClassLoaderValue (this type) + * @param <V> the type of values associated with ClassLoaderValue + */ +public abstract class AbstractClassLoaderValue<CLV extends AbstractClassLoaderValue<CLV, V>, V> { + + /** + * Sole constructor. + */ + AbstractClassLoaderValue() {} + + /** + * Returns the key component of this ClassLoaderValue. The key component of + * the root-{@link ClassLoaderValue} is the ClassLoaderValue itself, + * while the key component of a {@link #sub(Object) sub}-ClassLoaderValue + * is what was given to construct it. + * + * @return the key component of this ClassLoaderValue. + */ + public abstract Object key(); + + /** + * Constructs new sub-ClassLoaderValue of this ClassLoaderValue with given + * key component. + * + * @param key the key component of the sub-ClassLoaderValue. + * @param <K> the type of the key component. + * @return a sub-ClassLoaderValue of this ClassLoaderValue for given key + */ + public <K> Sub<K> sub(K key) { + return new Sub<>(key); + } + + /** + * Returns {@code true} if this ClassLoaderValue is equal to given {@code clv} + * or if this ClassLoaderValue was derived from given {@code clv} by a chain + * of {@link #sub(Object)} invocations. + * + * @param clv the ClassLoaderValue to test this against + * @return if this ClassLoaderValue is equal to given {@code clv} or + * its descendant + */ + public abstract boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv); + + /** + * Returns the value associated with this ClassLoaderValue and given ClassLoader + * or {@code null} if there is none. + * + * @param cl the ClassLoader for the associated value + * @return the value associated with this ClassLoaderValue and given ClassLoader + * or {@code null} if there is none. + */ + public V get(ClassLoader cl) { + Object val = AbstractClassLoaderValue.<CLV>map(cl).get(this); + try { + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate recursive get() for the same key that is just + // being calculated in computeIfAbsent() + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from Memoizer - pretend + // that there was no entry + // (computeIfAbsent invocation will try to remove it anyway) + return null; + } + } + + /** + * Associates given value {@code v} with this ClassLoaderValue and given + * ClassLoader and returns {@code null} if there was no previously associated + * value or does nothing and returns previously associated value if there + * was one. + * + * @param cl the ClassLoader for the associated value + * @param v the value to associate + * @return previously associated value or null if there was none + */ + public V putIfAbsent(ClassLoader cl, V v) { + ConcurrentHashMap<CLV, Object> map = map(cl); + @SuppressWarnings("unchecked") + CLV clv = (CLV) this; + while (true) { + try { + Object val = map.putIfAbsent(clv, v); + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate RecursiveInvocationException for the same key that + // is just being calculated in computeIfAbsent + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from foreign Memoizer - + // pretend that there was no entry and retry + // (foreign computeIfAbsent invocation will try to remove it anyway) + } + // TODO: + // Thread.onSpinLoop(); // when available + } + } + + /** + * Removes the value associated with this ClassLoaderValue and given + * ClassLoader if the associated value is equal to given value {@code v} and + * returns {@code true} or does nothing and returns {@code false} if there is + * no currently associated value or it is not equal to given value {@code v}. + * + * @param cl the ClassLoader for the associated value + * @param v the value to compare with currently associated value + * @return {@code true} if the association was removed or {@code false} if not + */ + public boolean remove(ClassLoader cl, Object v) { + return AbstractClassLoaderValue.<CLV>map(cl).remove(this, v); + } + + /** + * Returns the value associated with this ClassLoaderValue and given + * ClassLoader if there is one or computes the value by invoking given + * {@code mappingFunction}, associates it and returns it. + * <p> + * Computation and association of the computed value is performed atomically + * by the 1st thread that requests a particular association while holding a + * lock associated with this ClassLoaderValue and given ClassLoader. + * Nested calls from the {@code mappingFunction} to {@link #get}, + * {@link #putIfAbsent} or {@link #computeIfAbsent} for the same association + * are not allowed and throw {@link IllegalStateException}. Nested call to + * {@link #remove} for the same association is allowed but will always return + * {@code false} regardless of passed-in comparison value. Nested calls for + * other association(s) are allowed, but care should be taken to avoid + * deadlocks. When two threads perform nested computations of the overlapping + * set of associations they should always request them in the same order. + * + * @param cl the ClassLoader for the associated value + * @param mappingFunction the function to compute the value + * @return the value associated with this ClassLoaderValue and given + * ClassLoader. + * @throws IllegalStateException if a direct or indirect invocation from + * within given {@code mappingFunction} that + * computes the value of a particular association + * to {@link #get}, {@link #putIfAbsent} or + * {@link #computeIfAbsent} + * for the same association is attempted. + */ + public V computeIfAbsent(ClassLoader cl, + BiFunction< + ? super ClassLoader, + ? super CLV, + ? extends V + > mappingFunction) throws IllegalStateException { + ConcurrentHashMap<CLV, Object> map = map(cl); + @SuppressWarnings("unchecked") + CLV clv = (CLV) this; + Memoizer<CLV, V> mv = null; + while (true) { + Object val = (mv == null) ? map.get(clv) : map.putIfAbsent(clv, mv); + if (val == null) { + if (mv == null) { + // create Memoizer lazily when 1st needed and restart loop + mv = new Memoizer<>(cl, clv, mappingFunction); + continue; + } + // mv != null, therefore sv == null was a result of successful + // putIfAbsent + try { + // trigger Memoizer to compute the value + V v = mv.get(); + // attempt to replace our Memoizer with the value + map.replace(clv, mv, v); + // return computed value + return v; + } catch (Throwable t) { + // our Memoizer has thrown, attempt to remove it + map.remove(clv, mv); + // propagate exception because it's from our Memoizer + throw t; + } + } else { + try { + return extractValue(val); + } catch (Memoizer.RecursiveInvocationException e) { + // propagate recursive attempts to calculate the same + // value as being calculated at the moment + throw e; + } catch (Throwable t) { + // don't propagate exceptions thrown from foreign Memoizer - + // pretend that there was no entry and retry + // (foreign computeIfAbsent invocation will try to remove it anyway) + } + } + // TODO: + // Thread.onSpinLoop(); // when available + } + } + + /** + * Removes all values associated with given ClassLoader {@code cl} and + * {@link #isEqualOrDescendantOf(AbstractClassLoaderValue) this or descendants} + * of this ClassLoaderValue. + * This is not an atomic operation. Other threads may see some associations + * be already removed and others still present while this method is executing. + * <p> + * The sole intention of this method is to cleanup after a unit test that + * tests ClassLoaderValue directly. It is not intended for use in + * actual algorithms. + * + * @param cl the associated ClassLoader of the values to be removed + */ + public void removeAll(ClassLoader cl) { + ConcurrentHashMap<CLV, Object> map = map(cl); + for (Iterator<CLV> i = map.keySet().iterator(); i.hasNext(); ) { + if (i.next().isEqualOrDescendantOf(this)) { + i.remove(); + } + } + } + + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + + /** + * @return a ConcurrentHashMap for given ClassLoader + */ + @SuppressWarnings("unchecked") + private static <CLV extends AbstractClassLoaderValue<CLV, ?>> + ConcurrentHashMap<CLV, Object> map(ClassLoader cl) { + return (ConcurrentHashMap<CLV, Object>) + (cl == null ? BootLoader.getClassLoaderValueMap() + : JLA.createOrGetClassLoaderValueMap(cl)); + } + + /** + * @return value extracted from the {@link Memoizer} if given + * {@code memoizerOrValue} parameter is a {@code Memoizer} or + * just return given parameter. + */ + @SuppressWarnings("unchecked") + private V extractValue(Object memoizerOrValue) { + if (memoizerOrValue instanceof Memoizer) { + return ((Memoizer<?, V>) memoizerOrValue).get(); + } else { + return (V) memoizerOrValue; + } + } + + /** + * A memoized supplier that invokes given {@code mappingFunction} just once + * and remembers the result or thrown exception for subsequent calls. + * If given mappingFunction returns null, it is converted to NullPointerException, + * thrown from the Memoizer's {@link #get()} method and remembered. + * If the Memoizer is invoked recursively from the given {@code mappingFunction}, + * {@link RecursiveInvocationException} is thrown, but it is not remembered. + * The in-flight call to the {@link #get()} can still complete successfully if + * such exception is handled by the mappingFunction. + */ + private static final class Memoizer<CLV extends AbstractClassLoaderValue<CLV, V>, V> + implements Supplier<V> { + + private final ClassLoader cl; + private final CLV clv; + private final BiFunction<? super ClassLoader, ? super CLV, ? extends V> + mappingFunction; + + private volatile V v; + private volatile Throwable t; + private boolean inCall; + + Memoizer(ClassLoader cl, + CLV clv, + BiFunction<? super ClassLoader, ? super CLV, ? extends V> + mappingFunction + ) { + this.cl = cl; + this.clv = clv; + this.mappingFunction = mappingFunction; + } + + @Override + public V get() throws RecursiveInvocationException { + V v = this.v; + if (v != null) return v; + Throwable t = this.t; + if (t == null) { + synchronized (this) { + if ((v = this.v) == null && (t = this.t) == null) { + if (inCall) { + throw new RecursiveInvocationException(); + } + inCall = true; + try { + this.v = v = Objects.requireNonNull( + mappingFunction.apply(cl, clv)); + } catch (Throwable x) { + this.t = t = x; + } finally { + inCall = false; + } + } + } + } + if (v != null) return v; + if (t instanceof Error) { + throw (Error) t; + } else if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else { + throw new UndeclaredThrowableException(t); + } + } + + static class RecursiveInvocationException extends IllegalStateException { + private static final long serialVersionUID = 1L; + + RecursiveInvocationException() { + super("Recursive call"); + } + } + } + + /** + * sub-ClassLoaderValue is an inner class of {@link AbstractClassLoaderValue} + * and also a subclass of it. It can therefore be instantiated as an inner + * class of either an instance of root-{@link ClassLoaderValue} or another + * instance of itself. This enables composing type-safe compound keys of + * arbitrary length: + * <pre>{@code + * ClassLoaderValue<V> clv = new ClassLoaderValue<>(); + * ClassLoaderValue<V>.Sub<K1>.Sub<K2>.Sub<K3> clv_k123 = + * clv.sub(k1).sub(k2).sub(k3); + * }</pre> + * From which individual components are accessible in a type-safe way: + * <pre>{@code + * K1 k1 = clv_k123.parent().parent().key(); + * K2 k2 = clv_k123.parent().key(); + * K3 k3 = clv_k123.key(); + * }</pre> + * This allows specifying non-capturing lambdas for the mapping function of + * {@link #computeIfAbsent(ClassLoader, BiFunction)} operation that can + * access individual key components from passed-in + * sub-[sub-...]ClassLoaderValue instance in a type-safe way. + * + * @param <K> the type of {@link #key()} component contained in the + * sub-ClassLoaderValue. + */ + public final class Sub<K> extends AbstractClassLoaderValue<Sub<K>, V> { + + private final K key; + + Sub(K key) { + this.key = key; + } + + /** + * @return the parent ClassLoaderValue this sub-ClassLoaderValue + * has been {@link #sub(Object) derived} from. + */ + public AbstractClassLoaderValue<CLV, V> parent() { + return AbstractClassLoaderValue.this; + } + + /** + * @return the key component of this sub-ClassLoaderValue. + */ + @Override + public K key() { + return key; + } + + /** + * sub-ClassLoaderValue is a descendant of given {@code clv} if it is + * either equal to it or if its {@link #parent() parent} is a + * descendant of given {@code clv}. + */ + @Override + public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { + return equals(Objects.requireNonNull(clv)) || + parent().isEqualOrDescendantOf(clv); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Sub)) return false; + @SuppressWarnings("unchecked") + Sub<?> that = (Sub<?>) o; + return this.parent().equals(that.parent()) && + Objects.equals(this.key, that.key); + } + + @Override + public int hashCode() { + return 31 * parent().hashCode() + + Objects.hashCode(key); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaderValue.java Fri Aug 19 18:48:25 2016 -0700 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.loader; + +import java.util.Objects; +import java.util.function.BiFunction; + +/** + * root-ClassLoaderValue. Each instance defines a separate namespace for + * associated values. + * <p> + * ClassLoaderValue allows associating a + * {@link #computeIfAbsent(ClassLoader, BiFunction) computed} non-null value with + * a {@code (ClassLoader, keys...)} tuple. The associated value, as well as the + * keys are strongly reachable from the associated ClassLoader so care should be + * taken to use such keys and values that only reference types resolvable from + * the associated ClassLoader. Failing that, ClassLoader leaks are inevitable. + * <p> + * Example usage: + * <pre>{@code + * // create a root instance which represents a namespace and declares the type of + * // associated values (Class instances in this example) + * static final ClassLoaderValue<Class<?>> proxyClasses = new ClassLoaderValue<>(); + * + * // create a compound key composed of a Module and a list of interfaces + * Module module = ...; + * List<Class<?>> interfaces = ...; + * ClassLoaderValue<Class<?>>.Sub<Module>.Sub<List<Class<?>>> key = + * proxyClasses.sub(module).sub(interfaces); + * + * // use the compound key together with ClassLoader to lazily associate + * // the value with tuple (loader, module, interfaces) and return it + * ClassLoader loader = ...; + * Class<?> proxyClass = key.computeIfAbsent(loader, (ld, ky) -> { + * List<Class<?>> intfcs = ky.key(); + * Module m = ky.parent().key(); + * Class<?> clazz = defineProxyClass(ld, m, intfcs); + * return clazz; + * }); + * }</pre> + * <p> + * {@code classLoaderValue.<operation>(classLoader, ...)} represents an operation + * to {@link #get}, {@link #putIfAbsent}, {@link #computeIfAbsent} or {@link #remove} + * a value associated with a (classLoader, classLoaderValue) tuple. ClassLoader + * instances and root-{@link ClassLoaderValue} instances are compared using + * identity equality while {@link Sub sub}-ClassLoaderValue instances define + * {@link #equals(Object) equality} in terms of equality of its + * {@link Sub#parent() parent} ClassLoaderValue and its + * {@link #key() key} component. + * + * @param <V> the type of value(s) associated with the root-ClassLoaderValue and + * all its {@link #sub(Object) descendants}. + * @author Peter Levart + * @since 9 + */ +public final class ClassLoaderValue<V> + extends AbstractClassLoaderValue<ClassLoaderValue<V>, V> { + + /** + * Constructs new root-ClassLoaderValue representing its own namespace. + */ + public ClassLoaderValue() {} + + /** + * @return the key component of this root-ClassLoaderValue (itself). + */ + @Override + public ClassLoaderValue<V> key() { + return this; + } + + /** + * root-ClassLoaderValue can only be equal to itself and has no predecessors. + */ + @Override + public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) { + return equals(Objects.requireNonNull(clv)); + } +}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java Fri Aug 19 18:48:25 2016 -0700 @@ -51,8 +51,17 @@ * an {@code int} representing method type. Used by * GenerateJLIClassesPlugin to generate such a class during the jlink phase. */ - byte[] generateDMHClassBytes(String className, MethodType[] methodTypes, - int[] types); + byte[] generateDirectMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes, int[] types); + + /** + * Returns a {@code byte[]} containing the bytecode for a class implementing + * DelegatingMethodHandles of each {@code MethodType} kind in the + * {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to + * generate such a class during the jlink phase. + */ + byte[] generateDelegatingMethodHandleHolderClassBytes(String className, + MethodType[] methodTypes); /** * Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle @@ -63,4 +72,10 @@ */ Map.Entry<String, byte[]> generateConcreteBMHClassBytes( final String types); + + /** + * Returns a {@code byte[]} containing the bytecode for a class implementing + * the zero and identity forms of all {@code LambdaForm.BasicType}s. + */ + byte[] generateBasicFormsClassBytes(final String className); }
--- a/jdk/src/java.base/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -24,9 +24,8 @@ */ /** - * java.base defines and exports the core APIs of the Java SE platform. + * Defines the foundational APIs of the Java SE Platform. */ - module java.base { exports java.io;
--- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java Fri Aug 19 18:48:25 2016 -0700 @@ -76,7 +76,7 @@ // dummy provider object to use during initialization // used to avoid explicit null checks in various places private static final Provider EMPTY_PROVIDER = - new Provider("##Empty##", 1.0d, "initialization in progress") { + new Provider("##Empty##", "1.0", "initialization in progress") { private static final long serialVersionUID = 1151354171352296389L; // override getService() to return null slightly faster public Service getService(String type, String algorithm) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/MD4.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/provider/MD4.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. 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 @@ -28,6 +28,7 @@ import java.security.*; import static sun.security.provider.ByteArrayAccess.*; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * The MD4 class is used to compute an MD4 message digest over a given @@ -65,7 +66,8 @@ private static final Provider md4Provider; static { - md4Provider = new Provider("MD4Provider", 9.0d, "MD4 MessageDigest") { + md4Provider = new Provider("MD4Provider", PROVIDER_VER, + "MD4 MessageDigest") { private static final long serialVersionUID = -8850464997518327965L; }; AccessController.doPrivileged(new PrivilegedAction<Void>() {
--- a/jdk/src/java.base/share/classes/sun/security/provider/Sun.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/provider/Sun.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. 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 @@ -29,6 +29,8 @@ import java.security.*; import sun.security.action.PutAllAction; +import static sun.security.util.SecurityConstants.PROVIDER_VER; + /** * The SUN Security Provider. @@ -47,7 +49,7 @@ public Sun() { /* We are the SUN provider */ - super("SUN", 9.0d, INFO); + super("SUN", PROVIDER_VER, INFO); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a
--- a/jdk/src/java.base/share/classes/sun/security/provider/VerificationProvider.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/provider/VerificationProvider.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. 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 @@ -31,6 +31,8 @@ import sun.security.action.PutAllAction; import sun.security.rsa.SunRsaSignEntries; +import static sun.security.util.SecurityConstants.PROVIDER_VER; + /** * Provider used for verification of signed JAR files *if* the Sun and @@ -61,7 +63,7 @@ } public VerificationProvider() { - super("SunJarVerification", 9.0d, "Jar Verification Provider"); + super("SunJarVerification", PROVIDER_VER, "Jar Verification Provider"); // register all algorithms normally registered by the Sun and SunRsaSign // providers, but only if they are missing if (ACTIVE == false) {
--- a/jdk/src/java.base/share/classes/sun/security/rsa/SunRsaSign.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/rsa/SunRsaSign.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. 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 @@ -30,6 +30,7 @@ import java.security.*; import sun.security.action.PutAllAction; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * Provider class for the RSA signature provider. Supports RSA keyfactory, @@ -43,7 +44,7 @@ private static final long serialVersionUID = 866040293550393045L; public SunRsaSign() { - super("SunRsaSign", 9.0d, "Sun RSA signature provider"); + super("SunRsaSign", PROVIDER_VER, "Sun RSA signature provider"); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a
--- a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Fri Aug 19 18:48:25 2016 -0700 @@ -44,6 +44,7 @@ import sun.security.util.ECUtil; import static sun.security.ssl.SunJSSE.cryptoProvider; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * This class contains a few static methods for interaction with the JCA/JCE @@ -90,7 +91,7 @@ private static final long serialVersionUID = -3284138292032213752L; SunCertificates(final Provider p) { - super("SunCertificates", 9.0d, "SunJSSE internal"); + super("SunCertificates", PROVIDER_VER, "SunJSSE internal"); AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SunJSSE.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SunJSSE.java Fri Aug 19 18:48:25 2016 -0700 @@ -27,6 +27,7 @@ package sun.security.ssl; import java.security.*; +import static sun.security.util.SecurityConstants.PROVIDER_VER; /** * The JSSE provider. @@ -104,7 +105,7 @@ // standard constructor protected SunJSSE() { - super("SunJSSE", 9.0d, info); + super("SunJSSE", PROVIDER_VER, info); subclassCheck(); if (Boolean.TRUE.equals(fips)) { throw new ProviderException @@ -132,7 +133,7 @@ private SunJSSE(java.security.Provider cryptoProvider, String providerName) { - super("SunJSSE", 9.0d, fipsInfo + providerName + ")"); + super("SunJSSE", PROVIDER_VER, fipsInfo + providerName + ")"); subclassCheck(); if (cryptoProvider == null) { // Calling Security.getProvider() will cause other providers to be
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Fri Aug 19 18:48:25 2016 -0700 @@ -3631,8 +3631,8 @@ if (time != null) { if (time.matches("\\d\\d:\\d\\d:\\d\\d")) { c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(time.substring(0, 2))); - c.set(Calendar.MINUTE, Integer.valueOf(time.substring(0, 2))); - c.set(Calendar.SECOND, Integer.valueOf(time.substring(0, 2))); + c.set(Calendar.MINUTE, Integer.valueOf(time.substring(3, 5))); + c.set(Calendar.SECOND, Integer.valueOf(time.substring(6, 8))); c.set(Calendar.MILLISECOND, 0); } else { throw ioe;
--- a/jdk/src/java.base/share/classes/sun/security/util/SecurityConstants.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/util/SecurityConstants.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. 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 @@ -33,6 +33,7 @@ import java.security.BasicPermission; import java.security.SecurityPermission; import java.security.AllPermission; +import sun.security.action.GetPropertyAction; /** * Permission constants and string constants used to create permissions @@ -145,4 +146,7 @@ // java.lang.SecurityManager public static final SocketPermission LOCAL_LISTEN_PERMISSION = new SocketPermission("localhost:0", SOCKET_LISTEN_ACTION); + + public static final String PROVIDER_VER = + GetPropertyAction.privilegedGetProperty("java.specification.version"); }
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Aug 19 18:48:25 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. 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 @@ -143,8 +143,8 @@ defaultLocaleProviderAdapter = Type.CLDR; if (!typeList.isEmpty()) { // bona fide preference exists - if (!typeList.contains(Type.CLDR)) { - // Append FALLBACK as the last resort. + if (!(typeList.contains(Type.CLDR) || (typeList.contains(Type.JRE)))) { + // Append FALLBACK as the last resort when no ResourceBundleBasedAdapter is available. typeList.add(Type.FALLBACK); defaultLocaleProviderAdapter = Type.FALLBACK; }
--- a/jdk/src/java.compact1/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.compact1/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,9 @@ * questions. */ +/** + * Aggregates {@code java.base}, {@code java.logging}, and {@code java.scripting}. + */ module java.compact1 { requires public java.logging; requires public java.scripting;
--- a/jdk/src/java.compact2/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.compact2/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,9 @@ * questions. */ +/** + * Supplements {@code java.compact1} with JDBC, JAXP, and RMI. + */ module java.compact2 { requires public java.compact1; requires public java.rmi;
--- a/jdk/src/java.compact3/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.compact3/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -23,6 +23,10 @@ * questions. */ +/** + * Supplements {@code java.compact2} with JDBC RowSet, JMX, JNDI, Compiler, + * Instrumentation, Preferences, Security, and XML cryptography APIs. + */ module java.compact3 { requires public java.compact2; requires public java.compiler;
--- a/jdk/src/java.datatransfer/share/classes/module-info.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.datatransfer/share/classes/module-info.java Fri Aug 19 18:48:25 2016 -0700 @@ -24,10 +24,8 @@ */ /** - * Provides interfaces and classes for transferring data between and - * within applications. + * Defines an API for transferring data between and within applications. */ - module java.datatransfer { exports java.awt.datatransfer; exports sun.datatransfer to java.desktop;
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java Fri Aug 19 18:48:25 2016 -0700 @@ -124,7 +124,9 @@ if (!progressBar.isIndeterminate()) return; stopAnimationTimer(); // start the animation thread - startAnimationTimer(); + if (progressBar.isDisplayable()) { + startAnimationTimer(); + } } if ("JProgressBar.style".equals(prop)) { @@ -141,7 +143,9 @@ public void ancestorAdded(final AncestorEvent e) { if (!progressBar.isIndeterminate()) return; - startAnimationTimer(); + if (progressBar.isDisplayable()) { + startAnimationTimer(); + } } public void ancestorMoved(final AncestorEvent e) { }
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Fri Aug 19 18:48:25 2016 -0700 @@ -807,6 +807,18 @@ - (void)sendEvent:(NSEvent *)event { if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) { + // Move parent windows to front and make sure that a child window is displayed + // in front of its nearest parent. + if (self.ownerWindow != nil) { + JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; + jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env]; + if (platformWindow != NULL) { + static JNF_MEMBER_CACHE(jm_orderAboveSiblings, jc_CPlatformWindow, "orderAboveSiblings", "()V"); + JNFCallVoidMethod(env,platformWindow, jm_orderAboveSiblings); + (*env)->DeleteLocalRef(env, platformWindow); + } + } + [self orderChildWindows:YES]; NSPoint p = [NSEvent mouseLocation]; NSRect frame = [self.nsWindow frame]; @@ -1159,6 +1171,16 @@ NSWindow *nsWindow = OBJC(windowPtr); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ [nsWindow orderBack:nil]; + // Order parent windows + AWTWindow *awtWindow = (AWTWindow*)[nsWindow delegate]; + while (awtWindow.ownerWindow != nil) { + awtWindow = awtWindow.ownerWindow; + if ([AWTWindow isJavaPlatformWindowVisible:awtWindow.nsWindow]) { + [awtWindow.nsWindow orderBack:nil]; + } + } + // Order child windows + [(AWTWindow*)[nsWindow delegate] orderChildWindows:NO]; }]; JNF_COCOA_EXIT(env);
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFColorConverter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFColorConverter.java Fri Aug 19 18:48:25 2016 -0700 @@ -47,7 +47,7 @@ * @throws NullPointerException if {@code result} is * {@code null}. * @throws ArrayIndexOutOfBoundsException if - * {@code result.length < 3}. + * {@code result.length < 3}. */ public abstract void fromRGB(float r, float g, float b, float[] result); @@ -63,7 +63,7 @@ * @throws NullPointerException if {@code rgb} is * {@code null}. * @throws ArrayIndexOutOfBoundsException if - * {@code rgb.length < 3}. + * {@code rgb.length < 3}. */ public abstract void toRGB(float x0, float x1, float x2, float[] rgb); }
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java Fri Aug 19 18:48:25 2016 -0700 @@ -353,7 +353,7 @@ * <p> The pixels in the source region to be copied are * those with X coordinates of the form {@code activeSrcMinX + * k*subsampleX}, where {@code k} is an integer such - * that {@code 0 ≤ k < dstWidth}. + * that {@code 0 <= k < dstWidth}. */ protected int activeSrcMinX; @@ -365,7 +365,7 @@ * <p> The pixels in the source region to be copied are * those with Y coordinates of the form {@code activeSrcMinY + * k*subsampleY}, where {@code k} is an integer such - * that {@code 0 ≤ k < dstHeight}. + * that {@code 0 <= k < dstHeight}. */ protected int activeSrcMinY;
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java Fri Aug 19 18:48:25 2016 -0700 @@ -49,6 +49,45 @@ private long stripOrTileOffsetsPosition = -1; private long lastPosition = -1; + + /** + * Converts a {@code TIFFDirectory} to a {@code TIFFIFD}. + */ + public static TIFFIFD getDirectoryAsIFD(TIFFDirectory dir) { + if(dir instanceof TIFFIFD) { + return (TIFFIFD)dir; + } + + TIFFIFD ifd = new TIFFIFD(Arrays.asList(dir.getTagSets()), + dir.getParentTag()); + TIFFField[] fields = dir.getTIFFFields(); + int numFields = fields.length; + for(int i = 0; i < numFields; i++) { + TIFFField f = fields[i]; + TIFFTag tag = f.getTag(); + if(tag.isIFDPointer()) { + TIFFDirectory subDir = null; + if (f.hasDirectory()) { + subDir = f.getDirectory(); + } else if (f.getData() instanceof TIFFDirectory) { + subDir = (TIFFDirectory)f.getData(); + } + if (subDir != null) { + TIFFDirectory subIFD = getDirectoryAsIFD(subDir); + f = new TIFFField(tag, f.getType(), (long)f.getCount(), + subIFD); + } else { + f = null; + } + } + if (f != null) { + ifd.addTIFFField(f); + } + } + + return ifd; + } + public static TIFFTag getTag(int tagNumber, List<TIFFTagSet> tagSets) { Iterator<TIFFTagSet> iter = tagSets.iterator(); while (iter.hasNext()) { @@ -704,7 +743,7 @@ pos = nextSpace; if (tag.isIFDPointer() && f.hasDirectory()) { - TIFFIFD subIFD = (TIFFIFD)f.getDirectory(); + TIFFIFD subIFD = getDirectoryAsIFD(f.getDirectory()); subIFD.writeToStream(stream); nextSpace = subIFD.lastPosition; } else {
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageMetadata.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageMetadata.java Fri Aug 19 18:48:25 2016 -0700 @@ -132,7 +132,7 @@ if (tag == null) { node = f.getAsNativeNode(); } else if (tag.isIFDPointer() && f.hasDirectory()) { - TIFFIFD subIFD = (TIFFIFD)f.getDirectory(); + TIFFIFD subIFD = TIFFIFD.getDirectoryAsIFD(f.getDirectory()); // Recurse node = getIFDAsTree(subIFD, tag.getName(), tag.getNumber()); @@ -1465,8 +1465,14 @@ String className = st.nextToken(); Object o = null; + Class<?> setClass = null; try { - Class<?> setClass = Class.forName(className); + ClassLoader cl = TIFFImageMetadata.class.getClassLoader(); + setClass = Class.forName(className, false, cl); + if (!TIFFTagSet.class.isAssignableFrom(setClass)) { + fatal(node, "TagSets in IFD must be subset of" + + " TIFFTagSet class"); + } Method getInstanceMethod = setClass.getMethod("getInstance", (Class[])null); o = getInstanceMethod.invoke(null, (Object[])null);
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Fri Aug 19 18:48:25 2016 -0700 @@ -35,6 +35,7 @@ import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; +import java.io.EOFException; import java.io.IOException; import java.nio.ByteOrder; import java.util.ArrayList; @@ -189,8 +190,8 @@ // Seek to start of first IFD long offset = stream.readUnsignedInt(); + stream.seek(offset); imageStartPosition.add(Long.valueOf(offset)); - stream.seek(offset); } catch (IOException e) { throw new IIOException("I/O error reading header!", e); } @@ -201,10 +202,10 @@ private int locateImage(int imageIndex) throws IIOException { readHeader(); + // Find closest known index + int index = Math.min(imageIndex, imageStartPosition.size() - 1); + try { - // Find closest known index - int index = Math.min(imageIndex, imageStartPosition.size() - 1); - // Seek to that position Long l = imageStartPosition.get(index); stream.seek(l.longValue()); @@ -212,6 +213,11 @@ // Skip IFDs until at desired index or last image found while (index < imageIndex) { int count = stream.readUnsignedShort(); + // If zero-entry IFD, decrement the index and exit the loop + if (count == 0) { + imageIndex = index > 0 ? index - 1 : 0; + break; + } stream.skipBytes(12 * count); long offset = stream.readUnsignedInt(); @@ -219,12 +225,17 @@ return index; } + stream.seek(offset); imageStartPosition.add(Long.valueOf(offset)); - stream.seek(offset); ++index; } - } catch (IOException e) { - throw new IIOException("Couldn't seek!", e); + } catch (EOFException eofe) { + forwardWarningMessage("Ignored " + eofe); + + // Ran off the end of stream: decrement index + imageIndex = index > 0 ? index - 1 : 0; + } catch (IOException ioe) { + throw new IIOException("Couldn't seek!", ioe); } if (currIndex != imageIndex) {
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java Fri Aug 19 18:48:25 2016 -0700 @@ -1478,7 +1478,7 @@ (ExifParentTIFFTagSet.TAG_EXIF_IFD_POINTER); if(f != null && f.hasDirectory()) { // Retrieve the Exif IFD. - exifIFD = (TIFFIFD)f.getDirectory(); + exifIFD = TIFFIFD.getDirectoryAsIFD(f.getDirectory()); } else if(isPrimaryIFD) { // Create the Exif IFD. List<TIFFTagSet> exifTagSets = new ArrayList<TIFFTagSet>(1); @@ -3622,6 +3622,8 @@ streamMetadata = null; imageMetadata = null; + isRescaling = false; + isWritingSequence = false; isWritingEmpty = false; isInsertingEmpty = false;
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFMetadataFormat.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFMetadataFormat.java Fri Aug 19 18:48:25 2016 -0700 @@ -49,7 +49,8 @@ } try { ResourceBundle bundle = - ResourceBundle.getBundle(resourceBaseName, locale); + ResourceBundle.getBundle(resourceBaseName, locale, + this.getClass().getModule()); return bundle.getString(key); } catch (MissingResourceException e) { return null;
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java Fri Aug 19 18:48:25 2016 -0700 @@ -657,7 +657,6 @@ protected void paintToImage(Component c, Image image, Graphics g, int w, int h, Object[] args) { - boolean accEnabled = false; Skin skin = (Skin)args[0]; Part part = skin.part; State state = (State)args[1]; @@ -668,6 +667,8 @@ c = skin.component; } BufferedImage bi = (BufferedImage)image; + w = bi.getWidth(); + h = bi.getHeight(); WritableRaster raster = bi.getRaster(); DataBufferInt dbi = (DataBufferInt)raster.getDataBuffer();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java Fri Aug 19 18:48:25 2016 -0700 @@ -32,7 +32,6 @@ import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineUnavailableException; - /** * AbstractDataLine * @@ -147,36 +146,35 @@ } } - public final void open(AudioFormat format) throws LineUnavailableException { open(format, AudioSystem.NOT_SPECIFIED); } - /** * This implementation always returns 0. */ + @Override public int available() { return 0; } + /** + * This implementation does nothing. + */ + @Override + public void drain() { + if (Printer.trace) Printer.trace("AbstractDataLine: drain"); + } /** * This implementation does nothing. */ - public void drain() { - if (Printer.trace) Printer.trace("AbstractDataLine: drain"); - } - - - /** - * This implementation does nothing. - */ + @Override public void flush() { if (Printer.trace) Printer.trace("AbstractDataLine: flush"); } - + @Override public final void start() { //$$fb 2001-10-09: Bug #4517739: avoiding deadlock by synchronizing to mixer ! synchronized(mixer) { @@ -200,7 +198,7 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+".start() - AbstractDataLine"); } - + @Override public final void stop() { //$$fb 2001-10-09: Bug #4517739: avoiding deadlock by synchronizing to mixer ! @@ -245,15 +243,17 @@ // in MixerSourceLine and MixerClip, and I want to touch as little // code as possible to change isStarted() back to isRunning(). + @Override public final boolean isRunning() { return started; } + @Override public final boolean isActive() { return active; } - + @Override public final long getMicrosecondPosition() { long microseconds = getLongFramePosition(); @@ -263,12 +263,12 @@ return microseconds; } - + @Override public final AudioFormat getFormat() { return format; } - + @Override public final int getBufferSize() { return bufferSize; } @@ -283,11 +283,11 @@ /** * This implementation returns AudioSystem.NOT_SPECIFIED. */ + @Override public final float getLevel() { return (float)AudioSystem.NOT_SPECIFIED; } - // HELPER METHODS /** @@ -317,19 +317,12 @@ synchronized (this) { - //if (Printer.debug) Printer.debug(" AbstractDataLine: setActive: this.active: " + this.active); - //if (Printer.debug) Printer.debug(" active: " + active); - if (this.active != active) { this.active = active; //sendEvents = true; } } - //if (Printer.debug) Printer.debug(" this.active: " + this.active); - //if (Printer.debug) Printer.debug(" sendEvents: " + sendEvents); - - // $$kk: 11.19.99: take ACTIVE / INACTIVE / EOM events out; // putting them in is technically an API change. // do not generate ACTIVE / INACTIVE events for now @@ -356,18 +349,12 @@ synchronized (this) { - //if (Printer.debug) Printer.debug(" AbstractDataLine: setStarted: this.started: " + this.started); - //if (Printer.debug) Printer.debug(" started: " + started); - if (this.started != started) { this.started = started; sendEvents = true; } } - //if (Printer.debug) Printer.debug(" this.started: " + this.started); - //if (Printer.debug) Printer.debug(" sendEvents: " + sendEvents); - if (sendEvents) { if (started) { @@ -379,7 +366,6 @@ if (Printer.trace) Printer.trace("< AbstractDataLine: setStarted completed"); } - /** * This method generates a STOP event and sets the started state to false. * It is here for historic reasons when an EOM event existed. @@ -393,9 +379,6 @@ if (Printer.trace) Printer.trace("< AbstractDataLine: setEOM() completed"); } - - - // OVERRIDES OF ABSTRACT LINE METHODS /** @@ -404,6 +387,7 @@ * line is open, this should return quietly because the values * requested will match the current ones. */ + @Override public final void open() throws LineUnavailableException { if (Printer.trace) Printer.trace("> "+getClass().getName()+".open() - AbstractDataLine"); @@ -413,11 +397,11 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+".open() - AbstractDataLine"); } - /** * This should also stop the line. The closed line should not be running or active. * After we close the line, we reset the format and buffer size to the defaults. */ + @Override public final void close() { //$$fb 2001-10-09: Bug #4517739: avoiding deadlock by synchronizing to mixer ! synchronized (mixer) { @@ -445,12 +429,6 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+".close() - in AbstractDataLine"); } - - // IMPLEMENTATIONS OF ABSTRACT LINE ABSTRACE METHODS - - - // ABSTRACT METHODS - abstract void implOpen(AudioFormat format, int bufferSize) throws LineUnavailableException; abstract void implClose();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java Fri Aug 19 18:48:25 2016 -0700 @@ -36,7 +36,6 @@ import javax.sound.sampled.LineListener; import javax.sound.sampled.LineUnavailableException; - /** * AbstractLine * @@ -72,19 +71,19 @@ this.controls = controls; } - // LINE METHODS + @Override public final Line.Info getLineInfo() { return info; } - + @Override public final boolean isOpen() { return open; } - + @Override public final void addLineListener(LineListener listener) { synchronized(listeners) { if ( ! (listeners.contains(listener)) ) { @@ -93,22 +92,22 @@ } } - /** * Removes an audio listener. * @param listener listener to remove */ + @Override public final void removeLineListener(LineListener listener) { listeners.removeElement(listener); } - /** * Obtains the set of controls supported by the * line. If no controls are supported, returns an * array of length 0. * @return control set */ + @Override public final Control[] getControls() { Control[] returnedArray = new Control[controls.length]; @@ -119,7 +118,7 @@ return returnedArray; } - + @Override public final boolean isControlSupported(Control.Type controlType) { // protect against a NullPointerException if (controlType == null) { @@ -135,7 +134,7 @@ return false; } - + @Override public final Control getControl(Control.Type controlType) { // protect against a NullPointerException if (controlType != null) { @@ -150,10 +149,8 @@ throw new IllegalArgumentException("Unsupported control type: " + controlType); } - // HELPER METHODS - /** * This method sets the open state and generates * events if it changes. @@ -182,7 +179,6 @@ if (Printer.trace) Printer.trace("< "+getClass().getName()+" (AbstractLine): setOpen(" + open + ") this.open: " + this.open); } - /** * Send line events. */ @@ -190,7 +186,6 @@ getEventDispatcher().sendAudioEvents(event, listeners); } - /** * This is an error in the API: getFramePosition * should return a long value. At CD quality, @@ -200,7 +195,6 @@ return (int) getLongFramePosition(); } - /** * Return the frame position in a long value * This implementation returns AudioSystem.NOT_SPECIFIED. @@ -209,7 +203,6 @@ return AudioSystem.NOT_SPECIFIED; } - // $$kk: 06.03.99: returns the mixer used in construction. // this is a hold-over from when there was a public method like // this on line and should be fixed!! @@ -232,8 +225,8 @@ } } - // ABSTRACT METHODS - + @Override public abstract void open() throws LineUnavailableException; + @Override public abstract void close(); }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java Fri Aug 19 18:48:25 2016 -0700 @@ -26,10 +26,17 @@ package com.sun.media.sound; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Collections; -import javax.sound.midi.*; +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiDeviceReceiver; +import javax.sound.midi.MidiDeviceTransmitter; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Transmitter; /** @@ -43,11 +50,8 @@ */ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice { - // STATIC VARIABLES private static final boolean TRACE_TRANSMITTER = false; - // INSTANCE VARIABLES - private ArrayList<Receiver> receiverList; private TransmitterList transmitterList; @@ -62,7 +66,6 @@ private final MidiDevice.Info info; - // DEVICE STATE private volatile boolean open; @@ -73,15 +76,10 @@ private List<Object> openKeepingObjects; /** - * This is the device handle returned from native code + * This is the device handle returned from native code. */ protected volatile long id; - - - // CONSTRUCTOR - - /** * Constructs an AbstractMidiDevice with the specified info object. * @param info the description of the device @@ -99,9 +97,9 @@ if(Printer.trace) Printer.trace("<< AbstractMidiDevice CONSTRUCTOR completed"); } - // MIDI DEVICE METHODS + @Override public final MidiDevice.Info getDeviceInfo() { return info; } @@ -111,6 +109,7 @@ * opened the device implicitly from closing it. The only way to close the device after * this call is a call to close(). */ + @Override public final void open() throws MidiUnavailableException { if (Printer.trace) Printer.trace("> AbstractMidiDevice: open()"); synchronized(this) { @@ -120,8 +119,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: open() completed"); } - - /** Open the device implicitly. * This method is intended to be used by AbstractReceiver * and BasicTransmitter. Actually, it is called by getReceiverReferenceCounting() and @@ -146,7 +143,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: openInternal() completed"); } - private void doOpen() throws MidiUnavailableException { if (Printer.trace) Printer.trace("> AbstractMidiDevice: doOpen()"); synchronized(this) { @@ -158,7 +154,7 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: doOpen() completed"); } - + @Override public final void close() { if (Printer.trace) Printer.trace("> AbstractMidiDevice: close()"); synchronized (this) { @@ -168,7 +164,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: close() completed"); } - /** Close the device for an object that implicitely opened it. * This method is intended to be used by Transmitter.close() and Receiver.close(). * Those methods should pass this for the object parameter. Since Transmitters or Receivers @@ -196,7 +191,6 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: closeInternal() completed"); } - public final void doClose() { if (Printer.trace) Printer.trace("> AbstractMidiDevice: doClose()"); synchronized(this) { @@ -208,12 +202,11 @@ if (Printer.trace) Printer.trace("< AbstractMidiDevice: doClose() completed"); } - + @Override public final boolean isOpen() { return open; } - protected void implClose() { synchronized (traRecLock) { if (receiverList != null) { @@ -230,21 +223,21 @@ } } - /** * This implementation always returns -1. * Devices that actually provide this should over-ride * this method. */ + @Override public long getMicrosecondPosition() { return -1; } - /** Return the maximum number of Receivers supported by this device. Depending on the return value of hasReceivers(), this method returns either 0 or -1. Subclasses should rather override hasReceivers() than override this method. */ + @Override public final int getMaxReceivers() { if (hasReceivers()) { return -1; @@ -253,11 +246,11 @@ } } - /** Return the maximum number of Transmitters supported by this device. Depending on the return value of hasTransmitters(), this method returns either 0 or -1. Subclasses should override hasTransmitters(). */ + @Override public final int getMaxTransmitters() { if (hasTransmitters()) { return -1; @@ -266,7 +259,6 @@ } } - /** Retrieve a Receiver for this device. This method returns the value returned by createReceiver(), if it doesn't throw an exception. Subclasses should rather override createReceiver() than override @@ -274,6 +266,7 @@ If createReceiver returns a Receiver, it is added to the internal list of Receivers (see getReceiversList) */ + @Override public final Receiver getReceiver() throws MidiUnavailableException { Receiver receiver; synchronized (traRecLock) { @@ -283,7 +276,7 @@ return receiver; } - + @Override @SuppressWarnings("unchecked") // Cast of result of clone public final List<Receiver> getReceivers() { List<Receiver> recs; @@ -298,12 +291,12 @@ return recs; } - /** * This implementation uses createTransmitter, which may throw an exception. * If a transmitter is returned in createTransmitter, it is added to the internal * TransmitterList */ + @Override public final Transmitter getTransmitter() throws MidiUnavailableException { Transmitter transmitter; synchronized (traRecLock) { @@ -313,7 +306,7 @@ return transmitter; } - + @Override @SuppressWarnings("unchecked") // Cast of result of clone public final List<Transmitter> getTransmitters() { List<Transmitter> tras; @@ -328,19 +321,16 @@ return tras; } - - // HELPER METHODS - final long getId() { return id; } - // REFERENCE COUNTING /** Retrieve a Receiver and open the device implicitly. This method is called by MidiSystem.getReceiver(). */ + @Override public final Receiver getReceiverReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getReceiver() throws an exception, @@ -354,10 +344,10 @@ return receiver; } - /** Retrieve a Transmitter and open the device implicitly. This method is called by MidiSystem.getTransmitter(). */ + @Override public final Transmitter getTransmitterReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getTransmitter() throws an exception, @@ -371,7 +361,6 @@ return transmitter; } - /** Return the list of objects that have opened the device implicitely. */ private synchronized List<Object> getOpenKeepingObjects() { @@ -381,23 +370,19 @@ return openKeepingObjects; } - - // RECEIVER HANDLING METHODS - /** Return the internal list of Receivers, possibly creating it first. */ private List<Receiver> getReceiverList() { synchronized (traRecLock) { if (receiverList == null) { - receiverList = new ArrayList<Receiver>(); + receiverList = new ArrayList<>(); } } return receiverList; } - /** Returns if this device supports Receivers. Subclasses that use Receivers should override this method to return true. They also should override createReceiver(). @@ -408,7 +393,6 @@ return false; } - /** Create a Receiver object. throwing an exception here means that Receivers aren't enabled. Subclasses that use Receivers should override this method with @@ -420,8 +404,6 @@ throw new MidiUnavailableException("MIDI IN receiver not available"); } - - // TRANSMITTER HANDLING /** Return the internal list of Transmitters, possibly creating it first. @@ -435,7 +417,6 @@ return transmitterList; } - /** Returns if this device supports Transmitters. Subclasses that use Transmitters should override this method to return true. They also should override createTransmitter(). @@ -446,7 +427,6 @@ return false; } - /** Create a Transmitter object. throwing an exception here means that Transmitters aren't enabled. Subclasses that use Transmitters should override this method with @@ -458,20 +438,16 @@ throw new MidiUnavailableException("MIDI OUT transmitter not available"); } - // ABSTRACT METHODS - protected abstract void implOpen() throws MidiUnavailableException; - /** - * close this device if discarded by the garbage collector + * close this device if discarded by the garbage collector. */ + @Override protected final void finalize() { close(); } - // INNER CLASSES - /** Base class for Receivers. Subclasses that use Receivers must use this base class, since it contains magic necessary to manage implicit closing the device. @@ -550,6 +526,7 @@ this.tlist = tlist; } + @Override public final void setReceiver(Receiver receiver) { if (tlist != null && this.receiver != receiver) { if (Printer.debug) Printer.debug("Transmitter "+toString()+": set receiver "+receiver); @@ -558,16 +535,17 @@ } } + @Override public final Receiver getReceiver() { return receiver; } - /** Close the Transmitter. * Here, the call to the magic method closeInternal() takes place. * Therefore, subclasses that override this method must call * 'super.close()'. */ + @Override public final void close() { AbstractMidiDevice.this.closeInternal(this); if (tlist != null) { @@ -577,19 +555,19 @@ } } + @Override public final MidiDevice getMidiDevice() { return AbstractMidiDevice.this; } } // class BasicTransmitter - /** - * a class to manage a list of transmitters + * a class to manage a list of transmitters. */ final class TransmitterList { - private final ArrayList<Transmitter> transmitters = new ArrayList<Transmitter>(); + private final ArrayList<Transmitter> transmitters = new ArrayList<>(); private MidiOutDevice.MidiOutReceiver midiOutReceiver; // how many transmitters must be present for optimized @@ -712,9 +690,8 @@ } } - /** - * Send this message to all transmitters + * Send this message to all transmitters. */ void sendMessage(MidiMessage message, long timeStamp) { if (message instanceof FastShortMessage) { @@ -746,8 +723,5 @@ } } } - - } // TransmitterList - }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java Fri Aug 19 18:48:25 2016 -0700 @@ -52,7 +52,6 @@ // also for memory's sake, do not initialize the arrays here } - final synchronized void readDeviceInfos() { Info[] infos = getInfoCache(); MidiDevice[] devices = getDeviceCache(); @@ -148,10 +147,6 @@ throw MidiUtils.unsupportedDevice(info); } - - // INNER CLASSES - - /** * Info class for MidiDevices. Adds an index value for * making native references to a particular device. @@ -182,9 +177,6 @@ } // class Info - - // ABSTRACT METHODS - abstract int getNumDevices(); abstract MidiDevice[] getDeviceCache(); abstract void setDeviceCache(MidiDevice[] devices);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMixer.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMixer.java Fri Aug 19 18:48:25 2016 -0700 @@ -28,9 +28,9 @@ import java.util.Vector; import javax.sound.sampled.Control; -import javax.sound.sampled.Mixer; import javax.sound.sampled.Line; import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; /** * Abstract Mixer. Implements Mixer (with abstract methods) and specifies @@ -76,29 +76,18 @@ */ private boolean manuallyOpened = false; + // STATE VARIABLES /** - * Supported formats for the mixer. - */ - //$$fb DELETE - //protected Vector formats = new Vector(); - - - // STATE VARIABLES - - - /** - * Source lines (ports) currently open + * Source lines (ports) currently open. */ private final Vector<Line> sourceLines = new Vector<>(); - /** * Target lines currently open. */ private final Vector<Line> targetLines = new Vector<>(); - /** * Constructs a new AbstractMixer. * @param mixer the mixer with which this line is associated @@ -124,30 +113,28 @@ this.targetLineInfo = targetLineInfo; } - // MIXER METHODS - + @Override public final Mixer.Info getMixerInfo() { return mixerInfo; } - + @Override public final Line.Info[] getSourceLineInfo() { Line.Info[] localArray = new Line.Info[sourceLineInfo.length]; System.arraycopy(sourceLineInfo, 0, localArray, 0, sourceLineInfo.length); return localArray; } - + @Override public final Line.Info[] getTargetLineInfo() { - Line.Info[] localArray = new Line.Info[targetLineInfo.length]; System.arraycopy(targetLineInfo, 0, localArray, 0, targetLineInfo.length); return localArray; } - + @Override public final Line.Info[] getSourceLineInfo(Line.Info info) { int i; @@ -168,7 +155,7 @@ return returnedArray; } - + @Override public final Line.Info[] getTargetLineInfo(Line.Info info) { int i; @@ -189,7 +176,7 @@ return returnedArray; } - + @Override public final boolean isLineSupported(Line.Info info) { int i; @@ -211,9 +198,10 @@ return false; } - + @Override public abstract Line getLine(Line.Info info) throws LineUnavailableException; + @Override public abstract int getMaxLines(Line.Info info); protected abstract void implOpen() throws LineUnavailableException; @@ -221,7 +209,7 @@ protected abstract void implStop(); protected abstract void implClose(); - + @Override public final Line[] getSourceLines() { Line[] localLines; @@ -238,7 +226,7 @@ return localLines; } - + @Override public final Line[] getTargetLines() { Line[] localLines; @@ -255,37 +243,37 @@ return localLines; } + /** + * Default implementation always throws an exception. + */ + @Override + public final void synchronize(Line[] lines, boolean maintainSync) { + throw new IllegalArgumentException("Synchronization not supported by this mixer."); + } /** * Default implementation always throws an exception. */ - public final void synchronize(Line[] lines, boolean maintainSync) { - throw new IllegalArgumentException("Synchronization not supported by this mixer."); - } - - - /** - * Default implementation always throws an exception. - */ + @Override public final void unsynchronize(Line[] lines) { throw new IllegalArgumentException("Synchronization not supported by this mixer."); } - /** * Default implementation always returns false. */ + @Override public final boolean isSynchronizationSupported(Line[] lines, boolean maintainSync) { return false; } - // OVERRIDES OF ABSTRACT DATA LINE METHODS /** * This implementation tries to open the mixer with its current format and buffer size settings. */ + @Override public final synchronized void open() throws LineUnavailableException { open(true); } @@ -307,10 +295,8 @@ if (Printer.trace) Printer.trace("<< AbstractMixer: open() succeeded"); } - // METHOD FOR INTERNAL IMPLEMENTATION USE - /** * The default implementation of this method just determines whether * this line is a source or target line, calls open(no-arg) on the @@ -357,7 +343,6 @@ if (Printer.trace) Printer.trace("<< AbstractMixer: open(" + line + ") completed"); } - /** * Removes this line from the list of open source lines and * open target lines, if it exists in either. @@ -388,10 +373,10 @@ if (Printer.trace) Printer.trace("<< AbstractMixer: close(" + line + ") succeeded"); } - /** * Close all lines and then close this mixer. */ + @Override public final synchronized void close() { if (Printer.trace) Printer.trace(">> AbstractMixer: close()"); if (isOpen()) { @@ -439,7 +424,6 @@ if (Printer.trace) Printer.trace("<< AbstractMixer: start(" + line + ") succeeded"); } - /** * Stops the mixer if this was the last running line. */ @@ -492,8 +476,6 @@ if (Printer.trace) Printer.trace("<< AbstractMixer: stop(" + line + ") succeeded"); } - - /** * Determines whether this is a source line for this mixer. * Right now this just checks whether it's supported, but should @@ -510,7 +492,6 @@ return false; } - /** * Determines whether this is a target line for this mixer. * Right now this just checks whether it's supported, but should @@ -527,7 +508,6 @@ return false; } - /** * Returns the first complete Line.Info object it finds that * matches the one specified, or null if no matching Line.Info @@ -551,8 +531,6 @@ return targetLineInfo[i]; } } - return null; } - }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AiffFileFormat.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AiffFileFormat.java Fri Aug 19 18:48:25 2016 -0700 @@ -87,5 +87,4 @@ int getSsndChunkOffset() { return getHeaderSize()-16; } - }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AiffFileReader.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AiffFileReader.java Fri Aug 19 18:48:25 2016 -0700 @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; -import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFileFormat.Type; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem;
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java Fri Aug 19 18:48:25 2016 -0700 @@ -33,7 +33,6 @@ import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; - /** * A-law encodes linear data, and decodes a-law data to linear data. * @@ -52,7 +51,7 @@ 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; /** - * Initializes the decode tables + * Initializes the decode tables. */ static { for (int i=0;i<256;i++) { @@ -83,10 +82,7 @@ super(alawEncodings, alawEncodings); } - // NEW CODE - - /** - */ + @Override public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat){ if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED )) { @@ -117,8 +113,7 @@ } } - /** - */ + @Override public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){ Objects.requireNonNull(sourceFormat); if( (targetEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) && sourceFormat.getEncoding().equals( AudioFormat.Encoding.ALAW)) || @@ -129,8 +124,7 @@ } } - /** - */ + @Override public AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream){ AudioFormat sourceFormat = sourceStream.getFormat(); AudioFormat.Encoding sourceEncoding = sourceFormat.getEncoding(); @@ -169,9 +163,7 @@ return getConvertedStream(targetFormat, sourceStream); } - /** - * use old code... - */ + @Override public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){ if (!isConversionSupported(targetFormat, sourceStream.getFormat())) throw new IllegalArgumentException("Unsupported conversion: " @@ -180,10 +172,6 @@ return getConvertedStream( targetFormat, sourceStream ); } - - // OLD CODE - - /** * Opens the codec with the specified parameters. * @param stream stream from which data to be processed should be read @@ -192,7 +180,6 @@ * @throws IllegalArgumentException if the format combination supplied is * not supported. */ - /* public AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) { */ private AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) { AudioInputStream cs = null; @@ -201,7 +188,7 @@ if( inputFormat.matches(outputFormat) ) { cs = stream; } else { - cs = (AudioInputStream) (new AlawCodecStream(stream, outputFormat)); + cs = new AlawCodecStream(stream, outputFormat); } return cs; @@ -214,7 +201,6 @@ * returns an array of length 0. * @return array of supported output formats. */ - /* public AudioFormat[] getOutputFormats(AudioFormat inputFormat) { */ private AudioFormat[] getOutputFormats(AudioFormat inputFormat) { @@ -343,18 +329,20 @@ * Note that this won't actually read anything; must read in * two-byte units. */ + @Override public int read() throws IOException { byte[] b = new byte[1]; return read(b, 0, b.length); } - + @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } + @Override public int read(byte[] b, int off, int len) throws IOException { // don't read fractional frames
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java Fri Aug 19 18:48:25 2016 -0700 @@ -45,6 +45,7 @@ */ public final class AudioFileSoundbankReader extends SoundbankReader { + @Override public Soundbank getSoundbank(URL url) throws InvalidMidiDataException, IOException { try { @@ -59,6 +60,7 @@ } } + @Override public Soundbank getSoundbank(InputStream stream) throws InvalidMidiDataException, IOException { stream.mark(512); @@ -108,6 +110,7 @@ } } + @Override public Soundbank getSoundbank(File file) throws InvalidMidiDataException, IOException { try {
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatConverter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatConverter.java Fri Aug 19 18:48:25 2016 -0700 @@ -89,8 +89,9 @@ mask = (byte) 0xFF; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { byte[] ret = converter.toByteArray(in_buff, in_offset, in_len, out_buff, out_offset); @@ -102,8 +103,9 @@ return ret; } + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { if (mask_buffer == null || mask_buffer.length < in_buff.length) mask_buffer = new byte[in_buff.length]; System.arraycopy(in_buff, 0, mask_buffer, 0, in_buff.length); @@ -132,8 +134,9 @@ double[] double_buff = null; + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int in_len = out_len * 8; if (bytebuffer == null || bytebuffer.capacity() < in_len) { bytebuffer = ByteBuffer.allocate(in_len).order( @@ -154,8 +157,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int out_len = in_len * 8; if (bytebuffer == null || bytebuffer.capacity() < out_len) { bytebuffer = ByteBuffer.allocate(out_len).order( @@ -184,8 +188,9 @@ double[] double_buff = null; + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int in_len = out_len * 8; if (bytebuffer == null || bytebuffer.capacity() < in_len) { bytebuffer = ByteBuffer.allocate(in_len).order( @@ -206,8 +211,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int out_len = in_len * 8; if (bytebuffer == null || bytebuffer.capacity() < out_len) { bytebuffer = ByteBuffer.allocate(out_len).order( @@ -240,8 +246,9 @@ FloatBuffer floatbuffer = null; + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int in_len = out_len * 4; if (bytebuffer == null || bytebuffer.capacity() < in_len) { bytebuffer = ByteBuffer.allocate(in_len).order( @@ -255,8 +262,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int out_len = in_len * 4; if (bytebuffer == null || bytebuffer.capacity() < out_len) { bytebuffer = ByteBuffer.allocate(out_len).order( @@ -277,8 +285,9 @@ FloatBuffer floatbuffer = null; + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int in_len = out_len * 4; if (bytebuffer == null || bytebuffer.capacity() < in_len) { bytebuffer = ByteBuffer.allocate(in_len).order( @@ -292,8 +301,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int out_len = in_len * 4; if (bytebuffer == null || bytebuffer.capacity() < out_len) { bytebuffer = ByteBuffer.allocate(out_len).order( @@ -316,8 +326,9 @@ // PCM 8 bit, signed private static class AudioFloatConversion8S extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -327,8 +338,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -341,8 +353,9 @@ // PCM 8 bit, unsigned private static class AudioFloatConversion8U extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -352,8 +365,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -372,8 +386,9 @@ // PCM 16 bit, signed, little-endian private static class AudioFloatConversion16SL extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int len = out_offset + out_len; for (int ox = out_offset; ox < len; ox++) { @@ -383,8 +398,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ox = out_offset; int len = in_offset + in_len; for (int ix = in_offset; ix < len; ix++) { @@ -399,8 +415,9 @@ // PCM 16 bit, signed, big-endian private static class AudioFloatConversion16SB extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -410,8 +427,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -426,8 +444,9 @@ // PCM 16 bit, unsigned, little-endian private static class AudioFloatConversion16UL extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -438,8 +457,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -454,8 +474,9 @@ // PCM 16 bit, unsigned, big-endian private static class AudioFloatConversion16UB extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -466,8 +487,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -488,8 +510,9 @@ // PCM 24 bit, signed, little-endian private static class AudioFloatConversion24SL extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -502,8 +525,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -521,8 +545,9 @@ // PCM 24 bit, signed, big-endian private static class AudioFloatConversion24SB extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -535,8 +560,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -554,8 +580,9 @@ // PCM 24 bit, unsigned, little-endian private static class AudioFloatConversion24UL extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -567,8 +594,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -585,8 +613,9 @@ // PCM 24 bit, unsigned, big-endian private static class AudioFloatConversion24UB extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -598,8 +627,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -622,8 +652,9 @@ // PCM 32 bit, signed, little-endian private static class AudioFloatConversion32SL extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -635,8 +666,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -652,8 +684,9 @@ // PCM 32 bit, signed, big-endian private static class AudioFloatConversion32SB extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -665,8 +698,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -682,8 +716,9 @@ // PCM 32 bit, unsigned, little-endian private static class AudioFloatConversion32UL extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -696,8 +731,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -715,8 +751,9 @@ // PCM 32 bit, unsigned, big-endian private static class AudioFloatConversion32UB extends AudioFloatConverter { + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -729,8 +766,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -760,8 +798,9 @@ this.xbytes = xbytes; } + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -774,8 +813,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -801,8 +841,9 @@ this.xbytes = xbytes; } + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -816,8 +857,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -843,8 +885,9 @@ this.xbytes = xbytes; } + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -858,8 +901,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) { @@ -886,8 +930,9 @@ this.xbytes = xbytes; } + @Override public float[] toFloatArray(byte[] in_buff, int in_offset, - float[] out_buff, int out_offset, int out_len) { + float[] out_buff, int out_offset, int out_len) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < out_len; i++) { @@ -901,8 +946,9 @@ return out_buff; } + @Override public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, - byte[] out_buff, int out_offset) { + byte[] out_buff, int out_offset) { int ix = in_offset; int ox = out_offset; for (int i = 0; i < in_len; i++) {
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java Fri Aug 19 18:48:25 2016 -0700 @@ -32,9 +32,9 @@ import java.util.Objects; import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioFormat.Encoding; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.AudioFormat.Encoding; import javax.sound.sampled.spi.FormatConversionProvider; /** @@ -63,6 +63,7 @@ fsize = ((targetFormat.getSampleSizeInBits() + 7) / 8); } + @Override public int read() throws IOException { byte[] b = new byte[1]; int ret = read(b); @@ -71,6 +72,7 @@ return b[0] & 0xFF; } + @Override public int read(byte[] b, int off, int len) throws IOException { int flen = len / fsize; @@ -83,6 +85,7 @@ return ret * fsize; } + @Override public int available() throws IOException { int ret = stream.available(); if (ret < 0) @@ -90,22 +93,27 @@ return ret * fsize; } + @Override public void close() throws IOException { stream.close(); } + @Override public synchronized void mark(int readlimit) { stream.mark(readlimit * fsize); } + @Override public boolean markSupported() { return stream.markSupported(); } + @Override public synchronized void reset() throws IOException { stream.reset(); } + @Override public long skip(long n) throws IOException { long ret = stream.skip(n / fsize); if (ret < 0) @@ -141,30 +149,37 @@ .isBigEndian()); } + @Override public int available() throws IOException { return (ais.available() / sourceChannels) * targetChannels; } + @Override public void close() throws IOException { ais.close(); } + @Override public AudioFormat getFormat() { return targetFormat; } + @Override public long getFrameLength() { return ais.getFrameLength(); } + @Override public void mark(int readlimit) { ais.mark((readlimit / targetChannels) * sourceChannels); } + @Override public boolean markSupported() { return ais.markSupported(); } + @Override public int read(float[] b, int off, int len) throws IOException { int len2 = (len / targetChannels) * sourceChannels; if (conversion_buffer == null || conversion_buffer.length < len2) @@ -212,10 +227,12 @@ return (ret / sourceChannels) * targetChannels; } + @Override public void reset() throws IOException { ais.reset(); } + @Override public long skip(long len) throws IOException { long ret = ais.skip((len / targetChannels) * sourceChannels); if (ret < 0) @@ -305,22 +322,27 @@ ibuffer_len = buffer_len; } + @Override public int available() throws IOException { return 0; } + @Override public void close() throws IOException { ais.close(); } + @Override public AudioFormat getFormat() { return targetFormat; } + @Override public long getFrameLength() { return AudioSystem.NOT_SPECIFIED; // ais.getFrameLength(); } + @Override public void mark(int readlimit) { ais.mark((int) (readlimit * pitch[0])); mark_ibuffer_index = ibuffer_index; @@ -337,6 +359,7 @@ } } + @Override public boolean markSupported() { return ais.markSupported(); } @@ -381,6 +404,7 @@ } + @Override public int read(float[] b, int off, int len) throws IOException { if (cbuffer == null || cbuffer[0].length < len / nrofchannels) { @@ -431,6 +455,7 @@ return len - remain * nrofchannels; } + @Override public void reset() throws IOException { ais.reset(); if (mark_ibuffer == null) @@ -447,6 +472,7 @@ } + @Override public long skip(long len) throws IOException { if (len < 0) return 0; @@ -474,8 +500,9 @@ Encoding.PCM_UNSIGNED, Encoding.PCM_FLOAT}; + @Override public AudioInputStream getAudioInputStream(Encoding targetEncoding, - AudioInputStream sourceStream) { + AudioInputStream sourceStream) { if (!isConversionSupported(targetEncoding, sourceStream.getFormat())) { throw new IllegalArgumentException( "Unsupported conversion: " + sourceStream.getFormat() @@ -496,8 +523,9 @@ return getAudioInputStream(targetFormat, sourceStream); } + @Override public AudioInputStream getAudioInputStream(AudioFormat targetFormat, - AudioInputStream sourceStream) { + AudioInputStream sourceStream) { if (!isConversionSupported(targetFormat, sourceStream.getFormat())) throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " @@ -526,16 +554,19 @@ .getFrameLength()); } + @Override public Encoding[] getSourceEncodings() { return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, Encoding.PCM_FLOAT }; } + @Override public Encoding[] getTargetEncodings() { return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, Encoding.PCM_FLOAT }; } + @Override public Encoding[] getTargetEncodings(AudioFormat sourceFormat) { if (AudioFloatConverter.getConverter(sourceFormat) == null) return new Encoding[0]; @@ -543,14 +574,15 @@ Encoding.PCM_FLOAT }; } + @Override public AudioFormat[] getTargetFormats(Encoding targetEncoding, - AudioFormat sourceFormat) { + AudioFormat sourceFormat) { Objects.requireNonNull(targetEncoding); if (AudioFloatConverter.getConverter(sourceFormat) == null) return new AudioFormat[0]; int channels = sourceFormat.getChannels(); - ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>(); + ArrayList<AudioFormat> formats = new ArrayList<>(); if (targetEncoding.equals(Encoding.PCM_SIGNED)) formats.add(new AudioFormat(Encoding.PCM_SIGNED, @@ -598,8 +630,9 @@ return formats.toArray(new AudioFormat[formats.size()]); } + @Override public boolean isConversionSupported(AudioFormat targetFormat, - AudioFormat sourceFormat) { + AudioFormat sourceFormat) { Objects.requireNonNull(targetFormat); if (AudioFloatConverter.getConverter(sourceFormat) == null) return false; @@ -612,8 +645,9 @@ return true; } + @Override public boolean isConversionSupported(Encoding targetEncoding, - AudioFormat sourceFormat) { + AudioFormat sourceFormat) { Objects.requireNonNull(targetEncoding); if (AudioFloatConverter.getConverter(sourceFormat) == null) return false;
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatInputStream.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatInputStream.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; import java.io.ByteArrayInputStream; @@ -66,14 +67,17 @@ } + @Override public AudioFormat getFormat() { return format; } + @Override public long getFrameLength() { return buffer_len;// / format.getFrameSize(); } + @Override public int read(float[] b, int off, int len) throws IOException { if (b == null) throw new NullPointerException(); @@ -91,6 +95,7 @@ return len; } + @Override public long skip(long len) throws IOException { if (pos >= buffer_len) return -1; @@ -102,21 +107,26 @@ return len; } + @Override public int available() throws IOException { return buffer_len - pos; } + @Override public void close() throws IOException { } + @Override public void mark(int readlimit) { markpos = pos; } + @Override public boolean markSupported() { return true; } + @Override public void reset() throws IOException { pos = markpos; } @@ -163,14 +173,17 @@ this.stream = stream; } + @Override public AudioFormat getFormat() { return stream.getFormat(); } + @Override public long getFrameLength() { return stream.getFrameLength(); } + @Override public int read(float[] b, int off, int len) throws IOException { int b_len = len * framesize_pc; if (buffer == null || buffer.length < b_len) @@ -182,6 +195,7 @@ return ret / framesize_pc; } + @Override public long skip(long len) throws IOException { long b_len = len * framesize_pc; long ret = stream.skip(b_len); @@ -190,22 +204,27 @@ return ret / framesize_pc; } + @Override public int available() throws IOException { return stream.available() / framesize_pc; } + @Override public void close() throws IOException { stream.close(); } + @Override public void mark(int readlimit) { stream.mark(readlimit * framesize_pc); } + @Override public boolean markSupported() { return stream.markSupported(); } + @Override public void reset() throws IOException { stream.reset(); }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioSynthesizer.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioSynthesizer.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,9 +22,11 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; import java.util.Map; + import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Synthesizer; import javax.sound.sampled.AudioFormat; @@ -53,7 +55,7 @@ * @return current audio data format * @see AudioFormat */ - public AudioFormat getFormat(); + AudioFormat getFormat(); /** * Gets information about the possible properties for the synthesizer. @@ -63,8 +65,7 @@ * describing possible properties. This array may be an empty array if * no properties are required. */ - public AudioSynthesizerPropertyInfo[] getPropertyInfo( - Map<String, Object> info); + AudioSynthesizerPropertyInfo[] getPropertyInfo(Map<String, Object> info); /** * Opens the synthesizer and starts rendering audio into @@ -93,7 +94,7 @@ * @see #close * @see #isOpen */ - public void open(SourceDataLine line, Map<String, Object> info) + void open(SourceDataLine line, Map<String, Object> info) throws MidiUnavailableException; /** @@ -123,6 +124,7 @@ * @see #close * @see #isOpen */ - public AudioInputStream openStream(AudioFormat targetFormat, - Map<String, Object> info) throws MidiUnavailableException; + AudioInputStream openStream(AudioFormat targetFormat, + Map<String, Object> info) + throws MidiUnavailableException; }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; /**
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AutoClosingClip.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AutoClosingClip.java Fri Aug 19 18:48:25 2016 -0700 @@ -28,7 +28,7 @@ import javax.sound.sampled.Clip; /** - * Interface for Clip objects that close themselves automatically + * Interface for Clip objects that close themselves automatically. * * @author Florian Bomers */
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AutoConnectSequencer.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AutoConnectSequencer.java Fri Aug 19 18:48:25 2016 -0700 @@ -41,6 +41,5 @@ * needs to re-connect itself to a suitable * device in open(). */ - public void setAutoConnect(Receiver autoConnectReceiver); - + void setAutoConnect(Receiver autoConnectReceiver); }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSInfo.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSInfo.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; /**
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSInstrument.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSInstrument.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; import java.util.ArrayList; @@ -47,8 +48,8 @@ boolean druminstrument = false; byte[] guid = null; DLSInfo info = new DLSInfo(); - List<DLSRegion> regions = new ArrayList<DLSRegion>(); - List<DLSModulator> modulators = new ArrayList<DLSModulator>(); + List<DLSRegion> regions = new ArrayList<>(); + List<DLSModulator> modulators = new ArrayList<>(); public DLSInstrument() { super(null, null, null, null); @@ -62,6 +63,7 @@ return info; } + @Override public String getName() { return info.name; } @@ -70,6 +72,7 @@ info.name = name; } + @Override public ModelPatch getPatch() { return new ModelPatch(bank, preset, druminstrument); } @@ -86,6 +89,7 @@ } } + @Override public Object getData() { return null; } @@ -98,6 +102,7 @@ return modulators; } + @Override public String toString() { if (druminstrument) return "Drumkit: " + info.name @@ -362,17 +367,17 @@ return null; } + @Override public ModelPerformer[] getPerformers() { - List<ModelPerformer> performers = new ArrayList<ModelPerformer>(); + List<ModelPerformer> performers = new ArrayList<>(); - Map<String, DLSModulator> modmap = new HashMap<String, DLSModulator>(); + Map<String, DLSModulator> modmap = new HashMap<>(); for (DLSModulator mod: getModulators()) { modmap.put(mod.getSource() + "x" + mod.getControl() + "=" + mod.getDestination(), mod); } - Map<String, DLSModulator> insmodmap = - new HashMap<String, DLSModulator>(); + Map<String, DLSModulator> insmodmap = new HashMap<>(); for (DLSRegion zone: regions) { ModelPerformer performer = new ModelPerformer();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSModulator.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSModulator.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; /**
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSRegion.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSRegion.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; import java.util.ArrayList; @@ -39,7 +40,7 @@ public final class DLSRegion { public static final int OPTION_SELFNONEXCLUSIVE = 0x0001; - List<DLSModulator> modulators = new ArrayList<DLSModulator>(); + List<DLSModulator> modulators = new ArrayList<>(); int keyfrom; int keyto; int velfrom;
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSSample.java Fri Aug 19 14:33:52 2016 -0700 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DLSSample.java Fri Aug 19 18:48:25 2016 -0700 @@ -22,10 +22,12 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; import java.io.InputStream; import java.util.Arrays; + import javax.sound.midi.Soundbank; import javax.sound.midi.SoundbankResource; import javax.sound.sampled.AudioFormat; @@ -60,6 +62,7 @@ return info; } + @Override public Object getData() { AudioFormat format = getFormat(); @@ -93,6 +96,7 @@ this.data = new ModelByteBuffer(data, offset, length); } + @Override public String getName() { return info.name; } @@ -109,6 +113,7 @@ this.sampleoptions = sampleOptions; }