This commit is contained in:
Igor Veresov 2016-08-19 18:51:15 -07:00
commit 06492bebc5
704 changed files with 21574 additions and 11146 deletions

View File

@ -374,3 +374,4 @@ d53037a90c441cb528dc41c30827985de0e67c62 jdk-9+123
e8373543a3f0f60589b7d72b1f9b172721124caf jdk-9+129
e613affb88d178dc7c589f1679db113d589bddb4 jdk-9+130
4d2a15091124488080d65848b704e25599b2aaeb jdk-9+131
2e83d21d78cd9c1d52e6cd2599e9c8aa36ea1f52 jdk-9+132

View File

@ -374,3 +374,4 @@ b30ae794d974d7dd3eb4e84203f70021823fa6c6 jdk-9+128
f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131
a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132

View File

@ -251,8 +251,6 @@ SUPPORT_HEADLESS:=@SUPPORT_HEADLESS@
# 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

View File

@ -374,3 +374,4 @@ c7f5ba08fcd4b8416e62c21229f9a07c95498919 jdk-9+126
c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129
77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130
f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
1ab4b9399c4cba584f66c1c088188f2f565fbf9c jdk-9+132

View File

@ -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;

View File

@ -534,3 +534,4 @@ adc8c84b7cf8c540d920182f78a2bc982366432a jdk-9+126
e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132

View File

@ -7152,15 +7152,19 @@ class C2 extends C1 implements I2 {
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 @@ myInit() {
</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 @@ myInit() {
</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 @@ myInit() {
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 @@ typedef void (JNICALL *jvmtiEventVMInit)
- 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>

View File

@ -283,7 +283,7 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
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 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
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) {

View File

@ -130,7 +130,7 @@ bool VM_RedefineClasses::doit_prologue() {
}
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 @@ bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
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;

View File

@ -376,77 +376,99 @@ void BitMap::par_at_put_large_range(idx_t beg, idx_t end, bool value) {
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 BitMap::set_union_with_result(const BitMap& other) {
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() {

View File

@ -284,18 +284,9 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
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;

View File

@ -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)

View File

@ -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");
}
}

View File

@ -374,3 +374,4 @@ bdc3c0b737efbf899709eb3121ce760dcfb51151 jdk-9+127
74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129
e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130
874082a9b565a7092a40bfa934a6e3e3c3455a60 jdk-9+131
907445d85e680ea410fe2c83c0ec64b5508e4f3e jdk-9+132

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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); }
}

View File

@ -26,6 +26,7 @@ import java.util.ArrayList;
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 @@ public class DOMNormalizer implements XMLDocumentHandler {
// 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 @@ public class DOMNormalizer implements XMLDocumentHandler {
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 @@ public class DOMNormalizer implements XMLDocumentHandler {
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 @@ public class DOMNormalizer implements XMLDocumentHandler {
return null;
}
} // DOMNormalizer class

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 @@ InvalidElementSchemeToken = InvalidElementSchemeToken: The element() scheme XPoi
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}''.
InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''.

View File

@ -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;

View File

@ -28,6 +28,7 @@ import java.io.Writer;
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 @@ public class DOMSerializerImpl implements LSSerializer, DOMConfiguration {
} 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 @@ public class DOMSerializerImpl implements LSSerializer, DOMConfiguration {
} 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 @@ public class DOMSerializerImpl implements LSSerializer, DOMConfiguration {
} 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) {

View File

@ -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;

View File

@ -28,6 +28,7 @@ package com.sun.org.apache.xpath.internal.jaxp;
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 @@ class XPathImplUtil {
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);

View File

@ -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 class XPATHErrorResources extends ListResourceBundle
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 @@ public static final String ER_IGNORABLE_WHITESPACE_NOT_HANDLED =
{ 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!"},

View File

@ -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 @@ import org.xml.sax.InputSource;
*
* <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>

View File

@ -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 @@ import org.xml.sax.InputSource;
*
* <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>

View File

@ -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;

View File

@ -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 @@ import org.testng.annotations.Test;
* @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();
}
/*
* 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;
}
}
}

View File

@ -377,3 +377,4 @@ fe4e11bd2423635dc0f5f5cb9a64eb2f2cce7f4c jdk-9+128
46a02f57218e4a8c334dbccf656fb048f823f163 jdk-9+129
39c6293131d91aec7f2f5120395e070a937b8858 jdk-9+130
783e7e2c587f2c7e1b9998a46d90ec196ab2a195 jdk-9+131
9fff2477a4cadf2a9618a76f1f4fe0f20bb5ff3b jdk-9+132

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -374,3 +374,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129
6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131
d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132

View File

@ -183,7 +183,7 @@ DEF_POLICY_DST := $(LIB_DST_DIR)/security/default.policy
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

View File

@ -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 final class AppleProvider extends Provider {
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>() {

View File

@ -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 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
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();

View File

@ -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 @@ package com.sun.crypto.provider;
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 final class SunJCE extends Provider {
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" +

View File

@ -560,7 +560,7 @@ public class BufferedReader extends Reader {
* @since 1.8
*/
public Stream<String> lines() {
Iterator<String> iter = new Iterator<String>() {
Iterator<String> iter = new Iterator<>() {
String nextLine = null;
@Override

View File

@ -187,7 +187,7 @@ public class ByteArrayOutputStream extends OutputStream {
* @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);
}

View File

@ -165,7 +165,7 @@ class CharArrayWriter extends Writer {
*
* @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 @@ class CharArrayWriter extends Writer {
* @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 @@ class CharArrayWriter extends Writer {
* 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 @@ class CharArrayWriter extends Writer {
* @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 @@ class CharArrayWriter extends Writer {
*
* @return an array of chars copied from the input data.
*/
public char toCharArray()[] {
public char[] toCharArray() {
synchronized (lock) {
return Arrays.copyOf(buf, count);
}

View File

@ -228,13 +228,8 @@ abstract class FileSystem {
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 {

View File

@ -1265,22 +1265,21 @@ public class ObjectInputStream
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 @@ public class ObjectInputStream
}
}
);
return result.booleanValue();
}
/**

View File

@ -1050,22 +1050,21 @@ public class ObjectOutputStream
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 @@ public class ObjectOutputStream
}
}
);
return result.booleanValue();
}
/**

View File

@ -1509,11 +1509,9 @@ public class ObjectStreamClass implements Serializable {
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 @@ public class ObjectStreamClass implements Serializable {
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();
}
/**

View File

@ -233,22 +233,16 @@ public class OutputStreamWriter extends Writer {
@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;
}

View File

@ -568,7 +568,7 @@ public class PrintStream extends FilterOutputStream
* @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 @@ public class PrintStream extends FilterOutputStream
* @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 @@ public class PrintStream extends FilterOutputStream
* @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 @@ public class PrintStream extends FilterOutputStream
* @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));
}
/**

View File

@ -504,7 +504,7 @@ public class PrintWriter extends Writer {
* @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 @@ public class PrintWriter extends Writer {
* @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 @@ public class PrintWriter extends Writer {
* @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 @@ public class PrintWriter extends Writer {
* @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));
}
/**

View File

@ -65,12 +65,7 @@ class SequenceInputStream extends InputStream {
*/
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 @@ class SequenceInputStream extends InputStream {
*/
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 @@ class SequenceInputStream extends InputStream {
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;
}
/**

View File

@ -108,6 +108,7 @@ class StringBufferInputStream extends InputStream {
* <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 @@ class StringBufferInputStream extends InputStream {
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;
}

View File

@ -142,8 +142,8 @@ public class StringReader extends Reader {
*/
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
return true;
ensureOpen();
return true;
}
}

View File

@ -139,7 +139,7 @@ public class StringWriter extends Writer {
*
* @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 @@ public class StringWriter extends Writer {
* @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 @@ public class StringWriter extends Writer {
* 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 @@ public class StringWriter extends Writer {
* @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));
}
/**

View File

@ -221,7 +221,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
*
* @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 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
* @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 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
* 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 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
* @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));
}
/**

View File

@ -36,7 +36,6 @@ import sun.invoke.util.Wrapper;
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 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
/*non-public*/ char fieldTypeChar(int i) {
return typeChars.charAt(i);
}
Object fieldSignature() {
String fieldSignature() {
return typeChars;
}
public Class<? extends BoundMethodHandle> fieldHolder() {

View File

@ -27,6 +27,7 @@ package java.lang.invoke;
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 @@ abstract class DelegatingMethodHandle extends MethodHandle {
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 @@ abstract class DelegatingMethodHandle extends MethodHandle {
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 @@ abstract class DelegatingMethodHandle extends MethodHandle {
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 @@ abstract class DelegatingMethodHandle extends MethodHandle {
} 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 {}
}

View File

@ -38,6 +38,7 @@ import java.util.Arrays;
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 @@ class DirectMethodHandle extends MethodHandle {
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 @@ class DirectMethodHandle extends MethodHandle {
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 @@ class DirectMethodHandle extends MethodHandle {
}
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 @@ class DirectMethodHandle extends MethodHandle {
}
/* Placeholder class for DirectMethodHandles generated ahead of time */
private final class Holder {}
final class Holder {}
}

View File

@ -29,21 +29,82 @@ import java.util.Map;
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 @@ class GenerateJLIClassesHelper {
* 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()) {

View File

@ -46,6 +46,7 @@ import java.util.stream.Stream;
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 @@ class InvokerBytecodeGenerator {
}
/** 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 @@ class InvokerBytecodeGenerator {
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());
}

View File

@ -41,6 +41,7 @@ import java.util.HashMap;
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 @@ class LambdaForm {
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 @@ class LambdaForm {
}
}
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 @@ class LambdaForm {
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 @@ class LambdaForm {
}
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 @@ class LambdaForm {
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 @@ class LambdaForm {
/** 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 @@ class LambdaForm {
}
}
/**
* 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 @@ class LambdaForm {
// 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 @@ class LambdaForm {
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 @@ class LambdaForm {
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

View File

@ -1718,10 +1718,19 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
}
@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 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
return GenerateJLIClassesHelper
.generateConcreteBMHClassBytes(types);
}
@Override
public byte[] generateBasicFormsClassBytes(final String className) {
return GenerateJLIClassesHelper
.generateBasicFormsClassBytes(className);
}
});
}
@ -1925,7 +1940,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
* @return whether the counter has reached the limit.
*/
static boolean countedLoopPredicate(int counter, int limit) {
return counter <= limit;
return counter < limit;
}
/**

View File

@ -4583,7 +4583,8 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
* // 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 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
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);
}

View File

@ -29,11 +29,9 @@ import java.security.AccessController;
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.Unsafe;
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;

View File

@ -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 @@ public abstract class AuthProvider extends Provider {
* @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);
}
/**

View File

@ -67,14 +67,14 @@ import java.util.function.Function;
* <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 @@ import java.util.function.Function;
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 @@ public abstract class Provider extends Properties {
*/
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 @@ public abstract class Provider extends Properties {
}
}
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,11 +319,25 @@ public abstract class Provider extends Properties {
* 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 @@ public abstract class Provider extends Properties {
}
/**
* 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 abstract class Provider extends Properties {
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 abstract class Provider extends Properties {
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 abstract class Provider extends Properties {
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 abstract class Provider extends Properties {
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 @@ public abstract class Provider extends Properties {
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 @@ public abstract class Provider extends Properties {
}
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 @@ public abstract class Provider extends Properties {
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 @@ public abstract class Provider extends Properties {
return provider.getName() + ": " + type + "." + algorithm
+ " -> " + className + aString + attrs + "\r\n";
}
}
}

View File

@ -399,7 +399,10 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* 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 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* 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 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* 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 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* 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 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* 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 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* 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 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* 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 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* 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);

View File

@ -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 @@ public class Date
* 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;
}

View File

@ -295,7 +295,13 @@ public final class Collectors {
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);
}

View File

@ -861,6 +861,13 @@ public abstract class SSLEngine {
* 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 @@ public abstract class SSLEngine {
* 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 @@ public abstract class SSLEngine {
* 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.
*

View File

@ -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 @@ public class SSLParameters {
* <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 @@ public class SSLParameters {
* 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 @@ public class SSLParameters {
/**
* 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 @@ public class SSLParameters {
/**
* 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);

View File

@ -195,6 +195,13 @@ public abstract class SSLServerSocket extends ServerSocket {
* 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 @@ public abstract class SSLServerSocket extends ServerSocket {
* 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 @@ public abstract class SSLServerSocket extends ServerSocket {
* 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()

View File

@ -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 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory
* 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 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory
* 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()

View File

@ -265,6 +265,13 @@ public abstract class SSLSocket extends Socket
* 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 @@ public abstract class SSLSocket extends Socket
* 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 @@ public abstract class SSLSocket extends Socket
* 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.
*

View File

@ -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 @@ public abstract class SSLSocketFactory extends SocketFactory
* 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 @@ public abstract class SSLSocketFactory extends SocketFactory
* 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

View File

@ -53,6 +53,7 @@ var FileSystems = Java.type("java.nio.file.FileSystems");
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 @@ function getJrtFileSystem() {
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);
}
}

View File

@ -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");

View File

@ -21,12 +21,12 @@
* questions.
*/
package java.lang.reflect;
package jdk.internal.loader;
import jdk.internal.loader.BootLoader;
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;
@ -40,7 +40,7 @@ import java.util.function.Supplier;
* @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> {
public abstract class AbstractClassLoaderValue<CLV extends AbstractClassLoaderValue<CLV, V>, V> {
/**
* Sole constructor.
@ -377,7 +377,7 @@ abstract class AbstractClassLoaderValue<CLV extends AbstractClassLoaderValue<CLV
* @param <K> the type of {@link #key()} component contained in the
* sub-ClassLoaderValue.
*/
final class Sub<K> extends AbstractClassLoaderValue<Sub<K>, V> {
public final class Sub<K> extends AbstractClassLoaderValue<Sub<K>, V> {
private final K key;

View File

@ -21,7 +21,7 @@
* questions.
*/
package java.lang.reflect;
package jdk.internal.loader;
import java.util.Objects;
import java.util.function.BiFunction;
@ -74,7 +74,7 @@ import java.util.function.BiFunction;
* @author Peter Levart
* @since 9
*/
final class ClassLoaderValue<V>
public final class ClassLoaderValue<V>
extends AbstractClassLoaderValue<ClassLoaderValue<V>, V> {
/**

View File

@ -51,8 +51,17 @@ public interface JavaLangInvokeAccess {
* 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 @@ public interface JavaLangInvokeAccess {
*/
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);
}

View File

@ -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;

View File

@ -76,7 +76,7 @@ public final class ProviderList {
// 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) {

View File

@ -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 @@ package sun.security.provider;
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 @@ public final class MD4 extends DigestBase {
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>() {

View File

@ -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.util.*;
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 final class Sun extends Provider {
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

View File

@ -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 java.security.*;
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 final class VerificationProvider extends Provider {
}
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) {

View File

@ -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.util.*;
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 @@ public final class SunRsaSign extends Provider {
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

View File

@ -44,6 +44,7 @@ import sun.security.jca.ProviderList;
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 @@ final class JsseJce {
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() {

View File

@ -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 @@ public abstract class SunJSSE extends java.security.Provider {
// 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 @@ public abstract class SunJSSE extends java.security.Provider {
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

View File

@ -3631,8 +3631,8 @@ public final class Main {
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;

View File

@ -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.Permission;
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 @@ public final class SecurityConstants {
// 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");
}

View File

@ -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 @@ public abstract class LocaleProviderAdapter {
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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

Some files were not shown because too many files have changed in this diff Show More