--- a/.hgtags-top-repo Fri Aug 23 14:17:49 2013 -0700
+++ b/.hgtags-top-repo Wed Jul 05 19:09:26 2017 +0200
@@ -225,3 +225,4 @@
9f74a220677dc265a724515d8e2617548cef62f1 jdk8-b101
5eb3c1dc348f72a7f84f7d9d07834e8bbe09a799 jdk8-b102
b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
+96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104
--- a/README-builds.html Fri Aug 23 14:17:49 2013 -0700
+++ b/README-builds.html Wed Jul 05 19:09:26 2017 +0200
@@ -154,7 +154,7 @@
</code>
</blockquote>
Once you have all the repositories, keep in mind that each
- repository is it's own independent repository.
+ repository is its own independent repository.
You can also re-run <code>./get_source.sh</code> anytime to
pull over all the latest changesets in all the repositories.
This set of nested repositories has been given the term
@@ -241,6 +241,14 @@
source code for the OpenJDK Corba functionality
</td>
</tr>
+ <tr>
+ <td>
+ nashorn
+ </td>
+ <td>
+ source code for the OpenJDK JavaScript implementation
+ </td>
+ </tr>
</tbody>
</table>
</blockquote>
@@ -386,7 +394,7 @@
<code>--with-boot-jdk</code>.
</li>
<li>
- Insure that GNU make, the Bootstrap JDK,
+ Ensure that GNU make, the Bootstrap JDK,
and the compilers are all
in your PATH environment variable
</li>
@@ -1307,9 +1315,9 @@
you will need to modify the makefiles. But for normal file
additions or removals, no changes are needed. There are certan
exceptions for some native libraries where the source files are spread
- over many directories which also contain courses for other
+ over many directories which also contain sources for other
libraries. In these cases it was simply easier to create include lists
- rather thane excludes.
+ rather than excludes.
</p>
<p>
@@ -1327,14 +1335,14 @@
<p>
<b>Q:</b>
<code>configure</code> provides OpenJDK-specific features such as
- <code>--enable-jigsaw</code> or <code>--with-builddeps-server</code>
- that are not described in this document. What about those?
+ <code>--with-builddeps-server</code> that are not
+ described in this document. What about those?
<br>
<b>A:</b>
Try them out if you like! But be aware that most of these are
experimental features.
Many of them don't do anything at all at the moment; the option
- is just a placeholder. Other depends on
+ is just a placeholder. Others depend on
pieces of code or infrastructure that is currently
not ready for prime time.
</p>
@@ -1386,24 +1394,6 @@
</p>
<p>
- <b>Q:</b> What is @GenerateNativeHeaders?
- <br>
- <b>A:</b>
- To speed up compilation, we added a flag to javac which makes it
- do the job of javah as well, as a by-product; that is, generating
- native .h header files. These files are only generated
- if a class contains native methods. However, sometimes
- a class contains no native method,
- but still contains constants that native code needs to use.
- The new GenerateNativeHeaders annotation tells javac to
- force generation of a
- header file in these cases. (We don't want to generate
- native headers for all classes that contains constants
- but no native methods, since
- that would slow down the compilation process needlessly.)
- </p>
-
- <p>
<b>Q:</b>
Is anything able to use the results of the new build's default make target?
<br>
@@ -1429,10 +1419,9 @@
What should I do?
<br>
<b>A:</b>
- It might very well be that we have missed to add support for
+ It might very well be that we have neglected to add support for
an option that was actually used from outside the build system.
- Email us and we will
- add support for it!
+ Email us and we will add support for it!
</p>
</blockquote>
--- a/common/autoconf/generated-configure.sh Fri Aug 23 14:17:49 2013 -0700
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 19:09:26 2017 +0200
@@ -29573,7 +29573,7 @@
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DSOLARIS"
fi
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
+ CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
# Setting these parameters makes it an error to link to macosx APIs that are
# newer than the given OS version and makes the linked binaries compatible even
# if built on a newer version of the OS.
--- a/common/autoconf/toolchain.m4 Fri Aug 23 14:17:49 2013 -0700
+++ b/common/autoconf/toolchain.m4 Wed Jul 05 19:09:26 2017 +0200
@@ -905,7 +905,7 @@
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DSOLARIS"
fi
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
+ CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
# Setting these parameters makes it an error to link to macosx APIs that are
# newer than the given OS version and makes the linked binaries compatible even
# if built on a newer version of the OS.
--- a/corba/.hgtags Fri Aug 23 14:17:49 2013 -0700
+++ b/corba/.hgtags Wed Jul 05 19:09:26 2017 +0200
@@ -225,3 +225,4 @@
a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101
528c7e76eaeee022817ee085668459bc97cf5665 jdk8-b102
49c4a777fdfd648d4c3fffc940fdb97a23108ca8 jdk8-b103
+d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
--- a/hotspot/.hgtags Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/.hgtags Wed Jul 05 19:09:26 2017 +0200
@@ -369,3 +369,5 @@
7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45
6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103
580430d131ccd475e2f2ad4006531b8c4813d102 hs25-b46
+104743074675359cfbf7f4dcd9ab2a5974a16627 jdk8-b104
+c1604d5885a6f2adc0bcea2fa142a8f6bafad2f0 hs25-b47
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Wed Jul 05 19:09:26 2017 +0200
@@ -75,19 +75,19 @@
javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
constants = new MetadataField(type.getAddressField("_constants"), 0);
classLoaderData = type.getAddressField("_class_loader_data");
- sourceFileName = type.getAddressField("_source_file_name");
sourceDebugExtension = type.getAddressField("_source_debug_extension");
innerClasses = type.getAddressField("_inner_classes");
+ sourceFileNameIndex = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
- staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
+ staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
initState = new CIntField(type.getCIntegerField("_init_state"), 0);
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);
itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
breakpoints = type.getAddressField("_breakpoints");
- genericSignature = type.getAddressField("_generic_signature");
+ genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
headerSize = Oop.alignObjectOffset(type.getSize());
@@ -134,9 +134,9 @@
private static CIntField javaFieldsCount;
private static MetadataField constants;
private static AddressField classLoaderData;
- private static AddressField sourceFileName;
private static AddressField sourceDebugExtension;
private static AddressField innerClasses;
+ private static CIntField sourceFileNameIndex;
private static CIntField nonstaticFieldSize;
private static CIntField staticFieldSize;
private static CIntField staticOopFieldCount;
@@ -146,7 +146,7 @@
private static CIntField vtableLen;
private static CIntField itableLen;
private static AddressField breakpoints;
- private static AddressField genericSignature;
+ private static CIntField genericSignatureIndex;
private static CIntField majorVersion;
private static CIntField minorVersion;
@@ -346,7 +346,7 @@
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
- public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
+ public Symbol getSourceFileName() { return getConstants().getSymbolAt(sourceFileNameIndex.getValue(this)); }
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
@@ -354,7 +354,7 @@
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
public long getVtableLen() { return vtableLen.getValue(this); }
public long getItableLen() { return itableLen.getValue(this); }
- public Symbol getGenericSignature() { return getSymbol(genericSignature); }
+ public Symbol getGenericSignature() { return getConstants().getSymbolAt(genericSignatureIndex.getValue(this)); }
public long majorVersion() { return majorVersion.getValue(this); }
public long minorVersion() { return minorVersion.getValue(this); }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Wed Jul 05 19:09:26 2017 +0200
@@ -92,8 +92,13 @@
System.err.println("Warning: Can not create class filter!");
}
}
- String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
- setOutputDirectory(outputDirectory);
+
+ // outputDirectory and jarStream are alternatives: setting one closes the other.
+ // If neither is set, use outputDirectory from the System property:
+ if (outputDirectory == null && jarStream == null) {
+ String dirName = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
+ setOutputDirectory(dirName);
+ }
// walk through the system dictionary
SystemDictionary dict = VM.getVM().getSystemDictionary();
--- a/hotspot/make/bsd/makefiles/gcc.make Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/make/bsd/makefiles/gcc.make Wed Jul 05 19:09:26 2017 +0200
@@ -247,7 +247,7 @@
# Not yet supported by clang in Xcode 4.6.2
# WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare
WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
- WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
+ WARNINGS_ARE_ERRORS += -Wno-empty-body
endif
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
--- a/hotspot/make/hotspot_version Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/make/hotspot_version Wed Jul 05 19:09:26 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=46
+HS_BUILD_NUMBER=47
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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,7 @@
#include "interpreter/interpreter.hpp"
#include "memory/cardTableModRefBS.hpp"
#include "memory/resourceArea.hpp"
+#include "memory/universe.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -1145,7 +1146,7 @@
assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- narrowOop encoded_k = oopDesc::encode_klass(k);
+ narrowOop encoded_k = Klass::encode_klass(k);
assert_not_delayed();
// Relocation with special format (see relocInfo_sparc.hpp).
@@ -1419,7 +1420,6 @@
load_klass(O0_obj, O0_obj);
// assert((klass != NULL)
br_null_short(O0_obj, pn, fail);
- // TODO: Future assert that klass is lower 4g memory for UseCompressedKlassPointers
wrccr( O5_save_flags ); // Restore CCR's
@@ -4089,52 +4089,91 @@
}
void MacroAssembler::encode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- if (Universe::narrow_klass_base() != NULL)
- sub(r, G6_heapbase, r);
- srlx(r, LogKlassAlignmentInBytes, r);
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ assert(r != G6_heapbase, "bad register choice");
+ set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
+ sub(r, G6_heapbase, r);
+ if (Universe::narrow_klass_shift() != 0) {
+ assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
+ srlx(r, LogKlassAlignmentInBytes, r);
+ }
+ reinit_heapbase();
}
void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
- assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- if (Universe::narrow_klass_base() == NULL) {
- srlx(src, LogKlassAlignmentInBytes, dst);
+ if (src == dst) {
+ encode_klass_not_null(src);
} else {
- sub(src, G6_heapbase, dst);
- srlx(dst, LogKlassAlignmentInBytes, dst);
+ assert (UseCompressedKlassPointers, "must be compressed");
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ set((intptr_t)Universe::narrow_klass_base(), dst);
+ sub(src, dst, dst);
+ if (Universe::narrow_klass_shift() != 0) {
+ srlx(dst, LogKlassAlignmentInBytes, dst);
+ }
}
}
+// Function instr_size_for_decode_klass_not_null() counts the instructions
+// generated by decode_klass_not_null() and reinit_heapbase(). Hence, if
+// the instructions they generate change, then this method needs to be updated.
+int MacroAssembler::instr_size_for_decode_klass_not_null() {
+ assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
+ // set + add + set
+ int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 +
+ insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base());
+ if (Universe::narrow_klass_shift() == 0) {
+ return num_instrs * BytesPerInstWord;
+ } else { // sllx
+ return (num_instrs + 1) * BytesPerInstWord;
+ }
+}
+
+// !!! If the instructions that get generated here change then function
+// instr_size_for_decode_klass_not_null() needs to get updated.
void MacroAssembler::decode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit.
assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- sllx(r, LogKlassAlignmentInBytes, r);
- if (Universe::narrow_klass_base() != NULL)
- add(r, G6_heapbase, r);
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ assert(r != G6_heapbase, "bad register choice");
+ set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
+ if (Universe::narrow_klass_shift() != 0)
+ sllx(r, LogKlassAlignmentInBytes, r);
+ add(r, G6_heapbase, r);
+ reinit_heapbase();
}
void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
- // Do not add assert code to this unless you change vtableStubs_sparc.cpp
- // pd_code_size_limit.
- assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- sllx(src, LogKlassAlignmentInBytes, dst);
- if (Universe::narrow_klass_base() != NULL)
- add(dst, G6_heapbase, dst);
+ if (src == dst) {
+ decode_klass_not_null(src);
+ } else {
+ // Do not add assert code to this unless you change vtableStubs_sparc.cpp
+ // pd_code_size_limit.
+ assert (UseCompressedKlassPointers, "must be compressed");
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ if (Universe::narrow_klass_shift() != 0) {
+ assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice");
+ set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
+ sllx(src, LogKlassAlignmentInBytes, dst);
+ add(dst, G6_heapbase, dst);
+ reinit_heapbase();
+ } else {
+ set((intptr_t)Universe::narrow_klass_base(), dst);
+ add(src, dst, dst);
+ }
+ }
}
void MacroAssembler::reinit_heapbase() {
if (UseCompressedOops || UseCompressedKlassPointers) {
- AddressLiteral base(Universe::narrow_ptrs_base_addr());
- load_ptr_contents(base, G6_heapbase);
+ if (Universe::heap() != NULL) {
+ set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase);
+ } else {
+ AddressLiteral base(Universe::narrow_ptrs_base_addr());
+ load_ptr_contents(base, G6_heapbase);
+ }
}
}
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -1177,6 +1177,9 @@
void push_CPU_state();
void pop_CPU_state();
+ // Returns the byte size of the instructions generated by decode_klass_not_null().
+ static int instr_size_for_decode_klass_not_null();
+
// if heap base register is used - reinit it with the correct value
void reinit_heapbase();
--- a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, 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
@@ -97,7 +97,7 @@
guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
if (format() != 0) {
assert(type() == relocInfo::oop_type || type() == relocInfo::metadata_type, "only narrow oops or klasses case");
- jint np = type() == relocInfo::oop_type ? oopDesc::encode_heap_oop((oop)x) : oopDesc::encode_klass((Klass*)x);
+ jint np = type() == relocInfo::oop_type ? oopDesc::encode_heap_oop((oop)x) : Klass::encode_klass((Klass*)x);
inst &= ~Assembler::hi22(-1);
inst |= Assembler::hi22((intptr_t)np);
if (verify_only) {
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 19:09:26 2017 +0200
@@ -559,10 +559,7 @@
int klass_load_size;
if (UseCompressedKlassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
- if (Universe::narrow_klass_base() == NULL)
- klass_load_size = 2*BytesPerInstWord; // see MacroAssembler::load_klass()
- else
- klass_load_size = 3*BytesPerInstWord;
+ klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else {
klass_load_size = 1*BytesPerInstWord;
}
@@ -1663,9 +1660,12 @@
if (UseCompressedKlassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
- st->print_cr("\tSLL R_G5,3,R_G5");
- if (Universe::narrow_klass_base() != NULL)
- st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
+ st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base");
+ if (Universe::narrow_klass_shift() != 0) {
+ st->print_cr("\tSLL R_G5,3,R_G5");
+ }
+ st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
+ st->print_cr("\tSET Universe::narrow_ptrs_base,R_G6_heap_base");
} else {
st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
}
@@ -2563,10 +2563,7 @@
int klass_load_size;
if (UseCompressedKlassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
- if (Universe::narrow_klass_base() == NULL)
- klass_load_size = 2*BytesPerInstWord;
- else
- klass_load_size = 3*BytesPerInstWord;
+ klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else {
klass_load_size = 1*BytesPerInstWord;
}
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -219,13 +219,13 @@
const int basic = 5*BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based)
(UseCompressedKlassPointers ?
- ((Universe::narrow_klass_base() == NULL) ? BytesPerInstWord : 2*BytesPerInstWord) : 0);
+ MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return basic + slop;
} else {
const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based)
(UseCompressedKlassPointers ?
- ((Universe::narrow_klass_base() == NULL) ? BytesPerInstWord : 2*BytesPerInstWord) : 0);
+ MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return (basic + slop);
}
}
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -30,6 +30,7 @@
#include "interpreter/interpreter.hpp"
#include "memory/cardTableModRefBS.hpp"
#include "memory/resourceArea.hpp"
+#include "memory/universe.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -4810,23 +4811,8 @@
}
void MacroAssembler::load_prototype_header(Register dst, Register src) {
-#ifdef _LP64
- if (UseCompressedKlassPointers) {
- assert (Universe::heap() != NULL, "java heap should be initialized");
- movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
- if (Universe::narrow_klass_shift() != 0) {
- assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
- movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset()));
- } else {
- movq(dst, Address(dst, Klass::prototype_header_offset()));
- }
- } else
-#endif
- {
- movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
- movptr(dst, Address(dst, Klass::prototype_header_offset()));
- }
+ load_klass(dst, src);
+ movptr(dst, Address(dst, Klass::prototype_header_offset()));
}
void MacroAssembler::store_klass(Register dst, Register src) {
@@ -4914,7 +4900,7 @@
#ifdef ASSERT
void MacroAssembler::verify_heapbase(const char* msg) {
- assert (UseCompressedOops || UseCompressedKlassPointers, "should be compressed");
+ assert (UseCompressedOops, "should be compressed");
assert (Universe::heap() != NULL, "java heap should be initialized");
if (CheckCompressedOops) {
Label ok;
@@ -5058,69 +5044,80 @@
}
void MacroAssembler::encode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
-#ifdef ASSERT
- verify_heapbase("MacroAssembler::encode_klass_not_null: heap base corrupted?");
-#endif
- if (Universe::narrow_klass_base() != NULL) {
- subq(r, r12_heapbase);
- }
+ assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
+ // Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
+ assert(r != r12_heapbase, "Encoding a klass in r12");
+ mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
+ subq(r, r12_heapbase);
if (Universe::narrow_klass_shift() != 0) {
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
shrq(r, LogKlassAlignmentInBytes);
}
+ reinit_heapbase();
}
void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
-#ifdef ASSERT
- verify_heapbase("MacroAssembler::encode_klass_not_null2: heap base corrupted?");
-#endif
- if (dst != src) {
- movq(dst, src);
- }
- if (Universe::narrow_klass_base() != NULL) {
- subq(dst, r12_heapbase);
- }
- if (Universe::narrow_klass_shift() != 0) {
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- shrq(dst, LogKlassAlignmentInBytes);
- }
-}
-
+ if (dst == src) {
+ encode_klass_not_null(src);
+ } else {
+ mov64(dst, (int64_t)Universe::narrow_klass_base());
+ negq(dst);
+ addq(dst, src);
+ if (Universe::narrow_klass_shift() != 0) {
+ assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
+ shrq(dst, LogKlassAlignmentInBytes);
+ }
+ }
+}
+
+// Function instr_size_for_decode_klass_not_null() counts the instructions
+// generated by decode_klass_not_null(register r) and reinit_heapbase(),
+// when (Universe::heap() != NULL). Hence, if the instructions they
+// generate change, then this method needs to be updated.
+int MacroAssembler::instr_size_for_decode_klass_not_null() {
+ assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
+ // mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
+ return (Universe::narrow_klass_shift() == 0 ? 20 : 24);
+}
+
+// !!! If the instructions that get generated here change then function
+// instr_size_for_decode_klass_not_null() needs to get updated.
void MacroAssembler::decode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
// Note: it will change flags
+ assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert(r != r12_heapbase, "Decoding a klass in r12");
// Cannot assert, unverified entry point counts instructions (see .ad file)
// vtableStubs also counts instructions in pd_code_size_limit.
// Also do not verify_oop as this is called by verify_oop.
if (Universe::narrow_klass_shift() != 0) {
assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
shlq(r, LogKlassAlignmentInBytes);
- if (Universe::narrow_klass_base() != NULL) {
- addq(r, r12_heapbase);
- }
- } else {
- assert (Universe::narrow_klass_base() == NULL, "sanity");
- }
+ }
+ // Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
+ mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
+ addq(r, r12_heapbase);
+ reinit_heapbase();
}
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
// Note: it will change flags
+ assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
- // Cannot assert, unverified entry point counts instructions (see .ad file)
- // vtableStubs also counts instructions in pd_code_size_limit.
- // Also do not verify_oop as this is called by verify_oop.
- if (Universe::narrow_klass_shift() != 0) {
- assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
- leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
+ if (dst == src) {
+ decode_klass_not_null(dst);
} else {
- assert (Universe::narrow_klass_base() == NULL, "sanity");
- if (dst != src) {
- movq(dst, src);
+ // Cannot assert, unverified entry point counts instructions (see .ad file)
+ // vtableStubs also counts instructions in pd_code_size_limit.
+ // Also do not verify_oop as this is called by verify_oop.
+
+ mov64(dst, (int64_t)Universe::narrow_klass_base());
+ if (Universe::narrow_klass_shift() != 0) {
+ assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
+ assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
+ leaq(dst, Address(dst, src, Address::times_8, 0));
+ } else {
+ addq(dst, src);
}
}
}
@@ -5148,7 +5145,7 @@
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ mov_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::set_narrow_klass(Address dst, Klass* k) {
@@ -5156,7 +5153,7 @@
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ mov_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) {
@@ -5182,7 +5179,7 @@
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
@@ -5190,14 +5187,23 @@
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::reinit_heapbase() {
if (UseCompressedOops || UseCompressedKlassPointers) {
- movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
- }
-}
+ if (Universe::heap() != NULL) {
+ if (Universe::narrow_oop_base() == NULL) {
+ MacroAssembler::xorptr(r12_heapbase, r12_heapbase);
+ } else {
+ mov64(r12_heapbase, (int64_t)Universe::narrow_ptrs_base());
+ }
+ } else {
+ movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
+ }
+ }
+}
+
#endif // _LP64
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -371,6 +371,10 @@
void cmp_narrow_klass(Register dst, Klass* k);
void cmp_narrow_klass(Address dst, Klass* k);
+ // Returns the byte size of the instructions generated by decode_klass_not_null()
+ // when compressed klass pointers are being used.
+ static int instr_size_for_decode_klass_not_null();
+
// if heap base register is used - reinit it with the correct value
void reinit_heapbase();
--- a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, 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
@@ -55,9 +55,9 @@
}
} else {
if (verify_only) {
- assert(*(uint32_t*) disp == oopDesc::encode_klass((Klass*)x), "instructions must match");
+ assert(*(uint32_t*) disp == Klass::encode_klass((Klass*)x), "instructions must match");
} else {
- *(int32_t*) disp = oopDesc::encode_klass((Klass*)x);
+ *(int32_t*) disp = Klass::encode_klass((Klass*)x);
}
}
} else {
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -675,7 +675,6 @@
__ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass
__ testptr(rax, rax);
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
- // TODO: Future assert that klass is lower 4g memory for UseCompressedKlassPointers
// return if everything seems ok
__ bind(exit);
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1021,7 +1021,6 @@
__ load_klass(rax, rax); // get klass
__ testptr(rax, rax);
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
- // TODO: Future assert that klass is lower 4g memory for UseCompressedKlassPointers
// return if everything seems ok
__ bind(exit);
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -849,9 +849,9 @@
address entry = __ pc();
// rbx,: Method*
- // rsi: senderSP must preserved for slow path, set SP to it on fast path
- // rdx: scratch
- // rdi: scratch
+ // r13: senderSP must preserved for slow path, set SP to it on fast path
+ // c_rarg0: scratch (rdi on non-Win64, rcx on Win64)
+ // c_rarg1: scratch (rsi on non-Win64, rdx on Win64)
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
@@ -865,8 +865,8 @@
// Load parameters
const Register crc = rax; // crc
- const Register val = rdx; // source java byte value
- const Register tbl = rdi; // scratch
+ const Register val = c_rarg0; // source java byte value
+ const Register tbl = c_rarg1; // scratch
// Arguments are reversed on java expression stack
__ movl(val, Address(rsp, wordSize)); // byte value
@@ -880,7 +880,7 @@
// _areturn
__ pop(rdi); // get return address
- __ mov(rsp, rsi); // set sp to sender sp
+ __ mov(rsp, r13); // set sp to sender sp
__ jmp(rdi);
// generate a vanilla native entry as the slow path
@@ -919,20 +919,24 @@
const Register crc = c_rarg0; // crc
const Register buf = c_rarg1; // source java byte array address
const Register len = c_rarg2; // length
+ const Register off = len; // offset (never overlaps with 'len')
// Arguments are reversed on java expression stack
- __ movl(len, Address(rsp, wordSize)); // Length
// Calculate address of start element
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
__ movptr(buf, Address(rsp, 3*wordSize)); // long buf
- __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
+ __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
+ __ addq(buf, off); // + offset
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
} else {
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
- __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
+ __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
+ __ addq(buf, off); // + offset
__ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC
}
+ // Can now load 'len' since we're finished with 'off'
+ __ movl(len, Address(rsp, wordSize)); // Length
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
// result in rax
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -211,11 +211,11 @@
if (is_vtable_stub) {
// Vtable stub size
return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0) +
- (UseCompressedKlassPointers ? 16 : 0); // 1 leaq can be 3 bytes + 1 long
+ (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
} else {
// Itable stub size
return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) +
- (UseCompressedKlassPointers ? 32 : 0); // 2 leaqs
+ (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
}
// In order to tune these parameters, run the JVM with VM options
// +PrintMiscellaneous and +WizardMode to see information about
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jul 05 19:09:26 2017 +0200
@@ -1393,9 +1393,7 @@
{
if (UseCompressedKlassPointers) {
st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
- if (Universe::narrow_klass_shift() != 0) {
- st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
- }
+ st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
} else {
st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
@@ -4035,146 +4033,6 @@
%}
%}
-operand indirectNarrowKlass(rRegN reg)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(DecodeNKlass reg);
-
- format %{ "[$reg]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index(0x4);
- scale(0x0);
- disp(0x0);
- %}
-%}
-
-operand indOffset8NarrowKlass(rRegN reg, immL8 off)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) off);
-
- format %{ "[$reg + $off (8-bit)]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index(0x4);
- scale(0x0);
- disp($off);
- %}
-%}
-
-operand indOffset32NarrowKlass(rRegN reg, immL32 off)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) off);
-
- format %{ "[$reg + $off (32-bit)]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index(0x4);
- scale(0x0);
- disp($off);
- %}
-%}
-
-operand indIndexOffsetNarrowKlass(rRegN reg, rRegL lreg, immL32 off)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (AddP (DecodeNKlass reg) lreg) off);
-
- op_cost(10);
- format %{"[$reg + $off + $lreg]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale(0x0);
- disp($off);
- %}
-%}
-
-operand indIndexNarrowKlass(rRegN reg, rRegL lreg)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) lreg);
-
- op_cost(10);
- format %{"[$reg + $lreg]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale(0x0);
- disp(0x0);
- %}
-%}
-
-operand indIndexScaleNarrowKlass(rRegN reg, rRegL lreg, immI2 scale)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) (LShiftL lreg scale));
-
- op_cost(10);
- format %{"[$reg + $lreg << $scale]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale($scale);
- disp(0x0);
- %}
-%}
-
-operand indIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (AddP (DecodeNKlass reg) (LShiftL lreg scale)) off);
-
- op_cost(10);
- format %{"[$reg + $off + $lreg << $scale]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale($scale);
- disp($off);
- %}
-%}
-
-operand indCompressedKlassOffset(rRegN reg, immL32 off) %{
- predicate(UseCompressedKlassPointers && (Universe::narrow_klass_shift() == Address::times_8));
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) off);
-
- op_cost(10);
- format %{"[R12 + $reg << 3 + $off] (compressed klass addressing)" %}
- interface(MEMORY_INTER) %{
- base(0xc); // R12
- index($reg);
- scale(0x3);
- disp($off);
- %}
-%}
-
-operand indPosIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegI idx, immI2 scale)
-%{
- constraint(ALLOC_IN_RC(ptr_reg));
- predicate(Universe::narrow_klass_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
- match(AddP (AddP (DecodeNKlass reg) (LShiftL (ConvI2L idx) scale)) off);
-
- op_cost(10);
- format %{"[$reg + $off + $idx << $scale]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($idx);
- scale($scale);
- disp($off);
- %}
-%}
-
//----------Special Memory Operands--------------------------------------------
// Stack Slot Operand - This operand is used for loading and storing temporary
// values on the stack where a match requires a value to
@@ -4345,11 +4203,7 @@
indCompressedOopOffset,
indirectNarrow, indOffset8Narrow, indOffset32Narrow,
indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
- indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow,
- indCompressedKlassOffset,
- indirectNarrowKlass, indOffset8NarrowKlass, indOffset32NarrowKlass,
- indIndexOffsetNarrowKlass, indIndexNarrowKlass, indIndexScaleNarrowKlass,
- indIndexScaleOffsetNarrowKlass, indPosIndexScaleOffsetNarrowKlass);
+ indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
//----------PIPELINE-----------------------------------------------------------
// Rules which define the behavior of the target architectures pipeline.
@@ -6665,7 +6519,7 @@
instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
match(Set dst (EncodePKlass src));
effect(KILL cr);
- format %{ "encode_heap_oop_not_null $dst,$src" %}
+ format %{ "encode_klass_not_null $dst,$src" %}
ins_encode %{
__ encode_klass_not_null($dst$$Register, $src$$Register);
%}
@@ -6675,7 +6529,7 @@
instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
match(Set dst (DecodeNKlass src));
effect(KILL cr);
- format %{ "decode_heap_oop_not_null $dst,$src" %}
+ format %{ "decode_klass_not_null $dst,$src" %}
ins_encode %{
Register s = $src$$Register;
Register d = $dst$$Register;
--- a/hotspot/src/cpu/zero/vm/assembler_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/assembler_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -50,6 +50,7 @@
#ifdef ASSERT
bool AbstractAssembler::pd_check_instruction_mark() {
ShouldNotCallThis();
+ return false;
}
#endif
@@ -73,6 +74,7 @@
RegisterOrConstant MacroAssembler::delayed_value_impl(
intptr_t* delayed_value_addr, Register tmpl, int offset) {
ShouldNotCallThis();
+ return RegisterOrConstant();
}
void MacroAssembler::store_oop(jobject obj) {
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1008,6 +1008,7 @@
address CppInterpreter::return_entry(TosState state, int length) {
ShouldNotCallThis();
+ return NULL;
}
address CppInterpreter::deopt_entry(TosState state, int length) {
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -116,6 +116,7 @@
bool frame::safe_for_sender(JavaThread *thread) {
ShouldNotCallThis();
+ return false;
}
void frame::pd_gc_epilog() {
@@ -123,6 +124,7 @@
bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
ShouldNotCallThis();
+ return false;
}
BasicType frame::interpreter_frame_result(oop* oop_result,
@@ -184,9 +186,8 @@
int frame::frame_size(RegisterMap* map) const {
#ifdef PRODUCT
ShouldNotCallThis();
-#else
+#endif // PRODUCT
return 0; // make javaVFrame::print_value work
-#endif // PRODUCT
}
intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -36,7 +36,7 @@
_deopt_state = unknown;
}
-inline address frame::sender_pc() const { ShouldNotCallThis(); }
+inline address frame::sender_pc() const { ShouldNotCallThis(); return NULL; }
inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
_zeroframe = zf;
@@ -89,6 +89,7 @@
inline intptr_t* frame::link() const {
ShouldNotCallThis();
+ return NULL;
}
#ifdef CC_INTERP
@@ -151,14 +152,17 @@
inline oop frame::saved_oop_result(RegisterMap* map) const {
ShouldNotCallThis();
+ return NULL;
}
inline bool frame::is_older(intptr_t* id) const {
ShouldNotCallThis();
+ return false;
}
inline intptr_t* frame::entry_frame_argument_at(int offset) const {
ShouldNotCallThis();
+ return NULL;
}
inline intptr_t* frame::unextended_sp() const {
--- a/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -49,8 +49,10 @@
address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
// NB ic_stub_code_size() must return the size of the code we generate
ShouldNotCallThis();
+ return NULL;
}
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) {
ShouldNotCallThis();
+ return NULL;
}
--- a/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -40,6 +40,7 @@
Register tmp,
int offset) {
ShouldNotCallThis();
+ return RegisterOrConstant();
}
};
--- a/hotspot/src/cpu/zero/vm/interpreter_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -64,6 +64,7 @@
return NULL;
Unimplemented();
+ return NULL;
}
address InterpreterGenerator::generate_abstract_entry() {
--- a/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -51,15 +51,18 @@
public:
bool is_jump() {
ShouldNotCallThis();
+ return false;
}
bool is_safepoint_poll() {
ShouldNotCallThis();
+ return false;
}
};
inline NativeInstruction* nativeInstruction_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeCall : public NativeInstruction {
@@ -70,18 +73,22 @@
address instruction_address() const {
ShouldNotCallThis();
+ return NULL;
}
address next_instruction_address() const {
ShouldNotCallThis();
+ return NULL;
}
address return_address() const {
ShouldNotCallThis();
+ return NULL;
}
address destination() const {
ShouldNotCallThis();
+ return NULL;
}
void set_destination_mt_safe(address dest) {
@@ -98,25 +105,30 @@
static bool is_call_before(address return_address) {
ShouldNotCallThis();
+ return false;
}
};
inline NativeCall* nativeCall_before(address return_address) {
ShouldNotCallThis();
+ return NULL;
}
inline NativeCall* nativeCall_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeMovConstReg : public NativeInstruction {
public:
address next_instruction_address() const {
ShouldNotCallThis();
+ return NULL;
}
intptr_t data() const {
ShouldNotCallThis();
+ return 0;
}
void set_data(intptr_t x) {
@@ -126,12 +138,14 @@
inline NativeMovConstReg* nativeMovConstReg_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeMovRegMem : public NativeInstruction {
public:
int offset() const {
ShouldNotCallThis();
+ return 0;
}
void set_offset(intptr_t x) {
@@ -145,6 +159,7 @@
inline NativeMovRegMem* nativeMovRegMem_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeJump : public NativeInstruction {
@@ -155,6 +170,7 @@
address jump_destination() const {
ShouldNotCallThis();
+ return NULL;
}
void set_jump_destination(address dest) {
@@ -172,12 +188,14 @@
inline NativeJump* nativeJump_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeGeneralJump : public NativeInstruction {
public:
address jump_destination() const {
ShouldNotCallThis();
+ return NULL;
}
static void insert_unconditional(address code_pos, address entry) {
@@ -191,6 +209,7 @@
inline NativeGeneralJump* nativeGeneralJump_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
#endif // CPU_ZERO_VM_NATIVEINST_ZERO_HPP
--- a/hotspot/src/cpu/zero/vm/register_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/register_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -32,8 +32,10 @@
const char* RegisterImpl::name() const {
ShouldNotCallThis();
+ return NULL;
}
const char* FloatRegisterImpl::name() const {
ShouldNotCallThis();
+ return NULL;
}
--- a/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -37,6 +37,7 @@
address Relocation::pd_call_destination(address orig_addr) {
ShouldNotCallThis();
+ return NULL;
}
void Relocation::pd_set_call_destination(address x) {
@@ -45,6 +46,7 @@
address Relocation::pd_get_address_from_code() {
ShouldNotCallThis();
+ return NULL;
}
address* Relocation::pd_address_in_code() {
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -89,6 +89,7 @@
ret_type);
#else
ShouldNotCallThis();
+ return NULL;
#endif // SHARK
}
@@ -99,6 +100,7 @@
uint SharedRuntime::out_preserve_stack_slots() {
ShouldNotCallThis();
+ return 0;
}
JRT_LEAF(void, zero_stub())
@@ -135,4 +137,5 @@
VMRegPair *regs,
int total_args_passed) {
ShouldNotCallThis();
+ return 0;
}
--- a/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -39,16 +39,20 @@
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
ShouldNotCallThis();
+ return NULL;
}
VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
ShouldNotCallThis();
+ return NULL;
}
int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
ShouldNotCallThis();
+ return 0;
}
int VtableStub::pd_code_alignment() {
ShouldNotCallThis();
+ return 0;
}
--- a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -190,7 +190,7 @@
inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store_fence((volatile jlong*)p, (jlong)v); }
inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jdouble_cast(v)); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
#ifdef AMD64
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -715,6 +715,7 @@
err.report_and_die();
ShouldNotReachHere();
+ return false;
}
// From solaris_i486.s ported to bsd_i486.s
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -66,6 +66,7 @@
frame os::get_sender_for_C_frame(frame* fr) {
ShouldNotCallThis();
+ return frame();
}
frame os::current_frame() {
@@ -103,16 +104,19 @@
address os::Bsd::ucontext_get_pc(ucontext_t* uc) {
ShouldNotCallThis();
+ return NULL;
}
ExtendedPC os::fetch_frame_from_context(void* ucVoid,
intptr_t** ret_sp,
intptr_t** ret_fp) {
ShouldNotCallThis();
+ return ExtendedPC();
}
frame os::fetch_frame_from_context(void* ucVoid) {
ShouldNotCallThis();
+ return frame();
}
extern "C" JNIEXPORT int
@@ -240,6 +244,7 @@
sprintf(buf, fmt, sig, info->si_addr);
fatal(buf);
+ return false;
}
void os::Bsd::init_thread_fpu_state(void) {
@@ -373,17 +378,7 @@
extern "C" {
int SpinPause() {
- }
-
- int SafeFetch32(int *adr, int errValue) {
- int value = errValue;
- value = *adr;
- return value;
- }
- intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
- intptr_t value = errValue;
- value = *adr;
- return value;
+ return 1;
}
void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
--- a/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -110,6 +110,7 @@
void* ucontext,
bool isInJava) {
ShouldNotCallThis();
+ return false;
}
// These routines are only used on cpu architectures that
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -915,16 +915,6 @@
// Return to the now deoptimized frame.
}
- // If we are patching in a non-perm oop, make sure the nmethod
- // is on the right list.
- if (ScavengeRootsInCode && mirror.not_null() && mirror()->is_scavengable()) {
- MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
- nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
- guarantee(nm != NULL, "only nmethods can contain non-perm oops");
- if (!nm->on_scavenge_root_list())
- CodeCache::add_scavenge_root_nmethod(nm);
- }
-
// Now copy code back
{
@@ -1125,6 +1115,21 @@
}
}
}
+
+ // If we are patching in a non-perm oop, make sure the nmethod
+ // is on the right list.
+ if (ScavengeRootsInCode && mirror.not_null() && mirror()->is_scavengable()) {
+ MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
+ guarantee(nm != NULL, "only nmethods can contain non-perm oops");
+ if (!nm->on_scavenge_root_list()) {
+ CodeCache::add_scavenge_root_nmethod(nm);
+ }
+
+ // Since we've patched some oops in the nmethod,
+ // (re)register it with the heap.
+ Universe::heap()->register_nmethod(nm);
+ }
JRT_END
//
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -2590,7 +2590,7 @@
valid_symbol_at(sourcefile_index),
"Invalid SourceFile attribute at constant pool index %u in class file %s",
sourcefile_index, CHECK);
- set_class_sourcefile(_cp->symbol_at(sourcefile_index));
+ set_class_sourcefile_index(sourcefile_index);
}
@@ -2728,7 +2728,7 @@
valid_symbol_at(signature_index),
"Invalid constant pool index %u in Signature attribute in class file %s",
signature_index, CHECK);
- set_class_generic_signature(_cp->symbol_at(signature_index));
+ set_class_generic_signature_index(signature_index);
}
void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_byte_length, TRAPS) {
@@ -2975,13 +2975,11 @@
void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) {
if (_synthetic_flag)
k->set_is_synthetic();
- if (_sourcefile != NULL) {
- _sourcefile->increment_refcount();
- k->set_source_file_name(_sourcefile);
+ if (_sourcefile_index != 0) {
+ k->set_source_file_name_index(_sourcefile_index);
}
- if (_generic_signature != NULL) {
- _generic_signature->increment_refcount();
- k->set_generic_signature(_generic_signature);
+ if (_generic_signature_index != 0) {
+ k->set_generic_signature_index(_generic_signature_index);
}
if (_sde_buffer != NULL) {
k->set_source_debug_extension(_sde_buffer, _sde_length);
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -62,8 +62,8 @@
bool _synthetic_flag;
int _sde_length;
char* _sde_buffer;
- Symbol* _sourcefile;
- Symbol* _generic_signature;
+ u2 _sourcefile_index;
+ u2 _generic_signature_index;
// Metadata created before the instance klass is created. Must be deallocated
// if not transferred to the InstanceKlass upon successful class loading
@@ -81,16 +81,16 @@
Array<AnnotationArray*>* _fields_type_annotations;
InstanceKlass* _klass; // InstanceKlass once created.
- void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
- void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
- void set_class_generic_signature(Symbol* x) { _generic_signature = x; }
- void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
+ void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
+ void set_class_sourcefile_index(u2 x) { _sourcefile_index = x; }
+ void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; }
+ void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
void init_parsed_class_attributes(ClassLoaderData* loader_data) {
_loader_data = loader_data;
_synthetic_flag = false;
- _sourcefile = NULL;
- _generic_signature = NULL;
+ _sourcefile_index = 0;
+ _generic_signature_index = 0;
_sde_buffer = NULL;
_sde_length = 0;
// initialize the other flags too:
--- a/hotspot/src/share/vm/code/nmethod.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -687,6 +687,7 @@
code_buffer->copy_values_to(this);
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
CodeCache::add_scavenge_root_nmethod(this);
+ Universe::heap()->register_nmethod(this);
}
debug_only(verify_scavenge_root_oops());
CodeCache::commit(this);
@@ -881,6 +882,7 @@
dependencies->copy_to(this);
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
CodeCache::add_scavenge_root_nmethod(this);
+ Universe::heap()->register_nmethod(this);
}
debug_only(verify_scavenge_root_oops());
@@ -1300,6 +1302,13 @@
methodHandle the_method(method());
No_Safepoint_Verifier nsv;
+ // during patching, depending on the nmethod state we must notify the GC that
+ // code has been unloaded, unregistering it. We cannot do this right while
+ // holding the Patching_lock because we need to use the CodeCache_lock. This
+ // would be prone to deadlocks.
+ // This flag is used to remember whether we need to later lock and unregister.
+ bool nmethod_needs_unregister = false;
+
{
// invalidate osr nmethod before acquiring the patching lock since
// they both acquire leaf locks and we don't want a deadlock.
@@ -1332,6 +1341,13 @@
inc_decompile_count();
}
+ // If the state is becoming a zombie, signal to unregister the nmethod with
+ // the heap.
+ // This nmethod may have already been unloaded during a full GC.
+ if ((state == zombie) && !is_unloaded()) {
+ nmethod_needs_unregister = true;
+ }
+
// Change state
_state = state;
@@ -1367,6 +1383,9 @@
// safepoint can sneak in, otherwise the oops used by the
// dependency logic could have become stale.
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ if (nmethod_needs_unregister) {
+ Universe::heap()->unregister_nmethod(this);
+ }
flush_dependencies(NULL);
}
@@ -1817,21 +1836,10 @@
if (_method != NULL) f(_method);
}
-
-// This method is called twice during GC -- once while
-// tracing the "active" nmethods on thread stacks during
-// the (strong) marking phase, and then again when walking
-// the code cache contents during the weak roots processing
-// phase. The two uses are distinguished by means of the
-// 'do_strong_roots_only' flag, which is true in the first
-// case. We want to walk the weak roots in the nmethod
-// only in the second case. The weak roots in the nmethod
-// are the oops in the ExceptionCache and the InlineCache
-// oops.
-void nmethod::oops_do(OopClosure* f, bool do_strong_roots_only) {
+void nmethod::oops_do(OopClosure* f, bool allow_zombie) {
// make sure the oops ready to receive visitors
- assert(!is_zombie() && !is_unloaded(),
- "should not call follow on zombie or unloaded nmethod");
+ assert(allow_zombie || !is_zombie(), "should not call follow on zombie nmethod");
+ assert(!is_unloaded(), "should not call follow on unloaded nmethod");
// If the method is not entrant or zombie then a JMP is plastered over the
// first few bytes. If an oop in the old code was there, that oop
--- a/hotspot/src/share/vm/code/nmethod.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -566,7 +566,7 @@
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
OopClosure* f);
void oops_do(OopClosure* f) { oops_do(f, false); }
- void oops_do(OopClosure* f, bool do_strong_roots_only);
+ void oops_do(OopClosure* f, bool allow_zombie);
bool detect_scavenge_root_oops();
void verify_scavenge_root_oops() PRODUCT_RETURN;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -5478,40 +5478,42 @@
HandleMark hm;
SequentialSubTasksDone* pst = space->par_seq_tasks();
- assert(pst->valid(), "Uninitialized use?");
uint nth_task = 0;
uint n_tasks = pst->n_tasks();
- HeapWord *start, *end;
- while (!pst->is_task_claimed(/* reference */ nth_task)) {
- // We claimed task # nth_task; compute its boundaries.
- if (chunk_top == 0) { // no samples were taken
- assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
- start = space->bottom();
- end = space->top();
- } else if (nth_task == 0) {
- start = space->bottom();
- end = chunk_array[nth_task];
- } else if (nth_task < (uint)chunk_top) {
- assert(nth_task >= 1, "Control point invariant");
- start = chunk_array[nth_task - 1];
- end = chunk_array[nth_task];
- } else {
- assert(nth_task == (uint)chunk_top, "Control point invariant");
- start = chunk_array[chunk_top - 1];
- end = space->top();
- }
- MemRegion mr(start, end);
- // Verify that mr is in space
- assert(mr.is_empty() || space->used_region().contains(mr),
- "Should be in space");
- // Verify that "start" is an object boundary
- assert(mr.is_empty() || oop(mr.start())->is_oop(),
- "Should be an oop");
- space->par_oop_iterate(mr, cl);
- }
- pst->all_tasks_completed();
+ if (n_tasks > 0) {
+ assert(pst->valid(), "Uninitialized use?");
+ HeapWord *start, *end;
+ while (!pst->is_task_claimed(/* reference */ nth_task)) {
+ // We claimed task # nth_task; compute its boundaries.
+ if (chunk_top == 0) { // no samples were taken
+ assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
+ start = space->bottom();
+ end = space->top();
+ } else if (nth_task == 0) {
+ start = space->bottom();
+ end = chunk_array[nth_task];
+ } else if (nth_task < (uint)chunk_top) {
+ assert(nth_task >= 1, "Control point invariant");
+ start = chunk_array[nth_task - 1];
+ end = chunk_array[nth_task];
+ } else {
+ assert(nth_task == (uint)chunk_top, "Control point invariant");
+ start = chunk_array[chunk_top - 1];
+ end = space->top();
+ }
+ MemRegion mr(start, end);
+ // Verify that mr is in space
+ assert(mr.is_empty() || space->used_region().contains(mr),
+ "Should be in space");
+ // Verify that "start" is an object boundary
+ assert(mr.is_empty() || oop(mr.start())->is_oop(),
+ "Should be an oop");
+ space->par_oop_iterate(mr, cl);
+ }
+ pst->all_tasks_completed();
+ }
}
void
@@ -5788,7 +5790,7 @@
DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
// Eden space
- {
+ if (!dng->eden()->is_empty()) {
SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
assert(!pst->valid(), "Clobbering existing data?");
// Each valid entry in [0, _eden_chunk_index) represents a task.
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -4529,7 +4529,7 @@
_total_prev_live_bytes(0), _total_next_live_bytes(0),
_hum_used_bytes(0), _hum_capacity_bytes(0),
_hum_prev_live_bytes(0), _hum_next_live_bytes(0),
- _total_remset_bytes(0) {
+ _total_remset_bytes(0), _total_strong_code_roots_bytes(0) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
MemRegion g1_committed = g1h->g1_committed();
MemRegion g1_reserved = g1h->g1_reserved();
@@ -4553,9 +4553,11 @@
G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT
G1PPRL_DOUBLE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT,
"type", "address-range",
- "used", "prev-live", "next-live", "gc-eff", "remset");
+ "used", "prev-live", "next-live", "gc-eff",
+ "remset", "code-roots");
_out->print_cr(G1PPRL_LINE_PREFIX
G1PPRL_TYPE_H_FORMAT
G1PPRL_ADDR_BASE_H_FORMAT
@@ -4563,9 +4565,11 @@
G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT
G1PPRL_DOUBLE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT,
"", "",
- "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)", "(bytes)");
+ "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
+ "(bytes)", "(bytes)");
}
// It takes as a parameter a reference to one of the _hum_* fields, it
@@ -4608,6 +4612,8 @@
size_t next_live_bytes = r->next_live_bytes();
double gc_eff = r->gc_efficiency();
size_t remset_bytes = r->rem_set()->mem_size();
+ size_t strong_code_roots_bytes = r->rem_set()->strong_code_roots_mem_size();
+
if (r->used() == 0) {
type = "FREE";
} else if (r->is_survivor()) {
@@ -4642,6 +4648,7 @@
_total_prev_live_bytes += prev_live_bytes;
_total_next_live_bytes += next_live_bytes;
_total_remset_bytes += remset_bytes;
+ _total_strong_code_roots_bytes += strong_code_roots_bytes;
// Print a line for this particular region.
_out->print_cr(G1PPRL_LINE_PREFIX
@@ -4651,9 +4658,11 @@
G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT
G1PPRL_DOUBLE_FORMAT
+ G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT,
type, bottom, end,
- used_bytes, prev_live_bytes, next_live_bytes, gc_eff , remset_bytes);
+ used_bytes, prev_live_bytes, next_live_bytes, gc_eff,
+ remset_bytes, strong_code_roots_bytes);
return false;
}
@@ -4669,7 +4678,8 @@
G1PPRL_SUM_MB_PERC_FORMAT("used")
G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
G1PPRL_SUM_MB_PERC_FORMAT("next-live")
- G1PPRL_SUM_MB_FORMAT("remset"),
+ G1PPRL_SUM_MB_FORMAT("remset")
+ G1PPRL_SUM_MB_FORMAT("code-roots"),
bytes_to_mb(_total_capacity_bytes),
bytes_to_mb(_total_used_bytes),
perc(_total_used_bytes, _total_capacity_bytes),
@@ -4677,6 +4687,7 @@
perc(_total_prev_live_bytes, _total_capacity_bytes),
bytes_to_mb(_total_next_live_bytes),
perc(_total_next_live_bytes, _total_capacity_bytes),
- bytes_to_mb(_total_remset_bytes));
+ bytes_to_mb(_total_remset_bytes),
+ bytes_to_mb(_total_strong_code_roots_bytes));
_out->cr();
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -1257,6 +1257,9 @@
// Accumulator for the remembered set size
size_t _total_remset_bytes;
+ // Accumulator for strong code roots memory size
+ size_t _total_strong_code_roots_bytes;
+
static double perc(size_t val, size_t total) {
if (total == 0) {
return 0.0;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
#include "gc_implementation/g1/bufferingOopClosure.hpp"
#include "gc_implementation/g1/concurrentG1Refine.hpp"
@@ -1176,20 +1177,27 @@
ModRefBarrierSet* _mr_bs;
public:
PostMCRemSetClearClosure(G1CollectedHeap* g1h, ModRefBarrierSet* mr_bs) :
- _g1h(g1h), _mr_bs(mr_bs) { }
+ _g1h(g1h), _mr_bs(mr_bs) {}
+
bool doHeapRegion(HeapRegion* r) {
+ HeapRegionRemSet* hrrs = r->rem_set();
+
if (r->continuesHumongous()) {
+ // We'll assert that the strong code root list and RSet is empty
+ assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
+ assert(hrrs->occupied() == 0, "RSet should be empty");
return false;
}
+
_g1h->reset_gc_time_stamps(r);
- HeapRegionRemSet* hrrs = r->rem_set();
- if (hrrs != NULL) hrrs->clear();
+ hrrs->clear();
// You might think here that we could clear just the cards
// corresponding to the used region. But no: if we leave a dirty card
// in a region we might allocate into, then it would prevent that card
// from being enqueued, and cause it to be missed.
// Re: the performance cost: we shouldn't be doing full GC anyway!
_mr_bs->clear(MemRegion(r->bottom(), r->end()));
+
return false;
}
};
@@ -1269,30 +1277,6 @@
heap_region_iterate(&cl);
}
-double G1CollectedHeap::verify(bool guard, const char* msg) {
- double verify_time_ms = 0.0;
-
- if (guard && total_collections() >= VerifyGCStartAt) {
- double verify_start = os::elapsedTime();
- HandleMark hm; // Discard invalid handles created during verification
- prepare_for_verify();
- Universe::verify(VerifyOption_G1UsePrevMarking, msg);
- verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
- }
-
- return verify_time_ms;
-}
-
-void G1CollectedHeap::verify_before_gc() {
- double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
- g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
-}
-
-void G1CollectedHeap::verify_after_gc() {
- double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
- g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
-}
-
bool G1CollectedHeap::do_collection(bool explicit_gc,
bool clear_all_soft_refs,
size_t word_size) {
@@ -1433,7 +1417,7 @@
// Delete metaspaces for unloaded class loaders and clean up loader_data graph
ClassLoaderDataGraph::purge();
- MetaspaceAux::verify_metrics();
+ MetaspaceAux::verify_metrics();
// Note: since we've just done a full GC, concurrent
// marking is no longer active. Therefore we need not
@@ -1504,6 +1488,9 @@
heap_region_iterate(&rebuild_rs);
}
+ // Rebuild the strong code root lists for each region
+ rebuild_strong_code_roots();
+
if (true) { // FIXME
MetaspaceGC::compute_new_size();
}
@@ -3109,6 +3096,145 @@
return NULL; // keep some compilers happy
}
+// TODO: VerifyRootsClosure extends OopsInGenClosure so that we can
+// pass it as the perm_blk to SharedHeap::process_strong_roots.
+// When process_strong_roots stop calling perm_blk->younger_refs_iterate
+// we can change this closure to extend the simpler OopClosure.
+class VerifyRootsClosure: public OopsInGenClosure {
+private:
+ G1CollectedHeap* _g1h;
+ VerifyOption _vo;
+ bool _failures;
+public:
+ // _vo == UsePrevMarking -> use "prev" marking information,
+ // _vo == UseNextMarking -> use "next" marking information,
+ // _vo == UseMarkWord -> use mark word from object header.
+ VerifyRootsClosure(VerifyOption vo) :
+ _g1h(G1CollectedHeap::heap()),
+ _vo(vo),
+ _failures(false) { }
+
+ bool failures() { return _failures; }
+
+ template <class T> void do_oop_nv(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ if (_g1h->is_obj_dead_cond(obj, _vo)) {
+ gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
+ "points to dead obj "PTR_FORMAT, p, (void*) obj);
+ if (_vo == VerifyOption_G1UseMarkWord) {
+ gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark()));
+ }
+ obj->print_on(gclog_or_tty);
+ _failures = true;
+ }
+ }
+ }
+
+ void do_oop(oop* p) { do_oop_nv(p); }
+ void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+class G1VerifyCodeRootOopClosure: public OopsInGenClosure {
+ G1CollectedHeap* _g1h;
+ OopClosure* _root_cl;
+ nmethod* _nm;
+ VerifyOption _vo;
+ bool _failures;
+
+ template <class T> void do_oop_work(T* p) {
+ // First verify that this root is live
+ _root_cl->do_oop(p);
+
+ if (!G1VerifyHeapRegionCodeRoots) {
+ // We're not verifying the code roots attached to heap region.
+ return;
+ }
+
+ // Don't check the code roots during marking verification in a full GC
+ if (_vo == VerifyOption_G1UseMarkWord) {
+ return;
+ }
+
+ // Now verify that the current nmethod (which contains p) is
+ // in the code root list of the heap region containing the
+ // object referenced by p.
+
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+
+ // Now fetch the region containing the object
+ HeapRegion* hr = _g1h->heap_region_containing(obj);
+ HeapRegionRemSet* hrrs = hr->rem_set();
+ // Verify that the strong code root list for this region
+ // contains the nmethod
+ if (!hrrs->strong_code_roots_list_contains(_nm)) {
+ gclog_or_tty->print_cr("Code root location "PTR_FORMAT" "
+ "from nmethod "PTR_FORMAT" not in strong "
+ "code roots for region ["PTR_FORMAT","PTR_FORMAT")",
+ p, _nm, hr->bottom(), hr->end());
+ _failures = true;
+ }
+ }
+ }
+
+public:
+ G1VerifyCodeRootOopClosure(G1CollectedHeap* g1h, OopClosure* root_cl, VerifyOption vo):
+ _g1h(g1h), _root_cl(root_cl), _vo(vo), _nm(NULL), _failures(false) {}
+
+ void do_oop(oop* p) { do_oop_work(p); }
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+
+ void set_nmethod(nmethod* nm) { _nm = nm; }
+ bool failures() { return _failures; }
+};
+
+class G1VerifyCodeRootBlobClosure: public CodeBlobClosure {
+ G1VerifyCodeRootOopClosure* _oop_cl;
+
+public:
+ G1VerifyCodeRootBlobClosure(G1VerifyCodeRootOopClosure* oop_cl):
+ _oop_cl(oop_cl) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = cb->as_nmethod_or_null();
+ if (nm != NULL) {
+ _oop_cl->set_nmethod(nm);
+ nm->oops_do(_oop_cl);
+ }
+ }
+};
+
+class YoungRefCounterClosure : public OopClosure {
+ G1CollectedHeap* _g1h;
+ int _count;
+ public:
+ YoungRefCounterClosure(G1CollectedHeap* g1h) : _g1h(g1h), _count(0) {}
+ void do_oop(oop* p) { if (_g1h->is_in_young(*p)) { _count++; } }
+ void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+
+ int count() { return _count; }
+ void reset_count() { _count = 0; };
+};
+
+class VerifyKlassClosure: public KlassClosure {
+ YoungRefCounterClosure _young_ref_counter_closure;
+ OopClosure *_oop_closure;
+ public:
+ VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
+ void do_klass(Klass* k) {
+ k->oops_do(_oop_closure);
+
+ _young_ref_counter_closure.reset_count();
+ k->oops_do(&_young_ref_counter_closure);
+ if (_young_ref_counter_closure.count() > 0) {
+ guarantee(k->has_modified_oops(), err_msg("Klass %p, has young refs but is not dirty.", k));
+ }
+ }
+};
+
class VerifyLivenessOopClosure: public OopClosure {
G1CollectedHeap* _g1h;
VerifyOption _vo;
@@ -3242,75 +3368,7 @@
}
};
-class YoungRefCounterClosure : public OopClosure {
- G1CollectedHeap* _g1h;
- int _count;
- public:
- YoungRefCounterClosure(G1CollectedHeap* g1h) : _g1h(g1h), _count(0) {}
- void do_oop(oop* p) { if (_g1h->is_in_young(*p)) { _count++; } }
- void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-
- int count() { return _count; }
- void reset_count() { _count = 0; };
-};
-
-class VerifyKlassClosure: public KlassClosure {
- YoungRefCounterClosure _young_ref_counter_closure;
- OopClosure *_oop_closure;
- public:
- VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
- void do_klass(Klass* k) {
- k->oops_do(_oop_closure);
-
- _young_ref_counter_closure.reset_count();
- k->oops_do(&_young_ref_counter_closure);
- if (_young_ref_counter_closure.count() > 0) {
- guarantee(k->has_modified_oops(), err_msg("Klass %p, has young refs but is not dirty.", k));
- }
- }
-};
-
-// TODO: VerifyRootsClosure extends OopsInGenClosure so that we can
-// pass it as the perm_blk to SharedHeap::process_strong_roots.
-// When process_strong_roots stop calling perm_blk->younger_refs_iterate
-// we can change this closure to extend the simpler OopClosure.
-class VerifyRootsClosure: public OopsInGenClosure {
-private:
- G1CollectedHeap* _g1h;
- VerifyOption _vo;
- bool _failures;
-public:
- // _vo == UsePrevMarking -> use "prev" marking information,
- // _vo == UseNextMarking -> use "next" marking information,
- // _vo == UseMarkWord -> use mark word from object header.
- VerifyRootsClosure(VerifyOption vo) :
- _g1h(G1CollectedHeap::heap()),
- _vo(vo),
- _failures(false) { }
-
- bool failures() { return _failures; }
-
- template <class T> void do_oop_nv(T* p) {
- T heap_oop = oopDesc::load_heap_oop(p);
- if (!oopDesc::is_null(heap_oop)) {
- oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
- if (_g1h->is_obj_dead_cond(obj, _vo)) {
- gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
- "points to dead obj "PTR_FORMAT, p, (void*) obj);
- if (_vo == VerifyOption_G1UseMarkWord) {
- gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark()));
- }
- obj->print_on(gclog_or_tty);
- _failures = true;
- }
- }
- }
-
- void do_oop(oop* p) { do_oop_nv(p); }
- void do_oop(narrowOop* p) { do_oop_nv(p); }
-};
-
-// This is the task used for parallel heap verification.
+// This is the task used for parallel verification of the heap regions
class G1ParVerifyTask: public AbstractGangTask {
private:
@@ -3344,20 +3402,15 @@
}
};
-void G1CollectedHeap::verify(bool silent) {
- verify(silent, VerifyOption_G1UsePrevMarking);
-}
-
-void G1CollectedHeap::verify(bool silent,
- VerifyOption vo) {
+void G1CollectedHeap::verify(bool silent, VerifyOption vo) {
if (SafepointSynchronize::is_at_safepoint()) {
+ assert(Thread::current()->is_VM_thread(),
+ "Expected to be executed serially by the VM thread at this point");
+
if (!silent) { gclog_or_tty->print("Roots "); }
VerifyRootsClosure rootsCl(vo);
-
- assert(Thread::current()->is_VM_thread(),
- "Expected to be executed serially by the VM thread at this point");
-
- CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
+ G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
+ G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
VerifyKlassClosure klassCl(this, &rootsCl);
// We apply the relevant closures to all the oops in the
@@ -3376,7 +3429,7 @@
&klassCl
);
- bool failures = rootsCl.failures();
+ bool failures = rootsCl.failures() || codeRootsCl.failures();
if (vo != VerifyOption_G1UseMarkWord) {
// If we're verifying during a full GC then the region sets
@@ -3445,6 +3498,34 @@
}
}
+void G1CollectedHeap::verify(bool silent) {
+ verify(silent, VerifyOption_G1UsePrevMarking);
+}
+
+double G1CollectedHeap::verify(bool guard, const char* msg) {
+ double verify_time_ms = 0.0;
+
+ if (guard && total_collections() >= VerifyGCStartAt) {
+ double verify_start = os::elapsedTime();
+ HandleMark hm; // Discard invalid handles created during verification
+ prepare_for_verify();
+ Universe::verify(VerifyOption_G1UsePrevMarking, msg);
+ verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
+ }
+
+ return verify_time_ms;
+}
+
+void G1CollectedHeap::verify_before_gc() {
+ double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
+ g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+}
+
+void G1CollectedHeap::verify_after_gc() {
+ double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
+ g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+}
+
class PrintRegionClosure: public HeapRegionClosure {
outputStream* _st;
public:
@@ -3866,8 +3947,9 @@
append_secondary_free_list_if_not_empty_with_lock();
}
- assert(check_young_list_well_formed(),
- "young list should be well formed");
+ assert(check_young_list_well_formed(), "young list should be well formed");
+ assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
+ "sanity check");
// Don't dynamically change the number of GC threads this early. A value of
// 0 is used to indicate serial work. When parallel work is done,
@@ -4987,7 +5069,11 @@
G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
- int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
+ // Don't scan the scavengable methods in the code cache as part
+ // of strong root scanning. The code roots that point into a
+ // region in the collection set are scanned when we scan the
+ // region's RSet.
+ int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings;
pss.start_strong_roots();
_g1h->g1_process_strong_roots(/* is scavenging */ true,
@@ -5029,67 +5115,6 @@
// *** Common G1 Evacuation Stuff
-// Closures that support the filtering of CodeBlobs scanned during
-// external root scanning.
-
-// Closure applied to reference fields in code blobs (specifically nmethods)
-// to determine whether an nmethod contains references that point into
-// the collection set. Used as a predicate when walking code roots so
-// that only nmethods that point into the collection set are added to the
-// 'marked' list.
-
-class G1FilteredCodeBlobToOopClosure : public CodeBlobToOopClosure {
-
- class G1PointsIntoCSOopClosure : public OopClosure {
- G1CollectedHeap* _g1;
- bool _points_into_cs;
- public:
- G1PointsIntoCSOopClosure(G1CollectedHeap* g1) :
- _g1(g1), _points_into_cs(false) { }
-
- bool points_into_cs() const { return _points_into_cs; }
-
- template <class T>
- void do_oop_nv(T* p) {
- if (!_points_into_cs) {
- T heap_oop = oopDesc::load_heap_oop(p);
- if (!oopDesc::is_null(heap_oop) &&
- _g1->in_cset_fast_test(oopDesc::decode_heap_oop_not_null(heap_oop))) {
- _points_into_cs = true;
- }
- }
- }
-
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
- };
-
- G1CollectedHeap* _g1;
-
-public:
- G1FilteredCodeBlobToOopClosure(G1CollectedHeap* g1, OopClosure* cl) :
- CodeBlobToOopClosure(cl, true), _g1(g1) { }
-
- virtual void do_code_blob(CodeBlob* cb) {
- nmethod* nm = cb->as_nmethod_or_null();
- if (nm != NULL && !(nm->test_oops_do_mark())) {
- G1PointsIntoCSOopClosure predicate_cl(_g1);
- nm->oops_do(&predicate_cl);
-
- if (predicate_cl.points_into_cs()) {
- // At least one of the reference fields or the oop relocations
- // in the nmethod points into the collection set. We have to
- // 'mark' this nmethod.
- // Note: Revisit the following if CodeBlobToOopClosure::do_code_blob()
- // or MarkingCodeBlobClosure::do_code_blob() change.
- if (!nm->test_set_oops_do_mark()) {
- do_newly_marked_nmethod(nm);
- }
- }
- }
- }
-};
-
// This method is run in a GC worker.
void
@@ -5107,9 +5132,10 @@
BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
- // Walk the code cache w/o buffering, because StarTask cannot handle
- // unaligned oop locations.
- G1FilteredCodeBlobToOopClosure eager_scan_code_roots(this, scan_non_heap_roots);
+ assert(so & SO_CodeCache || scan_rs != NULL, "must scan code roots somehow");
+ // Walk the code cache/strong code roots w/o buffering, because StarTask
+ // cannot handle unaligned oop locations.
+ CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, true /* do_marking */);
process_strong_roots(false, // no scoping; this is parallel code
is_scavenging, so,
@@ -5154,9 +5180,22 @@
}
g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
+ // If this is an initial mark pause, and we're not scanning
+ // the entire code cache, we need to mark the oops in the
+ // strong code root lists for the regions that are not in
+ // the collection set.
+ // Note all threads participate in this set of root tasks.
+ double mark_strong_code_roots_ms = 0.0;
+ if (g1_policy()->during_initial_mark_pause() && !(so & SO_CodeCache)) {
+ double mark_strong_roots_start = os::elapsedTime();
+ mark_strong_code_roots(worker_i);
+ mark_strong_code_roots_ms = (os::elapsedTime() - mark_strong_roots_start) * 1000.0;
+ }
+ g1_policy()->phase_times()->record_strong_code_root_mark_time(worker_i, mark_strong_code_roots_ms);
+
// Now scan the complement of the collection set.
if (scan_rs != NULL) {
- g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i);
+ g1_rem_set()->oops_into_collection_set_do(scan_rs, &eager_scan_code_roots, worker_i);
}
_process_strong_tasks->all_tasks_completed();
}
@@ -5774,9 +5813,6 @@
process_discovered_references(n_workers);
// Weak root processing.
- // Note: when JSR 292 is enabled and code blobs can contain
- // non-perm oops then we will need to process the code blobs
- // here too.
{
G1STWIsAliveClosure is_alive(this);
G1KeepAliveClosure keep_alive(this);
@@ -5792,6 +5828,17 @@
hot_card_cache->reset_hot_cache();
hot_card_cache->set_use_cache(true);
+ // Migrate the strong code roots attached to each region in
+ // the collection set. Ideally we would like to do this
+ // after we have finished the scanning/evacuation of the
+ // strong code roots for a particular heap region.
+ migrate_strong_code_roots();
+
+ if (g1_policy()->during_initial_mark_pause()) {
+ // Reset the claim values set during marking the strong code roots
+ reset_heap_region_claim_values();
+ }
+
finalize_for_evac_failure();
if (evacuation_failed()) {
@@ -6588,3 +6635,208 @@
_humongous_set.verify_end();
_free_list.verify_end();
}
+
+// Optimized nmethod scanning
+
+class RegisterNMethodOopClosure: public OopClosure {
+ G1CollectedHeap* _g1h;
+ nmethod* _nm;
+
+ template <class T> void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ HeapRegion* hr = _g1h->heap_region_containing(obj);
+ assert(!hr->isHumongous(), "code root in humongous region?");
+
+ // HeapRegion::add_strong_code_root() avoids adding duplicate
+ // entries but having duplicates is OK since we "mark" nmethods
+ // as visited when we scan the strong code root lists during the GC.
+ hr->add_strong_code_root(_nm);
+ assert(hr->rem_set()->strong_code_roots_list_contains(_nm), "add failed?");
+ }
+ }
+
+public:
+ RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) :
+ _g1h(g1h), _nm(nm) {}
+
+ void do_oop(oop* p) { do_oop_work(p); }
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+};
+
+class UnregisterNMethodOopClosure: public OopClosure {
+ G1CollectedHeap* _g1h;
+ nmethod* _nm;
+
+ template <class T> void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ HeapRegion* hr = _g1h->heap_region_containing(obj);
+ assert(!hr->isHumongous(), "code root in humongous region?");
+ hr->remove_strong_code_root(_nm);
+ assert(!hr->rem_set()->strong_code_roots_list_contains(_nm), "remove failed?");
+ }
+ }
+
+public:
+ UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) :
+ _g1h(g1h), _nm(nm) {}
+
+ void do_oop(oop* p) { do_oop_work(p); }
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+};
+
+void G1CollectedHeap::register_nmethod(nmethod* nm) {
+ CollectedHeap::register_nmethod(nm);
+
+ guarantee(nm != NULL, "sanity");
+ RegisterNMethodOopClosure reg_cl(this, nm);
+ nm->oops_do(®_cl);
+}
+
+void G1CollectedHeap::unregister_nmethod(nmethod* nm) {
+ CollectedHeap::unregister_nmethod(nm);
+
+ guarantee(nm != NULL, "sanity");
+ UnregisterNMethodOopClosure reg_cl(this, nm);
+ nm->oops_do(®_cl, true);
+}
+
+class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure {
+public:
+ bool doHeapRegion(HeapRegion *hr) {
+ assert(!hr->isHumongous(), "humongous region in collection set?");
+ hr->migrate_strong_code_roots();
+ return false;
+ }
+};
+
+void G1CollectedHeap::migrate_strong_code_roots() {
+ MigrateCodeRootsHeapRegionClosure cl;
+ double migrate_start = os::elapsedTime();
+ collection_set_iterate(&cl);
+ double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0;
+ g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms);
+}
+
+// Mark all the code roots that point into regions *not* in the
+// collection set.
+//
+// Note we do not want to use a "marking" CodeBlobToOopClosure while
+// walking the the code roots lists of regions not in the collection
+// set. Suppose we have an nmethod (M) that points to objects in two
+// separate regions - one in the collection set (R1) and one not (R2).
+// Using a "marking" CodeBlobToOopClosure here would result in "marking"
+// nmethod M when walking the code roots for R1. When we come to scan
+// the code roots for R2, we would see that M is already marked and it
+// would be skipped and the objects in R2 that are referenced from M
+// would not be evacuated.
+
+class MarkStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
+
+ class MarkStrongCodeRootOopClosure: public OopClosure {
+ ConcurrentMark* _cm;
+ HeapRegion* _hr;
+ uint _worker_id;
+
+ template <class T> void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ // Only mark objects in the region (which is assumed
+ // to be not in the collection set).
+ if (_hr->is_in(obj)) {
+ _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
+ }
+ }
+ }
+
+ public:
+ MarkStrongCodeRootOopClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id) :
+ _cm(cm), _hr(hr), _worker_id(worker_id) {
+ assert(!_hr->in_collection_set(), "sanity");
+ }
+
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+ void do_oop(oop* p) { do_oop_work(p); }
+ };
+
+ MarkStrongCodeRootOopClosure _oop_cl;
+
+public:
+ MarkStrongCodeRootCodeBlobClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id):
+ _oop_cl(cm, hr, worker_id) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null();
+ if (nm != NULL) {
+ nm->oops_do(&_oop_cl);
+ }
+ }
+};
+
+class MarkStrongCodeRootsHRClosure: public HeapRegionClosure {
+ G1CollectedHeap* _g1h;
+ uint _worker_id;
+
+public:
+ MarkStrongCodeRootsHRClosure(G1CollectedHeap* g1h, uint worker_id) :
+ _g1h(g1h), _worker_id(worker_id) {}
+
+ bool doHeapRegion(HeapRegion *hr) {
+ HeapRegionRemSet* hrrs = hr->rem_set();
+ if (hr->isHumongous()) {
+ // Code roots should never be attached to a humongous region
+ assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
+ return false;
+ }
+
+ if (hr->in_collection_set()) {
+ // Don't mark code roots into regions in the collection set here.
+ // They will be marked when we scan them.
+ return false;
+ }
+
+ MarkStrongCodeRootCodeBlobClosure cb_cl(_g1h->concurrent_mark(), hr, _worker_id);
+ hr->strong_code_roots_do(&cb_cl);
+ return false;
+ }
+};
+
+void G1CollectedHeap::mark_strong_code_roots(uint worker_id) {
+ MarkStrongCodeRootsHRClosure cl(this, worker_id);
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ heap_region_par_iterate_chunked(&cl,
+ worker_id,
+ workers()->active_workers(),
+ HeapRegion::ParMarkRootClaimValue);
+ } else {
+ heap_region_iterate(&cl);
+ }
+}
+
+class RebuildStrongCodeRootClosure: public CodeBlobClosure {
+ G1CollectedHeap* _g1h;
+
+public:
+ RebuildStrongCodeRootClosure(G1CollectedHeap* g1h) :
+ _g1h(g1h) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = (cb != NULL) ? cb->as_nmethod_or_null() : NULL;
+ if (nm == NULL) {
+ return;
+ }
+
+ if (ScavengeRootsInCode && nm->detect_scavenge_root_oops()) {
+ _g1h->register_nmethod(nm);
+ }
+ }
+};
+
+void G1CollectedHeap::rebuild_strong_code_roots() {
+ RebuildStrongCodeRootClosure blob_cl(this);
+ CodeCache::blobs_do(&blob_cl);
+}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -46,6 +46,7 @@
// may combine concurrent marking with parallel, incremental compaction of
// heap subsets that will yield large amounts of garbage.
+// Forward declarations
class HeapRegion;
class HRRSCleanupTask;
class GenerationSpec;
@@ -69,6 +70,7 @@
class G1NewTracer;
class G1OldTracer;
class EvacuationFailedInfo;
+class nmethod;
typedef OverflowTaskQueue<StarTask, mtGC> RefToScanQueue;
typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
@@ -163,18 +165,6 @@
: G1AllocRegion("Mutator Alloc Region", false /* bot_updates */) { }
};
-// The G1 STW is alive closure.
-// An instance is embedded into the G1CH and used as the
-// (optional) _is_alive_non_header closure in the STW
-// reference processor. It is also extensively used during
-// reference processing during STW evacuation pauses.
-class G1STWIsAliveClosure: public BoolObjectClosure {
- G1CollectedHeap* _g1;
-public:
- G1STWIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
- bool do_object_b(oop p);
-};
-
class SurvivorGCAllocRegion : public G1AllocRegion {
protected:
virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
@@ -193,6 +183,18 @@
: G1AllocRegion("Old GC Alloc Region", true /* bot_updates */) { }
};
+// The G1 STW is alive closure.
+// An instance is embedded into the G1CH and used as the
+// (optional) _is_alive_non_header closure in the STW
+// reference processor. It is also extensively used during
+// reference processing during STW evacuation pauses.
+class G1STWIsAliveClosure: public BoolObjectClosure {
+ G1CollectedHeap* _g1;
+public:
+ G1STWIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
+ bool do_object_b(oop p);
+};
+
class RefineCardTableEntryClosure;
class G1CollectedHeap : public SharedHeap {
@@ -1549,42 +1551,6 @@
virtual jlong millis_since_last_gc();
- // Perform any cleanup actions necessary before allowing a verification.
- virtual void prepare_for_verify();
-
- // Perform verification.
-
- // vo == UsePrevMarking -> use "prev" marking information,
- // vo == UseNextMarking -> use "next" marking information
- // vo == UseMarkWord -> use the mark word in the object header
- //
- // NOTE: Only the "prev" marking information is guaranteed to be
- // consistent most of the time, so most calls to this should use
- // vo == UsePrevMarking.
- // Currently, there is only one case where this is called with
- // vo == UseNextMarking, which is to verify the "next" marking
- // information at the end of remark.
- // Currently there is only one place where this is called with
- // vo == UseMarkWord, which is to verify the marking during a
- // full GC.
- void verify(bool silent, VerifyOption vo);
-
- // Override; it uses the "prev" marking information
- virtual void verify(bool silent);
-
- virtual void print_on(outputStream* st) const;
- virtual void print_extended_on(outputStream* st) const;
- virtual void print_on_error(outputStream* st) const;
-
- virtual void print_gc_threads_on(outputStream* st) const;
- virtual void gc_threads_do(ThreadClosure* tc) const;
-
- // Override
- void print_tracing_info() const;
-
- // The following two methods are helpful for debugging RSet issues.
- void print_cset_rsets() PRODUCT_RETURN;
- void print_all_rsets() PRODUCT_RETURN;
// Convenience function to be used in situations where the heap type can be
// asserted to be this type.
@@ -1661,13 +1627,86 @@
else return is_obj_ill(obj, hr);
}
+ bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
+ HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
+ bool is_marked(oop obj, VerifyOption vo);
+ const char* top_at_mark_start_str(VerifyOption vo);
+
+ ConcurrentMark* concurrent_mark() const { return _cm; }
+
+ // Refinement
+
+ ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
+
+ // The dirty cards region list is used to record a subset of regions
+ // whose cards need clearing. The list if populated during the
+ // remembered set scanning and drained during the card table
+ // cleanup. Although the methods are reentrant, population/draining
+ // phases must not overlap. For synchronization purposes the last
+ // element on the list points to itself.
+ HeapRegion* _dirty_cards_region_list;
+ void push_dirty_cards_region(HeapRegion* hr);
+ HeapRegion* pop_dirty_cards_region();
+
+ // Optimized nmethod scanning support routines
+
+ // Register the given nmethod with the G1 heap
+ virtual void register_nmethod(nmethod* nm);
+
+ // Unregister the given nmethod from the G1 heap
+ virtual void unregister_nmethod(nmethod* nm);
+
+ // Migrate the nmethods in the code root lists of the regions
+ // in the collection set to regions in to-space. In the event
+ // of an evacuation failure, nmethods that reference objects
+ // that were not successfullly evacuated are not migrated.
+ void migrate_strong_code_roots();
+
+ // During an initial mark pause, mark all the code roots that
+ // point into regions *not* in the collection set.
+ void mark_strong_code_roots(uint worker_id);
+
+ // Rebuild the stong code root lists for each region
+ // after a full GC
+ void rebuild_strong_code_roots();
+
+ // Verification
+
+ // The following is just to alert the verification code
+ // that a full collection has occurred and that the
+ // remembered sets are no longer up to date.
+ bool _full_collection;
+ void set_full_collection() { _full_collection = true;}
+ void clear_full_collection() {_full_collection = false;}
+ bool full_collection() {return _full_collection;}
+
+ // Perform any cleanup actions necessary before allowing a verification.
+ virtual void prepare_for_verify();
+
+ // Perform verification.
+
+ // vo == UsePrevMarking -> use "prev" marking information,
+ // vo == UseNextMarking -> use "next" marking information
+ // vo == UseMarkWord -> use the mark word in the object header
+ //
+ // NOTE: Only the "prev" marking information is guaranteed to be
+ // consistent most of the time, so most calls to this should use
+ // vo == UsePrevMarking.
+ // Currently, there is only one case where this is called with
+ // vo == UseNextMarking, which is to verify the "next" marking
+ // information at the end of remark.
+ // Currently there is only one place where this is called with
+ // vo == UseMarkWord, which is to verify the marking during a
+ // full GC.
+ void verify(bool silent, VerifyOption vo);
+
+ // Override; it uses the "prev" marking information
+ virtual void verify(bool silent);
+
// The methods below are here for convenience and dispatch the
// appropriate method depending on value of the given VerifyOption
- // parameter. The options for that parameter are:
- //
- // vo == UsePrevMarking -> use "prev" marking information,
- // vo == UseNextMarking -> use "next" marking information,
- // vo == UseMarkWord -> use mark word from object header
+ // parameter. The values for that parameter, and their meanings,
+ // are the same as those above.
bool is_obj_dead_cond(const oop obj,
const HeapRegion* hr,
@@ -1692,31 +1731,21 @@
return false; // keep some compilers happy
}
- bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
- HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
- bool is_marked(oop obj, VerifyOption vo);
- const char* top_at_mark_start_str(VerifyOption vo);
+ // Printing
- // The following is just to alert the verification code
- // that a full collection has occurred and that the
- // remembered sets are no longer up to date.
- bool _full_collection;
- void set_full_collection() { _full_collection = true;}
- void clear_full_collection() {_full_collection = false;}
- bool full_collection() {return _full_collection;}
+ virtual void print_on(outputStream* st) const;
+ virtual void print_extended_on(outputStream* st) const;
+ virtual void print_on_error(outputStream* st) const;
- ConcurrentMark* concurrent_mark() const { return _cm; }
- ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
+ virtual void print_gc_threads_on(outputStream* st) const;
+ virtual void gc_threads_do(ThreadClosure* tc) const;
- // The dirty cards region list is used to record a subset of regions
- // whose cards need clearing. The list if populated during the
- // remembered set scanning and drained during the card table
- // cleanup. Although the methods are reentrant, population/draining
- // phases must not overlap. For synchronization purposes the last
- // element on the list points to itself.
- HeapRegion* _dirty_cards_region_list;
- void push_dirty_cards_region(HeapRegion* hr);
- HeapRegion* pop_dirty_cards_region();
+ // Override
+ void print_tracing_info() const;
+
+ // The following two methods are helpful for debugging RSet issues.
+ void print_cset_rsets() PRODUCT_RETURN;
+ void print_all_rsets() PRODUCT_RETURN;
public:
void stop_conc_gc_threads();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -161,6 +161,8 @@
_last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
_last_update_rs_processed_buffers(_max_gc_threads, "%d"),
_last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
+ _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
+ _last_strong_code_root_mark_times_ms(_max_gc_threads, "%.1lf"),
_last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
_last_termination_times_ms(_max_gc_threads, "%.1lf"),
_last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
@@ -182,6 +184,8 @@
_last_update_rs_times_ms.reset();
_last_update_rs_processed_buffers.reset();
_last_scan_rs_times_ms.reset();
+ _last_strong_code_root_scan_times_ms.reset();
+ _last_strong_code_root_mark_times_ms.reset();
_last_obj_copy_times_ms.reset();
_last_termination_times_ms.reset();
_last_termination_attempts.reset();
@@ -197,6 +201,8 @@
_last_update_rs_times_ms.verify();
_last_update_rs_processed_buffers.verify();
_last_scan_rs_times_ms.verify();
+ _last_strong_code_root_scan_times_ms.verify();
+ _last_strong_code_root_mark_times_ms.verify();
_last_obj_copy_times_ms.verify();
_last_termination_times_ms.verify();
_last_termination_attempts.verify();
@@ -210,6 +216,8 @@
_last_satb_filtering_times_ms.get(i) +
_last_update_rs_times_ms.get(i) +
_last_scan_rs_times_ms.get(i) +
+ _last_strong_code_root_scan_times_ms.get(i) +
+ _last_strong_code_root_mark_times_ms.get(i) +
_last_obj_copy_times_ms.get(i) +
_last_termination_times_ms.get(i);
@@ -239,6 +247,9 @@
// Now subtract the time taken to fix up roots in generated code
misc_time_ms += _cur_collection_code_root_fixup_time_ms;
+ // Strong code root migration time
+ misc_time_ms += _cur_strong_code_root_migration_time_ms;
+
// Subtract the time taken to clean the card table from the
// current value of "other time"
misc_time_ms += _cur_clear_ct_time_ms;
@@ -257,9 +268,13 @@
if (_last_satb_filtering_times_ms.sum() > 0.0) {
_last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
}
+ if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+ _last_strong_code_root_mark_times_ms.print(2, "Code Root Marking (ms)");
+ }
_last_update_rs_times_ms.print(2, "Update RS (ms)");
_last_update_rs_processed_buffers.print(3, "Processed Buffers");
_last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+ _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
_last_obj_copy_times_ms.print(2, "Object Copy (ms)");
_last_termination_times_ms.print(2, "Termination (ms)");
if (G1Log::finest()) {
@@ -273,12 +288,17 @@
if (_last_satb_filtering_times_ms.sum() > 0.0) {
_last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
}
+ if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+ _last_strong_code_root_mark_times_ms.print(1, "Code Root Marking (ms)");
+ }
_last_update_rs_times_ms.print(1, "Update RS (ms)");
_last_update_rs_processed_buffers.print(2, "Processed Buffers");
_last_scan_rs_times_ms.print(1, "Scan RS (ms)");
+ _last_strong_code_root_scan_times_ms.print(1, "Code Root Scanning (ms)");
_last_obj_copy_times_ms.print(1, "Object Copy (ms)");
}
print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
+ print_stats(1, "Code Root Migration", _cur_strong_code_root_migration_time_ms);
print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
print_stats(1, "Other", misc_time_ms);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -119,6 +119,8 @@
WorkerDataArray<double> _last_update_rs_times_ms;
WorkerDataArray<int> _last_update_rs_processed_buffers;
WorkerDataArray<double> _last_scan_rs_times_ms;
+ WorkerDataArray<double> _last_strong_code_root_scan_times_ms;
+ WorkerDataArray<double> _last_strong_code_root_mark_times_ms;
WorkerDataArray<double> _last_obj_copy_times_ms;
WorkerDataArray<double> _last_termination_times_ms;
WorkerDataArray<size_t> _last_termination_attempts;
@@ -128,6 +130,7 @@
double _cur_collection_par_time_ms;
double _cur_collection_code_root_fixup_time_ms;
+ double _cur_strong_code_root_migration_time_ms;
double _cur_clear_ct_time_ms;
double _cur_ref_proc_time_ms;
@@ -179,6 +182,14 @@
_last_scan_rs_times_ms.set(worker_i, ms);
}
+ void record_strong_code_root_scan_time(uint worker_i, double ms) {
+ _last_strong_code_root_scan_times_ms.set(worker_i, ms);
+ }
+
+ void record_strong_code_root_mark_time(uint worker_i, double ms) {
+ _last_strong_code_root_mark_times_ms.set(worker_i, ms);
+ }
+
void record_obj_copy_time(uint worker_i, double ms) {
_last_obj_copy_times_ms.set(worker_i, ms);
}
@@ -208,6 +219,10 @@
_cur_collection_code_root_fixup_time_ms = ms;
}
+ void record_strong_code_root_migration_time(double ms) {
+ _cur_strong_code_root_migration_time_ms = ms;
+ }
+
void record_ref_proc_time(double ms) {
_cur_ref_proc_time_ms = ms;
}
@@ -294,6 +309,14 @@
return _last_scan_rs_times_ms.average();
}
+ double average_last_strong_code_root_scan_time(){
+ return _last_strong_code_root_scan_times_ms.average();
+ }
+
+ double average_last_strong_code_root_mark_time(){
+ return _last_strong_code_root_mark_times_ms.average();
+ }
+
double average_last_obj_copy_time() {
return _last_obj_copy_times_ms.average();
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -262,6 +262,7 @@
old_collection_counters()->update_all();
young_collection_counters()->update_all();
MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -104,15 +104,25 @@
class ScanRSClosure : public HeapRegionClosure {
size_t _cards_done, _cards;
G1CollectedHeap* _g1h;
+
OopsInHeapRegionClosure* _oc;
+ CodeBlobToOopClosure* _code_root_cl;
+
G1BlockOffsetSharedArray* _bot_shared;
CardTableModRefBS *_ct_bs;
- int _worker_i;
- int _block_size;
- bool _try_claimed;
+
+ double _strong_code_root_scan_time_sec;
+ int _worker_i;
+ int _block_size;
+ bool _try_claimed;
+
public:
- ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
+ ScanRSClosure(OopsInHeapRegionClosure* oc,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i) :
_oc(oc),
+ _code_root_cl(code_root_cl),
+ _strong_code_root_scan_time_sec(0.0),
_cards(0),
_cards_done(0),
_worker_i(worker_i),
@@ -160,6 +170,12 @@
card_start, card_start + G1BlockOffsetSharedArray::N_words);
}
+ void scan_strong_code_roots(HeapRegion* r) {
+ double scan_start = os::elapsedTime();
+ r->strong_code_roots_do(_code_root_cl);
+ _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
+ }
+
bool doHeapRegion(HeapRegion* r) {
assert(r->in_collection_set(), "should only be called on elements of CS.");
HeapRegionRemSet* hrrs = r->rem_set();
@@ -173,6 +189,7 @@
// _try_claimed || r->claim_iter()
// is true: either we're supposed to work on claimed-but-not-complete
// regions, or we successfully claimed the region.
+
HeapRegionRemSetIterator iter(hrrs);
size_t card_index;
@@ -205,30 +222,43 @@
}
}
if (!_try_claimed) {
+ // Scan the strong code root list attached to the current region
+ scan_strong_code_roots(r);
+
hrrs->set_iter_complete();
}
return false;
}
+
+ double strong_code_root_scan_time_sec() {
+ return _strong_code_root_scan_time_sec;
+ }
+
size_t cards_done() { return _cards_done;}
size_t cards_looked_up() { return _cards;}
};
-void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
+void G1RemSet::scanRS(OopsInHeapRegionClosure* oc,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i) {
double rs_time_start = os::elapsedTime();
HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i);
- ScanRSClosure scanRScl(oc, worker_i);
+ ScanRSClosure scanRScl(oc, code_root_cl, worker_i);
_g1->collection_set_iterate_from(startRegion, &scanRScl);
scanRScl.set_try_claimed();
_g1->collection_set_iterate_from(startRegion, &scanRScl);
- double scan_rs_time_sec = os::elapsedTime() - rs_time_start;
+ double scan_rs_time_sec = (os::elapsedTime() - rs_time_start)
+ - scanRScl.strong_code_root_scan_time_sec();
- assert( _cards_scanned != NULL, "invariant" );
+ assert(_cards_scanned != NULL, "invariant");
_cards_scanned[worker_i] = scanRScl.cards_done();
_g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
+ _g1p->phase_times()->record_strong_code_root_scan_time(worker_i,
+ scanRScl.strong_code_root_scan_time_sec() * 1000.0);
}
// Closure used for updating RSets and recording references that
@@ -288,7 +318,8 @@
}
void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
- int worker_i) {
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i) {
#if CARD_REPEAT_HISTO
ct_freq_update_histo_and_reset();
#endif
@@ -328,7 +359,7 @@
_g1p->phase_times()->record_update_rs_time(worker_i, 0.0);
}
if (G1UseParallelRSetScanning || (worker_i == 0)) {
- scanRS(oc, worker_i);
+ scanRS(oc, code_root_cl, worker_i);
} else {
_g1p->phase_times()->record_scan_rs_time(worker_i, 0.0);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -81,14 +81,23 @@
G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
~G1RemSet();
- // Invoke "blk->do_oop" on all pointers into the CS in objects in regions
- // outside the CS (having invoked "blk->set_region" to set the "from"
- // region correctly beforehand.) The "worker_i" param is for the
- // parallel case where the number of the worker thread calling this
- // function can be helpful in partitioning the work to be done. It
- // should be the same as the "i" passed to the calling thread's
- // work(i) function. In the sequential case this param will be ingored.
- void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, int worker_i);
+ // Invoke "blk->do_oop" on all pointers into the collection set
+ // from objects in regions outside the collection set (having
+ // invoked "blk->set_region" to set the "from" region correctly
+ // beforehand.)
+ //
+ // Invoke code_root_cl->do_code_blob on the unmarked nmethods
+ // on the strong code roots list for each region in the
+ // collection set.
+ //
+ // The "worker_i" param is for the parallel case where the id
+ // of the worker thread calling this function can be helpful in
+ // partitioning the work to be done. It should be the same as
+ // the "i" passed to the calling thread's work(i) function.
+ // In the sequential case this param will be ignored.
+ void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i);
// Prepare for and cleanup after an oops_into_collection_set_do
// call. Must call each of these once before and after (in sequential
@@ -98,7 +107,10 @@
void prepare_for_oops_into_collection_set_do();
void cleanup_after_oops_into_collection_set_do();
- void scanRS(OopsInHeapRegionClosure* oc, int worker_i);
+ void scanRS(OopsInHeapRegionClosure* oc,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i);
+
void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i);
CardTableModRefBS* ct_bs() { return _ct_bs; }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -127,32 +127,55 @@
class HRRSStatsIter: public HeapRegionClosure {
size_t _occupied;
- size_t _total_mem_sz;
- size_t _max_mem_sz;
- HeapRegion* _max_mem_sz_region;
+
+ size_t _total_rs_mem_sz;
+ size_t _max_rs_mem_sz;
+ HeapRegion* _max_rs_mem_sz_region;
+
+ size_t _total_code_root_mem_sz;
+ size_t _max_code_root_mem_sz;
+ HeapRegion* _max_code_root_mem_sz_region;
public:
HRRSStatsIter() :
_occupied(0),
- _total_mem_sz(0),
- _max_mem_sz(0),
- _max_mem_sz_region(NULL)
+ _total_rs_mem_sz(0),
+ _max_rs_mem_sz(0),
+ _max_rs_mem_sz_region(NULL),
+ _total_code_root_mem_sz(0),
+ _max_code_root_mem_sz(0),
+ _max_code_root_mem_sz_region(NULL)
{}
bool doHeapRegion(HeapRegion* r) {
- size_t mem_sz = r->rem_set()->mem_size();
- if (mem_sz > _max_mem_sz) {
- _max_mem_sz = mem_sz;
- _max_mem_sz_region = r;
+ HeapRegionRemSet* hrrs = r->rem_set();
+
+ // HeapRegionRemSet::mem_size() includes the
+ // size of the strong code roots
+ size_t rs_mem_sz = hrrs->mem_size();
+ if (rs_mem_sz > _max_rs_mem_sz) {
+ _max_rs_mem_sz = rs_mem_sz;
+ _max_rs_mem_sz_region = r;
}
- _total_mem_sz += mem_sz;
- size_t occ = r->rem_set()->occupied();
+ _total_rs_mem_sz += rs_mem_sz;
+
+ size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
+ if (code_root_mem_sz > _max_code_root_mem_sz) {
+ _max_code_root_mem_sz = code_root_mem_sz;
+ _max_code_root_mem_sz_region = r;
+ }
+ _total_code_root_mem_sz += code_root_mem_sz;
+
+ size_t occ = hrrs->occupied();
_occupied += occ;
return false;
}
- size_t total_mem_sz() { return _total_mem_sz; }
- size_t max_mem_sz() { return _max_mem_sz; }
+ size_t total_rs_mem_sz() { return _total_rs_mem_sz; }
+ size_t max_rs_mem_sz() { return _max_rs_mem_sz; }
+ HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; }
+ size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; }
+ size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; }
+ HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; }
size_t occupied() { return _occupied; }
- HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
};
double calc_percentage(size_t numerator, size_t denominator) {
@@ -184,22 +207,33 @@
HRRSStatsIter blk;
G1CollectedHeap::heap()->heap_region_iterate(&blk);
+ // RemSet stats
out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K."
" Max = "SIZE_FORMAT"K.",
- blk.total_mem_sz()/K, blk.max_mem_sz()/K);
+ blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K);
out->print_cr(" Static structures = "SIZE_FORMAT"K,"
" free_lists = "SIZE_FORMAT"K.",
HeapRegionRemSet::static_mem_size() / K,
HeapRegionRemSet::fl_mem_size() / K);
out->print_cr(" "SIZE_FORMAT" occupied cards represented.",
blk.occupied());
- HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
- HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
+ HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region();
+ HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set();
out->print_cr(" Max size region = "HR_FORMAT", "
"size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
- HR_FORMAT_PARAMS(max_mem_sz_region),
- (rem_set->mem_size() + K - 1)/K,
- (rem_set->occupied() + K - 1)/K);
-
+ HR_FORMAT_PARAMS(max_rs_mem_sz_region),
+ (max_rs_rem_set->mem_size() + K - 1)/K,
+ (max_rs_rem_set->occupied() + K - 1)/K);
out->print_cr(" Did %d coarsenings.", num_coarsenings());
+ // Strong code root stats
+ out->print_cr(" Total heap region code-root set sizes = "SIZE_FORMAT"K."
+ " Max = "SIZE_FORMAT"K.",
+ blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K);
+ HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region();
+ HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set();
+ out->print_cr(" Max size region = "HR_FORMAT", "
+ "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
+ HR_FORMAT_PARAMS(max_code_root_mem_sz_region),
+ (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K,
+ (max_code_root_rem_set->strong_code_roots_list_length()));
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -319,7 +319,10 @@
\
diagnostic(bool, G1VerifyRSetsDuringFullGC, false, \
"If true, perform verification of each heap region's " \
- "remembered set when verifying the heap during a full GC.")
+ "remembered set when verifying the heap during a full GC.") \
+ \
+ diagnostic(bool, G1VerifyHeapRegionCodeRoots, false, \
+ "Verify the code root lists attached to each heap region.")
G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "code/nmethod.hpp"
#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
@@ -50,144 +51,6 @@
OopClosure* oc) :
_r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { }
-class VerifyLiveClosure: public OopClosure {
-private:
- G1CollectedHeap* _g1h;
- CardTableModRefBS* _bs;
- oop _containing_obj;
- bool _failures;
- int _n_failures;
- VerifyOption _vo;
-public:
- // _vo == UsePrevMarking -> use "prev" marking information,
- // _vo == UseNextMarking -> use "next" marking information,
- // _vo == UseMarkWord -> use mark word from object header.
- VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
- _g1h(g1h), _bs(NULL), _containing_obj(NULL),
- _failures(false), _n_failures(0), _vo(vo)
- {
- BarrierSet* bs = _g1h->barrier_set();
- if (bs->is_a(BarrierSet::CardTableModRef))
- _bs = (CardTableModRefBS*)bs;
- }
-
- void set_containing_obj(oop obj) {
- _containing_obj = obj;
- }
-
- bool failures() { return _failures; }
- int n_failures() { return _n_failures; }
-
- virtual void do_oop(narrowOop* p) { do_oop_work(p); }
- virtual void do_oop( oop* p) { do_oop_work(p); }
-
- void print_object(outputStream* out, oop obj) {
-#ifdef PRODUCT
- Klass* k = obj->klass();
- const char* class_name = InstanceKlass::cast(k)->external_name();
- out->print_cr("class name %s", class_name);
-#else // PRODUCT
- obj->print_on(out);
-#endif // PRODUCT
- }
-
- template <class T>
- void do_oop_work(T* p) {
- assert(_containing_obj != NULL, "Precondition");
- assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
- "Precondition");
- T heap_oop = oopDesc::load_heap_oop(p);
- if (!oopDesc::is_null(heap_oop)) {
- oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
- bool failed = false;
- if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) {
- MutexLockerEx x(ParGCRareEvent_lock,
- Mutex::_no_safepoint_check_flag);
-
- if (!_failures) {
- gclog_or_tty->print_cr("");
- gclog_or_tty->print_cr("----------");
- }
- if (!_g1h->is_in_closed_subset(obj)) {
- HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
- gclog_or_tty->print_cr("Field "PTR_FORMAT
- " of live obj "PTR_FORMAT" in region "
- "["PTR_FORMAT", "PTR_FORMAT")",
- p, (void*) _containing_obj,
- from->bottom(), from->end());
- print_object(gclog_or_tty, _containing_obj);
- gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
- (void*) obj);
- } else {
- HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
- HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
- gclog_or_tty->print_cr("Field "PTR_FORMAT
- " of live obj "PTR_FORMAT" in region "
- "["PTR_FORMAT", "PTR_FORMAT")",
- p, (void*) _containing_obj,
- from->bottom(), from->end());
- print_object(gclog_or_tty, _containing_obj);
- gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
- "["PTR_FORMAT", "PTR_FORMAT")",
- (void*) obj, to->bottom(), to->end());
- print_object(gclog_or_tty, obj);
- }
- gclog_or_tty->print_cr("----------");
- gclog_or_tty->flush();
- _failures = true;
- failed = true;
- _n_failures++;
- }
-
- if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) {
- HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
- HeapRegion* to = _g1h->heap_region_containing(obj);
- if (from != NULL && to != NULL &&
- from != to &&
- !to->isHumongous()) {
- jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
- jbyte cv_field = *_bs->byte_for_const(p);
- const jbyte dirty = CardTableModRefBS::dirty_card_val();
-
- bool is_bad = !(from->is_young()
- || to->rem_set()->contains_reference(p)
- || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
- (_containing_obj->is_objArray() ?
- cv_field == dirty
- : cv_obj == dirty || cv_field == dirty));
- if (is_bad) {
- MutexLockerEx x(ParGCRareEvent_lock,
- Mutex::_no_safepoint_check_flag);
-
- if (!_failures) {
- gclog_or_tty->print_cr("");
- gclog_or_tty->print_cr("----------");
- }
- gclog_or_tty->print_cr("Missing rem set entry:");
- gclog_or_tty->print_cr("Field "PTR_FORMAT" "
- "of obj "PTR_FORMAT", "
- "in region "HR_FORMAT,
- p, (void*) _containing_obj,
- HR_FORMAT_PARAMS(from));
- _containing_obj->print_on(gclog_or_tty);
- gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
- "in region "HR_FORMAT,
- (void*) obj,
- HR_FORMAT_PARAMS(to));
- obj->print_on(gclog_or_tty);
- gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
- cv_obj, cv_field);
- gclog_or_tty->print_cr("----------");
- gclog_or_tty->flush();
- _failures = true;
- if (!failed) _n_failures++;
- }
- }
- }
- }
- }
-};
-
template<class ClosureType>
HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h,
HeapRegion* hr,
@@ -368,7 +231,7 @@
if (!par) {
// If this is parallel, this will be done later.
HeapRegionRemSet* hrrs = rem_set();
- if (hrrs != NULL) hrrs->clear();
+ hrrs->clear();
_claimed = InitialClaimValue;
}
zero_marked_bytes();
@@ -505,6 +368,7 @@
_rem_set(NULL), _recorded_rs_length(0), _predicted_elapsed_time_ms(0),
_predicted_bytes_to_copy(0)
{
+ _rem_set = new HeapRegionRemSet(sharedOffsetArray, this);
_orig_end = mr.end();
// Note that initialize() will set the start of the unmarked area of the
// region.
@@ -512,8 +376,6 @@
set_top(bottom());
set_saved_mark();
- _rem_set = new HeapRegionRemSet(sharedOffsetArray, this);
-
assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
}
@@ -733,6 +595,160 @@
return NULL;
}
+// Code roots support
+
+void HeapRegion::add_strong_code_root(nmethod* nm) {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->add_strong_code_root(nm);
+}
+
+void HeapRegion::remove_strong_code_root(nmethod* nm) {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->remove_strong_code_root(nm);
+}
+
+void HeapRegion::migrate_strong_code_roots() {
+ assert(in_collection_set(), "only collection set regions");
+ assert(!isHumongous(), "not humongous regions");
+
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->migrate_strong_code_roots();
+}
+
+void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->strong_code_roots_do(blk);
+}
+
+class VerifyStrongCodeRootOopClosure: public OopClosure {
+ const HeapRegion* _hr;
+ nmethod* _nm;
+ bool _failures;
+ bool _has_oops_in_region;
+
+ template <class T> void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+
+ // Note: not all the oops embedded in the nmethod are in the
+ // current region. We only look at those which are.
+ if (_hr->is_in(obj)) {
+ // Object is in the region. Check that its less than top
+ if (_hr->top() <= (HeapWord*)obj) {
+ // Object is above top
+ gclog_or_tty->print_cr("Object "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT") is above "
+ "top "PTR_FORMAT,
+ obj, _hr->bottom(), _hr->end(), _hr->top());
+ _failures = true;
+ return;
+ }
+ // Nmethod has at least one oop in the current region
+ _has_oops_in_region = true;
+ }
+ }
+ }
+
+public:
+ VerifyStrongCodeRootOopClosure(const HeapRegion* hr, nmethod* nm):
+ _hr(hr), _failures(false), _has_oops_in_region(false) {}
+
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+ void do_oop(oop* p) { do_oop_work(p); }
+
+ bool failures() { return _failures; }
+ bool has_oops_in_region() { return _has_oops_in_region; }
+};
+
+class VerifyStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
+ const HeapRegion* _hr;
+ bool _failures;
+public:
+ VerifyStrongCodeRootCodeBlobClosure(const HeapRegion* hr) :
+ _hr(hr), _failures(false) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null();
+ if (nm != NULL) {
+ // Verify that the nemthod is live
+ if (!nm->is_alive()) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has dead nmethod "
+ PTR_FORMAT" in its strong code roots",
+ _hr->bottom(), _hr->end(), nm);
+ _failures = true;
+ } else {
+ VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
+ nm->oops_do(&oop_cl);
+ if (!oop_cl.has_oops_in_region()) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has nmethod "
+ PTR_FORMAT" in its strong code roots "
+ "with no pointers into region",
+ _hr->bottom(), _hr->end(), nm);
+ _failures = true;
+ } else if (oop_cl.failures()) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has other "
+ "failures for nmethod "PTR_FORMAT,
+ _hr->bottom(), _hr->end(), nm);
+ _failures = true;
+ }
+ }
+ }
+ }
+
+ bool failures() { return _failures; }
+};
+
+void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const {
+ if (!G1VerifyHeapRegionCodeRoots) {
+ // We're not verifying code roots.
+ return;
+ }
+ if (vo == VerifyOption_G1UseMarkWord) {
+ // Marking verification during a full GC is performed after class
+ // unloading, code cache unloading, etc so the strong code roots
+ // attached to each heap region are in an inconsistent state. They won't
+ // be consistent until the strong code roots are rebuilt after the
+ // actual GC. Skip verifying the strong code roots in this particular
+ // time.
+ assert(VerifyDuringGC, "only way to get here");
+ return;
+ }
+
+ HeapRegionRemSet* hrrs = rem_set();
+ int strong_code_roots_length = hrrs->strong_code_roots_list_length();
+
+ // if this region is empty then there should be no entries
+ // on its strong code root list
+ if (is_empty()) {
+ if (strong_code_roots_length > 0) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty "
+ "but has "INT32_FORMAT" code root entries",
+ bottom(), end(), strong_code_roots_length);
+ *failures = true;
+ }
+ return;
+ }
+
+ // An H-region should have an empty strong code root list
+ if (isHumongous()) {
+ if (strong_code_roots_length > 0) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous "
+ "but has "INT32_FORMAT" code root entries",
+ bottom(), end(), strong_code_roots_length);
+ *failures = true;
+ }
+ return;
+ }
+
+ VerifyStrongCodeRootCodeBlobClosure cb_cl(this);
+ strong_code_roots_do(&cb_cl);
+
+ if (cb_cl.failures()) {
+ *failures = true;
+ }
+}
+
void HeapRegion::print() const { print_on(gclog_or_tty); }
void HeapRegion::print_on(outputStream* st) const {
if (isHumongous()) {
@@ -761,10 +777,143 @@
G1OffsetTableContigSpace::print_on(st);
}
-void HeapRegion::verify() const {
- bool dummy = false;
- verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
-}
+class VerifyLiveClosure: public OopClosure {
+private:
+ G1CollectedHeap* _g1h;
+ CardTableModRefBS* _bs;
+ oop _containing_obj;
+ bool _failures;
+ int _n_failures;
+ VerifyOption _vo;
+public:
+ // _vo == UsePrevMarking -> use "prev" marking information,
+ // _vo == UseNextMarking -> use "next" marking information,
+ // _vo == UseMarkWord -> use mark word from object header.
+ VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
+ _g1h(g1h), _bs(NULL), _containing_obj(NULL),
+ _failures(false), _n_failures(0), _vo(vo)
+ {
+ BarrierSet* bs = _g1h->barrier_set();
+ if (bs->is_a(BarrierSet::CardTableModRef))
+ _bs = (CardTableModRefBS*)bs;
+ }
+
+ void set_containing_obj(oop obj) {
+ _containing_obj = obj;
+ }
+
+ bool failures() { return _failures; }
+ int n_failures() { return _n_failures; }
+
+ virtual void do_oop(narrowOop* p) { do_oop_work(p); }
+ virtual void do_oop( oop* p) { do_oop_work(p); }
+
+ void print_object(outputStream* out, oop obj) {
+#ifdef PRODUCT
+ Klass* k = obj->klass();
+ const char* class_name = InstanceKlass::cast(k)->external_name();
+ out->print_cr("class name %s", class_name);
+#else // PRODUCT
+ obj->print_on(out);
+#endif // PRODUCT
+ }
+
+ template <class T>
+ void do_oop_work(T* p) {
+ assert(_containing_obj != NULL, "Precondition");
+ assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
+ "Precondition");
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ bool failed = false;
+ if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) {
+ MutexLockerEx x(ParGCRareEvent_lock,
+ Mutex::_no_safepoint_check_flag);
+
+ if (!_failures) {
+ gclog_or_tty->print_cr("");
+ gclog_or_tty->print_cr("----------");
+ }
+ if (!_g1h->is_in_closed_subset(obj)) {
+ HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+ gclog_or_tty->print_cr("Field "PTR_FORMAT
+ " of live obj "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT")",
+ p, (void*) _containing_obj,
+ from->bottom(), from->end());
+ print_object(gclog_or_tty, _containing_obj);
+ gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
+ (void*) obj);
+ } else {
+ HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+ HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
+ gclog_or_tty->print_cr("Field "PTR_FORMAT
+ " of live obj "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT")",
+ p, (void*) _containing_obj,
+ from->bottom(), from->end());
+ print_object(gclog_or_tty, _containing_obj);
+ gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT")",
+ (void*) obj, to->bottom(), to->end());
+ print_object(gclog_or_tty, obj);
+ }
+ gclog_or_tty->print_cr("----------");
+ gclog_or_tty->flush();
+ _failures = true;
+ failed = true;
+ _n_failures++;
+ }
+
+ if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) {
+ HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+ HeapRegion* to = _g1h->heap_region_containing(obj);
+ if (from != NULL && to != NULL &&
+ from != to &&
+ !to->isHumongous()) {
+ jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
+ jbyte cv_field = *_bs->byte_for_const(p);
+ const jbyte dirty = CardTableModRefBS::dirty_card_val();
+
+ bool is_bad = !(from->is_young()
+ || to->rem_set()->contains_reference(p)
+ || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
+ (_containing_obj->is_objArray() ?
+ cv_field == dirty
+ : cv_obj == dirty || cv_field == dirty));
+ if (is_bad) {
+ MutexLockerEx x(ParGCRareEvent_lock,
+ Mutex::_no_safepoint_check_flag);
+
+ if (!_failures) {
+ gclog_or_tty->print_cr("");
+ gclog_or_tty->print_cr("----------");
+ }
+ gclog_or_tty->print_cr("Missing rem set entry:");
+ gclog_or_tty->print_cr("Field "PTR_FORMAT" "
+ "of obj "PTR_FORMAT", "
+ "in region "HR_FORMAT,
+ p, (void*) _containing_obj,
+ HR_FORMAT_PARAMS(from));
+ _containing_obj->print_on(gclog_or_tty);
+ gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
+ "in region "HR_FORMAT,
+ (void*) obj,
+ HR_FORMAT_PARAMS(to));
+ obj->print_on(gclog_or_tty);
+ gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
+ cv_obj, cv_field);
+ gclog_or_tty->print_cr("----------");
+ gclog_or_tty->flush();
+ _failures = true;
+ if (!failed) _n_failures++;
+ }
+ }
+ }
+ }
+ }
+};
// This really ought to be commoned up into OffsetTableContigSpace somehow.
// We would need a mechanism to make that code skip dead objects.
@@ -904,6 +1053,13 @@
*failures = true;
return;
}
+
+ verify_strong_code_roots(vo, failures);
+}
+
+void HeapRegion::verify() const {
+ bool dummy = false;
+ verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
}
// G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -52,6 +52,7 @@
class HeapRegionRemSetIterator;
class HeapRegion;
class HeapRegionSetBase;
+class nmethod;
#define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
#define HR_FORMAT_PARAMS(_hr_) \
@@ -371,7 +372,8 @@
RebuildRSClaimValue = 5,
ParEvacFailureClaimValue = 6,
AggregateCountClaimValue = 7,
- VerifyCountClaimValue = 8
+ VerifyCountClaimValue = 8,
+ ParMarkRootClaimValue = 9
};
inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
@@ -796,6 +798,25 @@
virtual void reset_after_compaction();
+ // Routines for managing a list of code roots (attached to the
+ // this region's RSet) that point into this heap region.
+ void add_strong_code_root(nmethod* nm);
+ void remove_strong_code_root(nmethod* nm);
+
+ // During a collection, migrate the successfully evacuated
+ // strong code roots that referenced into this region to the
+ // new regions that they now point into. Unsuccessfully
+ // evacuated code roots are not migrated.
+ void migrate_strong_code_roots();
+
+ // Applies blk->do_code_blob() to each of the entries in
+ // the strong code roots list for this region
+ void strong_code_roots_do(CodeBlobClosure* blk) const;
+
+ // Verify that the entries on the strong code root list for this
+ // region are live and include at least one pointer into this region.
+ void verify_strong_code_roots(VerifyOption vo, bool* failures) const;
+
void print() const;
void print_on(outputStream* st) const;
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -33,6 +33,7 @@
#include "oops/oop.inline.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
class PerRegionTable: public CHeapObj<mtGC> {
friend class OtherRegionsTable;
@@ -849,7 +850,7 @@
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
HeapRegion* hr)
- : _bosa(bosa), _other_regions(hr) {
+ : _bosa(bosa), _strong_code_roots_list(NULL), _other_regions(hr) {
reset_for_par_iteration();
}
@@ -908,6 +909,12 @@
}
void HeapRegionRemSet::clear() {
+ if (_strong_code_roots_list != NULL) {
+ delete _strong_code_roots_list;
+ }
+ _strong_code_roots_list = new (ResourceObj::C_HEAP, mtGC)
+ GrowableArray<nmethod*>(10, 0, NULL, true);
+
_other_regions.clear();
assert(occupied() == 0, "Should be clear.");
reset_for_par_iteration();
@@ -925,6 +932,121 @@
_other_regions.scrub(ctbs, region_bm, card_bm);
}
+
+// Code roots support
+
+void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
+ assert(nm != NULL, "sanity");
+ // Search for the code blob from the RHS to avoid
+ // duplicate entries as much as possible
+ if (_strong_code_roots_list->find_from_end(nm) < 0) {
+ // Code blob isn't already in the list
+ _strong_code_roots_list->push(nm);
+ }
+}
+
+void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) {
+ assert(nm != NULL, "sanity");
+ int idx = _strong_code_roots_list->find(nm);
+ if (idx >= 0) {
+ _strong_code_roots_list->remove_at(idx);
+ }
+ // Check that there were no duplicates
+ guarantee(_strong_code_roots_list->find(nm) < 0, "duplicate entry found");
+}
+
+class NMethodMigrationOopClosure : public OopClosure {
+ G1CollectedHeap* _g1h;
+ HeapRegion* _from;
+ nmethod* _nm;
+
+ uint _num_self_forwarded;
+
+ template <class T> void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ if (_from->is_in(obj)) {
+ // Reference still points into the source region.
+ // Since roots are immediately evacuated this means that
+ // we must have self forwarded the object
+ assert(obj->is_forwarded(),
+ err_msg("code roots should be immediately evacuated. "
+ "Ref: "PTR_FORMAT", "
+ "Obj: "PTR_FORMAT", "
+ "Region: "HR_FORMAT,
+ p, (void*) obj, HR_FORMAT_PARAMS(_from)));
+ assert(obj->forwardee() == obj,
+ err_msg("not self forwarded? obj = "PTR_FORMAT, (void*)obj));
+
+ // The object has been self forwarded.
+ // Note, if we're during an initial mark pause, there is
+ // no need to explicitly mark object. It will be marked
+ // during the regular evacuation failure handling code.
+ _num_self_forwarded++;
+ } else {
+ // The reference points into a promotion or to-space region
+ HeapRegion* to = _g1h->heap_region_containing(obj);
+ to->rem_set()->add_strong_code_root(_nm);
+ }
+ }
+ }
+
+public:
+ NMethodMigrationOopClosure(G1CollectedHeap* g1h, HeapRegion* from, nmethod* nm):
+ _g1h(g1h), _from(from), _nm(nm), _num_self_forwarded(0) {}
+
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+ void do_oop(oop* p) { do_oop_work(p); }
+
+ uint retain() { return _num_self_forwarded > 0; }
+};
+
+void HeapRegionRemSet::migrate_strong_code_roots() {
+ assert(hr()->in_collection_set(), "only collection set regions");
+ assert(!hr()->isHumongous(), "not humongous regions");
+
+ ResourceMark rm;
+
+ // List of code blobs to retain for this region
+ GrowableArray<nmethod*> to_be_retained(10);
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+ while (_strong_code_roots_list->is_nonempty()) {
+ nmethod *nm = _strong_code_roots_list->pop();
+ if (nm != NULL) {
+ NMethodMigrationOopClosure oop_cl(g1h, hr(), nm);
+ nm->oops_do(&oop_cl);
+ if (oop_cl.retain()) {
+ to_be_retained.push(nm);
+ }
+ }
+ }
+
+ // Now push any code roots we need to retain
+ assert(to_be_retained.is_empty() || hr()->evacuation_failed(),
+ "Retained nmethod list must be empty or "
+ "evacuation of this region failed");
+
+ while (to_be_retained.is_nonempty()) {
+ nmethod* nm = to_be_retained.pop();
+ assert(nm != NULL, "sanity");
+ add_strong_code_root(nm);
+ }
+}
+
+void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const {
+ for (int i = 0; i < _strong_code_roots_list->length(); i += 1) {
+ nmethod* nm = _strong_code_roots_list->at(i);
+ blk->do_code_blob(nm);
+ }
+}
+
+size_t HeapRegionRemSet::strong_code_roots_mem_size() {
+ return sizeof(GrowableArray<nmethod*>) +
+ _strong_code_roots_list->max_length() * sizeof(nmethod*);
+}
+
//-------------------- Iteration --------------------
HeapRegionRemSetIterator:: HeapRegionRemSetIterator(const HeapRegionRemSet* hrrs) :
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -37,6 +37,7 @@
class HeapRegionRemSetIterator;
class PerRegionTable;
class SparsePRT;
+class nmethod;
// Essentially a wrapper around SparsePRTCleanupTask. See
// sparsePRT.hpp for more details.
@@ -191,6 +192,10 @@
G1BlockOffsetSharedArray* _bosa;
G1BlockOffsetSharedArray* bosa() const { return _bosa; }
+ // A list of code blobs (nmethods) whose code contains pointers into
+ // the region that owns this RSet.
+ GrowableArray<nmethod*>* _strong_code_roots_list;
+
OtherRegionsTable _other_regions;
enum ParIterState { Unclaimed, Claimed, Complete };
@@ -282,11 +287,13 @@
}
// The actual # of bytes this hr_remset takes up.
+ // Note also includes the strong code root set.
size_t mem_size() {
return _other_regions.mem_size()
// This correction is necessary because the above includes the second
// part.
- + sizeof(this) - sizeof(OtherRegionsTable);
+ + (sizeof(this) - sizeof(OtherRegionsTable))
+ + strong_code_roots_mem_size();
}
// Returns the memory occupancy of all static data structures associated
@@ -304,6 +311,37 @@
bool contains_reference(OopOrNarrowOopStar from) const {
return _other_regions.contains_reference(from);
}
+
+ // Routines for managing the list of code roots that point into
+ // the heap region that owns this RSet.
+ void add_strong_code_root(nmethod* nm);
+ void remove_strong_code_root(nmethod* nm);
+
+ // During a collection, migrate the successfully evacuated strong
+ // code roots that referenced into the region that owns this RSet
+ // to the RSets of the new regions that they now point into.
+ // Unsuccessfully evacuated code roots are not migrated.
+ void migrate_strong_code_roots();
+
+ // Applies blk->do_code_blob() to each of the entries in
+ // the strong code roots list
+ void strong_code_roots_do(CodeBlobClosure* blk) const;
+
+ // Returns the number of elements in the strong code roots list
+ int strong_code_roots_list_length() {
+ return _strong_code_roots_list->length();
+ }
+
+ // Returns true if the strong code roots contains the given
+ // nmethod.
+ bool strong_code_roots_list_contains(nmethod* nm) {
+ return _strong_code_roots_list->contains(nm);
+ }
+
+ // Returns the amount of memory, in bytes, currently
+ // consumed by the strong code roots.
+ size_t strong_code_roots_mem_size();
+
void print() const;
// Called during a stop-world phase to perform any deferred cleanups.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -216,6 +216,7 @@
young_gen()->update_counters();
old_gen()->update_counters();
MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
}
size_t ParallelScavengeHeap::capacity() const {
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -118,6 +118,14 @@
}
}
+void CollectedHeap::register_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+}
+
+void CollectedHeap::unregister_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+}
+
void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
const GCHeapSummary& heap_summary = create_heap_summary();
const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -49,6 +49,7 @@
class Thread;
class ThreadClosure;
class VirtualSpaceSummary;
+class nmethod;
class GCMessage : public FormatBuffer<1024> {
public:
@@ -603,6 +604,11 @@
void print_heap_before_gc();
void print_heap_after_gc();
+ // Registering and unregistering an nmethod (compiled code) with the heap.
+ // Override with specific mechanism for each specialized heap type.
+ virtual void register_nmethod(nmethod* nm);
+ virtual void unregister_nmethod(nmethod* nm);
+
void trace_heap_before_gc(GCTracer* gc_tracer);
void trace_heap_after_gc(GCTracer* gc_tracer);
--- a/hotspot/src/share/vm/memory/filemap.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -362,15 +362,12 @@
ReservedSpace FileMapInfo::reserve_shared_memory() {
struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
char* requested_addr = si->_base;
- size_t alignment = os::vm_allocation_granularity();
- size_t size = align_size_up(SharedReadOnlySize + SharedReadWriteSize +
- SharedMiscDataSize + SharedMiscCodeSize,
- alignment);
+ size_t size = FileMapInfo::shared_spaces_size();
// Reserve the space first, then map otherwise map will go right over some
// other reserved memory (like the code cache).
- ReservedSpace rs(size, alignment, false, requested_addr);
+ ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
if (!rs.is_reserved()) {
fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr));
return rs;
@@ -559,3 +556,19 @@
si->_base, si->_base + si->_used);
}
}
+
+// Unmap mapped regions of shared space.
+void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
+ FileMapInfo *map_info = FileMapInfo::current_info();
+ if (map_info) {
+ map_info->fail_continue(msg);
+ for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+ if (map_info->_header._space[i]._base != NULL) {
+ map_info->unmap_region(i);
+ map_info->_header._space[i]._base = NULL;
+ }
+ }
+ } else if (DumpSharedSpaces) {
+ fail_stop(msg, NULL);
+ }
+}
--- a/hotspot/src/share/vm/memory/filemap.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -150,6 +150,15 @@
// Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
void print_shared_spaces() NOT_CDS_RETURN;
+
+ static size_t shared_spaces_size() {
+ return align_size_up(SharedReadOnlySize + SharedReadWriteSize +
+ SharedMiscDataSize + SharedMiscCodeSize,
+ os::vm_allocation_granularity());
+ }
+
+ // Stop CDS sharing and unmap CDS regions.
+ static void stop_sharing_and_unmap(const char* msg);
};
#endif // SHARE_VM_MEMORY_FILEMAP_HPP
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1211,6 +1211,7 @@
}
MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
always_do_update_barrier = UseConcMarkSweepGC;
};
--- a/hotspot/src/share/vm/memory/heap.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/heap.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -118,9 +118,12 @@
_number_of_committed_segments = size_to_segments(_memory.committed_size());
_number_of_reserved_segments = size_to_segments(_memory.reserved_size());
assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
+ const size_t reserved_segments_alignment = MAX2((size_t)os::vm_page_size(), granularity);
+ const size_t reserved_segments_size = align_size_up(_number_of_reserved_segments, reserved_segments_alignment);
+ const size_t committed_segments_size = align_to_page_size(_number_of_committed_segments);
// reserve space for _segmap
- if (!_segmap.initialize(align_to_page_size(_number_of_reserved_segments), align_to_page_size(_number_of_committed_segments))) {
+ if (!_segmap.initialize(reserved_segments_size, committed_segments_size)) {
return false;
}
--- a/hotspot/src/share/vm/memory/iterator.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/iterator.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -64,7 +64,7 @@
}
void CodeBlobToOopClosure::do_newly_marked_nmethod(nmethod* nm) {
- nm->oops_do(_cl, /*do_strong_roots_only=*/ true);
+ nm->oops_do(_cl, /*allow_zombie=*/ false);
}
void CodeBlobToOopClosure::do_code_blob(CodeBlob* cb) {
--- a/hotspot/src/share/vm/memory/metaspace.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -35,6 +35,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "runtime/globals.hpp"
+#include "runtime/java.hpp"
#include "runtime/mutex.hpp"
#include "runtime/orderAccess.hpp"
#include "services/memTracker.hpp"
@@ -54,6 +55,8 @@
MetaWord* last_allocated = 0;
+size_t Metaspace::_class_metaspace_size;
+
// Used in declarations in SpaceManager and ChunkManager
enum ChunkIndex {
ZeroIndex = 0,
@@ -261,10 +264,6 @@
// count of chunks contained in this VirtualSpace
uintx _container_count;
- // Convenience functions for logical bottom and end
- MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
- MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
-
// Convenience functions to access the _virtual_space
char* low() const { return virtual_space()->low(); }
char* high() const { return virtual_space()->high(); }
@@ -284,6 +283,10 @@
VirtualSpaceNode(ReservedSpace rs) : _top(NULL), _next(NULL), _rs(rs), _container_count(0) {}
~VirtualSpaceNode();
+ // Convenience functions for logical bottom and end
+ MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
+ MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
+
// address of next available space in _virtual_space;
// Accessors
VirtualSpaceNode* next() { return _next; }
@@ -1313,7 +1316,8 @@
// Class virtual space should always be expanded. Call GC for the other
// metadata virtual space.
- if (vsl == Metaspace::class_space_list()) return true;
+ if (Metaspace::using_class_space() &&
+ (vsl == Metaspace::class_space_list())) return true;
// If this is part of an allocation after a GC, expand
// unconditionally.
@@ -2257,7 +2261,7 @@
size_t raw_word_size = get_raw_word_size(word_size);
size_t min_size = TreeChunk<Metablock, FreeList>::min_size();
assert(raw_word_size >= min_size,
- err_msg("Should not deallocate dark matter " SIZE_FORMAT, word_size));
+ err_msg("Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size));
block_freelists()->return_block(p, raw_word_size);
}
@@ -2374,7 +2378,7 @@
if (result == NULL) {
result = grow_and_allocate(word_size);
}
- if (result > 0) {
+ if (result != 0) {
inc_used_metrics(word_size);
assert(result != (MetaWord*) chunks_in_use(MediumIndex),
"Head of the list is being allocated");
@@ -2476,15 +2480,13 @@
size_t MetaspaceAux::_allocated_capacity_words[] = {0, 0};
size_t MetaspaceAux::_allocated_used_words[] = {0, 0};
+size_t MetaspaceAux::free_bytes(Metaspace::MetadataType mdtype) {
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ return list == NULL ? 0 : list->free_bytes();
+}
+
size_t MetaspaceAux::free_bytes() {
- size_t result = 0;
- if (Metaspace::class_space_list() != NULL) {
- result = result + Metaspace::class_space_list()->free_bytes();
- }
- if (Metaspace::space_list() != NULL) {
- result = result + Metaspace::space_list()->free_bytes();
- }
- return result;
+ return free_bytes(Metaspace::ClassType) + free_bytes(Metaspace::NonClassType);
}
void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
@@ -2549,6 +2551,9 @@
}
size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
+ if ((mdtype == Metaspace::ClassType) && !Metaspace::using_class_space()) {
+ return 0;
+ }
// Don't count the space in the freelists. That space will be
// added to the capacity calculation as needed.
size_t capacity = 0;
@@ -2563,18 +2568,18 @@
}
size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) {
- size_t reserved = (mdtype == Metaspace::ClassType) ?
- Metaspace::class_space_list()->virtual_space_total() :
- Metaspace::space_list()->virtual_space_total();
- return reserved * BytesPerWord;
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ return list == NULL ? 0 : list->virtual_space_total();
}
size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); }
size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) {
- ChunkManager* chunk = (mdtype == Metaspace::ClassType) ?
- Metaspace::class_space_list()->chunk_manager() :
- Metaspace::space_list()->chunk_manager();
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ if (list == NULL) {
+ return 0;
+ }
+ ChunkManager* chunk = list->chunk_manager();
chunk->slow_verify();
return chunk->free_chunks_total();
}
@@ -2615,7 +2620,6 @@
// This is printed when PrintGCDetails
void MetaspaceAux::print_on(outputStream* out) {
- Metaspace::MetadataType ct = Metaspace::ClassType;
Metaspace::MetadataType nct = Metaspace::NonClassType;
out->print_cr(" Metaspace total "
@@ -2629,12 +2633,15 @@
allocated_capacity_bytes(nct)/K,
allocated_used_bytes(nct)/K,
reserved_in_bytes(nct)/K);
- out->print_cr(" class space "
- SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
- " reserved " SIZE_FORMAT "K",
- allocated_capacity_bytes(ct)/K,
- allocated_used_bytes(ct)/K,
- reserved_in_bytes(ct)/K);
+ if (Metaspace::using_class_space()) {
+ Metaspace::MetadataType ct = Metaspace::ClassType;
+ out->print_cr(" class space "
+ SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
+ " reserved " SIZE_FORMAT "K",
+ allocated_capacity_bytes(ct)/K,
+ allocated_used_bytes(ct)/K,
+ reserved_in_bytes(ct)/K);
+ }
}
// Print information for class space and data space separately.
@@ -2659,13 +2666,37 @@
assert(!SafepointSynchronize::is_at_safepoint() || used_and_free == capacity_bytes, "Accounting is wrong");
}
-// Print total fragmentation for class and data metaspaces separately
+// Print total fragmentation for class metaspaces
+void MetaspaceAux::print_class_waste(outputStream* out) {
+ assert(Metaspace::using_class_space(), "class metaspace not used");
+ size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0;
+ size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_humongous_count = 0;
+ ClassLoaderDataGraphMetaspaceIterator iter;
+ while (iter.repeat()) {
+ Metaspace* msp = iter.get_next();
+ if (msp != NULL) {
+ cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
+ cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
+ cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex);
+ cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex);
+ cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex);
+ cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex);
+ cls_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
+ }
+ }
+ out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
+ SIZE_FORMAT " small(s) " SIZE_FORMAT ", "
+ SIZE_FORMAT " medium(s) " SIZE_FORMAT ", "
+ "large count " SIZE_FORMAT,
+ cls_specialized_count, cls_specialized_waste,
+ cls_small_count, cls_small_waste,
+ cls_medium_count, cls_medium_waste, cls_humongous_count);
+}
+
+// Print total fragmentation for data and class metaspaces separately
void MetaspaceAux::print_waste(outputStream* out) {
-
size_t specialized_waste = 0, small_waste = 0, medium_waste = 0;
size_t specialized_count = 0, small_count = 0, medium_count = 0, humongous_count = 0;
- size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0;
- size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_humongous_count = 0;
ClassLoaderDataGraphMetaspaceIterator iter;
while (iter.repeat()) {
@@ -2678,14 +2709,6 @@
medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex);
medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex);
humongous_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex);
-
- cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
- cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
- cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex);
- cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex);
- cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex);
- cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex);
- cls_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
}
}
out->print_cr("Total fragmentation waste (words) doesn't count free space");
@@ -2695,13 +2718,9 @@
"large count " SIZE_FORMAT,
specialized_count, specialized_waste, small_count,
small_waste, medium_count, medium_waste, humongous_count);
- out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
- SIZE_FORMAT " small(s) " SIZE_FORMAT ", "
- SIZE_FORMAT " medium(s) " SIZE_FORMAT ", "
- "large count " SIZE_FORMAT,
- cls_specialized_count, cls_specialized_waste,
- cls_small_count, cls_small_waste,
- cls_medium_count, cls_medium_waste, cls_humongous_count);
+ if (Metaspace::using_class_space()) {
+ print_class_waste(out);
+ }
}
// Dump global metaspace things from the end of ClassLoaderDataGraph
@@ -2714,7 +2733,9 @@
void MetaspaceAux::verify_free_chunks() {
Metaspace::space_list()->chunk_manager()->verify();
- Metaspace::class_space_list()->chunk_manager()->verify();
+ if (Metaspace::using_class_space()) {
+ Metaspace::class_space_list()->chunk_manager()->verify();
+ }
}
void MetaspaceAux::verify_capacity() {
@@ -2776,7 +2797,9 @@
Metaspace::~Metaspace() {
delete _vsm;
- delete _class_vsm;
+ if (using_class_space()) {
+ delete _class_vsm;
+ }
}
VirtualSpaceList* Metaspace::_space_list = NULL;
@@ -2784,9 +2807,123 @@
#define VIRTUALSPACEMULTIPLIER 2
+#ifdef _LP64
+void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) {
+ // Figure out the narrow_klass_base and the narrow_klass_shift. The
+ // narrow_klass_base is the lower of the metaspace base and the cds base
+ // (if cds is enabled). The narrow_klass_shift depends on the distance
+ // between the lower base and higher address.
+ address lower_base;
+ address higher_address;
+ if (UseSharedSpaces) {
+ higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
+ (address)(metaspace_base + class_metaspace_size()));
+ lower_base = MIN2(metaspace_base, cds_base);
+ } else {
+ higher_address = metaspace_base + class_metaspace_size();
+ lower_base = metaspace_base;
+ }
+ Universe::set_narrow_klass_base(lower_base);
+ if ((uint64_t)(higher_address - lower_base) < (uint64_t)max_juint) {
+ Universe::set_narrow_klass_shift(0);
+ } else {
+ assert(!UseSharedSpaces, "Cannot shift with UseSharedSpaces");
+ Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);
+ }
+}
+
+// Return TRUE if the specified metaspace_base and cds_base are close enough
+// to work with compressed klass pointers.
+bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
+ assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS");
+ assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
+ address lower_base = MIN2((address)metaspace_base, cds_base);
+ address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
+ (address)(metaspace_base + class_metaspace_size()));
+ return ((uint64_t)(higher_address - lower_base) < (uint64_t)max_juint);
+}
+
+// Try to allocate the metaspace at the requested addr.
+void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
+ assert(using_class_space(), "called improperly");
+ assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
+ assert(class_metaspace_size() < KlassEncodingMetaspaceMax,
+ "Metaspace size is too big");
+
+ ReservedSpace metaspace_rs = ReservedSpace(class_metaspace_size(),
+ os::vm_allocation_granularity(),
+ false, requested_addr, 0);
+ if (!metaspace_rs.is_reserved()) {
+ if (UseSharedSpaces) {
+ // Keep trying to allocate the metaspace, increasing the requested_addr
+ // by 1GB each time, until we reach an address that will no longer allow
+ // use of CDS with compressed klass pointers.
+ char *addr = requested_addr;
+ while (!metaspace_rs.is_reserved() && (addr + 1*G > addr) &&
+ can_use_cds_with_metaspace_addr(addr + 1*G, cds_base)) {
+ addr = addr + 1*G;
+ metaspace_rs = ReservedSpace(class_metaspace_size(),
+ os::vm_allocation_granularity(), false, addr, 0);
+ }
+ }
+
+ // If no successful allocation then try to allocate the space anywhere. If
+ // that fails then OOM doom. At this point we cannot try allocating the
+ // metaspace as if UseCompressedKlassPointers is off because too much
+ // initialization has happened that depends on UseCompressedKlassPointers.
+ // So, UseCompressedKlassPointers cannot be turned off at this point.
+ if (!metaspace_rs.is_reserved()) {
+ metaspace_rs = ReservedSpace(class_metaspace_size(),
+ os::vm_allocation_granularity(), false);
+ if (!metaspace_rs.is_reserved()) {
+ vm_exit_during_initialization(err_msg("Could not allocate metaspace: %d bytes",
+ class_metaspace_size()));
+ }
+ }
+ }
+
+ // If we got here then the metaspace got allocated.
+ MemTracker::record_virtual_memory_type((address)metaspace_rs.base(), mtClass);
+
+ // Verify that we can use shared spaces. Otherwise, turn off CDS.
+ if (UseSharedSpaces && !can_use_cds_with_metaspace_addr(metaspace_rs.base(), cds_base)) {
+ FileMapInfo::stop_sharing_and_unmap(
+ "Could not allocate metaspace at a compatible address");
+ }
+
+ set_narrow_klass_base_and_shift((address)metaspace_rs.base(),
+ UseSharedSpaces ? (address)cds_base : 0);
+
+ initialize_class_space(metaspace_rs);
+
+ if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
+ gclog_or_tty->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: " SIZE_FORMAT,
+ Universe::narrow_klass_base(), Universe::narrow_klass_shift());
+ gclog_or_tty->print_cr("Metaspace Size: " SIZE_FORMAT " Address: " PTR_FORMAT " Req Addr: " PTR_FORMAT,
+ class_metaspace_size(), metaspace_rs.base(), requested_addr);
+ }
+}
+
+// For UseCompressedKlassPointers the class space is reserved above the top of
+// the Java heap. The argument passed in is at the base of the compressed space.
+void Metaspace::initialize_class_space(ReservedSpace rs) {
+ // The reserved space size may be bigger because of alignment, esp with UseLargePages
+ assert(rs.size() >= ClassMetaspaceSize,
+ err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
+ assert(using_class_space(), "Must be using class space");
+ _class_space_list = new VirtualSpaceList(rs);
+}
+
+#endif
+
void Metaspace::global_initialize() {
// Initialize the alignment for shared spaces.
int max_alignment = os::vm_page_size();
+ size_t cds_total = 0;
+
+ set_class_metaspace_size(align_size_up(ClassMetaspaceSize,
+ os::vm_allocation_granularity()));
+
MetaspaceShared::set_max_alignment(max_alignment);
if (DumpSharedSpaces) {
@@ -2798,15 +2935,31 @@
// Initialize with the sum of the shared space sizes. The read-only
// and read write metaspace chunks will be allocated out of this and the
// remainder is the misc code and data chunks.
- size_t total = align_size_up(SharedReadOnlySize + SharedReadWriteSize +
- SharedMiscDataSize + SharedMiscCodeSize,
- os::vm_allocation_granularity());
- size_t word_size = total/wordSize;
- _space_list = new VirtualSpaceList(word_size);
+ cds_total = FileMapInfo::shared_spaces_size();
+ _space_list = new VirtualSpaceList(cds_total/wordSize);
+
+#ifdef _LP64
+ // Set the compressed klass pointer base so that decoding of these pointers works
+ // properly when creating the shared archive.
+ assert(UseCompressedOops && UseCompressedKlassPointers,
+ "UseCompressedOops and UseCompressedKlassPointers must be set");
+ Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
+ if (TraceMetavirtualspaceAllocation && Verbose) {
+ gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
+ _space_list->current_virtual_space()->bottom());
+ }
+
+ // Set the shift to zero.
+ assert(class_metaspace_size() < (uint64_t)(max_juint) - cds_total,
+ "CDS region is too large");
+ Universe::set_narrow_klass_shift(0);
+#endif
+
} else {
// If using shared space, open the file that contains the shared space
// and map in the memory before initializing the rest of metaspace (so
// the addresses don't conflict)
+ address cds_address = NULL;
if (UseSharedSpaces) {
FileMapInfo* mapinfo = new FileMapInfo();
memset(mapinfo, 0, sizeof(FileMapInfo));
@@ -2821,8 +2974,22 @@
assert(!mapinfo->is_open() && !UseSharedSpaces,
"archive file not closed or shared spaces not disabled.");
}
+ cds_total = FileMapInfo::shared_spaces_size();
+ cds_address = (address)mapinfo->region_base(0);
}
+#ifdef _LP64
+ // If UseCompressedKlassPointers is set then allocate the metaspace area
+ // above the heap and above the CDS area (if it exists).
+ if (using_class_space()) {
+ if (UseSharedSpaces) {
+ allocate_metaspace_compressed_klass_ptrs((char *)(cds_address + cds_total), cds_address);
+ } else {
+ allocate_metaspace_compressed_klass_ptrs((char *)CompressedKlassPointersBase, 0);
+ }
+ }
+#endif
+
// Initialize these before initializing the VirtualSpaceList
_first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
_first_chunk_word_size = align_word_size_up(_first_chunk_word_size);
@@ -2840,39 +3007,28 @@
}
}
-// For UseCompressedKlassPointers the class space is reserved as a piece of the
-// Java heap because the compression algorithm is the same for each. The
-// argument passed in is at the top of the compressed space
-void Metaspace::initialize_class_space(ReservedSpace rs) {
- // The reserved space size may be bigger because of alignment, esp with UseLargePages
- assert(rs.size() >= ClassMetaspaceSize,
- err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
- _class_space_list = new VirtualSpaceList(rs);
-}
-
-void Metaspace::initialize(Mutex* lock,
- MetaspaceType type) {
+void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
assert(space_list() != NULL,
"Metadata VirtualSpaceList has not been initialized");
- _vsm = new SpaceManager(Metaspace::NonClassType, lock, space_list());
+ _vsm = new SpaceManager(NonClassType, lock, space_list());
if (_vsm == NULL) {
return;
}
size_t word_size;
size_t class_word_size;
- vsm()->get_initial_chunk_sizes(type,
- &word_size,
- &class_word_size);
-
- assert(class_space_list() != NULL,
- "Class VirtualSpaceList has not been initialized");
-
- // Allocate SpaceManager for classes.
- _class_vsm = new SpaceManager(Metaspace::ClassType, lock, class_space_list());
- if (_class_vsm == NULL) {
- return;
+ vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size);
+
+ if (using_class_space()) {
+ assert(class_space_list() != NULL,
+ "Class VirtualSpaceList has not been initialized");
+
+ // Allocate SpaceManager for classes.
+ _class_vsm = new SpaceManager(ClassType, lock, class_space_list());
+ if (_class_vsm == NULL) {
+ return;
+ }
}
MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
@@ -2888,11 +3044,13 @@
}
// Allocate chunk for class metadata objects
- Metachunk* class_chunk =
- class_space_list()->get_initialization_chunk(class_word_size,
- class_vsm()->medium_chunk_bunch());
- if (class_chunk != NULL) {
- class_vsm()->add_chunk(class_chunk, true);
+ if (using_class_space()) {
+ Metachunk* class_chunk =
+ class_space_list()->get_initialization_chunk(class_word_size,
+ class_vsm()->medium_chunk_bunch());
+ if (class_chunk != NULL) {
+ class_vsm()->add_chunk(class_chunk, true);
+ }
}
_alloc_record_head = NULL;
@@ -2906,7 +3064,8 @@
MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
// DumpSharedSpaces doesn't use class metadata area (yet)
- if (mdtype == ClassType && !DumpSharedSpaces) {
+ // Also, don't use class_vsm() unless UseCompressedKlassPointers is true.
+ if (mdtype == ClassType && using_class_space()) {
return class_vsm()->allocate(word_size);
} else {
return vsm()->allocate(word_size);
@@ -2937,14 +3096,19 @@
}
size_t Metaspace::used_words_slow(MetadataType mdtype) const {
- // return vsm()->allocated_used_words();
- return mdtype == ClassType ? class_vsm()->sum_used_in_chunks_in_use() :
- vsm()->sum_used_in_chunks_in_use(); // includes overhead!
+ if (mdtype == ClassType) {
+ return using_class_space() ? class_vsm()->sum_used_in_chunks_in_use() : 0;
+ } else {
+ return vsm()->sum_used_in_chunks_in_use(); // includes overhead!
+ }
}
size_t Metaspace::free_words(MetadataType mdtype) const {
- return mdtype == ClassType ? class_vsm()->sum_free_in_chunks_in_use() :
- vsm()->sum_free_in_chunks_in_use();
+ if (mdtype == ClassType) {
+ return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0;
+ } else {
+ return vsm()->sum_free_in_chunks_in_use();
+ }
}
// Space capacity in the Metaspace. It includes
@@ -2953,8 +3117,11 @@
// in the space available in the dictionary which
// is already counted in some chunk.
size_t Metaspace::capacity_words_slow(MetadataType mdtype) const {
- return mdtype == ClassType ? class_vsm()->sum_capacity_in_chunks_in_use() :
- vsm()->sum_capacity_in_chunks_in_use();
+ if (mdtype == ClassType) {
+ return using_class_space() ? class_vsm()->sum_capacity_in_chunks_in_use() : 0;
+ } else {
+ return vsm()->sum_capacity_in_chunks_in_use();
+ }
}
size_t Metaspace::used_bytes_slow(MetadataType mdtype) const {
@@ -2977,8 +3144,8 @@
#endif
return;
}
- if (is_class) {
- class_vsm()->deallocate(ptr, word_size);
+ if (is_class && using_class_space()) {
+ class_vsm()->deallocate(ptr, word_size);
} else {
vsm()->deallocate(ptr, word_size);
}
@@ -2992,7 +3159,7 @@
#endif
return;
}
- if (is_class) {
+ if (is_class && using_class_space()) {
class_vsm()->deallocate(ptr, word_size);
} else {
vsm()->deallocate(ptr, word_size);
@@ -3101,14 +3268,18 @@
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
space_list()->purge();
- class_space_list()->purge();
+ if (using_class_space()) {
+ class_space_list()->purge();
+ }
}
void Metaspace::print_on(outputStream* out) const {
// Print both class virtual space counts and metaspace.
if (Verbose) {
- vsm()->print_on(out);
+ vsm()->print_on(out);
+ if (using_class_space()) {
class_vsm()->print_on(out);
+ }
}
}
@@ -3122,17 +3293,21 @@
// be needed. Note, locking this can cause inversion problems with the
// caller in MetaspaceObj::is_metadata() function.
return space_list()->contains(ptr) ||
- class_space_list()->contains(ptr);
+ (using_class_space() && class_space_list()->contains(ptr));
}
void Metaspace::verify() {
vsm()->verify();
- class_vsm()->verify();
+ if (using_class_space()) {
+ class_vsm()->verify();
+ }
}
void Metaspace::dump(outputStream* const out) const {
out->print_cr("\nVirtual space manager: " INTPTR_FORMAT, vsm());
vsm()->dump(out);
- out->print_cr("\nClass space manager: " INTPTR_FORMAT, class_vsm());
- class_vsm()->dump(out);
+ if (using_class_space()) {
+ out->print_cr("\nClass space manager: " INTPTR_FORMAT, class_vsm());
+ class_vsm()->dump(out);
+ }
}
--- a/hotspot/src/share/vm/memory/metaspace.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -105,6 +105,16 @@
// Align up the word size to the allocation word size
static size_t align_word_size_up(size_t);
+ // Aligned size of the metaspace.
+ static size_t _class_metaspace_size;
+
+ static size_t class_metaspace_size() {
+ return _class_metaspace_size;
+ }
+ static void set_class_metaspace_size(size_t metaspace_size) {
+ _class_metaspace_size = metaspace_size;
+ }
+
static size_t _first_chunk_word_size;
static size_t _first_class_chunk_word_size;
@@ -126,11 +136,26 @@
static VirtualSpaceList* space_list() { return _space_list; }
static VirtualSpaceList* class_space_list() { return _class_space_list; }
+ static VirtualSpaceList* get_space_list(MetadataType mdtype) {
+ assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
+ return mdtype == ClassType ? class_space_list() : space_list();
+ }
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will
// maintain a single list for now.
void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
+#ifdef _LP64
+ static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
+
+ // Returns true if can use CDS with metaspace allocated as specified address.
+ static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base);
+
+ static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base);
+
+ static void initialize_class_space(ReservedSpace rs);
+#endif
+
class AllocRecord : public CHeapObj<mtClass> {
public:
AllocRecord(address ptr, MetaspaceObj::Type type, int byte_size)
@@ -151,7 +176,6 @@
// Initialize globals for Metaspace
static void global_initialize();
- static void initialize_class_space(ReservedSpace rs);
static size_t first_chunk_word_size() { return _first_chunk_word_size; }
static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; }
@@ -172,8 +196,6 @@
MetaWord* expand_and_allocate(size_t size,
MetadataType mdtype);
- static bool is_initialized() { return _class_space_list != NULL; }
-
static bool contains(const void *ptr);
void dump(outputStream* const out) const;
@@ -190,11 +212,16 @@
};
void iterate(AllocRecordClosure *closure);
+
+ // Return TRUE only if UseCompressedKlassPointers is True and DumpSharedSpaces is False.
+ static bool using_class_space() {
+ return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces);
+ }
+
};
class MetaspaceAux : AllStatic {
static size_t free_chunks_total(Metaspace::MetadataType mdtype);
- static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
public:
// Statistics for class space and data space in metaspace.
@@ -238,13 +265,15 @@
// Used by MetaspaceCounters
static size_t free_chunks_total();
static size_t free_chunks_total_in_bytes();
+ static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
return _allocated_capacity_words[mdtype];
}
static size_t allocated_capacity_words() {
- return _allocated_capacity_words[Metaspace::ClassType] +
- _allocated_capacity_words[Metaspace::NonClassType];
+ return _allocated_capacity_words[Metaspace::NonClassType] +
+ (Metaspace::using_class_space() ?
+ _allocated_capacity_words[Metaspace::ClassType] : 0);
}
static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) {
return allocated_capacity_words(mdtype) * BytesPerWord;
@@ -257,8 +286,9 @@
return _allocated_used_words[mdtype];
}
static size_t allocated_used_words() {
- return _allocated_used_words[Metaspace::ClassType] +
- _allocated_used_words[Metaspace::NonClassType];
+ return _allocated_used_words[Metaspace::NonClassType] +
+ (Metaspace::using_class_space() ?
+ _allocated_used_words[Metaspace::ClassType] : 0);
}
static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) {
return allocated_used_words(mdtype) * BytesPerWord;
@@ -268,6 +298,7 @@
}
static size_t free_bytes();
+ static size_t free_bytes(Metaspace::MetadataType mdtype);
// Total capacity in all Metaspaces
static size_t capacity_bytes_slow() {
@@ -300,6 +331,7 @@
static void print_on(outputStream * out);
static void print_on(outputStream * out, Metaspace::MetadataType mdtype);
+ static void print_class_waste(outputStream* out);
static void print_waste(outputStream* out);
static void dump(outputStream* out);
static void verify_free_chunks();
--- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -25,11 +25,47 @@
#include "precompiled.hpp"
#include "memory/metaspaceCounters.hpp"
#include "memory/resourceArea.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/perfData.hpp"
#include "utilities/exceptions.hpp"
-MetaspaceCounters* MetaspaceCounters::_metaspace_counters = NULL;
+class MetaspacePerfCounters: public CHeapObj<mtInternal> {
+ friend class VMStructs;
+ PerfVariable* _capacity;
+ PerfVariable* _used;
+ PerfVariable* _max_capacity;
+
+ PerfVariable* create_variable(const char *ns, const char *name, size_t value, TRAPS) {
+ const char *path = PerfDataManager::counter_name(ns, name);
+ return PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value, THREAD);
+ }
+
+ void create_constant(const char *ns, const char *name, size_t value, TRAPS) {
+ const char *path = PerfDataManager::counter_name(ns, name);
+ PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, THREAD);
+ }
-size_t MetaspaceCounters::calc_total_capacity() {
+ public:
+ MetaspacePerfCounters(const char* ns, size_t min_capacity, size_t curr_capacity, size_t max_capacity, size_t used) {
+ EXCEPTION_MARK;
+ ResourceMark rm;
+
+ create_constant(ns, "minCapacity", min_capacity, THREAD);
+ _capacity = create_variable(ns, "capacity", curr_capacity, THREAD);
+ _max_capacity = create_variable(ns, "maxCapacity", max_capacity, THREAD);
+ _used = create_variable(ns, "used", used, THREAD);
+ }
+
+ void update(size_t capacity, size_t max_capacity, size_t used) {
+ _capacity->set_value(capacity);
+ _max_capacity->set_value(max_capacity);
+ _used->set_value(used);
+ }
+};
+
+MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
+
+size_t MetaspaceCounters::calculate_capacity() {
// The total capacity is the sum of
// 1) capacity of Metachunks in use by all Metaspaces
// 2) unused space at the end of each Metachunk
@@ -39,95 +75,65 @@
return total_capacity;
}
-MetaspaceCounters::MetaspaceCounters() :
- _capacity(NULL),
- _used(NULL),
- _max_capacity(NULL) {
+void MetaspaceCounters::initialize_performance_counters() {
if (UsePerfData) {
+ assert(_perf_counters == NULL, "Should only be initialized once");
+
size_t min_capacity = MetaspaceAux::min_chunk_size();
+ size_t capacity = calculate_capacity();
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
- size_t curr_capacity = calc_total_capacity();
size_t used = MetaspaceAux::allocated_used_bytes();
- initialize(min_capacity, max_capacity, curr_capacity, used);
- }
-}
-
-static PerfVariable* create_ms_variable(const char *ns,
- const char *name,
- size_t value,
- TRAPS) {
- const char *path = PerfDataManager::counter_name(ns, name);
- PerfVariable *result =
- PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value,
- CHECK_NULL);
- return result;
-}
-
-static void create_ms_constant(const char *ns,
- const char *name,
- size_t value,
- TRAPS) {
- const char *path = PerfDataManager::counter_name(ns, name);
- PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, CHECK);
-}
-
-void MetaspaceCounters::initialize(size_t min_capacity,
- size_t max_capacity,
- size_t curr_capacity,
- size_t used) {
-
- if (UsePerfData) {
- EXCEPTION_MARK;
- ResourceMark rm;
-
- const char *ms = "metaspace";
-
- create_ms_constant(ms, "minCapacity", min_capacity, CHECK);
- _max_capacity = create_ms_variable(ms, "maxCapacity", max_capacity, CHECK);
- _capacity = create_ms_variable(ms, "capacity", curr_capacity, CHECK);
- _used = create_ms_variable(ms, "used", used, CHECK);
- }
-}
-
-void MetaspaceCounters::update_capacity() {
- assert(UsePerfData, "Should not be called unless being used");
- size_t total_capacity = calc_total_capacity();
- _capacity->set_value(total_capacity);
-}
-
-void MetaspaceCounters::update_used() {
- assert(UsePerfData, "Should not be called unless being used");
- size_t used_in_bytes = MetaspaceAux::allocated_used_bytes();
- _used->set_value(used_in_bytes);
-}
-
-void MetaspaceCounters::update_max_capacity() {
- assert(UsePerfData, "Should not be called unless being used");
- assert(_max_capacity != NULL, "Should be initialized");
- size_t reserved_in_bytes = MetaspaceAux::reserved_in_bytes();
- _max_capacity->set_value(reserved_in_bytes);
-}
-
-void MetaspaceCounters::update_all() {
- if (UsePerfData) {
- update_used();
- update_capacity();
- update_max_capacity();
- }
-}
-
-void MetaspaceCounters::initialize_performance_counters() {
- if (UsePerfData) {
- assert(_metaspace_counters == NULL, "Should only be initialized once");
- _metaspace_counters = new MetaspaceCounters();
+ _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used);
}
}
void MetaspaceCounters::update_performance_counters() {
if (UsePerfData) {
- assert(_metaspace_counters != NULL, "Should be initialized");
- _metaspace_counters->update_all();
+ assert(_perf_counters != NULL, "Should be initialized");
+
+ size_t capacity = calculate_capacity();
+ size_t max_capacity = MetaspaceAux::reserved_in_bytes();
+ size_t used = MetaspaceAux::allocated_used_bytes();
+
+ _perf_counters->update(capacity, max_capacity, used);
}
}
+MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
+
+size_t CompressedClassSpaceCounters::calculate_capacity() {
+ return MetaspaceAux::allocated_capacity_bytes(_class_type) +
+ MetaspaceAux::free_bytes(_class_type) +
+ MetaspaceAux::free_chunks_total_in_bytes(_class_type);
+}
+
+void CompressedClassSpaceCounters::update_performance_counters() {
+ if (UsePerfData && UseCompressedKlassPointers) {
+ assert(_perf_counters != NULL, "Should be initialized");
+
+ size_t capacity = calculate_capacity();
+ size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
+ size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
+
+ _perf_counters->update(capacity, max_capacity, used);
+ }
+}
+
+void CompressedClassSpaceCounters::initialize_performance_counters() {
+ if (UsePerfData) {
+ assert(_perf_counters == NULL, "Should only be initialized once");
+ const char* ns = "compressedclassspace";
+
+ if (UseCompressedKlassPointers) {
+ size_t min_capacity = MetaspaceAux::min_chunk_size();
+ size_t capacity = calculate_capacity();
+ size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
+ size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
+
+ _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used);
+ } else {
+ _perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
+ }
+ }
+}
--- a/hotspot/src/share/vm/memory/metaspaceCounters.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -25,31 +25,27 @@
#ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
#define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
-#include "runtime/perfData.hpp"
+#include "memory/metaspace.hpp"
+
+class MetaspacePerfCounters;
-class MetaspaceCounters: public CHeapObj<mtClass> {
- friend class VMStructs;
- PerfVariable* _capacity;
- PerfVariable* _used;
- PerfVariable* _max_capacity;
- static MetaspaceCounters* _metaspace_counters;
- void initialize(size_t min_capacity,
- size_t max_capacity,
- size_t curr_capacity,
- size_t used);
- size_t calc_total_capacity();
+class MetaspaceCounters: public AllStatic {
+ static MetaspacePerfCounters* _perf_counters;
+ static size_t calculate_capacity();
+
public:
- MetaspaceCounters();
- ~MetaspaceCounters();
-
- void update_capacity();
- void update_used();
- void update_max_capacity();
-
- void update_all();
-
static void initialize_performance_counters();
static void update_performance_counters();
-
};
+
+class CompressedClassSpaceCounters: public AllStatic {
+ static MetaspacePerfCounters* _perf_counters;
+ static size_t calculate_capacity();
+ static const Metaspace::MetadataType _class_type = Metaspace::ClassType;
+
+ public:
+ static void initialize_performance_counters();
+ static void update_performance_counters();
+};
+
#endif // SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -52,7 +52,6 @@
int tag = 0;
soc->do_tag(--tag);
- assert(!UseCompressedOops, "UseCompressedOops doesn't work with shared archive");
// Verify the sizes of various metadata in the system.
soc->do_tag(sizeof(Method));
soc->do_tag(sizeof(ConstMethod));
--- a/hotspot/src/share/vm/memory/universe.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -145,8 +145,6 @@
NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true };
address Universe::_narrow_ptrs_base;
-size_t Universe::_class_metaspace_size;
-
void Universe::basic_type_classes_do(void f(Klass*)) {
f(boolArrayKlassObj());
f(byteArrayKlassObj());
@@ -641,6 +639,8 @@
return status;
}
+ Metaspace::global_initialize();
+
// Create memory for metadata. Must be after initializing heap for
// DumpSharedSpaces.
ClassLoaderData::init_null_class_loader_data();
@@ -693,13 +693,9 @@
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
base = HeapBaseMinAddress;
- // If the total size and the metaspace size are small enough to allow
- // UnscaledNarrowOop then just use UnscaledNarrowOop.
- } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop) &&
- (!UseCompressedKlassPointers ||
- (((OopEncodingHeapMax - heap_size) + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax))) {
- // We don't need to check the metaspace size here because it is always smaller
- // than total_size.
+ // If the total size is small enough to allow UnscaledNarrowOop then
+ // just use UnscaledNarrowOop.
+ } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) {
if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) &&
(Universe::narrow_oop_shift() == 0)) {
// Use 32-bits oops without encoding and
@@ -716,13 +712,6 @@
base = (OopEncodingHeapMax - heap_size);
}
}
-
- // See if ZeroBaseNarrowOop encoding will work for a heap based at
- // (KlassEncodingMetaspaceMax - class_metaspace_size()).
- } else if (UseCompressedKlassPointers && (mode != HeapBasedNarrowOop) &&
- (Universe::class_metaspace_size() + HeapBaseMinAddress <= KlassEncodingMetaspaceMax) &&
- (KlassEncodingMetaspaceMax + heap_size - Universe::class_metaspace_size() <= OopEncodingHeapMax)) {
- base = (KlassEncodingMetaspaceMax - Universe::class_metaspace_size());
} else {
// UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or
// HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb.
@@ -732,8 +721,7 @@
// Set narrow_oop_base and narrow_oop_use_implicit_null_checks
// used in ReservedHeapSpace() constructors.
// The final values will be set in initialize_heap() below.
- if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax) &&
- (!UseCompressedKlassPointers || (base + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax)) {
+ if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax)) {
// Use zero based compressed oops
Universe::set_narrow_oop_base(NULL);
// Don't need guard page for implicit checks in indexed
@@ -816,9 +804,7 @@
tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
}
- if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) ||
- (UseCompressedKlassPointers &&
- ((uint64_t)Universe::heap()->base() + Universe::class_metaspace_size() > KlassEncodingMetaspaceMax))) {
+ if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax)) {
// Can't reserve heap below 32Gb.
// keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
@@ -849,20 +835,16 @@
}
}
}
+
if (verbose) {
tty->cr();
tty->cr();
}
- if (UseCompressedKlassPointers) {
- Universe::set_narrow_klass_base(Universe::narrow_oop_base());
- Universe::set_narrow_klass_shift(MIN2(Universe::narrow_oop_shift(), LogKlassAlignmentInBytes));
- }
Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
}
- // Universe::narrow_oop_base() is one page below the metaspace
- // base. The actual metaspace base depends on alignment constraints
- // so we don't know its exact location here.
- assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() - os::vm_page_size() - ClassMetaspaceSize) ||
+ // Universe::narrow_oop_base() is one page below the heap.
+ assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() -
+ os::vm_page_size()) ||
Universe::narrow_oop_base() == NULL, "invalid value");
assert(Universe::narrow_oop_shift() == LogMinObjAlignmentInBytes ||
Universe::narrow_oop_shift() == 0, "invalid value");
@@ -882,12 +864,7 @@
// Reserve the Java heap, which is now the same for all GCs.
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
- // Add in the class metaspace area so the classes in the headers can
- // be compressed the same as instances.
- // Need to round class space size up because it's below the heap and
- // the actual alignment depends on its size.
- Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
- size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
+ size_t total_reserved = align_size_up(heap_size, alignment);
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
"heap size is too big for compressed oops");
char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
@@ -923,28 +900,17 @@
return total_rs;
}
- // Split the reserved space into main Java heap and a space for
- // classes so that they can be compressed using the same algorithm
- // as compressed oops. If compress oops and compress klass ptrs are
- // used we need the meta space first: if the alignment used for
- // compressed oops is greater than the one used for compressed klass
- // ptrs, a metadata space on top of the heap could become
- // unreachable.
- ReservedSpace class_rs = total_rs.first_part(Universe::class_metaspace_size());
- ReservedSpace heap_rs = total_rs.last_part(Universe::class_metaspace_size(), alignment);
- Metaspace::initialize_class_space(class_rs);
-
if (UseCompressedOops) {
// Universe::initialize_heap() will reset this to NULL if unscaled
// or zero-based narrow oops are actually used.
address base = (address)(total_rs.base() - os::vm_page_size());
Universe::set_narrow_oop_base(base);
}
- return heap_rs;
+ return total_rs;
}
-// It's the caller's repsonsibility to ensure glitch-freedom
+// It's the caller's responsibility to ensure glitch-freedom
// (if required).
void Universe::update_heap_info_at_gc() {
_heap_capacity_at_last_gc = heap()->capacity();
@@ -1135,6 +1101,8 @@
// Initialize performance counters for metaspaces
MetaspaceCounters::initialize_performance_counters();
+ CompressedClassSpaceCounters::initialize_performance_counters();
+
MemoryService::add_metaspace_memory_pools();
GC_locker::unlock(); // allow gc after bootstrapping
--- a/hotspot/src/share/vm/memory/universe.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -75,10 +75,10 @@
};
-// For UseCompressedOops and UseCompressedKlassPointers.
+// For UseCompressedOops.
struct NarrowPtrStruct {
- // Base address for oop/klass-within-java-object materialization.
- // NULL if using wide oops/klasses or zero based narrow oops/klasses.
+ // Base address for oop-within-java-object materialization.
+ // NULL if using wide oops or zero based narrow oops.
address _base;
// Number of shift bits for encoding/decoding narrow ptrs.
// 0 if using wide ptrs or zero based unscaled narrow ptrs,
@@ -106,6 +106,7 @@
friend class SystemDictionary;
friend class VMStructs;
friend class VM_PopulateDumpSharedSpace;
+ friend class Metaspace;
friend jint universe_init();
friend void universe2_init();
@@ -184,9 +185,6 @@
static struct NarrowPtrStruct _narrow_klass;
static address _narrow_ptrs_base;
- // Aligned size of the metaspace.
- static size_t _class_metaspace_size;
-
// array of dummy objects used with +FullGCAlot
debug_only(static objArrayOop _fullgc_alot_dummy_array;)
// index of next entry to clear
@@ -238,15 +236,6 @@
assert(UseCompressedOops, "no compressed ptrs?");
_narrow_oop._use_implicit_null_checks = use;
}
- static bool reserve_metaspace_helper(bool with_base = false);
- static ReservedHeapSpace reserve_heap_metaspace(size_t heap_size, size_t alignment, bool& contiguous);
-
- static size_t class_metaspace_size() {
- return _class_metaspace_size;
- }
- static void set_class_metaspace_size(size_t metaspace_size) {
- _class_metaspace_size = metaspace_size;
- }
// Debugging
static int _verify_count; // number of verifies done
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -269,7 +269,7 @@
set_fields(NULL, 0);
set_constants(NULL);
set_class_loader_data(NULL);
- set_source_file_name(NULL);
+ set_source_file_name_index(0);
set_source_debug_extension(NULL, 0);
set_array_name(NULL);
set_inner_classes(NULL);
@@ -284,7 +284,7 @@
set_osr_nmethods_head(NULL);
set_breakpoints(NULL);
init_previous_versions();
- set_generic_signature(NULL);
+ set_generic_signature_index(0);
release_set_methods_jmethod_ids(NULL);
release_set_methods_cached_itable_indices(NULL);
set_annotations(NULL);
@@ -2368,18 +2368,12 @@
// unreference array name derived from this class name (arrays of an unloaded
// class can't be referenced anymore).
if (_array_name != NULL) _array_name->decrement_refcount();
- if (_source_file_name != NULL) _source_file_name->decrement_refcount();
if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
assert(_total_instanceKlass_count >= 1, "Sanity check");
Atomic::dec(&_total_instanceKlass_count);
}
-void InstanceKlass::set_source_file_name(Symbol* n) {
- _source_file_name = n;
- if (_source_file_name != NULL) _source_file_name->increment_refcount();
-}
-
void InstanceKlass::set_source_debug_extension(char* array, int length) {
if (array == NULL) {
_source_debug_extension = NULL;
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -201,14 +201,10 @@
// number_of_inner_classes * 4 + enclosing_method_attribute_size.
Array<jushort>* _inner_classes;
- // Name of source file containing this klass, NULL if not specified.
- Symbol* _source_file_name;
// the source debug extension for this klass, NULL if not specified.
// Specified as UTF-8 string without terminating zero byte in the classfile,
// it is stored in the instanceklass as a NULL-terminated UTF-8 string
char* _source_debug_extension;
- // Generic signature, or null if none.
- Symbol* _generic_signature;
// Array name derived from this class which needs unreferencing
// if this class is unloaded.
Symbol* _array_name;
@@ -217,6 +213,12 @@
// (including inherited fields but after header_size()).
int _nonstatic_field_size;
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
+ // Constant pool index to the utf8 entry of the Generic signature,
+ // or 0 if none.
+ u2 _generic_signature_index;
+ // Constant pool index to the utf8 entry for the name of source file
+ // containing this klass, 0 if not specified.
+ u2 _source_file_name_index;
u2 _static_oop_field_count;// number of static oop fields in this klass
u2 _java_fields_count; // The number of declared Java fields
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
@@ -570,8 +572,16 @@
}
// source file name
- Symbol* source_file_name() const { return _source_file_name; }
- void set_source_file_name(Symbol* n);
+ Symbol* source_file_name() const {
+ return (_source_file_name_index == 0) ?
+ (Symbol*)NULL : _constants->symbol_at(_source_file_name_index);
+ }
+ u2 source_file_name_index() const {
+ return _source_file_name_index;
+ }
+ void set_source_file_name_index(u2 sourcefile_index) {
+ _source_file_name_index = sourcefile_index;
+ }
// minor and major version numbers of class file
u2 minor_version() const { return _minor_version; }
@@ -648,8 +658,16 @@
void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; }
// generics support
- Symbol* generic_signature() const { return _generic_signature; }
- void set_generic_signature(Symbol* sig) { _generic_signature = sig; }
+ Symbol* generic_signature() const {
+ return (_generic_signature_index == 0) ?
+ (Symbol*)NULL : _constants->symbol_at(_generic_signature_index);
+ }
+ u2 generic_signature_index() const {
+ return _generic_signature_index;
+ }
+ void set_generic_signature_index(u2 sig_index) {
+ _generic_signature_index = sig_index;
+ }
u2 enclosing_method_data(int offset);
u2 enclosing_method_class_index() {
--- a/hotspot/src/share/vm/oops/klass.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -352,7 +352,8 @@
static int layout_helper_log2_element_size(jint lh) {
assert(lh < (jint)_lh_neutral_value, "must be array");
int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
- assert(l2esz <= LogBitsPerLong, "sanity");
+ assert(l2esz <= LogBitsPerLong,
+ err_msg("sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh));
return l2esz;
}
static jint array_layout_helper(jint tag, int hsize, BasicType etype, int log2_esize) {
@@ -703,6 +704,16 @@
virtual void oop_verify_on(oop obj, outputStream* st);
+ static bool is_null(narrowKlass obj);
+ static bool is_null(Klass* obj);
+
+ // klass encoding for klass pointer in objects.
+ static narrowKlass encode_klass_not_null(Klass* v);
+ static narrowKlass encode_klass(Klass* v);
+
+ static Klass* decode_klass_not_null(narrowKlass v);
+ static Klass* decode_klass(narrowKlass v);
+
private:
// barriers used by klass_oop_store
void klass_update_barrier_set(oop v);
--- a/hotspot/src/share/vm/oops/klass.inline.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/klass.inline.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_OOPS_KLASS_INLINE_HPP
#define SHARE_VM_OOPS_KLASS_INLINE_HPP
+#include "memory/universe.hpp"
#include "oops/klass.hpp"
#include "oops/markOop.hpp"
@@ -33,4 +34,41 @@
_prototype_header = header;
}
+inline bool Klass::is_null(Klass* obj) { return obj == NULL; }
+inline bool Klass::is_null(narrowKlass obj) { return obj == 0; }
+
+// Encoding and decoding for klass field.
+
+inline bool check_klass_alignment(Klass* obj) {
+ return (intptr_t)obj % KlassAlignmentInBytes == 0;
+}
+
+inline narrowKlass Klass::encode_klass_not_null(Klass* v) {
+ assert(!is_null(v), "klass value can never be zero");
+ assert(check_klass_alignment(v), "Address not aligned");
+ int shift = Universe::narrow_klass_shift();
+ uint64_t pd = (uint64_t)(pointer_delta((void*)v, Universe::narrow_klass_base(), 1));
+ assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
+ uint64_t result = pd >> shift;
+ assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
+ assert(decode_klass(result) == v, "reversibility");
+ return (narrowKlass)result;
+}
+
+inline narrowKlass Klass::encode_klass(Klass* v) {
+ return is_null(v) ? (narrowKlass)0 : encode_klass_not_null(v);
+}
+
+inline Klass* Klass::decode_klass_not_null(narrowKlass v) {
+ assert(!is_null(v), "narrow klass value can never be zero");
+ int shift = Universe::narrow_klass_shift();
+ Klass* result = (Klass*)(void*)((uintptr_t)Universe::narrow_klass_base() + ((uintptr_t)v << shift));
+ assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
+ return result;
+}
+
+inline Klass* Klass::decode_klass(narrowKlass v) {
+ return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v);
+}
+
#endif // SHARE_VM_OOPS_KLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/method.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -747,6 +747,7 @@
set_not_c2_compilable();
}
CompilationPolicy::policy()->disable_compilation(this);
+ assert(!CompilationPolicy::can_be_compiled(this, comp_level), "sanity check");
}
bool Method::is_not_osr_compilable(int comp_level) const {
@@ -773,6 +774,7 @@
set_not_c2_osr_compilable();
}
CompilationPolicy::policy()->disable_compilation(this);
+ assert(!CompilationPolicy::can_be_osr_compiled(this, comp_level), "sanity check");
}
// Revert to using the interpreter and clear out the nmethod
--- a/hotspot/src/share/vm/oops/oop.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -62,7 +62,7 @@
volatile markOop _mark;
union _metadata {
Klass* _klass;
- narrowOop _compressed_klass;
+ narrowKlass _compressed_klass;
} _metadata;
// Fast access to barrier set. Must be initialized.
@@ -84,7 +84,7 @@
Klass* klass() const;
Klass* klass_or_null() const volatile;
Klass** klass_addr();
- narrowOop* compressed_klass_addr();
+ narrowKlass* compressed_klass_addr();
void set_klass(Klass* k);
@@ -189,13 +189,6 @@
oop compare_value,
bool prebarrier = false);
- // klass encoding for klass pointer in objects.
- static narrowOop encode_klass_not_null(Klass* v);
- static narrowOop encode_klass(Klass* v);
-
- static Klass* decode_klass_not_null(narrowOop v);
- static Klass* decode_klass(narrowOop v);
-
// Access to fields in a instanceOop through these methods.
oop obj_field(int offset) const;
volatile oop obj_field_volatile(int offset) const;
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -35,7 +35,7 @@
#include "memory/specialized_oop_closures.hpp"
#include "oops/arrayKlass.hpp"
#include "oops/arrayOop.hpp"
-#include "oops/klass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/markOop.inline.hpp"
#include "oops/oop.hpp"
#include "runtime/atomic.hpp"
@@ -70,7 +70,7 @@
inline Klass* oopDesc::klass() const {
if (UseCompressedKlassPointers) {
- return decode_klass_not_null(_metadata._compressed_klass);
+ return Klass::decode_klass_not_null(_metadata._compressed_klass);
} else {
return _metadata._klass;
}
@@ -79,7 +79,7 @@
inline Klass* oopDesc::klass_or_null() const volatile {
// can be NULL in CMS
if (UseCompressedKlassPointers) {
- return decode_klass(_metadata._compressed_klass);
+ return Klass::decode_klass(_metadata._compressed_klass);
} else {
return _metadata._klass;
}
@@ -87,7 +87,7 @@
inline int oopDesc::klass_gap_offset_in_bytes() {
assert(UseCompressedKlassPointers, "only applicable to compressed klass pointers");
- return oopDesc::klass_offset_in_bytes() + sizeof(narrowOop);
+ return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass);
}
inline Klass** oopDesc::klass_addr() {
@@ -97,9 +97,9 @@
return (Klass**) &_metadata._klass;
}
-inline narrowOop* oopDesc::compressed_klass_addr() {
+inline narrowKlass* oopDesc::compressed_klass_addr() {
assert(UseCompressedKlassPointers, "only called by compressed klass pointers");
- return (narrowOop*) &_metadata._compressed_klass;
+ return &_metadata._compressed_klass;
}
inline void oopDesc::set_klass(Klass* k) {
@@ -107,7 +107,7 @@
assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
if (UseCompressedKlassPointers) {
- *compressed_klass_addr() = encode_klass_not_null(k);
+ *compressed_klass_addr() = Klass::encode_klass_not_null(k);
} else {
*klass_addr() = k;
}
@@ -127,7 +127,7 @@
// This is only to be used during GC, for from-space objects, so no
// barrier is needed.
if (UseCompressedKlassPointers) {
- _metadata._compressed_klass = encode_heap_oop(k); // may be null (parnew overflow handling)
+ _metadata._compressed_klass = (narrowKlass)encode_heap_oop(k); // may be null (parnew overflow handling)
} else {
_metadata._klass = (Klass*)(address)k;
}
@@ -136,7 +136,7 @@
inline oop oopDesc::list_ptr_from_klass() {
// This is only to be used during GC, for from-space objects.
if (UseCompressedKlassPointers) {
- return decode_heap_oop(_metadata._compressed_klass);
+ return decode_heap_oop((narrowOop)_metadata._compressed_klass);
} else {
// Special case for GC
return (oop)(address)_metadata._klass;
@@ -176,7 +176,6 @@
// the right type and inlines the appopriate code).
inline bool oopDesc::is_null(oop obj) { return obj == NULL; }
-inline bool oopDesc::is_null(Klass* obj) { return obj == NULL; }
inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; }
// Algorithm for encoding and decoding oops from 64 bit pointers to 32 bit
@@ -186,9 +185,6 @@
inline bool check_obj_alignment(oop obj) {
return (intptr_t)obj % MinObjAlignmentInBytes == 0;
}
-inline bool check_klass_alignment(Klass* obj) {
- return (intptr_t)obj % KlassAlignmentInBytes == 0;
-}
inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
assert(!is_null(v), "oop value can never be zero");
@@ -224,39 +220,6 @@
inline oop oopDesc::decode_heap_oop_not_null(oop v) { return v; }
inline oop oopDesc::decode_heap_oop(oop v) { return v; }
-// Encoding and decoding for klass field. It is copied code, but someday
-// might not be the same as oop.
-
-inline narrowOop oopDesc::encode_klass_not_null(Klass* v) {
- assert(!is_null(v), "klass value can never be zero");
- assert(check_klass_alignment(v), "Address not aligned");
- address base = Universe::narrow_klass_base();
- int shift = Universe::narrow_klass_shift();
- uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
- assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
- uint64_t result = pd >> shift;
- assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
- assert(decode_klass(result) == v, "reversibility");
- return (narrowOop)result;
-}
-
-inline narrowOop oopDesc::encode_klass(Klass* v) {
- return (is_null(v)) ? (narrowOop)0 : encode_klass_not_null(v);
-}
-
-inline Klass* oopDesc::decode_klass_not_null(narrowOop v) {
- assert(!is_null(v), "narrow oop value can never be zero");
- address base = Universe::narrow_klass_base();
- int shift = Universe::narrow_klass_shift();
- Klass* result = (Klass*)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
- assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
- return result;
-}
-
-inline Klass* oopDesc::decode_klass(narrowOop v) {
- return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v);
-}
-
// Load an oop out of the Java heap as is without decoding.
// Called by GC to check for null before decoding.
inline oop oopDesc::load_heap_oop(oop* p) { return *p; }
--- a/hotspot/src/share/vm/oops/oopsHierarchy.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/oops/oopsHierarchy.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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,10 @@
// of B, A's representation is a prefix of B's representation.
typedef juint narrowOop; // Offset instead of address for an oop within a java object
+
+// If compressed klass pointers then use narrowKlass.
+typedef juint narrowKlass;
+
typedef void* OopOrNarrowOopStar;
typedef class markOopDesc* markOop;
--- a/hotspot/src/share/vm/opto/block.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/block.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -35,10 +35,6 @@
#include "opto/rootnode.hpp"
#include "utilities/copy.hpp"
-// Optimization - Graph Style
-
-
-//-----------------------------------------------------------------------------
void Block_Array::grow( uint i ) {
assert(i >= Max(), "must be an overflow");
debug_only(_limit = i+1);
@@ -54,7 +50,6 @@
Copy::zero_to_bytes( &_blocks[old], (_size-old)*sizeof(Block*) );
}
-//=============================================================================
void Block_List::remove(uint i) {
assert(i < _cnt, "index out of bounds");
Copy::conjoint_words_to_lower((HeapWord*)&_blocks[i+1], (HeapWord*)&_blocks[i], ((_cnt-i-1)*sizeof(Block*)));
@@ -76,8 +71,6 @@
}
#endif
-//=============================================================================
-
uint Block::code_alignment() {
// Check for Root block
if (_pre_order == 0) return CodeEntryAlignment;
@@ -113,7 +106,6 @@
return unit_sz; // no particular alignment
}
-//-----------------------------------------------------------------------------
// Compute the size of first 'inst_cnt' instructions in this block.
// Return the number of instructions left to compute if the block has
// less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
@@ -138,7 +130,6 @@
return inst_cnt;
}
-//-----------------------------------------------------------------------------
uint Block::find_node( const Node *n ) const {
for( uint i = 0; i < _nodes.size(); i++ ) {
if( _nodes[i] == n )
@@ -153,7 +144,6 @@
_nodes.remove(find_node(n));
}
-//------------------------------is_Empty---------------------------------------
// Return empty status of a block. Empty blocks contain only the head, other
// ideal nodes, and an optional trailing goto.
int Block::is_Empty() const {
@@ -192,7 +182,6 @@
return not_empty;
}
-//------------------------------has_uncommon_code------------------------------
// Return true if the block's code implies that it is likely to be
// executed infrequently. Check to see if the block ends in a Halt or
// a low probability call.
@@ -218,7 +207,6 @@
return op == Op_Halt;
}
-//------------------------------is_uncommon------------------------------------
// True if block is low enough frequency or guarded by a test which
// mostly does not go here.
bool Block::is_uncommon(PhaseCFG* cfg) const {
@@ -271,7 +259,6 @@
return false;
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void Block::dump_bidx(const Block* orig, outputStream* st) const {
if (_pre_order) st->print("B%d",_pre_order);
@@ -364,13 +351,12 @@
}
#endif
-//=============================================================================
-//------------------------------PhaseCFG---------------------------------------
PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
: Phase(CFG)
, _block_arena(arena)
+, _root(root)
+, _matcher(matcher)
, _node_to_block_mapping(arena)
-, _root(root)
, _node_latency(NULL)
#ifndef PRODUCT
, _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
@@ -390,11 +376,10 @@
_goto->set_req(0,_goto);
// Build the CFG in Reverse Post Order
- _num_blocks = build_cfg();
- _broot = get_block_for_node(_root);
+ _number_of_blocks = build_cfg();
+ _root_block = get_block_for_node(_root);
}
-//------------------------------build_cfg--------------------------------------
// Build a proper looking CFG. Make every block begin with either a StartNode
// or a RegionNode. Make every block end with either a Goto, If or Return.
// The RootNode both starts and ends it's own block. Do this with a recursive
@@ -496,13 +481,12 @@
return sum;
}
-//------------------------------insert_goto_at---------------------------------
// Inserts a goto & corresponding basic block between
// block[block_no] and its succ_no'th successor block
void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
// get block with block_no
- assert(block_no < _num_blocks, "illegal block number");
- Block* in = _blocks[block_no];
+ assert(block_no < number_of_blocks(), "illegal block number");
+ Block* in = get_block(block_no);
// get successor block succ_no
assert(succ_no < in->_num_succs, "illegal successor number");
Block* out = in->_succs[succ_no];
@@ -537,11 +521,9 @@
// Set the frequency of the new block
block->_freq = freq;
// add new basic block to basic block list
- _blocks.insert(block_no + 1, block);
- _num_blocks++;
+ add_block_at(block_no + 1, block);
}
-//------------------------------no_flip_branch---------------------------------
// Does this block end in a multiway branch that cannot have the default case
// flipped for another case?
static bool no_flip_branch( Block *b ) {
@@ -560,7 +542,6 @@
return false;
}
-//------------------------------convert_NeverBranch_to_Goto--------------------
// Check for NeverBranch at block end. This needs to become a GOTO to the
// true target. NeverBranch are treated as a conditional branch that always
// goes the same direction for most of the optimizer and are used to give a
@@ -598,7 +579,6 @@
dead->_nodes[k]->del_req(j);
}
-//------------------------------move_to_next-----------------------------------
// Helper function to move block bx to the slot following b_index. Return
// true if the move is successful, otherwise false
bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
@@ -606,20 +586,22 @@
// Return false if bx is already scheduled.
uint bx_index = bx->_pre_order;
- if ((bx_index <= b_index) && (_blocks[bx_index] == bx)) {
+ if ((bx_index <= b_index) && (get_block(bx_index) == bx)) {
return false;
}
// Find the current index of block bx on the block list
bx_index = b_index + 1;
- while( bx_index < _num_blocks && _blocks[bx_index] != bx ) bx_index++;
- assert(_blocks[bx_index] == bx, "block not found");
+ while (bx_index < number_of_blocks() && get_block(bx_index) != bx) {
+ bx_index++;
+ }
+ assert(get_block(bx_index) == bx, "block not found");
// If the previous block conditionally falls into bx, return false,
// because moving bx will create an extra jump.
for(uint k = 1; k < bx->num_preds(); k++ ) {
Block* pred = get_block_for_node(bx->pred(k));
- if (pred == _blocks[bx_index-1]) {
+ if (pred == get_block(bx_index - 1)) {
if (pred->_num_succs != 1) {
return false;
}
@@ -632,7 +614,6 @@
return true;
}
-//------------------------------move_to_end------------------------------------
// Move empty and uncommon blocks to the end.
void PhaseCFG::move_to_end(Block *b, uint i) {
int e = b->is_Empty();
@@ -650,31 +631,31 @@
_blocks.push(b);
}
-//---------------------------set_loop_alignment--------------------------------
// Set loop alignment for every block
void PhaseCFG::set_loop_alignment() {
- uint last = _num_blocks;
- assert( _blocks[0] == _broot, "" );
+ uint last = number_of_blocks();
+ assert(get_block(0) == get_root_block(), "");
- for (uint i = 1; i < last; i++ ) {
- Block *b = _blocks[i];
- if (b->head()->is_Loop()) {
- b->set_loop_alignment(b);
+ for (uint i = 1; i < last; i++) {
+ Block* block = get_block(i);
+ if (block->head()->is_Loop()) {
+ block->set_loop_alignment(block);
}
}
}
-//-----------------------------remove_empty------------------------------------
// Make empty basic blocks to be "connector" blocks, Move uncommon blocks
// to the end.
-void PhaseCFG::remove_empty() {
+void PhaseCFG::remove_empty_blocks() {
// Move uncommon blocks to the end
- uint last = _num_blocks;
- assert( _blocks[0] == _broot, "" );
+ uint last = number_of_blocks();
+ assert(get_block(0) == get_root_block(), "");
for (uint i = 1; i < last; i++) {
- Block *b = _blocks[i];
- if (b->is_connector()) break;
+ Block* block = get_block(i);
+ if (block->is_connector()) {
+ break;
+ }
// Check for NeverBranch at block end. This needs to become a GOTO to the
// true target. NeverBranch are treated as a conditional branch that
@@ -682,124 +663,127 @@
// to give a fake exit path to infinite loops. At this late stage they
// need to turn into Goto's so that when you enter the infinite loop you
// indeed hang.
- if( b->_nodes[b->end_idx()]->Opcode() == Op_NeverBranch )
- convert_NeverBranch_to_Goto(b);
+ if (block->_nodes[block->end_idx()]->Opcode() == Op_NeverBranch) {
+ convert_NeverBranch_to_Goto(block);
+ }
// Look for uncommon blocks and move to end.
if (!C->do_freq_based_layout()) {
- if (b->is_uncommon(this)) {
- move_to_end(b, i);
+ if (block->is_uncommon(this)) {
+ move_to_end(block, i);
last--; // No longer check for being uncommon!
- if( no_flip_branch(b) ) { // Fall-thru case must follow?
- b = _blocks[i]; // Find the fall-thru block
- move_to_end(b, i);
+ if (no_flip_branch(block)) { // Fall-thru case must follow?
+ // Find the fall-thru block
+ block = get_block(i);
+ move_to_end(block, i);
last--;
}
- i--; // backup block counter post-increment
+ // backup block counter post-increment
+ i--;
}
}
}
// Move empty blocks to the end
- last = _num_blocks;
+ last = number_of_blocks();
for (uint i = 1; i < last; i++) {
- Block *b = _blocks[i];
- if (b->is_Empty() != Block::not_empty) {
- move_to_end(b, i);
+ Block* block = get_block(i);
+ if (block->is_Empty() != Block::not_empty) {
+ move_to_end(block, i);
last--;
i--;
}
} // End of for all blocks
}
-//-----------------------------fixup_flow--------------------------------------
// Fix up the final control flow for basic blocks.
void PhaseCFG::fixup_flow() {
// Fixup final control flow for the blocks. Remove jump-to-next
// block. If neither arm of a IF follows the conditional branch, we
// have to add a second jump after the conditional. We place the
// TRUE branch target in succs[0] for both GOTOs and IFs.
- for (uint i=0; i < _num_blocks; i++) {
- Block *b = _blocks[i];
- b->_pre_order = i; // turn pre-order into block-index
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ block->_pre_order = i; // turn pre-order into block-index
// Connector blocks need no further processing.
- if (b->is_connector()) {
- assert((i+1) == _num_blocks || _blocks[i+1]->is_connector(),
- "All connector blocks should sink to the end");
+ if (block->is_connector()) {
+ assert((i+1) == number_of_blocks() || get_block(i + 1)->is_connector(), "All connector blocks should sink to the end");
continue;
}
- assert(b->is_Empty() != Block::completely_empty,
- "Empty blocks should be connectors");
+ assert(block->is_Empty() != Block::completely_empty, "Empty blocks should be connectors");
- Block *bnext = (i < _num_blocks-1) ? _blocks[i+1] : NULL;
- Block *bs0 = b->non_connector_successor(0);
+ Block* bnext = (i < number_of_blocks() - 1) ? get_block(i + 1) : NULL;
+ Block* bs0 = block->non_connector_successor(0);
// Check for multi-way branches where I cannot negate the test to
// exchange the true and false targets.
- if( no_flip_branch( b ) ) {
+ if (no_flip_branch(block)) {
// Find fall through case - if must fall into its target
- int branch_idx = b->_nodes.size() - b->_num_succs;
- for (uint j2 = 0; j2 < b->_num_succs; j2++) {
- const ProjNode* p = b->_nodes[branch_idx + j2]->as_Proj();
+ int branch_idx = block->_nodes.size() - block->_num_succs;
+ for (uint j2 = 0; j2 < block->_num_succs; j2++) {
+ const ProjNode* p = block->_nodes[branch_idx + j2]->as_Proj();
if (p->_con == 0) {
// successor j2 is fall through case
- if (b->non_connector_successor(j2) != bnext) {
+ if (block->non_connector_successor(j2) != bnext) {
// but it is not the next block => insert a goto
insert_goto_at(i, j2);
}
// Put taken branch in slot 0
- if( j2 == 0 && b->_num_succs == 2) {
+ if (j2 == 0 && block->_num_succs == 2) {
// Flip targets in succs map
- Block *tbs0 = b->_succs[0];
- Block *tbs1 = b->_succs[1];
- b->_succs.map( 0, tbs1 );
- b->_succs.map( 1, tbs0 );
+ Block *tbs0 = block->_succs[0];
+ Block *tbs1 = block->_succs[1];
+ block->_succs.map(0, tbs1);
+ block->_succs.map(1, tbs0);
}
break;
}
}
+
// Remove all CatchProjs
- for (uint j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
+ for (uint j = 0; j < block->_num_succs; j++) {
+ block->_nodes.pop();
+ }
- } else if (b->_num_succs == 1) {
+ } else if (block->_num_succs == 1) {
// Block ends in a Goto?
if (bnext == bs0) {
// We fall into next block; remove the Goto
- b->_nodes.pop();
+ block->_nodes.pop();
}
- } else if( b->_num_succs == 2 ) { // Block ends in a If?
+ } else if(block->_num_succs == 2) { // Block ends in a If?
// Get opcode of 1st projection (matches _succs[0])
// Note: Since this basic block has 2 exits, the last 2 nodes must
// be projections (in any order), the 3rd last node must be
// the IfNode (we have excluded other 2-way exits such as
// CatchNodes already).
- MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
- ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
- ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
+ MachNode* iff = block->_nodes[block->_nodes.size() - 3]->as_Mach();
+ ProjNode* proj0 = block->_nodes[block->_nodes.size() - 2]->as_Proj();
+ ProjNode* proj1 = block->_nodes[block->_nodes.size() - 1]->as_Proj();
// Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
- assert(proj0->raw_out(0) == b->_succs[0]->head(), "Mismatch successor 0");
- assert(proj1->raw_out(0) == b->_succs[1]->head(), "Mismatch successor 1");
+ assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0");
+ assert(proj1->raw_out(0) == block->_succs[1]->head(), "Mismatch successor 1");
- Block *bs1 = b->non_connector_successor(1);
+ Block* bs1 = block->non_connector_successor(1);
// Check for neither successor block following the current
// block ending in a conditional. If so, move one of the
// successors after the current one, provided that the
// successor was previously unscheduled, but moveable
// (i.e., all paths to it involve a branch).
- if( !C->do_freq_based_layout() && bnext != bs0 && bnext != bs1 ) {
+ if (!C->do_freq_based_layout() && bnext != bs0 && bnext != bs1) {
// Choose the more common successor based on the probability
// of the conditional branch.
- Block *bx = bs0;
- Block *by = bs1;
+ Block* bx = bs0;
+ Block* by = bs1;
// _prob is the probability of taking the true path. Make
// p the probability of taking successor #1.
float p = iff->as_MachIf()->_prob;
- if( proj0->Opcode() == Op_IfTrue ) {
+ if (proj0->Opcode() == Op_IfTrue) {
p = 1.0 - p;
}
@@ -826,14 +810,16 @@
// succs[1].
if (bnext == bs0) {
// Fall-thru case in succs[0], so flip targets in succs map
- Block *tbs0 = b->_succs[0];
- Block *tbs1 = b->_succs[1];
- b->_succs.map( 0, tbs1 );
- b->_succs.map( 1, tbs0 );
+ Block* tbs0 = block->_succs[0];
+ Block* tbs1 = block->_succs[1];
+ block->_succs.map(0, tbs1);
+ block->_succs.map(1, tbs0);
// Flip projection for each target
- { ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
+ ProjNode* tmp = proj0;
+ proj0 = proj1;
+ proj1 = tmp;
- } else if( bnext != bs1 ) {
+ } else if(bnext != bs1) {
// Need a double-branch
// The existing conditional branch need not change.
// Add a unconditional branch to the false target.
@@ -843,12 +829,12 @@
}
// Make sure we TRUE branch to the target
- if( proj0->Opcode() == Op_IfFalse ) {
+ if (proj0->Opcode() == Op_IfFalse) {
iff->as_MachIf()->negate();
}
- b->_nodes.pop(); // Remove IfFalse & IfTrue projections
- b->_nodes.pop();
+ block->_nodes.pop(); // Remove IfFalse & IfTrue projections
+ block->_nodes.pop();
} else {
// Multi-exit block, e.g. a switch statement
@@ -858,7 +844,6 @@
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void PhaseCFG::_dump_cfg( const Node *end, VectorSet &visited ) const {
const Node *x = end->is_block_proj();
@@ -884,10 +869,11 @@
}
void PhaseCFG::dump( ) const {
- tty->print("\n--- CFG --- %d BBs\n",_num_blocks);
+ tty->print("\n--- CFG --- %d BBs\n", number_of_blocks());
if (_blocks.size()) { // Did we do basic-block layout?
- for (uint i = 0; i < _num_blocks; i++) {
- _blocks[i]->dump(this);
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ const Block* block = get_block(i);
+ block->dump(this);
}
} else { // Else do it with a DFS
VectorSet visited(_block_arena);
@@ -896,27 +882,26 @@
}
void PhaseCFG::dump_headers() {
- for( uint i = 0; i < _num_blocks; i++ ) {
- if (_blocks[i]) {
- _blocks[i]->dump_head(this);
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ if (block != NULL) {
+ block->dump_head(this);
}
}
}
-void PhaseCFG::verify( ) const {
+void PhaseCFG::verify() const {
#ifdef ASSERT
// Verify sane CFG
- for (uint i = 0; i < _num_blocks; i++) {
- Block *b = _blocks[i];
- uint cnt = b->_nodes.size();
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ uint cnt = block->_nodes.size();
uint j;
for (j = 0; j < cnt; j++) {
- Node *n = b->_nodes[j];
- assert(get_block_for_node(n) == b, "");
- if (j >= 1 && n->is_Mach() &&
- n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
- assert(j == 1 || b->_nodes[j-1]->is_Phi(),
- "CreateEx must be first instruction in block");
+ Node *n = block->_nodes[j];
+ assert(get_block_for_node(n) == block, "");
+ if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
+ assert(j == 1 || block->_nodes[j-1]->is_Phi(), "CreateEx must be first instruction in block");
}
for (uint k = 0; k < n->req(); k++) {
Node *def = n->in(k);
@@ -926,8 +911,7 @@
// Uses must follow their definition if they are at the same block.
// Mostly done to check that MachSpillCopy nodes are placed correctly
// when CreateEx node is moved in build_ifg_physical().
- if (get_block_for_node(def) == b &&
- !(b->head()->is_Loop() && n->is_Phi()) &&
+ if (get_block_for_node(def) == block && !(block->head()->is_Loop() && n->is_Phi()) &&
// See (+++) comment in reg_split.cpp
!(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) {
bool is_loop = false;
@@ -939,29 +923,29 @@
}
}
}
- assert(is_loop || b->find_node(def) < j, "uses must follow definitions");
+ assert(is_loop || block->find_node(def) < j, "uses must follow definitions");
}
}
}
}
- j = b->end_idx();
- Node *bp = (Node*)b->_nodes[b->_nodes.size()-1]->is_block_proj();
- assert( bp, "last instruction must be a block proj" );
- assert( bp == b->_nodes[j], "wrong number of successors for this block" );
+ j = block->end_idx();
+ Node* bp = (Node*)block->_nodes[block->_nodes.size() - 1]->is_block_proj();
+ assert(bp, "last instruction must be a block proj");
+ assert(bp == block->_nodes[j], "wrong number of successors for this block");
if (bp->is_Catch()) {
- while (b->_nodes[--j]->is_MachProj()) ;
- assert(b->_nodes[j]->is_MachCall(), "CatchProj must follow call");
+ while (block->_nodes[--j]->is_MachProj()) {
+ ;
+ }
+ assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call");
} else if (bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If) {
- assert(b->_num_succs == 2, "Conditional branch must have two targets");
+ assert(block->_num_succs == 2, "Conditional branch must have two targets");
}
}
#endif
}
#endif
-//=============================================================================
-//------------------------------UnionFind--------------------------------------
UnionFind::UnionFind( uint max ) : _cnt(max), _max(max), _indices(NEW_RESOURCE_ARRAY(uint,max)) {
Copy::zero_to_bytes( _indices, sizeof(uint)*max );
}
@@ -986,7 +970,6 @@
for( uint i=0; i<max; i++ ) map(i,i);
}
-//------------------------------Find_compress----------------------------------
// Straight out of Tarjan's union-find algorithm
uint UnionFind::Find_compress( uint idx ) {
uint cur = idx;
@@ -1006,7 +989,6 @@
return idx;
}
-//------------------------------Find_const-------------------------------------
// Like Find above, but no path compress, so bad asymptotic behavior
uint UnionFind::Find_const( uint idx ) const {
if( idx == 0 ) return idx; // Ignore the zero idx
@@ -1021,7 +1003,6 @@
return next;
}
-//------------------------------Union------------------------------------------
// union 2 sets together.
void UnionFind::Union( uint idx1, uint idx2 ) {
uint src = Find(idx1);
@@ -1070,9 +1051,6 @@
}
#endif
-//=============================================================================
-
-//------------------------------edge_order-------------------------------------
// Comparison function for edges
static int edge_order(CFGEdge **e0, CFGEdge **e1) {
float freq0 = (*e0)->freq();
@@ -1087,7 +1065,6 @@
return dist1 - dist0;
}
-//------------------------------trace_frequency_order--------------------------
// Comparison function for edges
extern "C" int trace_frequency_order(const void *p0, const void *p1) {
Trace *tr0 = *(Trace **) p0;
@@ -1113,17 +1090,15 @@
return diff;
}
-//------------------------------find_edges-------------------------------------
// Find edges of interest, i.e, those which can fall through. Presumes that
// edges which don't fall through are of low frequency and can be generally
// ignored. Initialize the list of traces.
-void PhaseBlockLayout::find_edges()
-{
+void PhaseBlockLayout::find_edges() {
// Walk the blocks, creating edges and Traces
uint i;
Trace *tr = NULL;
- for (i = 0; i < _cfg._num_blocks; i++) {
- Block *b = _cfg._blocks[i];
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* b = _cfg.get_block(i);
tr = new Trace(b, next, prev);
traces[tr->id()] = tr;
@@ -1147,7 +1122,7 @@
if (n->num_preds() != 1) break;
i++;
- assert(n = _cfg._blocks[i], "expecting next block");
+ assert(n = _cfg.get_block(i), "expecting next block");
tr->append(n);
uf->map(n->_pre_order, tr->id());
traces[n->_pre_order] = NULL;
@@ -1171,8 +1146,8 @@
}
// Group connector blocks into one trace
- for (i++; i < _cfg._num_blocks; i++) {
- Block *b = _cfg._blocks[i];
+ for (i++; i < _cfg.number_of_blocks(); i++) {
+ Block *b = _cfg.get_block(i);
assert(b->is_connector(), "connector blocks at the end");
tr->append(b);
uf->map(b->_pre_order, tr->id());
@@ -1180,10 +1155,8 @@
}
}
-//------------------------------union_traces----------------------------------
// Union two traces together in uf, and null out the trace in the list
-void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
-{
+void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace) {
uint old_id = old_trace->id();
uint updated_id = updated_trace->id();
@@ -1207,10 +1180,8 @@
traces[hi_id] = NULL;
}
-//------------------------------grow_traces-------------------------------------
// Append traces together via the most frequently executed edges
-void PhaseBlockLayout::grow_traces()
-{
+void PhaseBlockLayout::grow_traces() {
// Order the edges, and drive the growth of Traces via the most
// frequently executed edges.
edges->sort(edge_order);
@@ -1252,11 +1223,9 @@
}
}
-//------------------------------merge_traces-----------------------------------
// Embed one trace into another, if the fork or join points are sufficiently
// balanced.
-void PhaseBlockLayout::merge_traces(bool fall_thru_only)
-{
+void PhaseBlockLayout::merge_traces(bool fall_thru_only) {
// Walk the edge list a another time, looking at unprocessed edges.
// Fold in diamonds
for (int i = 0; i < edges->length(); i++) {
@@ -1310,7 +1279,7 @@
src_trace->insert_after(src_block, targ_trace);
union_traces(src_trace, targ_trace);
} else if (src_at_tail) {
- if (src_trace != trace(_cfg._broot)) {
+ if (src_trace != trace(_cfg.get_root_block())) {
e->set_state(CFGEdge::connected);
targ_trace->insert_before(targ_block, src_trace);
union_traces(targ_trace, src_trace);
@@ -1319,7 +1288,7 @@
} else if (e->state() == CFGEdge::open) {
// Append traces, even without a fall-thru connection.
// But leave root entry at the beginning of the block list.
- if (targ_trace != trace(_cfg._broot)) {
+ if (targ_trace != trace(_cfg.get_root_block())) {
e->set_state(CFGEdge::connected);
src_trace->append(targ_trace);
union_traces(src_trace, targ_trace);
@@ -1328,11 +1297,9 @@
}
}
-//----------------------------reorder_traces-----------------------------------
// Order the sequence of the traces in some desirable way, and fixup the
// jumps at the end of each block.
-void PhaseBlockLayout::reorder_traces(int count)
-{
+void PhaseBlockLayout::reorder_traces(int count) {
ResourceArea *area = Thread::current()->resource_area();
Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
Block_List worklist;
@@ -1347,15 +1314,14 @@
}
// The entry block should be first on the new trace list.
- Trace *tr = trace(_cfg._broot);
+ Trace *tr = trace(_cfg.get_root_block());
assert(tr == new_traces[0], "entry trace misplaced");
// Sort the new trace list by frequency
qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);
// Patch up the successor blocks
- _cfg._blocks.reset();
- _cfg._num_blocks = 0;
+ _cfg.clear_blocks();
for (int i = 0; i < new_count; i++) {
Trace *tr = new_traces[i];
if (tr != NULL) {
@@ -1364,17 +1330,15 @@
}
}
-//------------------------------PhaseBlockLayout-------------------------------
// Order basic blocks based on frequency
-PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
- Phase(BlockLayout),
- _cfg(cfg)
-{
+PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg)
+: Phase(BlockLayout)
+, _cfg(cfg) {
ResourceMark rm;
ResourceArea *area = Thread::current()->resource_area();
// List of traces
- int size = _cfg._num_blocks + 1;
+ int size = _cfg.number_of_blocks() + 1;
traces = NEW_ARENA_ARRAY(area, Trace *, size);
memset(traces, 0, size*sizeof(Trace*));
next = NEW_ARENA_ARRAY(area, Block *, size);
@@ -1407,11 +1371,10 @@
// Re-order all the remaining traces by frequency
reorder_traces(size);
- assert(_cfg._num_blocks >= (uint) (size - 1), "number of blocks can not shrink");
+ assert(_cfg.number_of_blocks() >= (uint) (size - 1), "number of blocks can not shrink");
}
-//------------------------------backedge---------------------------------------
// Edge e completes a loop in a trace. If the target block is head of the
// loop, rotate the loop block so that the loop ends in a conditional branch.
bool Trace::backedge(CFGEdge *e) {
@@ -1463,14 +1426,12 @@
return loop_rotated;
}
-//------------------------------fixup_blocks-----------------------------------
// push blocks onto the CFG list
// ensure that blocks have the correct two-way branch sense
void Trace::fixup_blocks(PhaseCFG &cfg) {
Block *last = last_block();
for (Block *b = first_block(); b != NULL; b = next(b)) {
- cfg._blocks.push(b);
- cfg._num_blocks++;
+ cfg.add_block(b);
if (!b->is_connector()) {
int nfallthru = b->num_fall_throughs();
if (b != last) {
--- a/hotspot/src/share/vm/opto/block.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/block.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -348,20 +348,77 @@
class PhaseCFG : public Phase {
friend class VMStructs;
private:
+
+ // Root of whole program
+ RootNode* _root;
+
+ // The block containing the root node
+ Block* _root_block;
+
+ // List of basic blocks that are created during CFG creation
+ Block_List _blocks;
+
+ // Count of basic blocks
+ uint _number_of_blocks;
+
// Arena for the blocks to be stored in
Arena* _block_arena;
+ // The matcher for this compilation
+ Matcher& _matcher;
+
// Map nodes to owning basic block
Block_Array _node_to_block_mapping;
+ // Loop from the root
+ CFGLoop* _root_loop;
+
+ // Outmost loop frequency
+ float _outer_loop_frequency;
+
+ // Per node latency estimation, valid only during GCM
+ GrowableArray<uint>* _node_latency;
+
// Build a proper looking cfg. Return count of basic blocks
uint build_cfg();
- // Perform DFS search.
+ // Build the dominator tree so that we know where we can move instructions
+ void build_dominator_tree();
+
+ // Estimate block frequencies based on IfNode probabilities, so that we know where we want to move instructions
+ void estimate_block_frequency();
+
+ // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
+ // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block.
+ // Move nodes to ensure correctness from GVN and also try to move nodes out of loops.
+ void global_code_motion();
+
+ // Schedule Nodes early in their basic blocks.
+ bool schedule_early(VectorSet &visited, Node_List &roots);
+
+ // For each node, find the latest block it can be scheduled into
+ // and then select the cheapest block between the latest and earliest
+ // block to place the node.
+ void schedule_late(VectorSet &visited, Node_List &stack);
+
+ // Compute the (backwards) latency of a node from a single use
+ int latency_from_use(Node *n, const Node *def, Node *use);
+
+ // Compute the (backwards) latency of a node from the uses of this instruction
+ void partial_latency_of_defs(Node *n);
+
+ // Compute the instruction global latency with a backwards walk
+ void compute_latencies_backwards(VectorSet &visited, Node_List &stack);
+
+ // Pick a block between early and late that is a cheaper alternative
+ // to late. Helper for schedule_late.
+ Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
+
+ // Perform a Depth First Search (DFS).
// Setup 'vertex' as DFS to vertex mapping.
// Setup 'semi' as vertex to DFS mapping.
// Set 'parent' to DFS parent.
- uint DFS( Tarjan *tarjan );
+ uint do_DFS(Tarjan* tarjan, uint rpo_counter);
// Helper function to insert a node into a block
void schedule_node_into_block( Node *n, Block *b );
@@ -372,7 +429,8 @@
void schedule_pinned_nodes( VectorSet &visited );
// I'll need a few machine-specific GotoNodes. Clone from this one.
- MachNode *_goto;
+ // Used when building the CFG and creating end nodes for blocks.
+ MachNode* _goto;
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
void verify_anti_dependences(Block* LCA, Node* load) {
@@ -380,17 +438,77 @@
insert_anti_dependences(LCA, load, true);
}
+ bool move_to_next(Block* bx, uint b_index);
+ void move_to_end(Block* bx, uint b_index);
+
+ void insert_goto_at(uint block_no, uint succ_no);
+
+ // Check for NeverBranch at block end. This needs to become a GOTO to the
+ // true target. NeverBranch are treated as a conditional branch that always
+ // goes the same direction for most of the optimizer and are used to give a
+ // fake exit path to infinite loops. At this late stage they need to turn
+ // into Goto's so that when you enter the infinite loop you indeed hang.
+ void convert_NeverBranch_to_Goto(Block *b);
+
+ CFGLoop* create_loop_tree();
+
+ #ifndef PRODUCT
+ bool _trace_opto_pipelining; // tracing flag
+ #endif
+
public:
PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher);
- uint _num_blocks; // Count of basic blocks
- Block_List _blocks; // List of basic blocks
- RootNode *_root; // Root of whole program
- Block *_broot; // Basic block of root
- uint _rpo_ctr;
- CFGLoop* _root_loop;
- float _outer_loop_freq; // Outmost loop frequency
+ void set_latency_for_node(Node* node, int latency) {
+ _node_latency->at_put_grow(node->_idx, latency);
+ }
+
+ uint get_latency_for_node(Node* node) {
+ return _node_latency->at_grow(node->_idx);
+ }
+
+ // Get the outer most frequency
+ float get_outer_loop_frequency() const {
+ return _outer_loop_frequency;
+ }
+
+ // Get the root node of the CFG
+ RootNode* get_root_node() const {
+ return _root;
+ }
+
+ // Get the block of the root node
+ Block* get_root_block() const {
+ return _root_block;
+ }
+ // Add a block at a position and moves the later ones one step
+ void add_block_at(uint pos, Block* block) {
+ _blocks.insert(pos, block);
+ _number_of_blocks++;
+ }
+
+ // Adds a block to the top of the block list
+ void add_block(Block* block) {
+ _blocks.push(block);
+ _number_of_blocks++;
+ }
+
+ // Clear the list of blocks
+ void clear_blocks() {
+ _blocks.reset();
+ _number_of_blocks = 0;
+ }
+
+ // Get the block at position pos in _blocks
+ Block* get_block(uint pos) const {
+ return _blocks[pos];
+ }
+
+ // Number of blocks
+ uint number_of_blocks() const {
+ return _number_of_blocks;
+ }
// set which block this node should reside in
void map_node_to_block(const Node* node, Block* block) {
@@ -412,72 +530,26 @@
return (_node_to_block_mapping.lookup(node->_idx) != NULL);
}
- // Per node latency estimation, valid only during GCM
- GrowableArray<uint> *_node_latency;
-
-#ifndef PRODUCT
- bool _trace_opto_pipelining; // tracing flag
-#endif
-
#ifdef ASSERT
Unique_Node_List _raw_oops;
#endif
- // Build dominators
- void Dominators();
-
- // Estimate block frequencies based on IfNode probabilities
- void Estimate_Block_Frequency();
-
- // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
- // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block.
- void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list );
+ // Do global code motion by first building dominator tree and estimate block frequency
+ // Returns true on success
+ bool do_global_code_motion();
// Compute the (backwards) latency of a node from the uses
void latency_from_uses(Node *n);
- // Compute the (backwards) latency of a node from a single use
- int latency_from_use(Node *n, const Node *def, Node *use);
-
- // Compute the (backwards) latency of a node from the uses of this instruction
- void partial_latency_of_defs(Node *n);
-
- // Schedule Nodes early in their basic blocks.
- bool schedule_early(VectorSet &visited, Node_List &roots);
-
- // For each node, find the latest block it can be scheduled into
- // and then select the cheapest block between the latest and earliest
- // block to place the node.
- void schedule_late(VectorSet &visited, Node_List &stack);
-
- // Pick a block between early and late that is a cheaper alternative
- // to late. Helper for schedule_late.
- Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
-
- // Compute the instruction global latency with a backwards walk
- void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
-
// Set loop alignment
void set_loop_alignment();
// Remove empty basic blocks
- void remove_empty();
+ void remove_empty_blocks();
void fixup_flow();
- bool move_to_next(Block* bx, uint b_index);
- void move_to_end(Block* bx, uint b_index);
- void insert_goto_at(uint block_no, uint succ_no);
- // Check for NeverBranch at block end. This needs to become a GOTO to the
- // true target. NeverBranch are treated as a conditional branch that always
- // goes the same direction for most of the optimizer and are used to give a
- // fake exit path to infinite loops. At this late stage they need to turn
- // into Goto's so that when you enter the infinite loop you indeed hang.
- void convert_NeverBranch_to_Goto(Block *b);
-
- CFGLoop* create_loop_tree();
-
- // Insert a node into a block, and update the _bbs
- void insert( Block *b, uint idx, Node *n ) {
+ // Insert a node into a block at index and map the node to the block
+ void insert(Block *b, uint idx, Node *n) {
b->_nodes.insert( idx, n );
map_node_to_block(n, b);
}
--- a/hotspot/src/share/vm/opto/buildOopMap.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/buildOopMap.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -87,7 +87,6 @@
// OptoReg::Bad for not-callee-saved.
-//------------------------------OopFlow----------------------------------------
// Structure to pass around
struct OopFlow : public ResourceObj {
short *_callees; // Array mapping register to callee-saved
@@ -119,7 +118,6 @@
OopMap *build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live );
};
-//------------------------------compute_reach----------------------------------
// Given reaching-defs for this block start, compute it for this block end
void OopFlow::compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehash ) {
@@ -177,7 +175,6 @@
}
}
-//------------------------------merge------------------------------------------
// Merge the given flow into the 'this' flow
void OopFlow::merge( OopFlow *flow, int max_reg ) {
assert( _b == NULL, "merging into a happy flow" );
@@ -197,14 +194,12 @@
}
-//------------------------------clone------------------------------------------
void OopFlow::clone( OopFlow *flow, int max_size ) {
_b = flow->_b;
memcpy( _callees, flow->_callees, sizeof(short)*max_size);
memcpy( _defs , flow->_defs , sizeof(Node*)*max_size);
}
-//------------------------------make-------------------------------------------
OopFlow *OopFlow::make( Arena *A, int max_size, Compile* C ) {
short *callees = NEW_ARENA_ARRAY(A,short,max_size+1);
Node **defs = NEW_ARENA_ARRAY(A,Node*,max_size+1);
@@ -215,7 +210,6 @@
return flow;
}
-//------------------------------bit twiddlers----------------------------------
static int get_live_bit( int *live, int reg ) {
return live[reg>>LogBitsPerInt] & (1<<(reg&(BitsPerInt-1))); }
static void set_live_bit( int *live, int reg ) {
@@ -223,7 +217,6 @@
static void clr_live_bit( int *live, int reg ) {
live[reg>>LogBitsPerInt] &= ~(1<<(reg&(BitsPerInt-1))); }
-//------------------------------build_oop_map----------------------------------
// Build an oopmap from the current flow info
OopMap *OopFlow::build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live ) {
int framesize = regalloc->_framesize;
@@ -412,19 +405,18 @@
return omap;
}
-//------------------------------do_liveness------------------------------------
// Compute backwards liveness on registers
-static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *worklist, int max_reg_ints, Arena *A, Dict *safehash ) {
- int *live = NEW_ARENA_ARRAY(A, int, (cfg->_num_blocks+1) * max_reg_ints);
- int *tmp_live = &live[cfg->_num_blocks * max_reg_ints];
- Node *root = cfg->C->root();
+static void do_liveness(PhaseRegAlloc* regalloc, PhaseCFG* cfg, Block_List* worklist, int max_reg_ints, Arena* A, Dict* safehash) {
+ int* live = NEW_ARENA_ARRAY(A, int, (cfg->number_of_blocks() + 1) * max_reg_ints);
+ int* tmp_live = &live[cfg->number_of_blocks() * max_reg_ints];
+ Node* root = cfg->get_root_node();
// On CISC platforms, get the node representing the stack pointer that regalloc
// used for spills
Node *fp = NodeSentinel;
if (UseCISCSpill && root->req() > 1) {
fp = root->in(1)->in(TypeFunc::FramePtr);
}
- memset( live, 0, cfg->_num_blocks * (max_reg_ints<<LogBytesPerInt) );
+ memset(live, 0, cfg->number_of_blocks() * (max_reg_ints << LogBytesPerInt));
// Push preds onto worklist
for (uint i = 1; i < root->req(); i++) {
Block* block = cfg->get_block_for_node(root->in(i));
@@ -549,29 +541,32 @@
// Scan for any missing safepoints. Happens to infinite loops
// ala ZKM.jar
uint i;
- for( i=1; i<cfg->_num_blocks; i++ ) {
- Block *b = cfg->_blocks[i];
+ for (i = 1; i < cfg->number_of_blocks(); i++) {
+ Block* block = cfg->get_block(i);
uint j;
- for( j=1; j<b->_nodes.size(); j++ )
- if( b->_nodes[j]->jvms() &&
- (*safehash)[b->_nodes[j]] == NULL )
+ for (j = 1; j < block->_nodes.size(); j++) {
+ if (block->_nodes[j]->jvms() && (*safehash)[block->_nodes[j]] == NULL) {
break;
- if( j<b->_nodes.size() ) break;
+ }
+ }
+ if (j < block->_nodes.size()) {
+ break;
+ }
}
- if( i == cfg->_num_blocks )
+ if (i == cfg->number_of_blocks()) {
break; // Got 'em all
+ }
#ifndef PRODUCT
if( PrintOpto && Verbose )
tty->print_cr("retripping live calc");
#endif
// Force the issue (expensively): recheck everybody
- for( i=1; i<cfg->_num_blocks; i++ )
- worklist->push(cfg->_blocks[i]);
+ for (i = 1; i < cfg->number_of_blocks(); i++) {
+ worklist->push(cfg->get_block(i));
+ }
}
-
}
-//------------------------------BuildOopMaps-----------------------------------
// Collect GC mask info - where are all the OOPs?
void Compile::BuildOopMaps() {
NOT_PRODUCT( TracePhase t3("bldOopMaps", &_t_buildOopMaps, TimeCompiler); )
@@ -592,12 +587,12 @@
OopFlow *free_list = NULL; // Free, unused
// Array mapping blocks to completed oopflows
- OopFlow **flows = NEW_ARENA_ARRAY(A, OopFlow*, _cfg->_num_blocks);
- memset( flows, 0, _cfg->_num_blocks*sizeof(OopFlow*) );
+ OopFlow **flows = NEW_ARENA_ARRAY(A, OopFlow*, _cfg->number_of_blocks());
+ memset( flows, 0, _cfg->number_of_blocks() * sizeof(OopFlow*) );
// Do the first block 'by hand' to prime the worklist
- Block *entry = _cfg->_blocks[1];
+ Block *entry = _cfg->get_block(1);
OopFlow *rootflow = OopFlow::make(A,max_reg,this);
// Initialize to 'bottom' (not 'top')
memset( rootflow->_callees, OptoReg::Bad, max_reg*sizeof(short) );
@@ -623,7 +618,9 @@
Block *b = worklist.pop();
// Ignore root block
- if( b == _cfg->_broot ) continue;
+ if (b == _cfg->get_root_block()) {
+ continue;
+ }
// Block is already done? Happens if block has several predecessors,
// he can get on the worklist more than once.
if( flows[b->_pre_order] ) continue;
--- a/hotspot/src/share/vm/opto/chaitin.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -40,10 +40,8 @@
#include "opto/opcodes.hpp"
#include "opto/rootnode.hpp"
-//=============================================================================
-
#ifndef PRODUCT
-void LRG::dump( ) const {
+void LRG::dump() const {
ttyLocker ttyl;
tty->print("%d ",num_regs());
_mask.dump();
@@ -94,7 +92,6 @@
}
#endif
-//------------------------------score------------------------------------------
// Compute score from cost and area. Low score is best to spill.
static double raw_score( double cost, double area ) {
return cost - (area*RegisterCostAreaRatio) * 1.52588e-5;
@@ -125,7 +122,6 @@
return score;
}
-//------------------------------LRG_List---------------------------------------
LRG_List::LRG_List( uint max ) : _cnt(max), _max(max), _lidxs(NEW_RESOURCE_ARRAY(uint,max)) {
memset( _lidxs, 0, sizeof(uint)*max );
}
@@ -211,7 +207,6 @@
return next;
}
-//------------------------------Chaitin----------------------------------------
PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
: PhaseRegAlloc(unique, cfg, matcher,
#ifndef PRODUCT
@@ -232,31 +227,31 @@
{
NOT_PRODUCT( Compile::TracePhase t3("ctorChaitin", &_t_ctorChaitin, TimeCompiler); )
- _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg._outer_loop_freq);
+ _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency());
// Build a list of basic blocks, sorted by frequency
- _blks = NEW_RESOURCE_ARRAY( Block *, _cfg._num_blocks );
+ _blks = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
// Experiment with sorting strategies to speed compilation
double cutoff = BLOCK_FREQUENCY(1.0); // Cutoff for high frequency bucket
Block **buckets[NUMBUCKS]; // Array of buckets
uint buckcnt[NUMBUCKS]; // Array of bucket counters
double buckval[NUMBUCKS]; // Array of bucket value cutoffs
for (uint i = 0; i < NUMBUCKS; i++) {
- buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg._num_blocks);
+ buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
buckcnt[i] = 0;
// Bump by three orders of magnitude each time
cutoff *= 0.001;
buckval[i] = cutoff;
- for (uint j = 0; j < _cfg._num_blocks; j++) {
+ for (uint j = 0; j < _cfg.number_of_blocks(); j++) {
buckets[i][j] = NULL;
}
}
// Sort blocks into buckets
- for (uint i = 0; i < _cfg._num_blocks; i++) {
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
for (uint j = 0; j < NUMBUCKS; j++) {
- if ((j == NUMBUCKS - 1) || (_cfg._blocks[i]->_freq > buckval[j])) {
+ if ((j == NUMBUCKS - 1) || (_cfg.get_block(i)->_freq > buckval[j])) {
// Assign block to end of list for appropriate bucket
- buckets[j][buckcnt[j]++] = _cfg._blocks[i];
+ buckets[j][buckcnt[j]++] = _cfg.get_block(i);
break; // kick out of inner loop
}
}
@@ -269,10 +264,9 @@
}
}
- assert(blkcnt == _cfg._num_blocks, "Block array not totally filled");
+ assert(blkcnt == _cfg.number_of_blocks(), "Block array not totally filled");
}
-//------------------------------Union------------------------------------------
// union 2 sets together.
void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
uint src = _lrg_map.find(src_n);
@@ -285,7 +279,6 @@
_lrg_map.uf_map(dst, src);
}
-//------------------------------new_lrg----------------------------------------
void PhaseChaitin::new_lrg(const Node *x, uint lrg) {
// Make the Node->LRG mapping
_lrg_map.extend(x->_idx,lrg);
@@ -294,24 +287,28 @@
}
-bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) {
- Block* bcon = _cfg.get_block_for_node(con);
- uint cindex = bcon->find_node(con);
- Node *con_next = bcon->_nodes[cindex+1];
- if (con_next->in(0) != con || !con_next->is_MachProj()) {
- return false; // No MachProj's follow
+int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) {
+ assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections");
+ DEBUG_ONLY( Block* borig = _cfg.get_block_for_node(orig); )
+ int found_projs = 0;
+ uint cnt = orig->outcnt();
+ for (uint i = 0; i < cnt; i++) {
+ Node* proj = orig->raw_out(i);
+ if (proj->is_MachProj()) {
+ assert(proj->outcnt() == 0, "only kill projections are expected here");
+ assert(_cfg.get_block_for_node(proj) == borig, "incorrect block for kill projections");
+ found_projs++;
+ // Copy kill projections after the cloned node
+ Node* kills = proj->clone();
+ kills->set_req(0, copy);
+ b->_nodes.insert(idx++, kills);
+ _cfg.map_node_to_block(kills, b);
+ new_lrg(kills, max_lrg_id++);
+ }
}
-
- // Copy kills after the cloned constant
- Node *kills = con_next->clone();
- kills->set_req(0, copy);
- b->_nodes.insert(idx, kills);
- _cfg.map_node_to_block(kills, b);
- new_lrg(kills, max_lrg_id);
- return true;
+ return found_projs;
}
-//------------------------------compact----------------------------------------
// Renumber the live ranges to compact them. Makes the IFG smaller.
void PhaseChaitin::compact() {
// Current the _uf_map contains a series of short chains which are headed
@@ -677,20 +674,19 @@
C->set_indexSet_arena(NULL); // ResourceArea is at end of scope
}
-//------------------------------de_ssa-----------------------------------------
void PhaseChaitin::de_ssa() {
// Set initial Names for all Nodes. Most Nodes get the virtual register
// number. A few get the ZERO live range number. These do not
// get allocated, but instead rely on correct scheduling to ensure that
// only one instance is simultaneously live at a time.
uint lr_counter = 1;
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- uint cnt = b->_nodes.size();
+ for( uint i = 0; i < _cfg.number_of_blocks(); i++ ) {
+ Block* block = _cfg.get_block(i);
+ uint cnt = block->_nodes.size();
// Handle all the normal Nodes in the block
for( uint j = 0; j < cnt; j++ ) {
- Node *n = b->_nodes[j];
+ Node *n = block->_nodes[j];
// Pre-color to the zero live range, or pick virtual register
const RegMask &rm = n->out_RegMask();
_lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0);
@@ -701,52 +697,55 @@
}
-//------------------------------gather_lrg_masks-------------------------------
// Gather LiveRanGe information, including register masks. Modification of
// cisc spillable in_RegMasks should not be done before AggressiveCoalesce.
void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
// Nail down the frame pointer live range
- uint fp_lrg = _lrg_map.live_range_id(_cfg._root->in(1)->in(TypeFunc::FramePtr));
+ uint fp_lrg = _lrg_map.live_range_id(_cfg.get_root_node()->in(1)->in(TypeFunc::FramePtr));
lrgs(fp_lrg)._cost += 1e12; // Cost is infinite
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// For all instructions
- for( uint j = 1; j < b->_nodes.size(); j++ ) {
- Node *n = b->_nodes[j];
+ for (uint j = 1; j < block->_nodes.size(); j++) {
+ Node* n = block->_nodes[j];
uint input_edge_start =1; // Skip control most nodes
- if( n->is_Mach() ) input_edge_start = n->as_Mach()->oper_input_base();
+ if (n->is_Mach()) {
+ input_edge_start = n->as_Mach()->oper_input_base();
+ }
uint idx = n->is_Copy();
// Get virtual register number, same as LiveRanGe index
uint vreg = _lrg_map.live_range_id(n);
- LRG &lrg = lrgs(vreg);
- if( vreg ) { // No vreg means un-allocable (e.g. memory)
+ LRG& lrg = lrgs(vreg);
+ if (vreg) { // No vreg means un-allocable (e.g. memory)
// Collect has-copy bit
- if( idx ) {
+ if (idx) {
lrg._has_copy = 1;
uint clidx = _lrg_map.live_range_id(n->in(idx));
- LRG ©_src = lrgs(clidx);
+ LRG& copy_src = lrgs(clidx);
copy_src._has_copy = 1;
}
// Check for float-vs-int live range (used in register-pressure
// calculations)
const Type *n_type = n->bottom_type();
- if (n_type->is_floatingpoint())
+ if (n_type->is_floatingpoint()) {
lrg._is_float = 1;
+ }
// Check for twice prior spilling. Once prior spilling might have
// spilled 'soft', 2nd prior spill should have spilled 'hard' and
// further spilling is unlikely to make progress.
- if( _spilled_once.test(n->_idx) ) {
+ if (_spilled_once.test(n->_idx)) {
lrg._was_spilled1 = 1;
- if( _spilled_twice.test(n->_idx) )
+ if (_spilled_twice.test(n->_idx)) {
lrg._was_spilled2 = 1;
+ }
}
#ifndef PRODUCT
@@ -783,16 +782,18 @@
// Check for bound register masks
const RegMask &lrgmask = lrg.mask();
- if (lrgmask.is_bound(ireg))
+ if (lrgmask.is_bound(ireg)) {
lrg._is_bound = 1;
+ }
// Check for maximum frequency value
- if (lrg._maxfreq < b->_freq)
- lrg._maxfreq = b->_freq;
+ if (lrg._maxfreq < block->_freq) {
+ lrg._maxfreq = block->_freq;
+ }
// Check for oop-iness, or long/double
// Check for multi-kill projection
- switch( ireg ) {
+ switch (ireg) {
case MachProjNode::fat_proj:
// Fat projections have size equal to number of registers killed
lrg.set_num_regs(rm.Size());
@@ -962,7 +963,7 @@
// AggressiveCoalesce. This effectively pre-virtual-splits
// around uncommon uses of common defs.
const RegMask &rm = n->in_RegMask(k);
- if (!after_aggressive && _cfg.get_block_for_node(n->in(k))->_freq > 1000 * b->_freq) {
+ if (!after_aggressive && _cfg.get_block_for_node(n->in(k))->_freq > 1000 * block->_freq) {
// Since we are BEFORE aggressive coalesce, leave the register
// mask untrimmed by the call. This encourages more coalescing.
// Later, AFTER aggressive, this live range will have to spill
@@ -1006,8 +1007,9 @@
}
// Check for maximum frequency value
- if( lrg._maxfreq < b->_freq )
- lrg._maxfreq = b->_freq;
+ if (lrg._maxfreq < block->_freq) {
+ lrg._maxfreq = block->_freq;
+ }
} // End for all allocated inputs
} // end for all instructions
@@ -1029,7 +1031,6 @@
}
}
-//------------------------------set_was_low------------------------------------
// Set the was-lo-degree bit. Conservative coalescing should not change the
// colorability of the graph. If any live range was of low-degree before
// coalescing, it should Simplify. This call sets the was-lo-degree bit.
@@ -1066,7 +1067,6 @@
#define REGISTER_CONSTRAINED 16
-//------------------------------cache_lrg_info---------------------------------
// Compute cost/area ratio, in case we spill. Build the lo-degree list.
void PhaseChaitin::cache_lrg_info( ) {
@@ -1100,7 +1100,6 @@
}
}
-//------------------------------Pre-Simplify-----------------------------------
// Simplify the IFG by removing LRGs of low degree that have NO copies
void PhaseChaitin::Pre_Simplify( ) {
@@ -1151,7 +1150,6 @@
// No more lo-degree no-copy live ranges to simplify
}
-//------------------------------Simplify---------------------------------------
// Simplify the IFG by removing LRGs of low degree.
void PhaseChaitin::Simplify( ) {
@@ -1288,7 +1286,6 @@
}
-//------------------------------is_legal_reg-----------------------------------
// Is 'reg' register legal for 'lrg'?
static bool is_legal_reg(LRG &lrg, OptoReg::Name reg, int chunk) {
if (reg >= chunk && reg < (chunk + RegMask::CHUNK_SIZE) &&
@@ -1315,7 +1312,6 @@
return false;
}
-//------------------------------bias_color-------------------------------------
// Choose a color using the biasing heuristic
OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
@@ -1377,7 +1373,6 @@
return OptoReg::add( reg, chunk );
}
-//------------------------------choose_color-----------------------------------
// Choose a color in the current chunk
OptoReg::Name PhaseChaitin::choose_color( LRG &lrg, int chunk ) {
assert( C->in_preserve_stack_slots() == 0 || chunk != 0 || lrg._is_bound || lrg.mask().is_bound1() || !lrg.mask().Member(OptoReg::Name(_matcher._old_SP-1)), "must not allocate stack0 (inside preserve area)");
@@ -1399,7 +1394,6 @@
return lrg.mask().find_last_elem();
}
-//------------------------------Select-----------------------------------------
// Select colors by re-inserting LRGs back into the IFG. LRGs are re-inserted
// in reverse order of removal. As long as nothing of hi-degree was yanked,
// everything going back is guaranteed a color. Select that color. If some
@@ -1574,8 +1568,6 @@
return spill_reg-LRG::SPILL_REG; // Return number of spills
}
-
-//------------------------------copy_was_spilled-------------------------------
// Copy 'was_spilled'-edness from the source Node to the dst Node.
void PhaseChaitin::copy_was_spilled( Node *src, Node *dst ) {
if( _spilled_once.test(src->_idx) ) {
@@ -1588,14 +1580,12 @@
}
}
-//------------------------------set_was_spilled--------------------------------
// Set the 'spilled_once' or 'spilled_twice' flag on a node.
void PhaseChaitin::set_was_spilled( Node *n ) {
if( _spilled_once.test_set(n->_idx) )
_spilled_twice.set(n->_idx);
}
-//------------------------------fixup_spills-----------------------------------
// Convert Ideal spill instructions into proper FramePtr + offset Loads and
// Stores. Use-def chains are NOT preserved, but Node->LRG->reg maps are.
void PhaseChaitin::fixup_spills() {
@@ -1605,16 +1595,16 @@
NOT_PRODUCT( Compile::TracePhase t3("fixupSpills", &_t_fixupSpills, TimeCompiler); )
// Grab the Frame Pointer
- Node *fp = _cfg._broot->head()->in(1)->in(TypeFunc::FramePtr);
+ Node *fp = _cfg.get_root_block()->head()->in(1)->in(TypeFunc::FramePtr);
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// For all instructions in block
- uint last_inst = b->end_idx();
- for( uint j = 1; j <= last_inst; j++ ) {
- Node *n = b->_nodes[j];
+ uint last_inst = block->end_idx();
+ for (uint j = 1; j <= last_inst; j++) {
+ Node* n = block->_nodes[j];
// Dead instruction???
assert( n->outcnt() != 0 ||// Nothing dead after post alloc
@@ -1651,7 +1641,7 @@
assert( cisc->oper_input_base() == 2, "Only adding one edge");
cisc->ins_req(1,src); // Requires a memory edge
}
- b->_nodes.map(j,cisc); // Insert into basic block
+ block->_nodes.map(j,cisc); // Insert into basic block
n->subsume_by(cisc, C); // Correct graph
//
++_used_cisc_instructions;
@@ -1677,7 +1667,6 @@
} // End of for all blocks
}
-//------------------------------find_base_for_derived--------------------------
// Helper to stretch above; recursively discover the base Node for a
// given derived Node. Easy for AddP-related machine nodes, but needs
// to be recursive for derived Phis.
@@ -1707,7 +1696,7 @@
// Initialize it once and make it shared:
// set control to _root and place it into Start block
// (where top() node is placed).
- base->init_req(0, _cfg._root);
+ base->init_req(0, _cfg.get_root_node());
Block *startb = _cfg.get_block_for_node(C->top());
startb->_nodes.insert(startb->find_node(C->top()), base );
_cfg.map_node_to_block(base, startb);
@@ -1716,7 +1705,7 @@
if (_lrg_map.live_range_id(base) == 0) {
new_lrg(base, maxlrg++);
}
- assert(base->in(0) == _cfg._root && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared");
+ assert(base->in(0) == _cfg.get_root_node() && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared");
derived_base_map[derived->_idx] = base;
return base;
}
@@ -1779,8 +1768,6 @@
return base;
}
-
-//------------------------------stretch_base_pointer_live_ranges---------------
// At each Safepoint, insert extra debug edges for each pair of derived value/
// base pointer that is live across the Safepoint for oopmap building. The
// edge pairs get added in after sfpt->jvmtail()->oopoff(), but are in the
@@ -1792,14 +1779,14 @@
memset( derived_base_map, 0, sizeof(Node*)*C->unique() );
// For all blocks in RPO do...
- for( uint i=0; i<_cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// Note use of deep-copy constructor. I cannot hammer the original
// liveout bits, because they are needed by the following coalesce pass.
- IndexSet liveout(_live->live(b));
+ IndexSet liveout(_live->live(block));
- for( uint j = b->end_idx() + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j-1];
+ for (uint j = block->end_idx() + 1; j > 1; j--) {
+ Node* n = block->_nodes[j - 1];
// Pre-split compares of loop-phis. Loop-phis form a cycle we would
// like to see in the same register. Compare uses the loop-phi and so
@@ -1814,7 +1801,7 @@
Node *phi = n->in(1);
if( phi->is_Phi() && phi->as_Phi()->region()->is_Loop() ) {
Block *phi_block = _cfg.get_block_for_node(phi);
- if (_cfg.get_block_for_node(phi_block->pred(2)) == b) {
+ if (_cfg.get_block_for_node(phi_block->pred(2)) == block) {
const RegMask *mask = C->matcher()->idealreg2spillmask[Op_RegI];
Node *spill = new (C) MachSpillCopyNode( phi, *mask, *mask );
insert_proj( phi_block, 1, spill, maxlrg++ );
@@ -1868,7 +1855,7 @@
if ((_lrg_map.live_range_id(base) >= _lrg_map.max_lrg_id() || // (Brand new base (hence not live) or
!liveout.member(_lrg_map.live_range_id(base))) && // not live) AND
(_lrg_map.live_range_id(base) > 0) && // not a constant
- _cfg.get_block_for_node(base) != b) { // base not def'd in blk)
+ _cfg.get_block_for_node(base) != block) { // base not def'd in blk)
// Base pointer is not currently live. Since I stretched
// the base pointer to here and it crosses basic-block
// boundaries, the global live info is now incorrect.
@@ -1903,15 +1890,12 @@
return must_recompute_live != 0;
}
-
-//------------------------------add_reference----------------------------------
// Extend the node to LRG mapping
void PhaseChaitin::add_reference(const Node *node, const Node *old_node) {
_lrg_map.extend(node->_idx, _lrg_map.live_range_id(old_node));
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void PhaseChaitin::dump(const Node *n) const {
uint r = (n->_idx < _lrg_map.size()) ? _lrg_map.find_const(n) : 0;
@@ -2017,8 +2001,9 @@
_matcher._new_SP, _framesize );
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ )
- dump(_cfg._blocks[i]);
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ dump(_cfg.get_block(i));
+ }
// End of per-block dump
tty->print("\n");
@@ -2059,7 +2044,6 @@
tty->print_cr("");
}
-//------------------------------dump_degree_lists------------------------------
void PhaseChaitin::dump_degree_lists() const {
// Dump lo-degree list
tty->print("Lo degree: ");
@@ -2080,7 +2064,6 @@
tty->print_cr("");
}
-//------------------------------dump_simplified--------------------------------
void PhaseChaitin::dump_simplified() const {
tty->print("Simplified: ");
for( uint i = _simplified; i; i = lrgs(i)._next )
@@ -2099,7 +2082,6 @@
return buf+strlen(buf);
}
-//------------------------------dump_register----------------------------------
// Dump a register name into a buffer. Be intelligent if we get called
// before allocation is complete.
char *PhaseChaitin::dump_register( const Node *n, char *buf ) const {
@@ -2133,7 +2115,6 @@
return buf+strlen(buf);
}
-//----------------------dump_for_spill_split_recycle--------------------------
void PhaseChaitin::dump_for_spill_split_recycle() const {
if( WizardMode && (PrintCompilation || PrintOpto) ) {
// Display which live ranges need to be split and the allocator's state
@@ -2149,7 +2130,6 @@
}
}
-//------------------------------dump_frame------------------------------------
void PhaseChaitin::dump_frame() const {
const char *fp = OptoReg::regname(OptoReg::c_frame_pointer);
const TypeTuple *domain = C->tf()->domain();
@@ -2255,17 +2235,16 @@
tty->print_cr("#");
}
-//------------------------------dump_bb----------------------------------------
void PhaseChaitin::dump_bb( uint pre_order ) const {
tty->print_cr("---dump of B%d---",pre_order);
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- if( b->_pre_order == pre_order )
- dump(b);
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
+ if (block->_pre_order == pre_order) {
+ dump(block);
+ }
}
}
-//------------------------------dump_lrg---------------------------------------
void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
tty->print_cr("---dump of L%d---",lidx);
@@ -2287,17 +2266,17 @@
tty->cr();
}
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
int dump_once = 0;
// For all instructions
- for( uint j = 0; j < b->_nodes.size(); j++ ) {
- Node *n = b->_nodes[j];
+ for( uint j = 0; j < block->_nodes.size(); j++ ) {
+ Node *n = block->_nodes[j];
if (_lrg_map.find_const(n) == lidx) {
if (!dump_once++) {
tty->cr();
- b->dump_head(&_cfg);
+ block->dump_head(&_cfg);
}
dump(n);
continue;
@@ -2312,7 +2291,7 @@
if (_lrg_map.find_const(m) == lidx) {
if (!dump_once++) {
tty->cr();
- b->dump_head(&_cfg);
+ block->dump_head(&_cfg);
}
dump(n);
}
@@ -2324,7 +2303,6 @@
}
#endif // not PRODUCT
-//------------------------------print_chaitin_statistics-------------------------------
int PhaseChaitin::_final_loads = 0;
int PhaseChaitin::_final_stores = 0;
int PhaseChaitin::_final_memoves= 0;
--- a/hotspot/src/share/vm/opto/chaitin.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -412,33 +412,22 @@
uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx );
uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx );
- bool clone_projs(Block *b, uint idx, Node *con, Node *copy, LiveRangeMap &lrg_map) {
- bool found_projs = clone_projs_shared(b, idx, con, copy, lrg_map.max_lrg_id());
-
- if(found_projs) {
- uint max_lrg_id = lrg_map.max_lrg_id();
- lrg_map.set_max_lrg_id(max_lrg_id + 1);
- }
-
- return found_projs;
- }
-
//------------------------------clone_projs------------------------------------
// After cloning some rematerialized instruction, clone any MachProj's that
// follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
// use G3 as an address temp.
- bool clone_projs(Block *b, uint idx, Node *con, Node *copy, uint &max_lrg_id) {
- bool found_projs = clone_projs_shared(b, idx, con, copy, max_lrg_id);
+ int clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id);
- if(found_projs) {
- max_lrg_id++;
+ int clone_projs(Block* b, uint idx, Node* orig, Node* copy, LiveRangeMap& lrg_map) {
+ uint max_lrg_id = lrg_map.max_lrg_id();
+ int found_projs = clone_projs(b, idx, orig, copy, max_lrg_id);
+ if (found_projs > 0) {
+ // max_lrg_id is updated during call above
+ lrg_map.set_max_lrg_id(max_lrg_id);
}
-
return found_projs;
}
- bool clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id);
-
Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
// True if lidx is used before any real register is def'd in the block
--- a/hotspot/src/share/vm/opto/coalesce.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/coalesce.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -34,8 +34,6 @@
#include "opto/matcher.hpp"
#include "opto/regmask.hpp"
-//=============================================================================
-//------------------------------Dump-------------------------------------------
#ifndef PRODUCT
void PhaseCoalesce::dump(Node *n) const {
// Being a const function means I cannot use 'Find'
@@ -43,12 +41,11 @@
tty->print("L%d/N%d ",r,n->_idx);
}
-//------------------------------dump-------------------------------------------
void PhaseCoalesce::dump() const {
// I know I have a block layout now, so I can print blocks in a loop
- for( uint i=0; i<_phc._cfg._num_blocks; i++ ) {
+ for( uint i=0; i<_phc._cfg.number_of_blocks(); i++ ) {
uint j;
- Block *b = _phc._cfg._blocks[i];
+ Block* b = _phc._cfg.get_block(i);
// Print a nice block header
tty->print("B%d: ",b->_pre_order);
for( j=1; j<b->num_preds(); j++ )
@@ -85,7 +82,6 @@
}
#endif
-//------------------------------combine_these_two------------------------------
// Combine the live ranges def'd by these 2 Nodes. N2 is an input to N1.
void PhaseCoalesce::combine_these_two(Node *n1, Node *n2) {
uint lr1 = _phc._lrg_map.find(n1);
@@ -127,18 +123,15 @@
}
}
-//------------------------------coalesce_driver--------------------------------
// Copy coalescing
-void PhaseCoalesce::coalesce_driver( ) {
-
+void PhaseCoalesce::coalesce_driver() {
verify();
// Coalesce from high frequency to low
- for( uint i=0; i<_phc._cfg._num_blocks; i++ )
- coalesce( _phc._blks[i] );
-
+ for (uint i = 0; i < _phc._cfg.number_of_blocks(); i++) {
+ coalesce(_phc._blks[i]);
+ }
}
-//------------------------------insert_copy_with_overlap-----------------------
// I am inserting copies to come out of SSA form. In the general case, I am
// doing a parallel renaming. I'm in the Named world now, so I can't do a
// general parallel renaming. All the copies now use "names" (live-ranges)
@@ -216,7 +209,6 @@
b->_nodes.insert(last_use_idx+1,copy);
}
-//------------------------------insert_copies----------------------------------
void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
// We do LRGs compressing and fix a liveout data only here since the other
// place in Split() is guarded by the assert which we never hit.
@@ -225,8 +217,8 @@
for (uint lrg = 1; lrg < _phc._lrg_map.max_lrg_id(); lrg++) {
uint compressed_lrg = _phc._lrg_map.find(lrg);
if (lrg != compressed_lrg) {
- for (uint bidx = 0; bidx < _phc._cfg._num_blocks; bidx++) {
- IndexSet *liveout = _phc._live->live(_phc._cfg._blocks[bidx]);
+ for (uint bidx = 0; bidx < _phc._cfg.number_of_blocks(); bidx++) {
+ IndexSet *liveout = _phc._live->live(_phc._cfg.get_block(bidx));
if (liveout->member(lrg)) {
liveout->remove(lrg);
liveout->insert(compressed_lrg);
@@ -239,10 +231,10 @@
// Nodes with index less than '_unique' are original, non-virtual Nodes.
_unique = C->unique();
- for( uint i=0; i<_phc._cfg._num_blocks; i++ ) {
+ for (uint i = 0; i < _phc._cfg.number_of_blocks(); i++) {
C->check_node_count(NodeLimitFudgeFactor, "out of nodes in coalesce");
if (C->failing()) return;
- Block *b = _phc._cfg._blocks[i];
+ Block *b = _phc._cfg.get_block(i);
uint cnt = b->num_preds(); // Number of inputs to the Phi
for( uint l = 1; l<b->_nodes.size(); l++ ) {
@@ -330,9 +322,7 @@
copy = m->clone();
// Insert the copy in the basic block, just before us
b->_nodes.insert(l++, copy);
- if(_phc.clone_projs(b, l, m, copy, _phc._lrg_map)) {
- l++;
- }
+ l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map);
} else {
const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
copy = new (C) MachSpillCopyNode(m, *rm, *rm);
@@ -403,8 +393,7 @@
} // End of for all blocks
}
-//=============================================================================
-//------------------------------coalesce---------------------------------------
+
// Aggressive (but pessimistic) copy coalescing of a single block
// The following coalesce pass represents a single round of aggressive
@@ -464,20 +453,16 @@
} // End of for all instructions in block
}
-//=============================================================================
-//------------------------------PhaseConservativeCoalesce----------------------
PhaseConservativeCoalesce::PhaseConservativeCoalesce(PhaseChaitin &chaitin) : PhaseCoalesce(chaitin) {
_ulr.initialize(_phc._lrg_map.max_lrg_id());
}
-//------------------------------verify-----------------------------------------
void PhaseConservativeCoalesce::verify() {
#ifdef ASSERT
_phc.set_was_low();
#endif
}
-//------------------------------union_helper-----------------------------------
void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, uint lr1, uint lr2, Node *src_def, Node *dst_copy, Node *src_copy, Block *b, uint bindex ) {
// Join live ranges. Merge larger into smaller. Union lr2 into lr1 in the
// union-find tree
@@ -520,7 +505,6 @@
}
}
-//------------------------------compute_separating_interferences---------------
// Factored code from copy_copy that computes extra interferences from
// lengthening a live range by double-coalescing.
uint PhaseConservativeCoalesce::compute_separating_interferences(Node *dst_copy, Node *src_copy, Block *b, uint bindex, RegMask &rm, uint reg_degree, uint rm_size, uint lr1, uint lr2 ) {
@@ -586,7 +570,6 @@
return reg_degree;
}
-//------------------------------update_ifg-------------------------------------
void PhaseConservativeCoalesce::update_ifg(uint lr1, uint lr2, IndexSet *n_lr1, IndexSet *n_lr2) {
// Some original neighbors of lr1 might have gone away
// because the constrained register mask prevented them.
@@ -616,7 +599,6 @@
lrgs(neighbor).inc_degree( lrg1.compute_degree(lrgs(neighbor)) );
}
-//------------------------------record_bias------------------------------------
static void record_bias( const PhaseIFG *ifg, int lr1, int lr2 ) {
// Tag copy bias here
if( !ifg->lrgs(lr1)._copy_bias )
@@ -625,7 +607,6 @@
ifg->lrgs(lr2)._copy_bias = lr1;
}
-//------------------------------copy_copy--------------------------------------
// See if I can coalesce a series of multiple copies together. I need the
// final dest copy and the original src copy. They can be the same Node.
// Compute the compatible register masks.
@@ -785,7 +766,6 @@
return true;
}
-//------------------------------coalesce---------------------------------------
// Conservative (but pessimistic) copy coalescing of a single block
void PhaseConservativeCoalesce::coalesce( Block *b ) {
// Bail out on infrequent blocks
--- a/hotspot/src/share/vm/opto/compile.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -2136,7 +2136,9 @@
//------------------------------Code_Gen---------------------------------------
// Given a graph, generate code for it
void Compile::Code_Gen() {
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
// Perform instruction selection. You might think we could reclaim Matcher
// memory PDQ, but actually the Matcher is used in generating spill code.
@@ -2148,12 +2150,11 @@
// nodes. Mapping is only valid at the root of each matched subtree.
NOT_PRODUCT( verify_graph_edges(); )
- Node_List proj_list;
- Matcher m(proj_list);
- _matcher = &m;
+ Matcher matcher;
+ _matcher = &matcher;
{
TracePhase t2("matcher", &_t_matcher, true);
- m.match();
+ matcher.match();
}
// In debug mode can dump m._nodes.dump() for mapping of ideal to machine
// nodes. Mapping is only valid at the root of each matched subtree.
@@ -2161,31 +2162,26 @@
// If you have too many nodes, or if matching has failed, bail out
check_node_count(0, "out of nodes matching instructions");
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
// Build a proper-looking CFG
- PhaseCFG cfg(node_arena(), root(), m);
+ PhaseCFG cfg(node_arena(), root(), matcher);
_cfg = &cfg;
{
NOT_PRODUCT( TracePhase t2("scheduler", &_t_scheduler, TimeCompiler); )
- cfg.Dominators();
- if (failing()) return;
-
- NOT_PRODUCT( verify_graph_edges(); )
-
- cfg.Estimate_Block_Frequency();
- cfg.GlobalCodeMotion(m,unique(),proj_list);
- if (failing()) return;
+ bool success = cfg.do_global_code_motion();
+ if (!success) {
+ return;
+ }
print_method(PHASE_GLOBAL_CODE_MOTION, 2);
-
NOT_PRODUCT( verify_graph_edges(); )
-
debug_only( cfg.verify(); )
}
- NOT_PRODUCT( verify_graph_edges(); )
-
- PhaseChaitin regalloc(unique(), cfg, m);
+
+ PhaseChaitin regalloc(unique(), cfg, matcher);
_regalloc = ®alloc;
{
TracePhase t2("regalloc", &_t_registerAllocation, true);
@@ -2206,7 +2202,7 @@
// can now safely remove it.
{
NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); )
- cfg.remove_empty();
+ cfg.remove_empty_blocks();
if (do_freq_based_layout()) {
PhaseBlockLayout layout(cfg);
} else {
@@ -2253,38 +2249,50 @@
_regalloc->dump_frame();
Node *n = NULL;
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- if (VMThread::should_terminate()) { cut_short = true; break; }
- Block *b = _cfg->_blocks[i];
- if (b->is_connector() && !Verbose) continue;
- n = b->_nodes[0];
- if (pcs && n->_idx < pc_limit)
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ if (VMThread::should_terminate()) {
+ cut_short = true;
+ break;
+ }
+ Block* block = _cfg->get_block(i);
+ if (block->is_connector() && !Verbose) {
+ continue;
+ }
+ n = block->_nodes[0];
+ if (pcs && n->_idx < pc_limit) {
tty->print("%3.3x ", pcs[n->_idx]);
- else
+ } else {
tty->print(" ");
- b->dump_head(_cfg);
- if (b->is_connector()) {
+ }
+ block->dump_head(_cfg);
+ if (block->is_connector()) {
tty->print_cr(" # Empty connector block");
- } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
+ } else if (block->num_preds() == 2 && block->pred(1)->is_CatchProj() && block->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
tty->print_cr(" # Block is sole successor of call");
}
// For all instructions
Node *delay = NULL;
- for( uint j = 0; j<b->_nodes.size(); j++ ) {
- if (VMThread::should_terminate()) { cut_short = true; break; }
- n = b->_nodes[j];
+ for (uint j = 0; j < block->_nodes.size(); j++) {
+ if (VMThread::should_terminate()) {
+ cut_short = true;
+ break;
+ }
+ n = block->_nodes[j];
if (valid_bundle_info(n)) {
- Bundle *bundle = node_bundling(n);
+ Bundle* bundle = node_bundling(n);
if (bundle->used_in_unconditional_delay()) {
delay = n;
continue;
}
- if (bundle->starts_bundle())
+ if (bundle->starts_bundle()) {
starts_bundle = '+';
+ }
}
- if (WizardMode) n->dump();
+ if (WizardMode) {
+ n->dump();
+ }
if( !n->is_Region() && // Dont print in the Assembly
!n->is_Phi() && // a few noisely useless nodes
--- a/hotspot/src/share/vm/opto/domgraph.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/domgraph.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -32,9 +32,6 @@
// Portions of code courtesy of Clifford Click
-// Optimization - Graph Style
-
-//------------------------------Tarjan-----------------------------------------
// A data structure that holds all the information needed to find dominators.
struct Tarjan {
Block *_block; // Basic block for this info
@@ -60,23 +57,21 @@
};
-//------------------------------Dominator--------------------------------------
// Compute the dominator tree of the CFG. The CFG must already have been
// constructed. This is the Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
-void PhaseCFG::Dominators( ) {
+void PhaseCFG::build_dominator_tree() {
// Pre-grow the blocks array, prior to the ResourceMark kicking in
- _blocks.map(_num_blocks,0);
+ _blocks.map(number_of_blocks(), 0);
ResourceMark rm;
// Setup mappings from my Graph to Tarjan's stuff and back
// Note: Tarjan uses 1-based arrays
- Tarjan *tarjan = NEW_RESOURCE_ARRAY(Tarjan,_num_blocks+1);
+ Tarjan* tarjan = NEW_RESOURCE_ARRAY(Tarjan, number_of_blocks() + 1);
// Tarjan's algorithm, almost verbatim:
// Step 1:
- _rpo_ctr = _num_blocks;
- uint dfsnum = DFS( tarjan );
- if( dfsnum-1 != _num_blocks ) {// Check for unreachable loops!
+ uint dfsnum = do_DFS(tarjan, number_of_blocks());
+ if (dfsnum - 1 != number_of_blocks()) { // Check for unreachable loops!
// If the returned dfsnum does not match the number of blocks, then we
// must have some unreachable loops. These can be made at any time by
// IterGVN. They are cleaned up by CCP or the loop opts, but the last
@@ -93,14 +88,13 @@
C->record_method_not_compilable("unreachable loop");
return;
}
- _blocks._cnt = _num_blocks;
+ _blocks._cnt = number_of_blocks();
// Tarjan is using 1-based arrays, so these are some initialize flags
tarjan[0]._size = tarjan[0]._semi = 0;
tarjan[0]._label = &tarjan[0];
- uint i;
- for( i=_num_blocks; i>=2; i-- ) { // For all vertices in DFS order
+ for (uint i = number_of_blocks(); i >= 2; i--) { // For all vertices in DFS order
Tarjan *w = &tarjan[i]; // Get vertex from DFS
// Step 2:
@@ -130,19 +124,19 @@
}
// Step 4:
- for( i=2; i <= _num_blocks; i++ ) {
+ for (uint i = 2; i <= number_of_blocks(); i++) {
Tarjan *w = &tarjan[i];
if( w->_dom != &tarjan[w->_semi] )
w->_dom = w->_dom->_dom;
w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later
}
// No immediate dominator for the root
- Tarjan *w = &tarjan[_broot->_pre_order];
+ Tarjan *w = &tarjan[get_root_block()->_pre_order];
w->_dom = NULL;
w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later
// Convert the dominator tree array into my kind of graph
- for( i=1; i<=_num_blocks;i++){// For all Tarjan vertices
+ for(uint i = 1; i <= number_of_blocks(); i++){ // For all Tarjan vertices
Tarjan *t = &tarjan[i]; // Handy access
Tarjan *tdom = t->_dom; // Handy access to immediate dominator
if( tdom ) { // Root has no immediate dominator
@@ -152,11 +146,10 @@
} else
t->_block->_idom = NULL; // Root
}
- w->setdepth( _num_blocks+1 ); // Set depth in dominator tree
+ w->setdepth(number_of_blocks() + 1); // Set depth in dominator tree
}
-//----------------------------Block_Stack--------------------------------------
class Block_Stack {
private:
struct Block_Descr {
@@ -214,7 +207,6 @@
}
};
-//-------------------------most_frequent_successor-----------------------------
// Find the index into the b->succs[] array of the most frequent successor.
uint Block_Stack::most_frequent_successor( Block *b ) {
uint freq_idx = 0;
@@ -258,40 +250,38 @@
return freq_idx;
}
-//------------------------------DFS--------------------------------------------
// Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup
// 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent.
-uint PhaseCFG::DFS( Tarjan *tarjan ) {
- Block *b = _broot;
+uint PhaseCFG::do_DFS(Tarjan *tarjan, uint rpo_counter) {
+ Block* root_block = get_root_block();
uint pre_order = 1;
- // Allocate stack of size _num_blocks+1 to avoid frequent realloc
- Block_Stack bstack(tarjan, _num_blocks+1);
+ // Allocate stack of size number_of_blocks() + 1 to avoid frequent realloc
+ Block_Stack bstack(tarjan, number_of_blocks() + 1);
// Push on stack the state for the first block
- bstack.push(pre_order, b);
+ bstack.push(pre_order, root_block);
++pre_order;
while (bstack.is_nonempty()) {
if (!bstack.last_successor()) {
// Walk over all successors in pre-order (DFS).
- Block *s = bstack.next_successor();
- if (s->_pre_order == 0) { // Check for no-pre-order, not-visited
+ Block* next_block = bstack.next_successor();
+ if (next_block->_pre_order == 0) { // Check for no-pre-order, not-visited
// Push on stack the state of successor
- bstack.push(pre_order, s);
+ bstack.push(pre_order, next_block);
++pre_order;
}
}
else {
// Build a reverse post-order in the CFG _blocks array
Block *stack_top = bstack.pop();
- stack_top->_rpo = --_rpo_ctr;
+ stack_top->_rpo = --rpo_counter;
_blocks.map(stack_top->_rpo, stack_top);
}
}
return pre_order;
}
-//------------------------------COMPRESS---------------------------------------
void Tarjan::COMPRESS()
{
assert( _ancestor != 0, "" );
@@ -303,14 +293,12 @@
}
}
-//------------------------------EVAL-------------------------------------------
Tarjan *Tarjan::EVAL() {
if( !_ancestor ) return _label;
COMPRESS();
return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
}
-//------------------------------LINK-------------------------------------------
void Tarjan::LINK( Tarjan *w, Tarjan *tarjan0 ) {
Tarjan *s = w;
while( w->_label->_semi < s->_child->_label->_semi ) {
@@ -333,7 +321,6 @@
}
}
-//------------------------------setdepth---------------------------------------
void Tarjan::setdepth( uint stack_size ) {
Tarjan **top = NEW_RESOURCE_ARRAY(Tarjan*, stack_size);
Tarjan **next = top;
@@ -362,8 +349,7 @@
} while (last < top);
}
-//*********************** DOMINATORS ON THE SEA OF NODES***********************
-//------------------------------NTarjan----------------------------------------
+// Compute dominators on the Sea of Nodes form
// A data structure that holds all the information needed to find dominators.
struct NTarjan {
Node *_control; // Control node associated with this info
@@ -396,7 +382,6 @@
#endif
};
-//------------------------------Dominator--------------------------------------
// Compute the dominator tree of the sea of nodes. This version walks all CFG
// nodes (using the is_CFG() call) and places them in a dominator tree. Thus,
// it needs a count of the CFG nodes for the mapping table. This is the
@@ -517,7 +502,6 @@
}
}
-//------------------------------DFS--------------------------------------------
// Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup
// 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent.
int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) {
@@ -560,7 +544,6 @@
return dfsnum;
}
-//------------------------------COMPRESS---------------------------------------
void NTarjan::COMPRESS()
{
assert( _ancestor != 0, "" );
@@ -572,14 +555,12 @@
}
}
-//------------------------------EVAL-------------------------------------------
NTarjan *NTarjan::EVAL() {
if( !_ancestor ) return _label;
COMPRESS();
return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
}
-//------------------------------LINK-------------------------------------------
void NTarjan::LINK( NTarjan *w, NTarjan *ntarjan0 ) {
NTarjan *s = w;
while( w->_label->_semi < s->_child->_label->_semi ) {
@@ -602,7 +583,6 @@
}
}
-//------------------------------setdepth---------------------------------------
void NTarjan::setdepth( uint stack_size, uint *dom_depth ) {
NTarjan **top = NEW_RESOURCE_ARRAY(NTarjan*, stack_size);
NTarjan **next = top;
@@ -631,7 +611,6 @@
} while (last < top);
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void NTarjan::dump(int offset) const {
// Dump the data from this node
--- a/hotspot/src/share/vm/opto/gcm.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/gcm.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -121,27 +121,30 @@
//------------------------------schedule_pinned_nodes--------------------------
// Set the basic block for Nodes pinned into blocks
-void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) {
+void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
// Allocate node stack of size C->unique()+8 to avoid frequent realloc
- GrowableArray <Node *> spstack(C->unique()+8);
+ GrowableArray <Node *> spstack(C->unique() + 8);
spstack.push(_root);
- while ( spstack.is_nonempty() ) {
- Node *n = spstack.pop();
- if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
- if( n->pinned() && !has_block(n)) { // Pinned? Nail it down!
- assert( n->in(0), "pinned Node must have Control" );
+ while (spstack.is_nonempty()) {
+ Node* node = spstack.pop();
+ if (!visited.test_set(node->_idx)) { // Test node and flag it as visited
+ if (node->pinned() && !has_block(node)) { // Pinned? Nail it down!
+ assert(node->in(0), "pinned Node must have Control");
// Before setting block replace block_proj control edge
- replace_block_proj_ctrl(n);
- Node *input = n->in(0);
+ replace_block_proj_ctrl(node);
+ Node* input = node->in(0);
while (!input->is_block_start()) {
input = input->in(0);
}
- Block *b = get_block_for_node(input); // Basic block of controlling input
- schedule_node_into_block(n, b);
+ Block* block = get_block_for_node(input); // Basic block of controlling input
+ schedule_node_into_block(node, block);
}
- for( int i = n->req() - 1; i >= 0; --i ) { // For all inputs
- if( n->in(i) != NULL )
- spstack.push(n->in(i));
+
+ // process all inputs that are non NULL
+ for (int i = node->req() - 1; i >= 0; --i) {
+ if (node->in(i) != NULL) {
+ spstack.push(node->in(i));
+ }
}
}
}
@@ -205,32 +208,29 @@
// which all their inputs occur.
bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
// Allocate stack with enough space to avoid frequent realloc
- Node_Stack nstack(roots.Size() + 8); // (unique >> 1) + 24 from Java2D stats
- // roots.push(_root); _root will be processed among C->top() inputs
+ Node_Stack nstack(roots.Size() + 8);
+ // _root will be processed among C->top() inputs
roots.push(C->top());
visited.set(C->top()->_idx);
while (roots.size() != 0) {
// Use local variables nstack_top_n & nstack_top_i to cache values
// on stack's top.
- Node *nstack_top_n = roots.pop();
- uint nstack_top_i = 0;
-//while_nstack_nonempty:
+ Node* parent_node = roots.pop();
+ uint input_index = 0;
+
while (true) {
- // Get parent node and next input's index from stack's top.
- Node *n = nstack_top_n;
- uint i = nstack_top_i;
-
- if (i == 0) {
+ if (input_index == 0) {
// Fixup some control. Constants without control get attached
// to root and nodes that use is_block_proj() nodes should be attached
// to the region that starts their block.
- const Node *in0 = n->in(0);
- if (in0 != NULL) { // Control-dependent?
- replace_block_proj_ctrl(n);
- } else { // n->in(0) == NULL
- if (n->req() == 1) { // This guy is a constant with NO inputs?
- n->set_req(0, _root);
+ const Node* control_input = parent_node->in(0);
+ if (control_input != NULL) {
+ replace_block_proj_ctrl(parent_node);
+ } else {
+ // Is a constant with NO inputs?
+ if (parent_node->req() == 1) {
+ parent_node->set_req(0, _root);
}
}
}
@@ -239,37 +239,47 @@
// input is already in a block we quit following inputs (to avoid
// cycles). Instead we put that Node on a worklist to be handled
// later (since IT'S inputs may not have a block yet).
- bool done = true; // Assume all n's inputs will be processed
- while (i < n->len()) { // For all inputs
- Node *in = n->in(i); // Get input
- ++i;
- if (in == NULL) continue; // Ignore NULL, missing inputs
+
+ // Assume all n's inputs will be processed
+ bool done = true;
+
+ while (input_index < parent_node->len()) {
+ Node* in = parent_node->in(input_index++);
+ if (in == NULL) {
+ continue;
+ }
+
int is_visited = visited.test_set(in->_idx);
- if (!has_block(in)) { // Missing block selection?
+ if (!has_block(in)) {
if (is_visited) {
- // assert( !visited.test(in->_idx), "did not schedule early" );
return false;
}
- nstack.push(n, i); // Save parent node and next input's index.
- nstack_top_n = in; // Process current input now.
- nstack_top_i = 0;
- done = false; // Not all n's inputs processed.
- break; // continue while_nstack_nonempty;
- } else if (!is_visited) { // Input not yet visited?
- roots.push(in); // Visit this guy later, using worklist
+ // Save parent node and next input's index.
+ nstack.push(parent_node, input_index);
+ // Process current input now.
+ parent_node = in;
+ input_index = 0;
+ // Not all n's inputs processed.
+ done = false;
+ break;
+ } else if (!is_visited) {
+ // Visit this guy later, using worklist
+ roots.push(in);
}
}
+
if (done) {
// All of n's inputs have been processed, complete post-processing.
// Some instructions are pinned into a block. These include Region,
// Phi, Start, Return, and other control-dependent instructions and
// any projections which depend on them.
- if (!n->pinned()) {
+ if (!parent_node->pinned()) {
// Set earliest legal block.
- map_node_to_block(n, find_deepest_input(n, this));
+ Block* earliest_block = find_deepest_input(parent_node, this);
+ map_node_to_block(parent_node, earliest_block);
} else {
- assert(get_block_for_node(n) == get_block_for_node(n->in(0)), "Pinned Node should be at the same block as its control edge");
+ assert(get_block_for_node(parent_node) == get_block_for_node(parent_node->in(0)), "Pinned Node should be at the same block as its control edge");
}
if (nstack.is_empty()) {
@@ -278,12 +288,12 @@
break;
}
// Get saved parent node and next input's index.
- nstack_top_n = nstack.node();
- nstack_top_i = nstack.index();
+ parent_node = nstack.node();
+ input_index = nstack.index();
nstack.pop();
- } // if (done)
- } // while (true)
- } // while (roots.size() != 0)
+ }
+ }
+ }
return true;
}
@@ -847,7 +857,7 @@
//------------------------------ComputeLatenciesBackwards----------------------
// Compute the latency of all the instructions.
-void PhaseCFG::ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack) {
+void PhaseCFG::compute_latencies_backwards(VectorSet &visited, Node_List &stack) {
#ifndef PRODUCT
if (trace_opto_pipelining())
tty->print("\n#---- ComputeLatenciesBackwards ----\n");
@@ -870,31 +880,34 @@
// Set the latency for this instruction
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print("# latency_to_inputs: node_latency[%d] = %d for node",
- n->_idx, _node_latency->at_grow(n->_idx));
+ tty->print("# latency_to_inputs: node_latency[%d] = %d for node", n->_idx, get_latency_for_node(n));
dump();
}
#endif
- if (n->is_Proj())
+ if (n->is_Proj()) {
n = n->in(0);
+ }
- if (n->is_Root())
+ if (n->is_Root()) {
return;
+ }
uint nlen = n->len();
- uint use_latency = _node_latency->at_grow(n->_idx);
+ uint use_latency = get_latency_for_node(n);
uint use_pre_order = get_block_for_node(n)->_pre_order;
- for ( uint j=0; j<nlen; j++ ) {
+ for (uint j = 0; j < nlen; j++) {
Node *def = n->in(j);
- if (!def || def == n)
+ if (!def || def == n) {
continue;
+ }
// Walk backwards thru projections
- if (def->is_Proj())
+ if (def->is_Proj()) {
def = def->in(0);
+ }
#ifndef PRODUCT
if (trace_opto_pipelining()) {
@@ -907,22 +920,20 @@
Block *def_block = get_block_for_node(def);
uint def_pre_order = def_block ? def_block->_pre_order : 0;
- if ( (use_pre_order < def_pre_order) ||
- (use_pre_order == def_pre_order && n->is_Phi()) )
+ if ((use_pre_order < def_pre_order) || (use_pre_order == def_pre_order && n->is_Phi())) {
continue;
+ }
uint delta_latency = n->latency(j);
uint current_latency = delta_latency + use_latency;
- if (_node_latency->at_grow(def->_idx) < current_latency) {
- _node_latency->at_put_grow(def->_idx, current_latency);
+ if (get_latency_for_node(def) < current_latency) {
+ set_latency_for_node(def, current_latency);
}
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print_cr("# %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d",
- use_latency, j, delta_latency, current_latency, def->_idx,
- _node_latency->at_grow(def->_idx));
+ tty->print_cr("# %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d", use_latency, j, delta_latency, current_latency, def->_idx, get_latency_for_node(def));
}
#endif
}
@@ -957,7 +968,7 @@
return 0;
uint nlen = use->len();
- uint nl = _node_latency->at_grow(use->_idx);
+ uint nl = get_latency_for_node(use);
for ( uint j=0; j<nlen; j++ ) {
if (use->in(j) == n) {
@@ -992,8 +1003,7 @@
// Set the latency for this instruction
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print("# latency_from_outputs: node_latency[%d] = %d for node",
- n->_idx, _node_latency->at_grow(n->_idx));
+ tty->print("# latency_from_outputs: node_latency[%d] = %d for node", n->_idx, get_latency_for_node(n));
dump();
}
#endif
@@ -1006,7 +1016,7 @@
if (latency < l) latency = l;
}
- _node_latency->at_put_grow(n->_idx, latency);
+ set_latency_for_node(n, latency);
}
//------------------------------hoist_to_cheaper_block-------------------------
@@ -1016,9 +1026,9 @@
const double delta = 1+PROB_UNLIKELY_MAG(4);
Block* least = LCA;
double least_freq = least->_freq;
- uint target = _node_latency->at_grow(self->_idx);
- uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx);
- uint end_latency = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx);
+ uint target = get_latency_for_node(self);
+ uint start_latency = get_latency_for_node(LCA->_nodes[0]);
+ uint end_latency = get_latency_for_node(LCA->_nodes[LCA->end_idx()]);
bool in_latency = (target <= start_latency);
const Block* root_block = get_block_for_node(_root);
@@ -1035,8 +1045,7 @@
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print("# Find cheaper block for latency %d: ",
- _node_latency->at_grow(self->_idx));
+ tty->print("# Find cheaper block for latency %d: ", get_latency_for_node(self));
self->dump();
tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
LCA->_pre_order,
@@ -1065,9 +1074,9 @@
if (mach && LCA == root_block)
break;
- uint start_lat = _node_latency->at_grow(LCA->_nodes[0]->_idx);
+ uint start_lat = get_latency_for_node(LCA->_nodes[0]);
uint end_idx = LCA->end_idx();
- uint end_lat = _node_latency->at_grow(LCA->_nodes[end_idx]->_idx);
+ uint end_lat = get_latency_for_node(LCA->_nodes[end_idx]);
double LCA_freq = LCA->_freq;
#ifndef PRODUCT
if (trace_opto_pipelining()) {
@@ -1109,7 +1118,7 @@
tty->print_cr("# Change latency for [%4d] from %d to %d", self->_idx, target, end_latency);
}
#endif
- _node_latency->at_put_grow(self->_idx, end_latency);
+ set_latency_for_node(self, end_latency);
partial_latency_of_defs(self);
}
@@ -1255,7 +1264,7 @@
} // end ScheduleLate
//------------------------------GlobalCodeMotion-------------------------------
-void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_list ) {
+void PhaseCFG::global_code_motion() {
ResourceMark rm;
#ifndef PRODUCT
@@ -1265,21 +1274,22 @@
#endif
// Initialize the node to block mapping for things on the proj_list
- for (uint i = 0; i < proj_list.size(); i++) {
- unmap_node_from_block(proj_list[i]);
+ for (uint i = 0; i < _matcher.number_of_projections(); i++) {
+ unmap_node_from_block(_matcher.get_projection(i));
}
// Set the basic block for Nodes pinned into blocks
- Arena *a = Thread::current()->resource_area();
- VectorSet visited(a);
- schedule_pinned_nodes( visited );
+ Arena* arena = Thread::current()->resource_area();
+ VectorSet visited(arena);
+ schedule_pinned_nodes(visited);
// Find the earliest Block any instruction can be placed in. Some
// instructions are pinned into Blocks. Unpinned instructions can
// appear in last block in which all their inputs occur.
visited.Clear();
- Node_List stack(a);
- stack.map( (unique >> 1) + 16, NULL); // Pre-grow the list
+ Node_List stack(arena);
+ // Pre-grow the list
+ stack.map((C->unique() >> 1) + 16, NULL);
if (!schedule_early(visited, stack)) {
// Bailout without retry
C->record_method_not_compilable("early schedule failed");
@@ -1287,29 +1297,25 @@
}
// Build Def-Use edges.
- proj_list.push(_root); // Add real root as another root
- proj_list.pop();
-
// Compute the latency information (via backwards walk) for all the
// instructions in the graph
_node_latency = new GrowableArray<uint>(); // resource_area allocation
- if( C->do_scheduling() )
- ComputeLatenciesBackwards(visited, stack);
+ if (C->do_scheduling()) {
+ compute_latencies_backwards(visited, stack);
+ }
// Now schedule all codes as LATE as possible. This is the LCA in the
// dominator tree of all USES of a value. Pick the block with the least
// loop nesting depth that is lowest in the dominator tree.
// ( visited.Clear() called in schedule_late()->Node_Backward_Iterator() )
schedule_late(visited, stack);
- if( C->failing() ) {
+ if (C->failing()) {
// schedule_late fails only when graph is incorrect.
assert(!VerifyGraphEdges, "verification should have failed");
return;
}
- unique = C->unique();
-
#ifndef PRODUCT
if (trace_opto_pipelining()) {
tty->print("\n---- Detect implicit null checks ----\n");
@@ -1332,10 +1338,11 @@
// By reversing the loop direction we get a very minor gain on mpegaudio.
// Feel free to revert to a forward loop for clarity.
// for( int i=0; i < (int)matcher._null_check_tests.size(); i+=2 ) {
- for( int i= matcher._null_check_tests.size()-2; i>=0; i-=2 ) {
- Node *proj = matcher._null_check_tests[i ];
- Node *val = matcher._null_check_tests[i+1];
- get_block_for_node(proj)->implicit_null_check(this, proj, val, allowed_reasons);
+ for (int i = _matcher._null_check_tests.size() - 2; i >= 0; i -= 2) {
+ Node* proj = _matcher._null_check_tests[i];
+ Node* val = _matcher._null_check_tests[i + 1];
+ Block* block = get_block_for_node(proj);
+ block->implicit_null_check(this, proj, val, allowed_reasons);
// The implicit_null_check will only perform the transformation
// if the null branch is truly uncommon, *and* it leads to an
// uncommon trap. Combined with the too_many_traps guards
@@ -1352,11 +1359,11 @@
// Schedule locally. Right now a simple topological sort.
// Later, do a real latency aware scheduler.
- uint max_idx = C->unique();
- GrowableArray<int> ready_cnt(max_idx, max_idx, -1);
+ GrowableArray<int> ready_cnt(C->unique(), C->unique(), -1);
visited.Clear();
- for (uint i = 0; i < _num_blocks; i++) {
- if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) {
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ if (!block->schedule_local(this, _matcher, ready_cnt, visited)) {
if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
C->record_method_not_compilable("local schedule failed");
}
@@ -1366,15 +1373,17 @@
// If we inserted any instructions between a Call and his CatchNode,
// clone the instructions on all paths below the Catch.
- for (uint i = 0; i < _num_blocks; i++) {
- _blocks[i]->call_catch_cleanup(this, C);
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ block->call_catch_cleanup(this, C);
}
#ifndef PRODUCT
if (trace_opto_pipelining()) {
tty->print("\n---- After GlobalCodeMotion ----\n");
- for (uint i = 0; i < _num_blocks; i++) {
- _blocks[i]->dump();
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ block->dump();
}
}
#endif
@@ -1382,10 +1391,29 @@
_node_latency = (GrowableArray<uint> *)0xdeadbeef;
}
+bool PhaseCFG::do_global_code_motion() {
+
+ build_dominator_tree();
+ if (C->failing()) {
+ return false;
+ }
+
+ NOT_PRODUCT( C->verify_graph_edges(); )
+
+ estimate_block_frequency();
+
+ global_code_motion();
+
+ if (C->failing()) {
+ return false;
+ }
+
+ return true;
+}
//------------------------------Estimate_Block_Frequency-----------------------
// Estimate block frequencies based on IfNode probabilities.
-void PhaseCFG::Estimate_Block_Frequency() {
+void PhaseCFG::estimate_block_frequency() {
// Force conditional branches leading to uncommon traps to be unlikely,
// not because we get to the uncommon_trap with less relative frequency,
@@ -1393,7 +1421,7 @@
// there once.
if (C->do_freq_based_layout()) {
Block_List worklist;
- Block* root_blk = _blocks[0];
+ Block* root_blk = get_block(0);
for (uint i = 1; i < root_blk->num_preds(); i++) {
Block *pb = get_block_for_node(root_blk->pred(i));
if (pb->has_uncommon_code()) {
@@ -1402,7 +1430,9 @@
}
while (worklist.size() > 0) {
Block* uct = worklist.pop();
- if (uct == _broot) continue;
+ if (uct == get_root_block()) {
+ continue;
+ }
for (uint i = 1; i < uct->num_preds(); i++) {
Block *pb = get_block_for_node(uct->pred(i));
if (pb->_num_succs == 1) {
@@ -1426,12 +1456,12 @@
_root_loop->scale_freq();
// Save outmost loop frequency for LRG frequency threshold
- _outer_loop_freq = _root_loop->outer_loop_freq();
+ _outer_loop_frequency = _root_loop->outer_loop_freq();
// force paths ending at uncommon traps to be infrequent
if (!C->do_freq_based_layout()) {
Block_List worklist;
- Block* root_blk = _blocks[0];
+ Block* root_blk = get_block(0);
for (uint i = 1; i < root_blk->num_preds(); i++) {
Block *pb = get_block_for_node(root_blk->pred(i));
if (pb->has_uncommon_code()) {
@@ -1451,8 +1481,8 @@
}
#ifdef ASSERT
- for (uint i = 0; i < _num_blocks; i++ ) {
- Block *b = _blocks[i];
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* b = get_block(i);
assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requires meaningful block frequency");
}
#endif
@@ -1476,16 +1506,16 @@
CFGLoop* PhaseCFG::create_loop_tree() {
#ifdef ASSERT
- assert( _blocks[0] == _broot, "" );
- for (uint i = 0; i < _num_blocks; i++ ) {
- Block *b = _blocks[i];
+ assert(get_block(0) == get_root_block(), "first block should be root block");
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
// Check that _loop field are clear...we could clear them if not.
- assert(b->_loop == NULL, "clear _loop expected");
+ assert(block->_loop == NULL, "clear _loop expected");
// Sanity check that the RPO numbering is reflected in the _blocks array.
// It doesn't have to be for the loop tree to be built, but if it is not,
// then the blocks have been reordered since dom graph building...which
// may question the RPO numbering
- assert(b->_rpo == i, "unexpected reverse post order number");
+ assert(block->_rpo == i, "unexpected reverse post order number");
}
#endif
@@ -1495,11 +1525,11 @@
Block_List worklist;
// Assign blocks to loops
- for(uint i = _num_blocks - 1; i > 0; i-- ) { // skip Root block
- Block *b = _blocks[i];
+ for(uint i = number_of_blocks() - 1; i > 0; i-- ) { // skip Root block
+ Block* block = get_block(i);
- if (b->head()->is_Loop()) {
- Block* loop_head = b;
+ if (block->head()->is_Loop()) {
+ Block* loop_head = block;
assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
Node* tail_n = loop_head->pred(LoopNode::LoopBackControl);
Block* tail = get_block_for_node(tail_n);
@@ -1533,23 +1563,23 @@
// Create a member list for each loop consisting
// of both blocks and (immediate child) loops.
- for (uint i = 0; i < _num_blocks; i++) {
- Block *b = _blocks[i];
- CFGLoop* lp = b->_loop;
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ CFGLoop* lp = block->_loop;
if (lp == NULL) {
// Not assigned to a loop. Add it to the method's pseudo loop.
- b->_loop = root_loop;
+ block->_loop = root_loop;
lp = root_loop;
}
- if (lp == root_loop || b != lp->head()) { // loop heads are already members
- lp->add_member(b);
+ if (lp == root_loop || block != lp->head()) { // loop heads are already members
+ lp->add_member(block);
}
if (lp != root_loop) {
if (lp->parent() == NULL) {
// Not a nested loop. Make it a child of the method's pseudo loop.
root_loop->add_nested_loop(lp);
}
- if (b == lp->head()) {
+ if (block == lp->head()) {
// Add nested loop to member list of parent loop.
lp->parent()->add_member(lp);
}
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -416,7 +416,7 @@
if (C->cfg() != NULL) {
Block* block = C->cfg()->get_block_for_node(node);
if (block == NULL) {
- print_prop("block", C->cfg()->_blocks[0]->_pre_order);
+ print_prop("block", C->cfg()->get_block(0)->_pre_order);
} else {
print_prop("block", block->_pre_order);
}
@@ -637,10 +637,10 @@
if (C->cfg() != NULL) {
// once we have a CFG there are some nodes that aren't really
// reachable but are in the CFG so add them here.
- for (uint i = 0; i < C->cfg()->_blocks.size(); i++) {
- Block *b = C->cfg()->_blocks[i];
- for (uint s = 0; s < b->_nodes.size(); s++) {
- nodeStack.push(b->_nodes[s]);
+ for (uint i = 0; i < C->cfg()->number_of_blocks(); i++) {
+ Block* block = C->cfg()->get_block(i);
+ for (uint s = 0; s < block->_nodes.size(); s++) {
+ nodeStack.push(block->_nodes[s]);
}
}
}
@@ -698,24 +698,24 @@
tail(EDGES_ELEMENT);
if (C->cfg() != NULL) {
head(CONTROL_FLOW_ELEMENT);
- for (uint i = 0; i < C->cfg()->_blocks.size(); i++) {
- Block *b = C->cfg()->_blocks[i];
+ for (uint i = 0; i < C->cfg()->number_of_blocks(); i++) {
+ Block* block = C->cfg()->get_block(i);
begin_head(BLOCK_ELEMENT);
- print_attr(BLOCK_NAME_PROPERTY, b->_pre_order);
+ print_attr(BLOCK_NAME_PROPERTY, block->_pre_order);
end_head();
head(SUCCESSORS_ELEMENT);
- for (uint s = 0; s < b->_num_succs; s++) {
+ for (uint s = 0; s < block->_num_succs; s++) {
begin_elem(SUCCESSOR_ELEMENT);
- print_attr(BLOCK_NAME_PROPERTY, b->_succs[s]->_pre_order);
+ print_attr(BLOCK_NAME_PROPERTY, block->_succs[s]->_pre_order);
end_elem();
}
tail(SUCCESSORS_ELEMENT);
head(NODES_ELEMENT);
- for (uint s = 0; s < b->_nodes.size(); s++) {
+ for (uint s = 0; s < block->_nodes.size(); s++) {
begin_elem(NODE_ELEMENT);
- print_attr(NODE_ID_PROPERTY, get_node_id(b->_nodes[s]));
+ print_attr(NODE_ID_PROPERTY, get_node_id(block->_nodes[s]));
end_elem();
}
tail(NODES_ELEMENT);
--- a/hotspot/src/share/vm/opto/ifg.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/ifg.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -37,12 +37,9 @@
#include "opto/memnode.hpp"
#include "opto/opcodes.hpp"
-//=============================================================================
-//------------------------------IFG--------------------------------------------
PhaseIFG::PhaseIFG( Arena *arena ) : Phase(Interference_Graph), _arena(arena) {
}
-//------------------------------init-------------------------------------------
void PhaseIFG::init( uint maxlrg ) {
_maxlrg = maxlrg;
_yanked = new (_arena) VectorSet(_arena);
@@ -59,7 +56,6 @@
}
}
-//------------------------------add--------------------------------------------
// Add edge between vertices a & b. These are sorted (triangular matrix),
// then the smaller number is inserted in the larger numbered array.
int PhaseIFG::add_edge( uint a, uint b ) {
@@ -71,7 +67,6 @@
return _adjs[a].insert( b );
}
-//------------------------------add_vector-------------------------------------
// Add an edge between 'a' and everything in the vector.
void PhaseIFG::add_vector( uint a, IndexSet *vec ) {
// IFG is triangular, so do the inserts where 'a' < 'b'.
@@ -86,7 +81,6 @@
}
}
-//------------------------------test-------------------------------------------
// Is there an edge between a and b?
int PhaseIFG::test_edge( uint a, uint b ) const {
// Sort a and b, so that a is larger
@@ -95,7 +89,6 @@
return _adjs[a].member(b);
}
-//------------------------------SquareUp---------------------------------------
// Convert triangular matrix to square matrix
void PhaseIFG::SquareUp() {
assert( !_is_square, "only on triangular" );
@@ -111,7 +104,6 @@
_is_square = true;
}
-//------------------------------Compute_Effective_Degree-----------------------
// Compute effective degree in bulk
void PhaseIFG::Compute_Effective_Degree() {
assert( _is_square, "only on square" );
@@ -120,7 +112,6 @@
lrgs(i).set_degree(effective_degree(i));
}
-//------------------------------test_edge_sq-----------------------------------
int PhaseIFG::test_edge_sq( uint a, uint b ) const {
assert( _is_square, "only on square" );
// Swap, so that 'a' has the lesser count. Then binary search is on
@@ -130,7 +121,6 @@
return _adjs[a].member(b);
}
-//------------------------------Union------------------------------------------
// Union edges of B into A
void PhaseIFG::Union( uint a, uint b ) {
assert( _is_square, "only on square" );
@@ -146,7 +136,6 @@
}
}
-//------------------------------remove_node------------------------------------
// Yank a Node and all connected edges from the IFG. Return a
// list of neighbors (edges) yanked.
IndexSet *PhaseIFG::remove_node( uint a ) {
@@ -165,7 +154,6 @@
return neighbors(a);
}
-//------------------------------re_insert--------------------------------------
// Re-insert a yanked Node.
void PhaseIFG::re_insert( uint a ) {
assert( _is_square, "only on square" );
@@ -180,7 +168,6 @@
}
}
-//------------------------------compute_degree---------------------------------
// Compute the degree between 2 live ranges. If both live ranges are
// aligned-adjacent powers-of-2 then we use the MAX size. If either is
// mis-aligned (or for Fat-Projections, not-adjacent) then we have to
@@ -196,7 +183,6 @@
return tmp;
}
-//------------------------------effective_degree-------------------------------
// Compute effective degree for this live range. If both live ranges are
// aligned-adjacent powers-of-2 then we use the MAX size. If either is
// mis-aligned (or for Fat-Projections, not-adjacent) then we have to
@@ -221,7 +207,6 @@
#ifndef PRODUCT
-//------------------------------dump-------------------------------------------
void PhaseIFG::dump() const {
tty->print_cr("-- Interference Graph --%s--",
_is_square ? "square" : "triangular" );
@@ -260,7 +245,6 @@
tty->print("\n");
}
-//------------------------------stats------------------------------------------
void PhaseIFG::stats() const {
ResourceMark rm;
int *h_cnt = NEW_RESOURCE_ARRAY(int,_maxlrg*2);
@@ -276,7 +260,6 @@
tty->print_cr("");
}
-//------------------------------verify-----------------------------------------
void PhaseIFG::verify( const PhaseChaitin *pc ) const {
// IFG is square, sorted and no need for Find
for( uint i = 0; i < _maxlrg; i++ ) {
@@ -298,7 +281,6 @@
}
#endif
-//------------------------------interfere_with_live----------------------------
// Interfere this register with everything currently live. Use the RegMasks
// to trim the set of possible interferences. Return a count of register-only
// interferences as an estimate of register pressure.
@@ -315,7 +297,6 @@
_ifg->add_edge( r, l );
}
-//------------------------------build_ifg_virtual------------------------------
// Actually build the interference graph. Uses virtual registers only, no
// physical register masks. This allows me to be very aggressive when
// coalescing copies. Some of this aggressiveness will have to be undone
@@ -325,9 +306,9 @@
void PhaseChaitin::build_ifg_virtual( ) {
// For all blocks (in any order) do...
- for( uint i=0; i<_cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- IndexSet *liveout = _live->live(b);
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
+ IndexSet* liveout = _live->live(block);
// The IFG is built by a single reverse pass over each basic block.
// Starting with the known live-out set, we remove things that get
@@ -337,8 +318,8 @@
// The defined value interferes with everything currently live. The
// value is then removed from the live-ness set and it's inputs are
// added to the live-ness set.
- for( uint j = b->end_idx() + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j-1];
+ for (uint j = block->end_idx() + 1; j > 1; j--) {
+ Node* n = block->_nodes[j - 1];
// Get value being defined
uint r = _lrg_map.live_range_id(n);
@@ -408,7 +389,6 @@
} // End of forall blocks
}
-//------------------------------count_int_pressure-----------------------------
uint PhaseChaitin::count_int_pressure( IndexSet *liveout ) {
IndexSetIterator elements(liveout);
uint lidx;
@@ -424,7 +404,6 @@
return cnt;
}
-//------------------------------count_float_pressure---------------------------
uint PhaseChaitin::count_float_pressure( IndexSet *liveout ) {
IndexSetIterator elements(liveout);
uint lidx;
@@ -438,7 +417,6 @@
return cnt;
}
-//------------------------------lower_pressure---------------------------------
// Adjust register pressure down by 1. Capture last hi-to-low transition,
static void lower_pressure( LRG *lrg, uint where, Block *b, uint *pressure, uint *hrp_index ) {
if (lrg->mask().is_UP() && lrg->mask_size()) {
@@ -460,40 +438,41 @@
}
}
-//------------------------------build_ifg_physical-----------------------------
// Build the interference graph using physical registers when available.
// That is, if 2 live ranges are simultaneously alive but in their acceptable
// register sets do not overlap, then they do not interfere.
uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
NOT_PRODUCT( Compile::TracePhase t3("buildIFG", &_t_buildIFGphysical, TimeCompiler); )
- uint spill_reg = LRG::SPILL_REG;
uint must_spill = 0;
// For all blocks (in any order) do...
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// Clone (rather than smash in place) the liveout info, so it is alive
// for the "collect_gc_info" phase later.
- IndexSet liveout(_live->live(b));
- uint last_inst = b->end_idx();
+ IndexSet liveout(_live->live(block));
+ uint last_inst = block->end_idx();
// Compute first nonphi node index
uint first_inst;
- for( first_inst = 1; first_inst < last_inst; first_inst++ )
- if( !b->_nodes[first_inst]->is_Phi() )
+ for (first_inst = 1; first_inst < last_inst; first_inst++) {
+ if (!block->_nodes[first_inst]->is_Phi()) {
break;
+ }
+ }
// Spills could be inserted before CreateEx node which should be
// first instruction in block after Phis. Move CreateEx up.
- for( uint insidx = first_inst; insidx < last_inst; insidx++ ) {
- Node *ex = b->_nodes[insidx];
- if( ex->is_SpillCopy() ) continue;
- if( insidx > first_inst && ex->is_Mach() &&
- ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
+ for (uint insidx = first_inst; insidx < last_inst; insidx++) {
+ Node *ex = block->_nodes[insidx];
+ if (ex->is_SpillCopy()) {
+ continue;
+ }
+ if (insidx > first_inst && ex->is_Mach() && ex->as_Mach()->ideal_Opcode() == Op_CreateEx) {
// If the CreateEx isn't above all the MachSpillCopies
// then move it to the top.
- b->_nodes.remove(insidx);
- b->_nodes.insert(first_inst, ex);
+ block->_nodes.remove(insidx);
+ block->_nodes.insert(first_inst, ex);
}
// Stop once a CreateEx or any other node is found
break;
@@ -503,12 +482,12 @@
uint pressure[2], hrp_index[2];
pressure[0] = pressure[1] = 0;
hrp_index[0] = hrp_index[1] = last_inst+1;
- b->_reg_pressure = b->_freg_pressure = 0;
+ block->_reg_pressure = block->_freg_pressure = 0;
// Liveout things are presumed live for the whole block. We accumulate
// 'area' accordingly. If they get killed in the block, we'll subtract
// the unused part of the block from the area.
int inst_count = last_inst - first_inst;
- double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
+ double cost = (inst_count <= 0) ? 0.0 : block->_freq * double(inst_count);
assert(!(cost < 0.0), "negative spill cost" );
IndexSetIterator elements(&liveout);
uint lidx;
@@ -519,13 +498,15 @@
if (lrg.mask().is_UP() && lrg.mask_size()) {
if (lrg._is_float || lrg._is_vector) { // Count float pressure
pressure[1] += lrg.reg_pressure();
- if( pressure[1] > b->_freg_pressure )
- b->_freg_pressure = pressure[1];
+ if (pressure[1] > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1];
+ }
// Count int pressure, but do not count the SP, flags
- } else if( lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
+ } else if(lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI])) {
pressure[0] += lrg.reg_pressure();
- if( pressure[0] > b->_reg_pressure )
- b->_reg_pressure = pressure[0];
+ if (pressure[0] > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0];
+ }
}
}
}
@@ -541,8 +522,8 @@
// value is then removed from the live-ness set and it's inputs are added
// to the live-ness set.
uint j;
- for( j = last_inst + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j - 1];
+ for (j = last_inst + 1; j > 1; j--) {
+ Node* n = block->_nodes[j - 1];
// Get value being defined
uint r = _lrg_map.live_range_id(n);
@@ -551,7 +532,7 @@
if(r) {
// A DEF normally costs block frequency; rematerialized values are
// removed from the DEF sight, so LOWER costs here.
- lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq;
+ lrgs(r)._cost += n->rematerialize() ? 0 : block->_freq;
// If it is not live, then this instruction is dead. Probably caused
// by spilling and rematerialization. Who cares why, yank this baby.
@@ -560,7 +541,7 @@
if( !n->is_Proj() ||
// Could also be a flags-projection of a dead ADD or such.
(_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) {
- b->_nodes.remove(j - 1);
+ block->_nodes.remove(j - 1);
if (lrgs(r)._def == n) {
lrgs(r)._def = 0;
}
@@ -580,21 +561,21 @@
RegMask itmp = lrgs(r).mask();
itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
int iregs = itmp.Size();
- if( pressure[0]+iregs > b->_reg_pressure )
- b->_reg_pressure = pressure[0]+iregs;
- if( pressure[0] <= (uint)INTPRESSURE &&
- pressure[0]+iregs > (uint)INTPRESSURE ) {
- hrp_index[0] = j-1;
+ if (pressure[0]+iregs > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0] + iregs;
+ }
+ if (pressure[0] <= (uint)INTPRESSURE && pressure[0] + iregs > (uint)INTPRESSURE) {
+ hrp_index[0] = j - 1;
}
// Count the float-only registers
RegMask ftmp = lrgs(r).mask();
ftmp.AND(*Matcher::idealreg2regmask[Op_RegD]);
int fregs = ftmp.Size();
- if( pressure[1]+fregs > b->_freg_pressure )
- b->_freg_pressure = pressure[1]+fregs;
- if( pressure[1] <= (uint)FLOATPRESSURE &&
- pressure[1]+fregs > (uint)FLOATPRESSURE ) {
- hrp_index[1] = j-1;
+ if (pressure[1] + fregs > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1] + fregs;
+ }
+ if(pressure[1] <= (uint)FLOATPRESSURE && pressure[1]+fregs > (uint)FLOATPRESSURE) {
+ hrp_index[1] = j - 1;
}
}
@@ -607,7 +588,7 @@
if( n->is_SpillCopy()
&& lrgs(r).is_singledef() // MultiDef live range can still split
&& n->outcnt() == 1 // and use must be in this block
- && _cfg.get_block_for_node(n->unique_out()) == b ) {
+ && _cfg.get_block_for_node(n->unique_out()) == block) {
// All single-use MachSpillCopy(s) that immediately precede their
// use must color early. If a longer live range steals their
// color, the spill copy will split and may push another spill copy
@@ -617,14 +598,16 @@
//
Node *single_use = n->unique_out();
- assert( b->find_node(single_use) >= j, "Use must be later in block");
+ assert(block->find_node(single_use) >= j, "Use must be later in block");
// Use can be earlier in block if it is a Phi, but then I should be a MultiDef
// Find first non SpillCopy 'm' that follows the current instruction
// (j - 1) is index for current instruction 'n'
Node *m = n;
- for( uint i = j; i <= last_inst && m->is_SpillCopy(); ++i ) { m = b->_nodes[i]; }
- if( m == single_use ) {
+ for (uint i = j; i <= last_inst && m->is_SpillCopy(); ++i) {
+ m = block->_nodes[i];
+ }
+ if (m == single_use) {
lrgs(r)._area = 0.0;
}
}
@@ -633,7 +616,7 @@
if( liveout.remove(r) ) {
// Adjust register pressure.
// Capture last hi-to-lo pressure transition
- lower_pressure( &lrgs(r), j-1, b, pressure, hrp_index );
+ lower_pressure(&lrgs(r), j - 1, block, pressure, hrp_index);
assert( pressure[0] == count_int_pressure (&liveout), "" );
assert( pressure[1] == count_float_pressure(&liveout), "" );
}
@@ -646,7 +629,7 @@
if (liveout.remove(x)) {
lrgs(x)._area -= cost;
// Adjust register pressure.
- lower_pressure(&lrgs(x), j-1, b, pressure, hrp_index);
+ lower_pressure(&lrgs(x), j - 1, block, pressure, hrp_index);
assert( pressure[0] == count_int_pressure (&liveout), "" );
assert( pressure[1] == count_float_pressure(&liveout), "" );
}
@@ -718,7 +701,7 @@
// Area remaining in the block
inst_count--;
- cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
+ cost = (inst_count <= 0) ? 0.0 : block->_freq * double(inst_count);
// Make all inputs live
if( !n->is_Phi() ) { // Phi function uses come from prior block
@@ -743,7 +726,7 @@
if (k < debug_start) {
// A USE costs twice block frequency (once for the Load, once
// for a Load-delay). Rematerialized uses only cost once.
- lrg._cost += (def->rematerialize() ? b->_freq : (b->_freq + b->_freq));
+ lrg._cost += (def->rematerialize() ? block->_freq : (block->_freq + block->_freq));
}
// It is live now
if (liveout.insert(x)) {
@@ -753,12 +736,14 @@
if (lrg.mask().is_UP() && lrg.mask_size()) {
if (lrg._is_float || lrg._is_vector) {
pressure[1] += lrg.reg_pressure();
- if( pressure[1] > b->_freg_pressure )
- b->_freg_pressure = pressure[1];
+ if (pressure[1] > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1];
+ }
} else if( lrg.mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
pressure[0] += lrg.reg_pressure();
- if( pressure[0] > b->_reg_pressure )
- b->_reg_pressure = pressure[0];
+ if (pressure[0] > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0];
+ }
}
}
assert( pressure[0] == count_int_pressure (&liveout), "" );
@@ -772,44 +757,47 @@
// If we run off the top of the block with high pressure and
// never see a hi-to-low pressure transition, just record that
// the whole block is high pressure.
- if( pressure[0] > (uint)INTPRESSURE ) {
+ if (pressure[0] > (uint)INTPRESSURE) {
hrp_index[0] = 0;
- if( pressure[0] > b->_reg_pressure )
- b->_reg_pressure = pressure[0];
+ if (pressure[0] > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0];
+ }
}
- if( pressure[1] > (uint)FLOATPRESSURE ) {
+ if (pressure[1] > (uint)FLOATPRESSURE) {
hrp_index[1] = 0;
- if( pressure[1] > b->_freg_pressure )
- b->_freg_pressure = pressure[1];
+ if (pressure[1] > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1];
+ }
}
// Compute high pressure indice; avoid landing in the middle of projnodes
j = hrp_index[0];
- if( j < b->_nodes.size() && j < b->end_idx()+1 ) {
- Node *cur = b->_nodes[j];
- while( cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch() ) {
+ if (j < block->_nodes.size() && j < block->end_idx() + 1) {
+ Node* cur = block->_nodes[j];
+ while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) {
j--;
- cur = b->_nodes[j];
+ cur = block->_nodes[j];
}
}
- b->_ihrp_index = j;
+ block->_ihrp_index = j;
j = hrp_index[1];
- if( j < b->_nodes.size() && j < b->end_idx()+1 ) {
- Node *cur = b->_nodes[j];
- while( cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch() ) {
+ if (j < block->_nodes.size() && j < block->end_idx() + 1) {
+ Node* cur = block->_nodes[j];
+ while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) {
j--;
- cur = b->_nodes[j];
+ cur = block->_nodes[j];
}
}
- b->_fhrp_index = j;
+ block->_fhrp_index = j;
#ifndef PRODUCT
// Gather Register Pressure Statistics
if( PrintOptoStatistics ) {
- if( b->_reg_pressure > (uint)INTPRESSURE || b->_freg_pressure > (uint)FLOATPRESSURE )
+ if (block->_reg_pressure > (uint)INTPRESSURE || block->_freg_pressure > (uint)FLOATPRESSURE) {
_high_pressure++;
- else
+ } else {
_low_pressure++;
+ }
}
#endif
} // End of for all blocks
--- a/hotspot/src/share/vm/opto/lcm.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -501,7 +501,7 @@
n_choice = 1;
}
- uint n_latency = cfg->_node_latency->at_grow(n->_idx);
+ uint n_latency = cfg->get_latency_for_node(n);
uint n_score = n->req(); // Many inputs get high score to break ties
// Keep best latency found
@@ -797,7 +797,7 @@
Node *n = _nodes[j];
int idx = n->_idx;
tty->print("# ready cnt:%3d ", ready_cnt.at(idx));
- tty->print("latency:%3d ", cfg->_node_latency->at_grow(idx));
+ tty->print("latency:%3d ", cfg->get_latency_for_node(n));
tty->print("%4d: %s\n", idx, n->Name());
}
}
@@ -825,7 +825,7 @@
#ifndef PRODUCT
if (cfg->trace_opto_pipelining()) {
tty->print("# select %d: %s", n->_idx, n->Name());
- tty->print(", latency:%d", cfg->_node_latency->at_grow(n->_idx));
+ tty->print(", latency:%d", cfg->get_latency_for_node(n));
n->dump();
if (Verbose) {
tty->print("# ready list:");
--- a/hotspot/src/share/vm/opto/library_call.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -213,6 +213,7 @@
void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
+ static bool klass_needs_init_guard(Node* kls);
bool inline_unsafe_allocate();
bool inline_unsafe_copyMemory();
bool inline_native_currentThread();
@@ -2892,8 +2893,21 @@
}
}
+bool LibraryCallKit::klass_needs_init_guard(Node* kls) {
+ if (!kls->is_Con()) {
+ return true;
+ }
+ const TypeKlassPtr* klsptr = kls->bottom_type()->isa_klassptr();
+ if (klsptr == NULL) {
+ return true;
+ }
+ ciInstanceKlass* ik = klsptr->klass()->as_instance_klass();
+ // don't need a guard for a klass that is already initialized
+ return !ik->is_initialized();
+}
+
//----------------------------inline_unsafe_allocate---------------------------
-// public native Object sun.mics.Unsafe.allocateInstance(Class<?> cls);
+// public native Object sun.misc.Unsafe.allocateInstance(Class<?> cls);
bool LibraryCallKit::inline_unsafe_allocate() {
if (callee()->is_static()) return false; // caller must have the capability!
@@ -2905,16 +2919,19 @@
kls = null_check(kls);
if (stopped()) return true; // argument was like int.class
- // Note: The argument might still be an illegal value like
- // Serializable.class or Object[].class. The runtime will handle it.
- // But we must make an explicit check for initialization.
- Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
- // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
- // can generate code to load it as unsigned byte.
- Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
- Node* bits = intcon(InstanceKlass::fully_initialized);
- Node* test = _gvn.transform(new (C) SubINode(inst, bits));
- // The 'test' is non-zero if we need to take a slow path.
+ Node* test = NULL;
+ if (LibraryCallKit::klass_needs_init_guard(kls)) {
+ // Note: The argument might still be an illegal value like
+ // Serializable.class or Object[].class. The runtime will handle it.
+ // But we must make an explicit check for initialization.
+ Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
+ // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
+ // can generate code to load it as unsigned byte.
+ Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
+ Node* bits = intcon(InstanceKlass::fully_initialized);
+ test = _gvn.transform(new (C) SubINode(inst, bits));
+ // The 'test' is non-zero if we need to take a slow path.
+ }
Node* obj = new_instance(kls, test);
set_result(obj);
--- a/hotspot/src/share/vm/opto/live.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/live.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -30,9 +30,6 @@
#include "opto/machnode.hpp"
-
-//=============================================================================
-//------------------------------PhaseLive--------------------------------------
// Compute live-in/live-out. We use a totally incremental algorithm. The LIVE
// problem is monotonic. The steady-state solution looks like this: pull a
// block from the worklist. It has a set of delta's - values which are newly
@@ -53,9 +50,9 @@
// Init the sparse live arrays. This data is live on exit from here!
// The _live info is the live-out info.
- _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet)*_cfg._num_blocks);
+ _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks());
uint i;
- for( i=0; i<_cfg._num_blocks; i++ ) {
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
_live[i].initialize(_maxlrg);
}
@@ -65,14 +62,14 @@
// Does the memory used by _defs and _deltas get reclaimed? Does it matter? TT
// Array of values defined locally in blocks
- _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg._num_blocks);
- for( i=0; i<_cfg._num_blocks; i++ ) {
+ _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg.number_of_blocks());
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
_defs[i].initialize(_maxlrg);
}
// Array of delta-set pointers, indexed by block pre_order-1.
- _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg._num_blocks);
- memset( _deltas, 0, sizeof(IndexSet*)* _cfg._num_blocks);
+ _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg.number_of_blocks());
+ memset( _deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks());
_free_IndexSet = NULL;
@@ -80,31 +77,32 @@
VectorSet first_pass(Thread::current()->resource_area());
// Outer loop: must compute local live-in sets and push into predecessors.
- uint iters = _cfg._num_blocks; // stat counters
- for( uint j=_cfg._num_blocks; j>0; j-- ) {
- Block *b = _cfg._blocks[j-1];
+ for (uint j = _cfg.number_of_blocks(); j > 0; j--) {
+ Block* block = _cfg.get_block(j - 1);
// Compute the local live-in set. Start with any new live-out bits.
- IndexSet *use = getset( b );
- IndexSet *def = &_defs[b->_pre_order-1];
+ IndexSet* use = getset(block);
+ IndexSet* def = &_defs[block->_pre_order-1];
DEBUG_ONLY(IndexSet *def_outside = getfreeset();)
uint i;
- for( i=b->_nodes.size(); i>1; i-- ) {
- Node *n = b->_nodes[i-1];
- if( n->is_Phi() ) break;
+ for (i = block->_nodes.size(); i > 1; i--) {
+ Node* n = block->_nodes[i-1];
+ if (n->is_Phi()) {
+ break;
+ }
uint r = _names[n->_idx];
assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block");
def->insert( r );
use->remove( r );
uint cnt = n->req();
- for( uint k=1; k<cnt; k++ ) {
+ for (uint k = 1; k < cnt; k++) {
Node *nk = n->in(k);
uint nkidx = nk->_idx;
- if (_cfg.get_block_for_node(nk) != b) {
+ if (_cfg.get_block_for_node(nk) != block) {
uint u = _names[nkidx];
- use->insert( u );
- DEBUG_ONLY(def_outside->insert( u );)
+ use->insert(u);
+ DEBUG_ONLY(def_outside->insert(u);)
}
}
}
@@ -113,41 +111,38 @@
_free_IndexSet = def_outside; // Drop onto free list
#endif
// Remove anything defined by Phis and the block start instruction
- for( uint k=i; k>0; k-- ) {
- uint r = _names[b->_nodes[k-1]->_idx];
- def->insert( r );
- use->remove( r );
+ for (uint k = i; k > 0; k--) {
+ uint r = _names[block->_nodes[k - 1]->_idx];
+ def->insert(r);
+ use->remove(r);
}
// Push these live-in things to predecessors
- for( uint l=1; l<b->num_preds(); l++ ) {
- Block *p = _cfg.get_block_for_node(b->pred(l));
- add_liveout( p, use, first_pass );
+ for (uint l = 1; l < block->num_preds(); l++) {
+ Block* p = _cfg.get_block_for_node(block->pred(l));
+ add_liveout(p, use, first_pass);
// PhiNode uses go in the live-out set of prior blocks.
- for( uint k=i; k>0; k-- )
- add_liveout( p, _names[b->_nodes[k-1]->in(l)->_idx], first_pass );
+ for (uint k = i; k > 0; k--) {
+ add_liveout(p, _names[block->_nodes[k-1]->in(l)->_idx], first_pass);
+ }
}
- freeset( b );
- first_pass.set(b->_pre_order);
+ freeset(block);
+ first_pass.set(block->_pre_order);
// Inner loop: blocks that picked up new live-out values to be propagated
- while( _worklist->size() ) {
- // !!!!!
-// #ifdef ASSERT
- iters++;
-// #endif
- Block *b = _worklist->pop();
- IndexSet *delta = getset(b);
+ while (_worklist->size()) {
+ Block* block = _worklist->pop();
+ IndexSet *delta = getset(block);
assert( delta->count(), "missing delta set" );
// Add new-live-in to predecessors live-out sets
- for (uint l = 1; l < b->num_preds(); l++) {
- Block* block = _cfg.get_block_for_node(b->pred(l));
- add_liveout(block, delta, first_pass);
+ for (uint l = 1; l < block->num_preds(); l++) {
+ Block* predecessor = _cfg.get_block_for_node(block->pred(l));
+ add_liveout(predecessor, delta, first_pass);
}
- freeset(b);
+ freeset(block);
} // End of while-worklist-not-empty
} // End of for-all-blocks-outer-loop
@@ -155,7 +150,7 @@
// We explicitly clear all of the IndexSets which we are about to release.
// This allows us to recycle their internal memory into IndexSet's free list.
- for( i=0; i<_cfg._num_blocks; i++ ) {
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
_defs[i].clear();
if (_deltas[i]) {
// Is this always true?
@@ -171,13 +166,11 @@
}
-//------------------------------stats------------------------------------------
#ifndef PRODUCT
void PhaseLive::stats(uint iters) const {
}
#endif
-//------------------------------getset-----------------------------------------
// Get an IndexSet for a block. Return existing one, if any. Make a new
// empty one if a prior one does not exist.
IndexSet *PhaseLive::getset( Block *p ) {
@@ -188,7 +181,6 @@
return delta; // Return set of new live-out items
}
-//------------------------------getfreeset-------------------------------------
// Pull from free list, or allocate. Internal allocation on the returned set
// is always from thread local storage.
IndexSet *PhaseLive::getfreeset( ) {
@@ -207,7 +199,6 @@
return f;
}
-//------------------------------freeset----------------------------------------
// Free an IndexSet from a block.
void PhaseLive::freeset( const Block *p ) {
IndexSet *f = _deltas[p->_pre_order-1];
@@ -216,7 +207,6 @@
_deltas[p->_pre_order-1] = NULL;
}
-//------------------------------add_liveout------------------------------------
// Add a live-out value to a given blocks live-out set. If it is new, then
// also add it to the delta set and stick the block on the worklist.
void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) {
@@ -233,8 +223,6 @@
}
}
-
-//------------------------------add_liveout------------------------------------
// Add a vector of live-out values to a given blocks live-out set.
void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) {
IndexSet *live = &_live[p->_pre_order-1];
@@ -262,7 +250,6 @@
}
#ifndef PRODUCT
-//------------------------------dump-------------------------------------------
// Dump the live-out set for a block
void PhaseLive::dump( const Block *b ) const {
tty->print("Block %d: ",b->_pre_order);
@@ -275,18 +262,19 @@
tty->print("\n");
}
-//------------------------------verify_base_ptrs-------------------------------
// Verify that base pointers and derived pointers are still sane.
void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
#ifdef ASSERT
Unique_Node_List worklist(a);
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- for( uint j = b->end_idx() + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j-1];
- if( n->is_Phi() ) break;
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
+ for (uint j = block->end_idx() + 1; j > 1; j--) {
+ Node* n = block->_nodes[j-1];
+ if (n->is_Phi()) {
+ break;
+ }
// Found a safepoint?
- if( n->is_MachSafePoint() ) {
+ if (n->is_MachSafePoint()) {
MachSafePointNode *sfpt = n->as_MachSafePoint();
JVMState* jvms = sfpt->jvms();
if (jvms != NULL) {
@@ -358,7 +346,6 @@
#endif
}
-//------------------------------verify-------------------------------------
// Verify that graphs and base pointers are still sane.
void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
#ifdef ASSERT
--- a/hotspot/src/share/vm/opto/matcher.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -67,8 +67,8 @@
const uint Matcher::_end_rematerialize = _END_REMATERIALIZE;
//---------------------------Matcher-------------------------------------------
-Matcher::Matcher( Node_List &proj_list ) :
- PhaseTransform( Phase::Ins_Select ),
+Matcher::Matcher()
+: PhaseTransform( Phase::Ins_Select ),
#ifdef ASSERT
_old2new_map(C->comp_arena()),
_new2old_map(C->comp_arena()),
@@ -78,7 +78,7 @@
_swallowed(swallowed),
_begin_inst_chain_rule(_BEGIN_INST_CHAIN_RULE),
_end_inst_chain_rule(_END_INST_CHAIN_RULE),
- _must_clone(must_clone), _proj_list(proj_list),
+ _must_clone(must_clone),
_register_save_policy(register_save_policy),
_c_reg_save_policy(c_reg_save_policy),
_register_save_type(register_save_type),
@@ -1304,8 +1304,9 @@
for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
proj->_rout.Insert(OptoReg::Name(i));
}
- if( proj->_rout.is_NotEmpty() )
- _proj_list.push(proj);
+ if (proj->_rout.is_NotEmpty()) {
+ push_projection(proj);
+ }
}
// Transfer the safepoint information from the call to the mcall
// Move the JVMState list
@@ -1685,14 +1686,15 @@
}
// If the _leaf is an AddP, insert the base edge
- if( leaf->is_AddP() )
+ if (leaf->is_AddP()) {
mach->ins_req(AddPNode::Base,leaf->in(AddPNode::Base));
+ }
- uint num_proj = _proj_list.size();
+ uint number_of_projections_prior = number_of_projections();
// Perform any 1-to-many expansions required
- MachNode *ex = mach->Expand(s,_proj_list, mem);
- if( ex != mach ) {
+ MachNode *ex = mach->Expand(s, _projection_list, mem);
+ if (ex != mach) {
assert(ex->ideal_reg() == mach->ideal_reg(), "ideal types should match");
if( ex->in(1)->is_Con() )
ex->in(1)->set_req(0, C->root());
@@ -1713,7 +1715,7 @@
// generated belatedly during spill code generation.
if (_allocation_started) {
guarantee(ex == mach, "no expand rules during spill generation");
- guarantee(_proj_list.size() == num_proj, "no allocation during spill generation");
+ guarantee(number_of_projections_prior == number_of_projections(), "no allocation during spill generation");
}
if (leaf->is_Con() || leaf->is_DecodeNarrowPtr()) {
--- a/hotspot/src/share/vm/opto/matcher.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/matcher.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -88,7 +88,7 @@
Node *transform( Node *dummy );
- Node_List &_proj_list; // For Machine nodes killing many values
+ Node_List _projection_list; // For Machine nodes killing many values
Node_Array _shared_nodes;
@@ -183,10 +183,30 @@
void collect_null_checks( Node *proj, Node *orig_proj );
void validate_null_checks( );
- Matcher( Node_List &proj_list );
+ Matcher();
+
+ // Get a projection node at position pos
+ Node* get_projection(uint pos) {
+ return _projection_list[pos];
+ }
+
+ // Push a projection node onto the projection list
+ void push_projection(Node* node) {
+ _projection_list.push(node);
+ }
+
+ Node* pop_projection() {
+ return _projection_list.pop();
+ }
+
+ // Number of nodes in the projection list
+ uint number_of_projections() const {
+ return _projection_list.size();
+ }
// Select instructions for entire method
- void match( );
+ void match();
+
// Helper for match
OptoReg::Name warp_incoming_stk_arg( VMReg reg );
--- a/hotspot/src/share/vm/opto/output.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -54,11 +54,10 @@
extern int emit_exception_handler(CodeBuffer &cbuf);
extern int emit_deopt_handler(CodeBuffer &cbuf);
-//------------------------------Output-----------------------------------------
// Convert Nodes to instruction bits and pass off to the VM
void Compile::Output() {
// RootNode goes
- assert( _cfg->_broot->_nodes.size() == 0, "" );
+ assert( _cfg->get_root_block()->_nodes.size() == 0, "" );
// The number of new nodes (mostly MachNop) is proportional to
// the number of java calls and inner loops which are aligned.
@@ -68,8 +67,8 @@
return;
}
// Make sure I can find the Start Node
- Block *entry = _cfg->_blocks[1];
- Block *broot = _cfg->_broot;
+ Block *entry = _cfg->get_block(1);
+ Block *broot = _cfg->get_root_block();
const StartNode *start = entry->_nodes[0]->as_Start();
@@ -109,40 +108,44 @@
}
// Insert epilogs before every return
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- Block *b = _cfg->_blocks[i];
- if( !b->is_connector() && b->non_connector_successor(0) == _cfg->_broot ) { // Found a program exit point?
- Node *m = b->end();
- if( m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt ) {
- MachEpilogNode *epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return);
- b->add_inst( epilog );
- _cfg->map_node_to_block(epilog, b);
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ Block* block = _cfg->get_block(i);
+ if (!block->is_connector() && block->non_connector_successor(0) == _cfg->get_root_block()) { // Found a program exit point?
+ Node* m = block->end();
+ if (m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt) {
+ MachEpilogNode* epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return);
+ block->add_inst(epilog);
+ _cfg->map_node_to_block(epilog, block);
}
}
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
- if ( ZapDeadCompiledLocals ) Insert_zap_nodes();
+ if (ZapDeadCompiledLocals) {
+ Insert_zap_nodes();
+ }
# endif
- uint* blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
- blk_starts[0] = 0;
+ uint* blk_starts = NEW_RESOURCE_ARRAY(uint, _cfg->number_of_blocks() + 1);
+ blk_starts[0] = 0;
// Initialize code buffer and process short branches.
CodeBuffer* cb = init_buffer(blk_starts);
- if (cb == NULL || failing()) return;
+ if (cb == NULL || failing()) {
+ return;
+ }
ScheduleAndBundle();
#ifndef PRODUCT
if (trace_opto_output()) {
tty->print("\n---- After ScheduleAndBundle ----\n");
- for (uint i = 0; i < _cfg->_num_blocks; i++) {
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
tty->print("\nBB#%03d:\n", i);
- Block *bb = _cfg->_blocks[i];
- for (uint j = 0; j < bb->_nodes.size(); j++) {
- Node *n = bb->_nodes[j];
+ Block* block = _cfg->get_block(i);
+ for (uint j = 0; j < block->_nodes.size(); j++) {
+ Node* n = block->_nodes[j];
OptoReg::Name reg = _regalloc->get_reg_first(n);
tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : "");
n->dump();
@@ -151,11 +154,15 @@
}
#endif
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
BuildOopMaps();
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
fill_buffer(cb, blk_starts);
}
@@ -217,8 +224,8 @@
return; // no safepoints/oopmaps emitted for calls in stubs,so we don't care
// Insert call to zap runtime stub before every node with an oop map
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- Block *b = _cfg->_blocks[i];
+ for( uint i=0; i<_cfg->number_of_blocks(); i++ ) {
+ Block *b = _cfg->get_block(i);
for ( uint j = 0; j < b->_nodes.size(); ++j ) {
Node *n = b->_nodes[j];
@@ -275,7 +282,6 @@
return _matcher->match_sfpt(ideal_node);
}
-//------------------------------is_node_getting_a_safepoint--------------------
bool Compile::is_node_getting_a_safepoint( Node* n) {
// This code duplicates the logic prior to the call of add_safepoint
// below in this file.
@@ -285,7 +291,6 @@
# endif // ENABLE_ZAP_DEAD_LOCALS
-//------------------------------compute_loop_first_inst_sizes------------------
// Compute the size of first NumberOfLoopInstrToAlign instructions at the top
// of a loop. When aligning a loop we need to provide enough instructions
// in cpu's fetch buffer to feed decoders. The loop alignment could be
@@ -302,42 +307,39 @@
// or alignment padding is larger then MaxLoopPad. By default, MaxLoopPad
// is equal to OptoLoopAlignment-1 except on new Intel cpus, where it is
// equal to 11 bytes which is the largest address NOP instruction.
- if( MaxLoopPad < OptoLoopAlignment-1 ) {
- uint last_block = _cfg->_num_blocks-1;
- for( uint i=1; i <= last_block; i++ ) {
- Block *b = _cfg->_blocks[i];
+ if (MaxLoopPad < OptoLoopAlignment - 1) {
+ uint last_block = _cfg->number_of_blocks() - 1;
+ for (uint i = 1; i <= last_block; i++) {
+ Block* block = _cfg->get_block(i);
// Check the first loop's block which requires an alignment.
- if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) {
+ if (block->loop_alignment() > (uint)relocInfo::addr_unit()) {
uint sum_size = 0;
uint inst_cnt = NumberOfLoopInstrToAlign;
- inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+ inst_cnt = block->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
// Check subsequent fallthrough blocks if the loop's first
// block(s) does not have enough instructions.
- Block *nb = b;
- while( inst_cnt > 0 &&
- i < last_block &&
- !_cfg->_blocks[i+1]->has_loop_alignment() &&
- !nb->has_successor(b) ) {
+ Block *nb = block;
+ while(inst_cnt > 0 &&
+ i < last_block &&
+ !_cfg->get_block(i + 1)->has_loop_alignment() &&
+ !nb->has_successor(block)) {
i++;
- nb = _cfg->_blocks[i];
+ nb = _cfg->get_block(i);
inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
} // while( inst_cnt > 0 && i < last_block )
- b->set_first_inst_size(sum_size);
+ block->set_first_inst_size(sum_size);
} // f( b->head()->is_Loop() )
} // for( i <= last_block )
} // if( MaxLoopPad < OptoLoopAlignment-1 )
}
-//----------------------shorten_branches---------------------------------------
// The architecture description provides short branch variants for some long
// branch instructions. Replace eligible long branches with short branches.
void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size) {
-
- // ------------------
// Compute size of each block, method size, and relocation information size
- uint nblocks = _cfg->_num_blocks;
+ uint nblocks = _cfg->number_of_blocks();
uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks);
uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks);
@@ -364,7 +366,7 @@
uint last_avoid_back_to_back_adr = max_uint;
uint nop_size = (new (this) MachNopNode())->size(_regalloc);
for (uint i = 0; i < nblocks; i++) { // For all blocks
- Block *b = _cfg->_blocks[i];
+ Block* block = _cfg->get_block(i);
// During short branch replacement, we store the relative (to blk_starts)
// offset of jump in jmp_offset, rather than the absolute offset of jump.
@@ -377,10 +379,10 @@
DEBUG_ONLY( jmp_rule[i] = 0; )
// Sum all instruction sizes to compute block size
- uint last_inst = b->_nodes.size();
+ uint last_inst = block->_nodes.size();
uint blk_size = 0;
for (uint j = 0; j < last_inst; j++) {
- Node* nj = b->_nodes[j];
+ Node* nj = block->_nodes[j];
// Handle machine instruction nodes
if (nj->is_Mach()) {
MachNode *mach = nj->as_Mach();
@@ -441,8 +443,8 @@
// When the next block starts a loop, we may insert pad NOP
// instructions. Since we cannot know our future alignment,
// assume the worst.
- if (i< nblocks-1) {
- Block *nb = _cfg->_blocks[i+1];
+ if (i < nblocks - 1) {
+ Block* nb = _cfg->get_block(i + 1);
int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit();
if (max_loop_pad > 0) {
assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), "");
@@ -473,26 +475,26 @@
has_short_branch_candidate = false;
int adjust_block_start = 0;
for (uint i = 0; i < nblocks; i++) {
- Block *b = _cfg->_blocks[i];
+ Block* block = _cfg->get_block(i);
int idx = jmp_nidx[i];
- MachNode* mach = (idx == -1) ? NULL: b->_nodes[idx]->as_Mach();
+ MachNode* mach = (idx == -1) ? NULL: block->_nodes[idx]->as_Mach();
if (mach != NULL && mach->may_be_short_branch()) {
#ifdef ASSERT
assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity");
int j;
// Find the branch; ignore trailing NOPs.
- for (j = b->_nodes.size()-1; j>=0; j--) {
- Node* n = b->_nodes[j];
+ for (j = block->_nodes.size()-1; j>=0; j--) {
+ Node* n = block->_nodes[j];
if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con)
break;
}
- assert(j >= 0 && j == idx && b->_nodes[j] == (Node*)mach, "sanity");
+ assert(j >= 0 && j == idx && block->_nodes[j] == (Node*)mach, "sanity");
#endif
int br_size = jmp_size[i];
int br_offs = blk_starts[i] + jmp_offset[i];
// This requires the TRUE branch target be in succs[0]
- uint bnum = b->non_connector_successor(0)->_pre_order;
+ uint bnum = block->non_connector_successor(0)->_pre_order;
int offset = blk_starts[bnum] - br_offs;
if (bnum > i) { // adjust following block's offset
offset -= adjust_block_start;
@@ -520,7 +522,7 @@
diff -= nop_size;
}
adjust_block_start += diff;
- b->_nodes.map(idx, replacement);
+ block->_nodes.map(idx, replacement);
mach->subsume_by(replacement, C);
mach = replacement;
progress = true;
@@ -1083,8 +1085,8 @@
if (has_mach_constant_base_node()) {
// Fill the constant table.
// Note: This must happen before shorten_branches.
- for (uint i = 0; i < _cfg->_num_blocks; i++) {
- Block* b = _cfg->_blocks[i];
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ Block* b = _cfg->get_block(i);
for (uint j = 0; j < b->_nodes.size(); j++) {
Node* n = b->_nodes[j];
@@ -1170,7 +1172,7 @@
// !!!!! This preserves old handling of oopmaps for now
debug_info()->set_oopmaps(_oop_map_set);
- uint nblocks = _cfg->_num_blocks;
+ uint nblocks = _cfg->number_of_blocks();
// Count and start of implicit null check instructions
uint inct_cnt = 0;
uint *inct_starts = NEW_RESOURCE_ARRAY(uint, nblocks+1);
@@ -1218,21 +1220,21 @@
// Now fill in the code buffer
Node *delay_slot = NULL;
- for (uint i=0; i < nblocks; i++) {
- Block *b = _cfg->_blocks[i];
-
- Node *head = b->head();
+ for (uint i = 0; i < nblocks; i++) {
+ Block* block = _cfg->get_block(i);
+ Node* head = block->head();
// If this block needs to start aligned (i.e, can be reached other
// than by falling-thru from the previous block), then force the
// start of a new bundle.
- if (Pipeline::requires_bundling() && starts_bundle(head))
+ if (Pipeline::requires_bundling() && starts_bundle(head)) {
cb->flush_bundle(true);
+ }
#ifdef ASSERT
- if (!b->is_connector()) {
+ if (!block->is_connector()) {
stringStream st;
- b->dump_head(_cfg, &st);
+ block->dump_head(_cfg, &st);
MacroAssembler(cb).block_comment(st.as_string());
}
jmp_target[i] = 0;
@@ -1243,16 +1245,16 @@
int blk_offset = current_offset;
// Define the label at the beginning of the basic block
- MacroAssembler(cb).bind(blk_labels[b->_pre_order]);
-
- uint last_inst = b->_nodes.size();
+ MacroAssembler(cb).bind(blk_labels[block->_pre_order]);
+
+ uint last_inst = block->_nodes.size();
// Emit block normally, except for last instruction.
// Emit means "dump code bits into code buffer".
for (uint j = 0; j<last_inst; j++) {
// Get the node
- Node* n = b->_nodes[j];
+ Node* n = block->_nodes[j];
// See if delay slots are supported
if (valid_bundle_info(n) &&
@@ -1306,9 +1308,9 @@
assert((padding % nop_size) == 0, "padding is not a multiple of NOP size");
int nops_cnt = padding / nop_size;
MachNode *nop = new (this) MachNopNode(nops_cnt);
- b->_nodes.insert(j++, nop);
+ block->_nodes.insert(j++, nop);
last_inst++;
- _cfg->map_node_to_block(nop, b);
+ _cfg->map_node_to_block(nop, block);
nop->emit(*cb, _regalloc);
cb->flush_bundle(true);
current_offset = cb->insts_size();
@@ -1322,7 +1324,7 @@
mcall->method_set((intptr_t)mcall->entry_point());
// Save the return address
- call_returns[b->_pre_order] = current_offset + mcall->ret_addr_offset();
+ call_returns[block->_pre_order] = current_offset + mcall->ret_addr_offset();
if (mcall->is_MachCallLeaf()) {
is_mcall = false;
@@ -1359,7 +1361,7 @@
// If this is a branch, then fill in the label with the target BB's label
else if (mach->is_MachBranch()) {
// This requires the TRUE branch target be in succs[0]
- uint block_num = b->non_connector_successor(0)->_pre_order;
+ uint block_num = block->non_connector_successor(0)->_pre_order;
// Try to replace long branch if delay slot is not used,
// it is mostly for back branches since forward branch's
@@ -1392,8 +1394,8 @@
// Insert padding between avoid_back_to_back branches.
if (needs_padding && replacement->avoid_back_to_back()) {
MachNode *nop = new (this) MachNopNode();
- b->_nodes.insert(j++, nop);
- _cfg->map_node_to_block(nop, b);
+ block->_nodes.insert(j++, nop);
+ _cfg->map_node_to_block(nop, block);
last_inst++;
nop->emit(*cb, _regalloc);
cb->flush_bundle(true);
@@ -1405,7 +1407,7 @@
jmp_size[i] = new_size;
jmp_rule[i] = mach->rule();
#endif
- b->_nodes.map(j, replacement);
+ block->_nodes.map(j, replacement);
mach->subsume_by(replacement, C);
n = replacement;
mach = replacement;
@@ -1413,8 +1415,8 @@
}
mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num );
} else if (mach->ideal_Opcode() == Op_Jump) {
- for (uint h = 0; h < b->_num_succs; h++) {
- Block* succs_block = b->_succs[h];
+ for (uint h = 0; h < block->_num_succs; h++) {
+ Block* succs_block = block->_succs[h];
for (uint j = 1; j < succs_block->num_preds(); j++) {
Node* jpn = succs_block->pred(j);
if (jpn->is_JumpProj() && jpn->in(0) == mach) {
@@ -1425,7 +1427,6 @@
}
}
}
-
#ifdef ASSERT
// Check that oop-store precedes the card-mark
else if (mach->ideal_Opcode() == Op_StoreCM) {
@@ -1436,17 +1437,18 @@
if (oop_store == NULL) continue;
count++;
uint i4;
- for( i4 = 0; i4 < last_inst; ++i4 ) {
- if( b->_nodes[i4] == oop_store ) break;
+ for (i4 = 0; i4 < last_inst; ++i4) {
+ if (block->_nodes[i4] == oop_store) {
+ break;
+ }
}
// Note: This test can provide a false failure if other precedence
// edges have been added to the storeCMNode.
- assert( i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store");
+ assert(i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store");
}
assert(count > 0, "storeCM expects at least one precedence edge");
}
#endif
-
else if (!n->is_Proj()) {
// Remember the beginning of the previous instruction, in case
// it's followed by a flag-kill and a null-check. Happens on
@@ -1542,12 +1544,12 @@
// If the next block is the top of a loop, pad this block out to align
// the loop top a little. Helps prevent pipe stalls at loop back branches.
if (i < nblocks-1) {
- Block *nb = _cfg->_blocks[i+1];
+ Block *nb = _cfg->get_block(i + 1);
int padding = nb->alignment_padding(current_offset);
if( padding > 0 ) {
MachNode *nop = new (this) MachNopNode(padding / nop_size);
- b->_nodes.insert( b->_nodes.size(), nop );
- _cfg->map_node_to_block(nop, b);
+ block->_nodes.insert(block->_nodes.size(), nop);
+ _cfg->map_node_to_block(nop, block);
nop->emit(*cb, _regalloc);
current_offset = cb->insts_size();
}
@@ -1587,8 +1589,6 @@
}
#endif
- // ------------------
-
#ifndef PRODUCT
// Information on the size of the method, without the extraneous code
Scheduling::increment_method_size(cb->insts_size());
@@ -1649,52 +1649,55 @@
_inc_table.set_size(cnt);
uint inct_cnt = 0;
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- Block *b = _cfg->_blocks[i];
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ Block* block = _cfg->get_block(i);
Node *n = NULL;
int j;
// Find the branch; ignore trailing NOPs.
- for( j = b->_nodes.size()-1; j>=0; j-- ) {
- n = b->_nodes[j];
- if( !n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con )
+ for (j = block->_nodes.size() - 1; j >= 0; j--) {
+ n = block->_nodes[j];
+ if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) {
break;
+ }
}
// If we didn't find anything, continue
- if( j < 0 ) continue;
+ if (j < 0) {
+ continue;
+ }
// Compute ExceptionHandlerTable subtable entry and add it
// (skip empty blocks)
- if( n->is_Catch() ) {
+ if (n->is_Catch()) {
// Get the offset of the return from the call
- uint call_return = call_returns[b->_pre_order];
+ uint call_return = call_returns[block->_pre_order];
#ifdef ASSERT
assert( call_return > 0, "no call seen for this basic block" );
- while( b->_nodes[--j]->is_MachProj() ) ;
- assert( b->_nodes[j]->is_MachCall(), "CatchProj must follow call" );
+ while (block->_nodes[--j]->is_MachProj()) ;
+ assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call");
#endif
// last instruction is a CatchNode, find it's CatchProjNodes
- int nof_succs = b->_num_succs;
+ int nof_succs = block->_num_succs;
// allocate space
GrowableArray<intptr_t> handler_bcis(nof_succs);
GrowableArray<intptr_t> handler_pcos(nof_succs);
// iterate through all successors
for (int j = 0; j < nof_succs; j++) {
- Block* s = b->_succs[j];
+ Block* s = block->_succs[j];
bool found_p = false;
- for( uint k = 1; k < s->num_preds(); k++ ) {
- Node *pk = s->pred(k);
- if( pk->is_CatchProj() && pk->in(0) == n ) {
+ for (uint k = 1; k < s->num_preds(); k++) {
+ Node* pk = s->pred(k);
+ if (pk->is_CatchProj() && pk->in(0) == n) {
const CatchProjNode* p = pk->as_CatchProj();
found_p = true;
// add the corresponding handler bci & pco information
- if( p->_con != CatchProjNode::fall_through_index ) {
+ if (p->_con != CatchProjNode::fall_through_index) {
// p leads to an exception handler (and is not fall through)
- assert(s == _cfg->_blocks[s->_pre_order],"bad numbering");
+ assert(s == _cfg->get_block(s->_pre_order), "bad numbering");
// no duplicates, please
- if( !handler_bcis.contains(p->handler_bci()) ) {
+ if (!handler_bcis.contains(p->handler_bci())) {
uint block_num = s->non_connector()->_pre_order;
handler_bcis.append(p->handler_bci());
handler_pcos.append(blk_labels[block_num].loc_pos());
@@ -1713,9 +1716,9 @@
}
// Handle implicit null exception table updates
- if( n->is_MachNullCheck() ) {
- uint block_num = b->non_connector_successor(0)->_pre_order;
- _inc_table.append( inct_starts[inct_cnt++], blk_labels[block_num].loc_pos() );
+ if (n->is_MachNullCheck()) {
+ uint block_num = block->non_connector_successor(0)->_pre_order;
+ _inc_table.append(inct_starts[inct_cnt++], blk_labels[block_num].loc_pos());
continue;
}
} // End of for all blocks fill in exception table entries
@@ -1774,14 +1777,12 @@
memset(_current_latency, 0, node_max * sizeof(unsigned short));
// Clear the bundling information
- memcpy(_bundle_use_elements,
- Pipeline_Use::elaborated_elements,
- sizeof(Pipeline_Use::elaborated_elements));
+ memcpy(_bundle_use_elements, Pipeline_Use::elaborated_elements, sizeof(Pipeline_Use::elaborated_elements));
// Get the last node
- Block *bb = _cfg->_blocks[_cfg->_blocks.size()-1];
-
- _next_node = bb->_nodes[bb->_nodes.size()-1];
+ Block* block = _cfg->get_block(_cfg->number_of_blocks() - 1);
+
+ _next_node = block->_nodes[block->_nodes.size() - 1];
}
#ifndef PRODUCT
@@ -1831,7 +1832,6 @@
sizeof(Pipeline_Use::elaborated_elements));
}
-//------------------------------ScheduleAndBundle------------------------------
// Perform instruction scheduling and bundling over the sequence of
// instructions in backwards order.
void Compile::ScheduleAndBundle() {
@@ -1858,7 +1858,6 @@
scheduling.DoScheduling();
}
-//------------------------------ComputeLocalLatenciesForward-------------------
// Compute the latency of all the instructions. This is fairly simple,
// because we already have a legal ordering. Walk over the instructions
// from first to last, and compute the latency of the instruction based
@@ -2028,7 +2027,6 @@
return _available[0];
}
-//------------------------------AddNodeToAvailableList-------------------------
void Scheduling::AddNodeToAvailableList(Node *n) {
assert( !n->is_Proj(), "projections never directly made available" );
#ifndef PRODUCT
@@ -2074,7 +2072,6 @@
#endif
}
-//------------------------------DecrementUseCounts-----------------------------
void Scheduling::DecrementUseCounts(Node *n, const Block *bb) {
for ( uint i=0; i < n->len(); i++ ) {
Node *def = n->in(i);
@@ -2097,7 +2094,6 @@
}
}
-//------------------------------AddNodeToBundle--------------------------------
void Scheduling::AddNodeToBundle(Node *n, const Block *bb) {
#ifndef PRODUCT
if (_cfg->C->trace_opto_output()) {
@@ -2312,7 +2308,6 @@
DecrementUseCounts(n,bb);
}
-//------------------------------ComputeUseCount--------------------------------
// This method sets the use count within a basic block. We will ignore all
// uses outside the current basic block. As we are doing a backwards walk,
// any node we reach that has a use count of 0 may be scheduled. This also
@@ -2397,20 +2392,22 @@
Block *bb;
// Walk over all the basic blocks in reverse order
- for( int i=_cfg->_num_blocks-1; i >= 0; succ_bb = bb, i-- ) {
- bb = _cfg->_blocks[i];
+ for (int i = _cfg->number_of_blocks() - 1; i >= 0; succ_bb = bb, i--) {
+ bb = _cfg->get_block(i);
#ifndef PRODUCT
if (_cfg->C->trace_opto_output()) {
tty->print("# Schedule BB#%03d (initial)\n", i);
- for (uint j = 0; j < bb->_nodes.size(); j++)
+ for (uint j = 0; j < bb->_nodes.size(); j++) {
bb->_nodes[j]->dump();
+ }
}
#endif
// On the head node, skip processing
- if( bb == _cfg->_broot )
+ if (bb == _cfg->get_root_block()) {
continue;
+ }
// Skip empty, connector blocks
if (bb->is_connector())
@@ -2547,7 +2544,6 @@
} // end DoScheduling
-//------------------------------verify_good_schedule---------------------------
// Verify that no live-range used in the block is killed in the block by a
// wrong DEF. This doesn't verify live-ranges that span blocks.
@@ -2560,7 +2556,6 @@
}
#ifdef ASSERT
-//------------------------------verify_do_def----------------------------------
void Scheduling::verify_do_def( Node *n, OptoReg::Name def, const char *msg ) {
// Check for bad kills
if( OptoReg::is_valid(def) ) { // Ignore stores & control flow
@@ -2576,7 +2571,6 @@
}
}
-//------------------------------verify_good_schedule---------------------------
void Scheduling::verify_good_schedule( Block *b, const char *msg ) {
// Zap to something reasonable for the verify code
@@ -2636,7 +2630,6 @@
from->add_prec(to);
}
-//------------------------------anti_do_def------------------------------------
void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is_def ) {
if( !OptoReg::is_valid(def_reg) ) // Ignore stores & control flow
return;
@@ -2706,7 +2699,6 @@
add_prec_edge_from_to(kill,pinch);
}
-//------------------------------anti_do_use------------------------------------
void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) {
if( !OptoReg::is_valid(use_reg) ) // Ignore stores & control flow
return;
@@ -2727,7 +2719,6 @@
}
}
-//------------------------------ComputeRegisterAntidependences-----------------
// We insert antidependences between the reads and following write of
// allocated registers to prevent illegal code motion. Hopefully, the
// number of added references should be fairly small, especially as we
@@ -2861,8 +2852,6 @@
}
}
-//------------------------------garbage_collect_pinch_nodes-------------------------------
-
// Garbage collect pinch nodes for reuse by other blocks.
//
// The block scheduler's insertion of anti-dependence
@@ -2937,7 +2926,6 @@
pinch->set_req(0, NULL);
}
-//------------------------------print_statistics-------------------------------
#ifndef PRODUCT
void Scheduling::dump_available() const {
--- a/hotspot/src/share/vm/opto/phaseX.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1643,8 +1643,8 @@
bool method_name_not_printed = true;
// Examine each basic block
- for( uint block_number = 1; block_number < _cfg._num_blocks; ++block_number ) {
- Block *block = _cfg._blocks[block_number];
+ for (uint block_number = 1; block_number < _cfg.number_of_blocks(); ++block_number) {
+ Block* block = _cfg.get_block(block_number);
bool block_not_printed = true;
// and each instruction within a block
--- a/hotspot/src/share/vm/opto/postaloc.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/postaloc.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -405,28 +405,29 @@
// Need a mapping from basic block Node_Lists. We need a Node_List to
// map from register number to value-producing Node.
- Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1);
- memset( blk2value, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) );
+ Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
+ memset(blk2value, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
// Need a mapping from basic block Node_Lists. We need a Node_List to
// map from register number to register-defining Node.
- Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1);
- memset( blk2regnd, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) );
+ Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
+ memset(blk2regnd, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
// We keep unused Node_Lists on a free_list to avoid wasting
// memory.
GrowableArray<Node_List*> free_list = GrowableArray<Node_List*>(16);
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
uint j;
- Block *b = _cfg._blocks[i];
+ Block* block = _cfg.get_block(i);
// Count of Phis in block
uint phi_dex;
- for( phi_dex = 1; phi_dex < b->_nodes.size(); phi_dex++ ) {
- Node *phi = b->_nodes[phi_dex];
- if( !phi->is_Phi() )
+ for (phi_dex = 1; phi_dex < block->_nodes.size(); phi_dex++) {
+ Node* phi = block->_nodes[phi_dex];
+ if (!phi->is_Phi()) {
break;
+ }
}
// If any predecessor has not been visited, we do not know the state
@@ -434,21 +435,23 @@
// along Phi input edges
bool missing_some_inputs = false;
Block *freed = NULL;
- for( j = 1; j < b->num_preds(); j++ ) {
- Block *pb = _cfg.get_block_for_node(b->pred(j));
+ for (j = 1; j < block->num_preds(); j++) {
+ Block* pb = _cfg.get_block_for_node(block->pred(j));
// Remove copies along phi edges
- for( uint k=1; k<phi_dex; k++ )
- elide_copy( b->_nodes[k], j, b, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false );
- if( blk2value[pb->_pre_order] ) { // Have a mapping on this edge?
+ for (uint k = 1; k < phi_dex; k++) {
+ elide_copy(block->_nodes[k], j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false);
+ }
+ if (blk2value[pb->_pre_order]) { // Have a mapping on this edge?
// See if this predecessor's mappings have been used by everybody
// who wants them. If so, free 'em.
uint k;
- for( k=0; k<pb->_num_succs; k++ ) {
- Block *pbsucc = pb->_succs[k];
- if( !blk2value[pbsucc->_pre_order] && pbsucc != b )
+ for (k = 0; k < pb->_num_succs; k++) {
+ Block* pbsucc = pb->_succs[k];
+ if (!blk2value[pbsucc->_pre_order] && pbsucc != block) {
break; // Found a future user
+ }
}
- if( k >= pb->_num_succs ) { // No more uses, free!
+ if (k >= pb->_num_succs) { // No more uses, free!
freed = pb; // Record last block freed
free_list.push(blk2value[pb->_pre_order]);
free_list.push(blk2regnd[pb->_pre_order]);
@@ -467,20 +470,20 @@
value.map(_max_reg,NULL);
regnd.map(_max_reg,NULL);
// Set mappings as OUR mappings
- blk2value[b->_pre_order] = &value;
- blk2regnd[b->_pre_order] = ®nd;
+ blk2value[block->_pre_order] = &value;
+ blk2regnd[block->_pre_order] = ®nd;
// Initialize value & regnd for this block
- if( missing_some_inputs ) {
+ if (missing_some_inputs) {
// Some predecessor has not yet been visited; zap map to empty
- for( uint k = 0; k < (uint)_max_reg; k++ ) {
+ for (uint k = 0; k < (uint)_max_reg; k++) {
value.map(k,NULL);
regnd.map(k,NULL);
}
} else {
if( !freed ) { // Didn't get a freebie prior block
// Must clone some data
- freed = _cfg.get_block_for_node(b->pred(1));
+ freed = _cfg.get_block_for_node(block->pred(1));
Node_List &f_value = *blk2value[freed->_pre_order];
Node_List &f_regnd = *blk2regnd[freed->_pre_order];
for( uint k = 0; k < (uint)_max_reg; k++ ) {
@@ -489,9 +492,11 @@
}
}
// Merge all inputs together, setting to NULL any conflicts.
- for( j = 1; j < b->num_preds(); j++ ) {
- Block *pb = _cfg.get_block_for_node(b->pred(j));
- if( pb == freed ) continue; // Did self already via freelist
+ for (j = 1; j < block->num_preds(); j++) {
+ Block* pb = _cfg.get_block_for_node(block->pred(j));
+ if (pb == freed) {
+ continue; // Did self already via freelist
+ }
Node_List &p_regnd = *blk2regnd[pb->_pre_order];
for( uint k = 0; k < (uint)_max_reg; k++ ) {
if( regnd[k] != p_regnd[k] ) { // Conflict on reaching defs?
@@ -503,9 +508,9 @@
}
// For all Phi's
- for( j = 1; j < phi_dex; j++ ) {
+ for (j = 1; j < phi_dex; j++) {
uint k;
- Node *phi = b->_nodes[j];
+ Node *phi = block->_nodes[j];
uint pidx = _lrg_map.live_range_id(phi);
OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg();
@@ -516,8 +521,8 @@
if( phi != x && u != x ) // Found a different input
u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
}
- if( u != NodeSentinel ) { // Junk Phi. Remove
- b->_nodes.remove(j--);
+ if (u != NodeSentinel) { // Junk Phi. Remove
+ block->_nodes.remove(j--);
phi_dex--;
_cfg.unmap_node_from_block(phi);
phi->replace_by(u);
@@ -547,13 +552,13 @@
}
// For all remaining instructions
- for( j = phi_dex; j < b->_nodes.size(); j++ ) {
- Node *n = b->_nodes[j];
+ for (j = phi_dex; j < block->_nodes.size(); j++) {
+ Node* n = block->_nodes[j];
- if( n->outcnt() == 0 && // Dead?
- n != C->top() && // (ignore TOP, it has no du info)
- !n->is_Proj() ) { // fat-proj kills
- j -= yank_if_dead(n,b,&value,®nd);
+ if(n->outcnt() == 0 && // Dead?
+ n != C->top() && // (ignore TOP, it has no du info)
+ !n->is_Proj() ) { // fat-proj kills
+ j -= yank_if_dead(n, block, &value, ®nd);
continue;
}
@@ -598,8 +603,9 @@
const uint two_adr = n->is_Mach() ? n->as_Mach()->two_adr() : 0;
// Remove copies along input edges
- for( k = 1; k < n->req(); k++ )
- j -= elide_copy( n, k, b, value, regnd, two_adr!=k );
+ for (k = 1; k < n->req(); k++) {
+ j -= elide_copy(n, k, block, value, regnd, two_adr != k);
+ }
// Unallocated Nodes define no registers
uint lidx = _lrg_map.live_range_id(n);
@@ -630,8 +636,8 @@
// then 'n' is a useless copy. Do not update the register->node
// mapping so 'n' will go dead.
if( value[nreg] != val ) {
- if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) {
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ if (eliminate_copy_of_constant(val, n, block, value, regnd, nreg, OptoReg::Bad)) {
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
} else {
// Update the mapping: record new Node defined by the register
regnd.map(nreg,n);
@@ -640,8 +646,8 @@
value.map(nreg,val);
}
} else if( !may_be_copy_of_callee(n) ) {
- assert( n->is_Copy(), "" );
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ assert(n->is_Copy(), "");
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
}
} else if (RegMask::is_vector(n_ideal_reg)) {
// If Node 'n' does not change the value mapped by the register,
@@ -660,7 +666,7 @@
}
} else if (n->is_Copy()) {
// Note: vector can't be constant and can't be copy of calee.
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
}
} else {
// If the value occupies a register pair, record same info
@@ -674,18 +680,18 @@
tmp.Remove(nreg);
nreg_lo = tmp.find_first_elem();
}
- if( value[nreg] != val || value[nreg_lo] != val ) {
- if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) {
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ if (value[nreg] != val || value[nreg_lo] != val) {
+ if (eliminate_copy_of_constant(val, n, block, value, regnd, nreg, nreg_lo)) {
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
} else {
regnd.map(nreg , n );
regnd.map(nreg_lo, n );
value.map(nreg ,val);
value.map(nreg_lo,val);
}
- } else if( !may_be_copy_of_callee(n) ) {
- assert( n->is_Copy(), "" );
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ } else if (!may_be_copy_of_callee(n)) {
+ assert(n->is_Copy(), "");
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
}
}
--- a/hotspot/src/share/vm/opto/reg_split.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/opto/reg_split.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -397,10 +397,15 @@
#endif
// See if the cloned def kills any flags, and copy those kills as well
uint i = insidx+1;
- if( clone_projs( b, i, def, spill, maxlrg) ) {
+ int found_projs = clone_projs( b, i, def, spill, maxlrg);
+ if (found_projs > 0) {
// Adjust the point where we go hi-pressure
- if( i <= b->_ihrp_index ) b->_ihrp_index++;
- if( i <= b->_fhrp_index ) b->_fhrp_index++;
+ if (i <= b->_ihrp_index) {
+ b->_ihrp_index += found_projs;
+ }
+ if (i <= b->_fhrp_index) {
+ b->_fhrp_index += found_projs;
+ }
}
return spill;
@@ -529,13 +534,13 @@
// a Def is UP or DOWN. UP means that it should get a register (ie -
// it is always in LRP regions), and DOWN means that it is probably
// on the stack (ie - it crosses HRP regions).
- Node ***Reaches = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
- bool **UP = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
+ Node ***Reaches = NEW_SPLIT_ARRAY( Node**, _cfg.number_of_blocks() + 1);
+ bool **UP = NEW_SPLIT_ARRAY( bool*, _cfg.number_of_blocks() + 1);
Node **debug_defs = NEW_SPLIT_ARRAY( Node*, spill_cnt );
VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
// Initialize Reaches & UP
- for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
+ for (bidx = 0; bidx < _cfg.number_of_blocks() + 1; bidx++) {
Reaches[bidx] = NEW_SPLIT_ARRAY( Node*, spill_cnt );
UP[bidx] = NEW_SPLIT_ARRAY( bool, spill_cnt );
Node **Reachblock = Reaches[bidx];
@@ -555,13 +560,13 @@
//----------PASS 1----------
//----------Propagation & Node Insertion Code----------
// Walk the Blocks in RPO for DEF & USE info
- for( bidx = 0; bidx < _cfg._num_blocks; bidx++ ) {
+ for( bidx = 0; bidx < _cfg.number_of_blocks(); bidx++ ) {
if (C->check_node_count(spill_cnt, out_of_nodes)) {
return 0;
}
- b = _cfg._blocks[bidx];
+ b = _cfg.get_block(bidx);
// Reaches & UP arrays for this block
Reachblock = Reaches[b->_pre_order];
UPblock = UP[b->_pre_order];
@@ -1394,8 +1399,8 @@
// DEBUG
#ifdef ASSERT
// Validate all live range index assignments
- for (bidx = 0; bidx < _cfg._num_blocks; bidx++) {
- b = _cfg._blocks[bidx];
+ for (bidx = 0; bidx < _cfg.number_of_blocks(); bidx++) {
+ b = _cfg.get_block(bidx);
for (insidx = 0; insidx <= b->end_idx(); insidx++) {
Node *n = b->_nodes[insidx];
uint defidx = _lrg_map.find(n);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1554,6 +1554,20 @@
return false;
}
+ // rewrite sourc file name index:
+ u2 source_file_name_idx = scratch_class->source_file_name_index();
+ if (source_file_name_idx != 0) {
+ u2 new_source_file_name_idx = find_new_index(source_file_name_idx);
+ scratch_class->set_source_file_name_index(new_source_file_name_idx);
+ }
+
+ // rewrite class generic signature index:
+ u2 generic_signature_index = scratch_class->generic_signature_index();
+ if (generic_signature_index != 0) {
+ u2 new_generic_signature_index = find_new_index(generic_signature_index);
+ scratch_class->set_generic_signature_index(new_generic_signature_index);
+ }
+
return true;
} // end rewrite_cp_refs()
@@ -3370,7 +3384,8 @@
// Leave arrays of jmethodIDs and itable index cache unchanged
// Copy the "source file name" attribute from new class version
- the_class->set_source_file_name(scratch_class->source_file_name());
+ the_class->set_source_file_name_index(
+ scratch_class->source_file_name_index());
// Copy the "source debug extension" attribute from new class version
the_class->set_source_debug_extension(
--- a/hotspot/src/share/vm/prims/whitebox.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -196,12 +196,22 @@
VMThread::execute(&op);
WB_END
-WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method))
+WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
int result = 0;
- nmethod* code = mh->code();
+ nmethod* code;
+ if (is_osr) {
+ int bci = InvocationEntryBci;
+ while ((code = mh->lookup_osr_nmethod_for(bci, CompLevel_none, false)) != NULL) {
+ code->mark_for_deoptimization();
+ ++result;
+ bci = code->osr_entry_bci() + 1;
+ }
+ } else {
+ code = mh->code();
+ }
if (code != NULL) {
code->mark_for_deoptimization();
++result;
@@ -214,22 +224,26 @@
return result;
WB_END
-WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method))
+WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
- nmethod* code = mh->code();
+ nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
if (code == NULL) {
return JNI_FALSE;
}
return (code->is_alive() && !code->is_marked_for_deoptimization());
WB_END
-WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level))
+WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
- return CompilationPolicy::can_be_compiled(mh, comp_level);
+ if (is_osr) {
+ return CompilationPolicy::can_be_osr_compiled(mh, comp_level);
+ } else {
+ return CompilationPolicy::can_be_compiled(mh, comp_level);
+ }
WB_END
WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
@@ -239,18 +253,28 @@
return mh->queued_for_compilation();
WB_END
-WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method))
+WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
- nmethod* code = mh->code();
+ nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
return (code != NULL ? code->comp_level() : CompLevel_none);
WB_END
-
-WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level))
+WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
- mh->set_not_compilable(comp_level, true /* report */, "WhiteBox");
+ if (is_osr) {
+ mh->set_not_osr_compilable(comp_level, true /* report */, "WhiteBox");
+ } else {
+ mh->set_not_compilable(comp_level, true /* report */, "WhiteBox");
+ }
+WB_END
+
+WB_ENTRY(jint, WB_GetMethodEntryBci(JNIEnv* env, jobject o, jobject method))
+ jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+ methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+ nmethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false);
+ return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci);
WB_END
WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
@@ -261,12 +285,15 @@
return result;
WB_END
-WB_ENTRY(jint, WB_GetCompileQueuesSize(JNIEnv* env, jobject o))
- return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
- CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
+WB_ENTRY(jint, WB_GetCompileQueueSize(JNIEnv* env, jobject o, jint comp_level))
+ if (comp_level == CompLevel_any) {
+ return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
+ CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
+ } else {
+ return CompileBroker::queue_size(comp_level);
+ }
WB_END
-
WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
@@ -275,10 +302,10 @@
return result;
WB_END
-WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level))
+WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
- nmethod* nm = CompileBroker::compile_method(mh, InvocationEntryBci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
+ nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
MutexLockerEx mu(Compile_lock);
return (mh->queued_for_compilation() || nm != NULL);
WB_END
@@ -324,7 +351,6 @@
return (StringTable::lookup(name, len) != NULL);
WB_END
-
WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
Universe::heap()->collect(GCCause::_last_ditch_collection);
@@ -423,31 +449,32 @@
{CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge},
#endif // INCLUDE_NMT
{CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
- {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;)I",
+ {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
(void*)&WB_DeoptimizeMethod },
- {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;)Z",
+ {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;Z)Z",
(void*)&WB_IsMethodCompiled },
- {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;I)Z",
+ {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;IZ)Z",
(void*)&WB_IsMethodCompilable},
{CC"isMethodQueuedForCompilation",
CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation},
{CC"makeMethodNotCompilable",
- CC"(Ljava/lang/reflect/Executable;I)V", (void*)&WB_MakeMethodNotCompilable},
+ CC"(Ljava/lang/reflect/Executable;IZ)V", (void*)&WB_MakeMethodNotCompilable},
{CC"testSetDontInlineMethod",
CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod},
{CC"getMethodCompilationLevel",
- CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodCompilationLevel},
- {CC"getCompileQueuesSize",
- CC"()I", (void*)&WB_GetCompileQueuesSize},
+ CC"(Ljava/lang/reflect/Executable;Z)I", (void*)&WB_GetMethodCompilationLevel},
+ {CC"getMethodEntryBci",
+ CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci},
+ {CC"getCompileQueueSize",
+ CC"(I)I", (void*)&WB_GetCompileQueueSize},
{CC"testSetForceInlineMethod",
CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod},
{CC"enqueueMethodForCompilation",
- CC"(Ljava/lang/reflect/Executable;I)Z", (void*)&WB_EnqueueMethodForCompilation},
+ CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation},
{CC"clearMethodState",
CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
{CC"fullGC", CC"()V", (void*)&WB_FullGC },
-
{CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
};
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1393,10 +1393,8 @@
inline uintx max_heap_for_compressed_oops() {
// Avoid sign flip.
- if (OopEncodingHeapMax < ClassMetaspaceSize + os::vm_page_size()) {
- return 0;
- }
- LP64_ONLY(return OopEncodingHeapMax - ClassMetaspaceSize - os::vm_page_size());
+ assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size");
+ LP64_ONLY(return OopEncodingHeapMax - os::vm_page_size());
NOT_LP64(ShouldNotReachHere(); return 0);
}
@@ -1448,6 +1446,35 @@
#endif // ZERO
}
+
+// NOTE: set_use_compressed_klass_ptrs() must be called after calling
+// set_use_compressed_oops().
+void Arguments::set_use_compressed_klass_ptrs() {
+#ifndef ZERO
+#ifdef _LP64
+ // UseCompressedOops must be on for UseCompressedKlassPointers to be on.
+ if (!UseCompressedOops) {
+ if (UseCompressedKlassPointers) {
+ warning("UseCompressedKlassPointers requires UseCompressedOops");
+ }
+ FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
+ } else {
+ // Turn on UseCompressedKlassPointers too
+ if (FLAG_IS_DEFAULT(UseCompressedKlassPointers)) {
+ FLAG_SET_ERGO(bool, UseCompressedKlassPointers, true);
+ }
+ // Check the ClassMetaspaceSize to make sure we use compressed klass ptrs.
+ if (UseCompressedKlassPointers) {
+ if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
+ warning("Class metaspace size is too large for UseCompressedKlassPointers");
+ FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
+ }
+ }
+ }
+#endif // _LP64
+#endif // !ZERO
+}
+
void Arguments::set_ergonomics_flags() {
if (os::is_server_class_machine()) {
@@ -1470,7 +1497,8 @@
// server performance. On server class machines, keep the default
// off unless it is asked for. Future work: either add bytecode rewriting
// at link time, or rewrite bytecodes in non-shared methods.
- if (!DumpSharedSpaces && !RequireSharedSpaces) {
+ if (!DumpSharedSpaces && !RequireSharedSpaces &&
+ (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
no_shared_spaces();
}
}
@@ -1478,33 +1506,11 @@
#ifndef ZERO
#ifdef _LP64
set_use_compressed_oops();
- // UseCompressedOops must be on for UseCompressedKlassPointers to be on.
- if (!UseCompressedOops) {
- if (UseCompressedKlassPointers) {
- warning("UseCompressedKlassPointers requires UseCompressedOops");
- }
- FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
- } else {
- // Turn on UseCompressedKlassPointers too
- if (FLAG_IS_DEFAULT(UseCompressedKlassPointers)) {
- FLAG_SET_ERGO(bool, UseCompressedKlassPointers, true);
- }
- // Set the ClassMetaspaceSize to something that will not need to be
- // expanded, since it cannot be expanded.
- if (UseCompressedKlassPointers) {
- if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
- warning("Class metaspace size is too large for UseCompressedKlassPointers");
- FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
- } else if (FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
- // 100,000 classes seems like a good size, so 100M assumes around 1K
- // per klass. The vtable and oopMap is embedded so we don't have a fixed
- // size per klass. Eventually, this will be parameterized because it
- // would also be useful to determine the optimal size of the
- // systemDictionary.
- FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
- }
- }
- }
+
+ // set_use_compressed_klass_ptrs() must be called after calling
+ // set_use_compressed_oops().
+ set_use_compressed_klass_ptrs();
+
// Also checks that certain machines are slower with compressed oops
// in vm_version initialization code.
#endif // _LP64
@@ -2153,7 +2159,7 @@
status = status && verify_object_alignment();
- status = status && verify_min_value(ClassMetaspaceSize, 1*M,
+ status = status && verify_interval(ClassMetaspaceSize, 1*M, 3*G,
"ClassMetaspaceSize");
status = status && verify_interval(MarkStackSizeMax,
@@ -3273,33 +3279,22 @@
}
void Arguments::set_shared_spaces_flags() {
-#ifdef _LP64
- const bool must_share = DumpSharedSpaces || RequireSharedSpaces;
-
- // CompressedOops cannot be used with CDS. The offsets of oopmaps and
- // static fields are incorrect in the archive. With some more clever
- // initialization, this restriction can probably be lifted.
- if (UseCompressedOops) {
- if (must_share) {
- warning("disabling compressed oops because of %s",
- DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on");
- FLAG_SET_CMDLINE(bool, UseCompressedOops, false);
- FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false);
- } else {
- // Prefer compressed oops to class data sharing
- if (UseSharedSpaces && Verbose) {
- warning("turning off use of shared archive because of compressed oops");
- }
- no_shared_spaces();
- }
- }
-#endif
-
if (DumpSharedSpaces) {
if (RequireSharedSpaces) {
warning("cannot dump shared archive while using shared archive");
}
UseSharedSpaces = false;
+#ifdef _LP64
+ if (!UseCompressedOops || !UseCompressedKlassPointers) {
+ vm_exit_during_initialization(
+ "Cannot dump shared archive when UseCompressedOops or UseCompressedKlassPointers is off.", NULL);
+ }
+ } else {
+ // UseCompressedOops and UseCompressedKlassPointers must be on for UseSharedSpaces.
+ if (!UseCompressedOops || !UseCompressedKlassPointers) {
+ no_shared_spaces();
+ }
+#endif
}
}
--- a/hotspot/src/share/vm/runtime/arguments.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -309,6 +309,7 @@
static void set_g1_gc_flags();
// GC ergonomics
static void set_use_compressed_oops();
+ static void set_use_compressed_klass_ptrs();
static void set_ergonomics_flags();
static void set_shared_spaces_flags();
// limits the given memory size by the maximum amount of memory this process is
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -138,6 +138,23 @@
return false;
}
+// Returns true if m is allowed to be osr compiled
+bool CompilationPolicy::can_be_osr_compiled(methodHandle m, int comp_level) {
+ bool result = false;
+ if (comp_level == CompLevel_all) {
+ if (TieredCompilation) {
+ // enough to be osr compilable at any level for tiered
+ result = !m->is_not_osr_compilable(CompLevel_simple) || !m->is_not_osr_compilable(CompLevel_full_optimization);
+ } else {
+ // must be osr compilable at available level for non-tiered
+ result = !m->is_not_osr_compilable(CompLevel_highest_tier);
+ }
+ } else if (is_compile(comp_level)) {
+ result = !m->is_not_osr_compilable(comp_level);
+ }
+ return (result && can_be_compiled(m, comp_level));
+}
+
bool CompilationPolicy::is_compilation_enabled() {
// NOTE: CompileBroker::should_compile_new_jobs() checks for UseCompiler
return !delay_compilation_during_startup() && CompileBroker::should_compile_new_jobs();
@@ -458,7 +475,7 @@
const int hot_count = m->backedge_count();
const char* comment = "backedge_count";
- if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) {
+ if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
@@ -514,7 +531,7 @@
const int hot_count = m->backedge_count();
const char* comment = "backedge_count";
- if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) {
+ if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
--- a/hotspot/src/share/vm/runtime/compilationPolicy.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -52,6 +52,8 @@
static bool must_be_compiled(methodHandle m, int comp_level = CompLevel_all);
// m is allowed to be compiled
static bool can_be_compiled(methodHandle m, int comp_level = CompLevel_all);
+ // m is allowed to be osr compiled
+ static bool can_be_osr_compiled(methodHandle m, int comp_level = CompLevel_all);
static bool is_compilation_enabled();
static void set_policy(CompilationPolicy* policy) { _policy = policy; }
static CompilationPolicy* policy() { return _policy; }
--- a/hotspot/src/share/vm/runtime/frame.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/frame.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "compiler/abstractCompiler.hpp"
#include "compiler/disassembler.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
@@ -559,7 +560,7 @@
st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
if (sp() != NULL)
- st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc());
+ st->print(", fp=" INTPTR_FORMAT ", real_fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), real_fp(), pc());
if (StubRoutines::contains(pc())) {
st->print_cr(")");
@@ -720,11 +721,14 @@
} else if (_cb->is_buffer_blob()) {
st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
} else if (_cb->is_nmethod()) {
- Method* m = ((nmethod *)_cb)->method();
+ nmethod* nm = (nmethod*)_cb;
+ Method* m = nm->method();
if (m != NULL) {
m->name_and_sig_as_C_string(buf, buflen);
- st->print("J %s @ " PTR_FORMAT " [" PTR_FORMAT "+" SIZE_FORMAT "]",
- buf, _pc, _cb->code_begin(), _pc - _cb->code_begin());
+ st->print("J %d%s %s %s (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+0x%x]",
+ nm->compile_id(), (nm->is_osr_method() ? "%" : ""),
+ ((nm->compiler() != NULL) ? nm->compiler()->name() : ""),
+ buf, m->code_size(), _pc, _cb->code_begin(), _pc - _cb->code_begin());
} else {
st->print("J " PTR_FORMAT, pc());
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -3036,7 +3036,7 @@
product(uintx, MaxMetaspaceSize, max_uintx, \
"Maximum size of Metaspaces (in bytes)") \
\
- product(uintx, ClassMetaspaceSize, 2*M, \
+ product(uintx, ClassMetaspaceSize, 1*G, \
"Maximum size of InstanceKlass area in Metaspace used for " \
"UseCompressedKlassPointers") \
\
--- a/hotspot/src/share/vm/runtime/init.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/init.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -95,7 +95,6 @@
management_init();
bytecodes_init();
classLoader_init();
- Metaspace::global_initialize(); // must be before codeCache
codeCache_init();
VM_Version_init();
os_init_globals();
--- a/hotspot/src/share/vm/runtime/sweeper.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/sweeper.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -83,6 +83,7 @@
static jlong peak_disconnect_time() { return _peak_disconnect_time; }
#ifdef ASSERT
+ static bool is_sweeping(nmethod* which) { return _current == which; }
// Keep track of sweeper activity in the ring buffer
static void record_sweep(nmethod* nm, int line);
static void report_events(int id, address entry);
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -294,7 +294,7 @@
nonstatic_field(InstanceKlass, _java_fields_count, u2) \
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
nonstatic_field(InstanceKlass, _class_loader_data, ClassLoaderData*) \
- nonstatic_field(InstanceKlass, _source_file_name, Symbol*) \
+ nonstatic_field(InstanceKlass, _source_file_name_index, u2) \
nonstatic_field(InstanceKlass, _source_debug_extension, char*) \
nonstatic_field(InstanceKlass, _inner_classes, Array<jushort>*) \
nonstatic_field(InstanceKlass, _nonstatic_field_size, int) \
@@ -313,7 +313,7 @@
nonstatic_field(InstanceKlass, _jni_ids, JNIid*) \
nonstatic_field(InstanceKlass, _osr_nmethods_head, nmethod*) \
nonstatic_field(InstanceKlass, _breakpoints, BreakpointInfo*) \
- nonstatic_field(InstanceKlass, _generic_signature, Symbol*) \
+ nonstatic_field(InstanceKlass, _generic_signature_index, u2) \
nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \
nonstatic_field(InstanceKlass, _methods_cached_itable_indices, int*) \
volatile_nonstatic_field(InstanceKlass, _idnum_allocated_count, u2) \
@@ -1096,10 +1096,10 @@
\
c2_nonstatic_field(MachCallRuntimeNode, _name, const char*) \
\
- c2_nonstatic_field(PhaseCFG, _num_blocks, uint) \
+ c2_nonstatic_field(PhaseCFG, _number_of_blocks, uint) \
c2_nonstatic_field(PhaseCFG, _blocks, Block_List) \
c2_nonstatic_field(PhaseCFG, _node_to_block_mapping, Block_Array) \
- c2_nonstatic_field(PhaseCFG, _broot, Block*) \
+ c2_nonstatic_field(PhaseCFG, _root_block, Block*) \
\
c2_nonstatic_field(PhaseRegAlloc, _node_regs, OptoRegPair*) \
c2_nonstatic_field(PhaseRegAlloc, _node_regs_max_index, uint) \
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -231,6 +231,8 @@
#define HOTSPOT_BUILD_COMPILER "Workshop 5.9"
#elif __SUNPRO_CC == 0x5100
#define HOTSPOT_BUILD_COMPILER "Sun Studio 12u1"
+ #elif __SUNPRO_CC == 0x5120
+ #define HOTSPOT_BUILD_COMPILER "Sun Studio 12u3"
#else
#define HOTSPOT_BUILD_COMPILER "unknown Workshop:" XSTR(__SUNPRO_CC)
#endif
--- a/hotspot/src/share/vm/services/memoryPool.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/services/memoryPool.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -268,11 +268,11 @@
}
size_t MetaspacePool::used_in_bytes() {
- return MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType);
+ return MetaspaceAux::allocated_used_bytes();
}
size_t MetaspacePool::capacity_in_bytes() const {
- return MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType);
+ return MetaspaceAux::allocated_capacity_bytes();
}
size_t MetaspacePool::calculate_max_size() const {
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -362,6 +362,8 @@
// Klass encoding metaspace max size
const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes;
+const jlong CompressedKlassPointersBase = NOT_LP64(0) LP64_ONLY(CONST64(0x800000000)); // 32*G
+
// Machine dependent stuff
#ifdef TARGET_ARCH_x86
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -194,6 +194,7 @@
void clear() { _len = 0; }
int length() const { return _len; }
+ int max_length() const { return _max; }
void trunc_to(int l) { assert(l <= _len,"cannot increase length"); _len = l; }
bool is_empty() const { return _len == 0; }
bool is_nonempty() const { return _len != 0; }
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, 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
@@ -132,6 +132,8 @@
}
#endif // TASKQUEUE_STATS
+// TaskQueueSuper collects functionality common to all GenericTaskQueue instances.
+
template <unsigned int N, MEMFLAGS F>
class TaskQueueSuper: public CHeapObj<F> {
protected:
@@ -249,7 +251,36 @@
TASKQUEUE_STATS_ONLY(TaskQueueStats stats;)
};
-
+//
+// GenericTaskQueue implements an ABP, Aurora-Blumofe-Plaxton, double-
+// ended-queue (deque), intended for use in work stealing. Queue operations
+// are non-blocking.
+//
+// A queue owner thread performs push() and pop_local() operations on one end
+// of the queue, while other threads may steal work using the pop_global()
+// method.
+//
+// The main difference to the original algorithm is that this
+// implementation allows wrap-around at the end of its allocated
+// storage, which is an array.
+//
+// The original paper is:
+//
+// Arora, N. S., Blumofe, R. D., and Plaxton, C. G.
+// Thread scheduling for multiprogrammed multiprocessors.
+// Theory of Computing Systems 34, 2 (2001), 115-144.
+//
+// The following paper provides an correctness proof and an
+// implementation for weakly ordered memory models including (pseudo-)
+// code containing memory barriers for a Chase-Lev deque. Chase-Lev is
+// similar to ABP, with the main difference that it allows resizing of the
+// underlying storage:
+//
+// Le, N. M., Pop, A., Cohen A., and Nardell, F. Z.
+// Correct and efficient work-stealing for weak memory models
+// Proceedings of the 18th ACM SIGPLAN symposium on Principles and
+// practice of parallel programming (PPoPP 2013), 69-80
+//
template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
class GenericTaskQueue: public TaskQueueSuper<N, F> {
--- a/hotspot/src/share/vm/utilities/vmError.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -586,6 +586,13 @@
while (count++ < StackPrintLimit) {
fr.print_on_error(st, buf, sizeof(buf));
st->cr();
+ // Compiled code may use EBP register on x86 so it looks like
+ // non-walkable C frame. Use frame.sender() for java frames.
+ if (_thread && _thread->is_Java_thread() && fr.is_java_frame()) {
+ RegisterMap map((JavaThread*)_thread, false); // No update
+ fr = fr.sender(&map);
+ continue;
+ }
if (os::is_first_C_frame(&fr)) break;
fr = os::get_sender_for_C_frame(&fr);
}
--- a/hotspot/test/Makefile Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/Makefile Wed Jul 05 19:09:26 2017 +0200
@@ -210,9 +210,7 @@
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
$(RM) $(PRODUCT_HOME)/jre/lib/*/client/classes.jsa
- $(RM) $(PRODUCT_HOME)/jre/lib/*/client/classes_g.jsa
$(RM) $(PRODUCT_HOME)/jre/bin/client/classes.jsa
- $(RM) $(PRODUCT_HOME)/jre/bin/client/classes_g.jsa
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -Xshare:dump
PHONY_LIST += clienttest
--- a/hotspot/test/compiler/ciReplay/common.sh Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/ciReplay/common.sh Wed Jul 05 19:09:26 2017 +0200
@@ -89,7 +89,10 @@
# $1 - initial error_code
common_tests() {
positive_test $1 "COMMON :: THE SAME FLAGS"
- positive_test `expr $1 + 1` "COMMON :: TIERED" -XX:+TieredCompilation
+ if [ $tiered_available -eq 1 ]
+ then
+ positive_test `expr $1 + 1` "COMMON :: TIERED" -XX:+TieredCompilation
+ fi
}
# $1 - initial error_code
@@ -115,8 +118,11 @@
then
negative_test $1 "SERVER :: NON-TIERED" -XX:-TieredCompilation \
-server
- positive_test `expr $1 + 1` "SERVER :: TIERED" -XX:+TieredCompilation \
- -server
+ if [ $tiered_available -eq 1 ]
+ then
+ positive_test `expr $1 + 1` "SERVER :: TIERED" -XX:+TieredCompilation \
+ -server
+ fi
fi
nontiered_tests `expr $1 + 2` $client_level
}
@@ -167,6 +173,9 @@
grep -c Client`
server_available=`${JAVA} ${TESTVMOPTS} -server -Xinternalversion 2>&1 | \
grep -c Server`
+tiered_available=`${JAVA} ${TESTVMOPTS} -XX:+TieredCompilation -XX:+PrintFlagsFinal -version | \
+ grep TieredCompilation | \
+ grep -c true`
is_tiered=`${JAVA} ${TESTVMOPTS} -XX:+PrintFlagsFinal -version | \
grep TieredCompilation | \
grep -c true`
@@ -177,6 +186,7 @@
echo "client_available=$client_available"
echo "server_available=$server_available"
+echo "tiered_available=$tiered_available"
echo "is_tiered=$is_tiered"
# crash vm in compiler thread with generation replay data and 'small' dump-file
@@ -186,6 +196,11 @@
then
# enable core dump
ulimit -c unlimited
+
+ if [ $VM_OS = "solaris" ]
+ then
+ coreadm -p core $$
+ fi
fi
cmd="${JAVA} ${TESTVMOPTS} $@ \
--- a/hotspot/test/compiler/whitebox/ClearMethodStateTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/ClearMethodStateTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
/*
* @test ClearMethodStateTest
+ * @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build ClearMethodStateTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
@@ -59,16 +60,19 @@
WHITE_BOX.clearMethodState(method);
checkCompiled();
WHITE_BOX.clearMethodState(method);
- WHITE_BOX.deoptimizeMethod(method);
+ deoptimize();
checkNotCompiled();
-
+ if (testCase.isOsr) {
+ // part test isn't applicable for OSR test case
+ return;
+ }
if (!TIERED_COMPILATION) {
WHITE_BOX.clearMethodState(method);
compile(COMPILE_THRESHOLD);
checkCompiled();
- WHITE_BOX.deoptimizeMethod(method);
+ deoptimize();
checkNotCompiled();
WHITE_BOX.clearMethodState(method);
--- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -44,8 +44,14 @@
protected static int COMP_LEVEL_ANY = -1;
/** {@code CompLevel::CompLevel_simple} -- C1 */
protected static int COMP_LEVEL_SIMPLE = 1;
+ /** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */
+ protected static int COMP_LEVEL_LIMITED_PROFILE = 2;
+ /** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */
+ protected static int COMP_LEVEL_FULL_PROFILE = 3;
/** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4;
+ /** Maximal value for CompLeveL */
+ protected static int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION;
/** Instance of WhiteBox */
protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
@@ -64,6 +70,21 @@
/** Flag for verbose output, true if {@code -Dverbose} specified */
protected static final boolean IS_VERBOSE
= System.getProperty("verbose") != null;
+ /** count of invocation to triger compilation */
+ protected static final int THRESHOLD;
+ /** count of invocation to triger OSR compilation */
+ protected static final long BACKEDGE_THRESHOLD;
+
+ static {
+ if (TIERED_COMPILATION) {
+ THRESHOLD = 150000;
+ BACKEDGE_THRESHOLD = 0xFFFFFFFFL;
+ } else {
+ THRESHOLD = COMPILE_THRESHOLD;
+ BACKEDGE_THRESHOLD = COMPILE_THRESHOLD * Long.parseLong(getVMOption(
+ "OnStackReplacePercentage"));
+ }
+ }
/**
* Returns value of VM option.
@@ -112,7 +133,7 @@
/** tested method */
protected final Executable method;
- private final Callable<Integer> callable;
+ protected final TestCase testCase;
/**
* Constructor.
@@ -123,7 +144,7 @@
Objects.requireNonNull(testCase);
System.out.println("TEST CASE:" + testCase.name());
method = testCase.executable;
- callable = testCase.callable;
+ this.testCase = testCase;
}
/**
@@ -169,12 +190,18 @@
if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
throw new RuntimeException(method + " must not be in queue");
}
- if (WHITE_BOX.isMethodCompiled(method)) {
+ if (WHITE_BOX.isMethodCompiled(method, false)) {
throw new RuntimeException(method + " must be not compiled");
}
- if (WHITE_BOX.getMethodCompilationLevel(method) != 0) {
+ if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) {
throw new RuntimeException(method + " comp_level must be == 0");
}
+ if (WHITE_BOX.isMethodCompiled(method, true)) {
+ throw new RuntimeException(method + " must be not osr_compiled");
+ }
+ if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) {
+ throw new RuntimeException(method + " osr_comp_level must be == 0");
+ }
}
/**
@@ -192,12 +219,44 @@
method, System.currentTimeMillis() - start);
return;
}
- if (!WHITE_BOX.isMethodCompiled(method)) {
- throw new RuntimeException(method + " must be compiled");
+ if (!WHITE_BOX.isMethodCompiled(method, testCase.isOsr)) {
+ throw new RuntimeException(method + " must be "
+ + (testCase.isOsr ? "osr_" : "") + "compiled");
+ }
+ if (WHITE_BOX.getMethodCompilationLevel(method, testCase.isOsr) == 0) {
+ throw new RuntimeException(method
+ + (testCase.isOsr ? " osr_" : " ")
+ + "comp_level must be != 0");
+ }
+ }
+
+ protected final void deoptimize() {
+ WHITE_BOX.deoptimizeMethod(method, testCase.isOsr);
+ if (testCase.isOsr) {
+ WHITE_BOX.deoptimizeMethod(method, false);
}
- if (WHITE_BOX.getMethodCompilationLevel(method) == 0) {
- throw new RuntimeException(method + " comp_level must be != 0");
- }
+ }
+
+ protected final int getCompLevel() {
+ return WHITE_BOX.getMethodCompilationLevel(method, testCase.isOsr);
+ }
+
+ protected final boolean isCompilable() {
+ return WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY,
+ testCase.isOsr);
+ }
+
+ protected final boolean isCompilable(int compLevel) {
+ return WHITE_BOX.isMethodCompilable(method, compLevel, testCase.isOsr);
+ }
+
+ protected final void makeNotCompilable() {
+ WHITE_BOX.makeMethodNotCompilable(method, COMP_LEVEL_ANY,
+ testCase.isOsr);
+ }
+
+ protected final void makeNotCompilable(int compLevel) {
+ WHITE_BOX.makeMethodNotCompilable(method, compLevel, testCase.isOsr);
}
/**
@@ -226,12 +285,18 @@
protected final void printInfo() {
System.out.printf("%n%s:%n", method);
System.out.printf("\tcompilable:\t%b%n",
- WHITE_BOX.isMethodCompilable(method));
+ WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, false));
System.out.printf("\tcompiled:\t%b%n",
- WHITE_BOX.isMethodCompiled(method));
+ WHITE_BOX.isMethodCompiled(method, false));
System.out.printf("\tcomp_level:\t%d%n",
- WHITE_BOX.getMethodCompilationLevel(method));
- System.out.printf("\tin_queue:\t%b%n",
+ WHITE_BOX.getMethodCompilationLevel(method, false));
+ System.out.printf("\tosr_compilable:\t%b%n",
+ WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, true));
+ System.out.printf("\tosr_compiled:\t%b%n",
+ WHITE_BOX.isMethodCompiled(method, true));
+ System.out.printf("\tosr_comp_level:\t%d%n",
+ WHITE_BOX.getMethodCompilationLevel(method, true));
+ System.out.printf("\tin_queue:\t%b%n",
WHITE_BOX.isMethodQueuedForCompilation(method));
System.out.printf("compile_queues_size:\t%d%n%n",
WHITE_BOX.getCompileQueuesSize());
@@ -244,18 +309,22 @@
/**
* Tries to trigger compilation of {@linkplain #method} by call
- * {@linkplain #callable} enough times.
+ * {@linkplain #testCase.callable} enough times.
*
* @return accumulated result
* @see #compile(int)
*/
protected final int compile() {
- return compile(Math.max(COMPILE_THRESHOLD, 150000));
+ if (testCase.isOsr) {
+ return compile(1);
+ } else {
+ return compile(THRESHOLD);
+ }
}
/**
* Tries to trigger compilation of {@linkplain #method} by call
- * {@linkplain #callable} specified times.
+ * {@linkplain #testCase.callable} specified times.
*
* @param count invocation count
* @return accumulated result
@@ -265,7 +334,7 @@
Integer tmp;
for (int i = 0; i < count; ++i) {
try {
- tmp = callable.call();
+ tmp = testCase.callable.call();
} catch (Exception e) {
tmp = null;
}
@@ -283,23 +352,36 @@
*/
enum TestCase {
/** constructor test case */
- CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE),
+ CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
/** method test case */
- METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE),
+ METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
/** static method test case */
- STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE);
+ STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
+
+ /** OSR constructor test case */
+ OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
+ Helper.OSR_CONSTRUCTOR_CALLABLE, true),
+ /** OSR method test case */
+ OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
+ /** OSR static method test case */
+ OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
/** tested method */
final Executable executable;
/** object to invoke {@linkplain #executable} */
final Callable<Integer> callable;
+ /** flag for OSR test case */
+ final boolean isOsr;
- private TestCase(Executable executable, Callable<Integer> callable) {
+ private TestCase(Executable executable, Callable<Integer> callable,
+ boolean isOsr) {
this.executable = executable;
this.callable = callable;
+ this.isOsr = isOsr;
}
private static class Helper {
+
private static final Callable<Integer> CONSTRUCTOR_CALLABLE
= new Callable<Integer>() {
@Override
@@ -326,9 +408,39 @@
}
};
+ private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE
+ = new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return new Helper(null).hashCode();
+ }
+ };
+
+ private static final Callable<Integer> OSR_METHOD_CALLABLE
+ = new Callable<Integer>() {
+ private final Helper helper = new Helper();
+
+ @Override
+ public Integer call() throws Exception {
+ return helper.osrMethod();
+ }
+ };
+
+ private static final Callable<Integer> OSR_STATIC_CALLABLE
+ = new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return osrStaticMethod();
+ }
+ };
+
+
private static final Constructor CONSTRUCTOR;
+ private static final Constructor OSR_CONSTRUCTOR;
private static final Method METHOD;
private static final Method STATIC;
+ private static final Method OSR_METHOD;
+ private static final Method OSR_STATIC;
static {
try {
@@ -338,17 +450,26 @@
"exception on getting method Helper.<init>(int)", e);
}
try {
- METHOD = Helper.class.getDeclaredMethod("method");
+ OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
+ Object.class);
} catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException(
- "exception on getting method Helper.method()", e);
+ "exception on getting method Helper.<init>(Object)", e);
}
+ METHOD = getMethod("method");
+ STATIC = getMethod("staticMethod");
+ OSR_METHOD = getMethod("osrMethod");
+ OSR_STATIC = getMethod("osrStaticMethod");
+ }
+
+ private static Method getMethod(String name) {
try {
- STATIC = Helper.class.getDeclaredMethod("staticMethod");
+ return Helper.class.getDeclaredMethod(name);
} catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException(
- "exception on getting method Helper.staticMethod()", e);
+ "exception on getting method Helper." + name, e);
}
+
}
private static int staticMethod() {
@@ -359,12 +480,39 @@
return 42;
}
+ private static int osrStaticMethod() {
+ int result = 0;
+ for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
+ result += staticMethod();
+ }
+ return result;
+ }
+
+ private int osrMethod() {
+ int result = 0;
+ for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
+ result += method();
+ }
+ return result;
+ }
+
private final int x;
+ // for method and OSR method test case
public Helper() {
x = 0;
}
+ // for OSR constructor test case
+ private Helper(Object o) {
+ int result = 0;
+ for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
+ result += method();
+ }
+ x = result;
+ }
+
+ // for constructor test case
private Helper(int x) {
this.x = x;
}
--- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
/*
* @test DeoptimizeAllTest
+ * @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build DeoptimizeAllTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
--- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
/*
* @test DeoptimizeMethodTest
+ * @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build DeoptimizeMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
@@ -54,7 +55,7 @@
protected void test() throws Exception {
compile();
checkCompiled();
- WHITE_BOX.deoptimizeMethod(method);
+ deoptimize();
checkNotCompiled();
}
}
--- a/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,10 +23,11 @@
/*
* @test EnqueueMethodForCompilationTest
+ * @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build EnqueueMethodForCompilationTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* EnqueueMethodForCompilationTest
+ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* EnqueueMethodForCompilationTest
* @summary testing of WB::enqueueMethodForCompilation()
* @author igor.ignatyev@oracle.com
*/
@@ -50,7 +51,7 @@
// method can not be compiled on level 'none'
WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_NONE);
- if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_NONE)) {
+ if (isCompilable(COMP_LEVEL_NONE)) {
throw new RuntimeException(method
+ " is compilable at level COMP_LEVEL_NONE");
}
@@ -60,27 +61,29 @@
WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_ANY);
checkNotCompiled();
- WHITE_BOX.enqueueMethodForCompilation(method, 5);
- if (!WHITE_BOX.isMethodCompilable(method, 5)) {
- checkNotCompiled();
- compile();
- checkCompiled();
- } else {
- checkCompiled();
- }
-
- int compLevel = WHITE_BOX.getMethodCompilationLevel(method);
- WHITE_BOX.deoptimizeMethod(method);
- checkNotCompiled();
-
- WHITE_BOX.enqueueMethodForCompilation(method, compLevel);
- checkCompiled();
- WHITE_BOX.deoptimizeMethod(method);
+ // not existing comp level
+ WHITE_BOX.enqueueMethodForCompilation(method, 42);
checkNotCompiled();
compile();
checkCompiled();
- WHITE_BOX.deoptimizeMethod(method);
+
+ int compLevel = getCompLevel();
+ int bci = WHITE_BOX.getMethodEntryBci(method);
+ System.out.println("bci = " + bci);
+ printInfo();
+ deoptimize();
+ printInfo();
+ checkNotCompiled();
+ printInfo();
+ WHITE_BOX.enqueueMethodForCompilation(method, compLevel, bci);
+ checkCompiled();
+ deoptimize();
+ checkNotCompiled();
+
+ compile();
+ checkCompiled();
+ deoptimize();
checkNotCompiled();
}
}
--- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,11 +23,11 @@
/*
* @test IsMethodCompilableTest
- * @bug 8007270
+ * @bug 8007270 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build IsMethodCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* IsMethodCompilableTest
+ * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* IsMethodCompilableTest
* @summary testing of WB::isMethodCompilable()
* @author igor.ignatyev@oracle.com
*/
@@ -68,7 +68,7 @@
*/
@Override
protected void test() throws Exception {
- if (!WHITE_BOX.isMethodCompilable(method)) {
+ if (!isCompilable()) {
throw new RuntimeException(method + " must be compilable");
}
System.out.println("PerMethodRecompilationCutoff = "
@@ -83,7 +83,8 @@
for (long i = 0L, n = PER_METHOD_RECOMPILATION_CUTOFF - 1; i < n; ++i) {
compileAndDeoptimize();
}
- if (!WHITE_BOX.isMethodCompilable(method)) {
+ if (!testCase.isOsr && !isCompilable()) {
+ // in osr test case count of deopt maybe more than iterations
throw new RuntimeException(method + " is not compilable after "
+ (PER_METHOD_RECOMPILATION_CUTOFF - 1) + " iterations");
}
@@ -92,15 +93,16 @@
// deoptimize 'PerMethodRecompilationCutoff' + 1 times
long i;
for (i = 0L; i < PER_METHOD_RECOMPILATION_CUTOFF
- && WHITE_BOX.isMethodCompilable(method); ++i) {
+ && isCompilable(); ++i) {
compileAndDeoptimize();
}
- if (i != PER_METHOD_RECOMPILATION_CUTOFF) {
+ if (!testCase.isOsr && i != PER_METHOD_RECOMPILATION_CUTOFF) {
+ // in osr test case count of deopt maybe more than iterations
throw new RuntimeException(method + " is not compilable after "
+ i + " iterations, but must only after "
+ PER_METHOD_RECOMPILATION_CUTOFF);
}
- if (WHITE_BOX.isMethodCompilable(method)) {
+ if (isCompilable()) {
throw new RuntimeException(method + " is still compilable after "
+ PER_METHOD_RECOMPILATION_CUTOFF + " iterations");
}
@@ -109,7 +111,7 @@
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method);
- if (!WHITE_BOX.isMethodCompilable(method)) {
+ if (!isCompilable()) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
@@ -120,6 +122,6 @@
private void compileAndDeoptimize() throws Exception {
compile();
waitBackgroundCompilation();
- WHITE_BOX.deoptimizeMethod(method);
+ deoptimize();
}
}
--- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,16 +23,16 @@
/*
* @test MakeMethodNotCompilableTest
- * @bug 8012322
+ * @bug 8012322 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build MakeMethodNotCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* MakeMethodNotCompilableTest
+ * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* MakeMethodNotCompilableTest
* @summary testing of WB::makeMethodNotCompilable()
* @author igor.ignatyev@oracle.com
*/
public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
-
+ private int bci;
public static void main(String[] args) throws Exception {
if (args.length == 0) {
for (TestCase test : TestCase.values()) {
@@ -63,25 +63,27 @@
@Override
protected void test() throws Exception {
checkNotCompiled();
- if (!WHITE_BOX.isMethodCompilable(method)) {
+ if (!isCompilable()) {
throw new RuntimeException(method + " must be compilable");
}
+ bci = getBci();
+
if (TIERED_COMPILATION) {
final int tierLimit = TIERED_STOP_AT_LEVEL + 1;
for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
testTier(testedTier);
}
for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
- WHITE_BOX.makeMethodNotCompilable(method, testedTier);
- if (WHITE_BOX.isMethodCompilable(method, testedTier)) {
+ makeNotCompilable(testedTier);
+ if (isCompilable(testedTier)) {
throw new RuntimeException(method
+ " must be not compilable at level" + testedTier);
}
- WHITE_BOX.enqueueMethodForCompilation(method, testedTier);
+ WHITE_BOX.enqueueMethodForCompilation(method, testedTier, bci);
checkNotCompiled();
- if (!WHITE_BOX.isMethodCompilable(method)) {
+ if (!isCompilable()) {
System.out.println(method
+ " is not compilable after level " + testedTier);
}
@@ -89,15 +91,20 @@
} else {
compile();
checkCompiled();
- int compLevel = WHITE_BOX.getMethodCompilationLevel(method);
- WHITE_BOX.deoptimizeMethod(method);
- WHITE_BOX.makeMethodNotCompilable(method, compLevel);
- if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
+ int compLevel = getCompLevel();
+ deoptimize();
+ makeNotCompilable(compLevel);
+ if (isCompilable(COMP_LEVEL_ANY)) {
throw new RuntimeException(method
+ " must be not compilable at CompLevel::CompLevel_any,"
+ " after it is not compilable at " + compLevel);
}
+
WHITE_BOX.clearMethodState(method);
+ if (!isCompilable()) {
+ throw new RuntimeException(method
+ + " is not compilable after clearMethodState()");
+ }
// nocompilable at opposite level must make no sense
int oppositeLevel;
@@ -106,16 +113,16 @@
} else {
oppositeLevel = COMP_LEVEL_SIMPLE;
}
- WHITE_BOX.makeMethodNotCompilable(method, oppositeLevel);
+ makeNotCompilable(oppositeLevel);
- if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
+ if (!isCompilable(COMP_LEVEL_ANY)) {
throw new RuntimeException(method
+ " must be compilable at CompLevel::CompLevel_any,"
+ " even it is not compilable at opposite level ["
+ compLevel + "]");
}
- if (!WHITE_BOX.isMethodCompilable(method, compLevel)) {
+ if (!isCompilable(compLevel)) {
throw new RuntimeException(method
+ " must be compilable at level " + compLevel
+ ", even it is not compilable at opposite level ["
@@ -126,24 +133,24 @@
// clearing after tiered/non-tiered tests
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method);
- if (!WHITE_BOX.isMethodCompilable(method)) {
+ if (!isCompilable()) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
- WHITE_BOX.makeMethodNotCompilable(method);
- if (WHITE_BOX.isMethodCompilable(method)) {
+ makeNotCompilable();
+ if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable");
}
compile();
checkNotCompiled();
- if (WHITE_BOX.isMethodCompilable(method)) {
+ if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable");
}
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method);
- if (!WHITE_BOX.isMethodCompilable(method)) {
+ if (!isCompilable()) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
@@ -153,24 +160,23 @@
// separately tests each tier
private void testTier(int testedTier) {
- if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
+ if (!isCompilable(testedTier)) {
throw new RuntimeException(method
+ " is not compilable on start");
}
- WHITE_BOX.makeMethodNotCompilable(method, testedTier);
+ makeNotCompilable(testedTier);
// tests for all other tiers
for (int anotherTier = 1, tierLimit = TIERED_STOP_AT_LEVEL + 1;
anotherTier < tierLimit; ++anotherTier) {
- boolean isCompilable = WHITE_BOX.isMethodCompilable(method,
- anotherTier);
+ boolean isCompilable = isCompilable(anotherTier);
if (sameCompile(testedTier, anotherTier)) {
if (isCompilable) {
throw new RuntimeException(method
+ " must be not compilable at level " + anotherTier
+ ", if it is not compilable at " + testedTier);
}
- WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
+ WHITE_BOX.enqueueMethodForCompilation(method, anotherTier, bci);
checkNotCompiled();
} else {
if (!isCompilable) {
@@ -179,12 +185,12 @@
+ ", even if it is not compilable at "
+ testedTier);
}
- WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
+ WHITE_BOX.enqueueMethodForCompilation(method, anotherTier, bci);
checkCompiled();
- WHITE_BOX.deoptimizeMethod(method);
+ deoptimize();
}
- if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
+ if (!isCompilable(COMP_LEVEL_ANY)) {
throw new RuntimeException(method
+ " must be compilable at 'CompLevel::CompLevel_any'"
+ ", if it is not compilable only at " + testedTier);
@@ -193,7 +199,7 @@
// clear state after test
WHITE_BOX.clearMethodState(method);
- if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
+ if (!isCompilable(testedTier)) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
@@ -211,4 +217,13 @@
}
return false;
}
+
+ private int getBci() {
+ compile();
+ checkCompiled();
+ int result = WHITE_BOX.getMethodEntryBci(method);
+ deoptimize();
+ WHITE_BOX.clearMethodState(method);
+ return result;
+ }
}
--- a/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
/*
* @test SetDontInlineMethodTest
+ * @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build SetDontInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
--- a/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,6 +23,7 @@
/*
* @test SetForceInlineMethodTest
+ * @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox
* @build SetForceInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+
+import com.oracle.java.testlibrary.*;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+/* @test TestMetaspacePerfCounters
+ * @bug 8014659
+ * @library /testlibrary
+ * @summary Tests that performance counters for metaspace and compressed class
+ * space exists and works.
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters
+ */
+public class TestMetaspacePerfCounters {
+ public static Class fooClass = null;
+ private static final String[] counterNames = {"minCapacity", "maxCapacity", "capacity", "used"};
+
+ public static void main(String[] args) throws Exception {
+ String metaspace = "sun.gc.metaspace";
+ String ccs = "sun.gc.compressedclassspace";
+
+ checkPerfCounters(metaspace);
+
+ if (isUsingCompressedClassPointers()) {
+ checkPerfCounters(ccs);
+ checkUsedIncreasesWhenLoadingClass(ccs);
+ } else {
+ checkEmptyPerfCounters(ccs);
+ checkUsedIncreasesWhenLoadingClass(metaspace);
+ }
+ }
+
+ private static void checkPerfCounters(String ns) throws Exception {
+ for (PerfCounter counter : countersInNamespace(ns)) {
+ String msg = "Expected " + counter.getName() + " to be larger than 0";
+ assertGT(counter.longValue(), 0L, msg);
+ }
+ }
+
+ private static void checkEmptyPerfCounters(String ns) throws Exception {
+ for (PerfCounter counter : countersInNamespace(ns)) {
+ String msg = "Expected " + counter.getName() + " to equal 0";
+ assertEQ(counter.longValue(), 0L, msg);
+ }
+ }
+
+ private static void checkUsedIncreasesWhenLoadingClass(String ns) throws Exception {
+ PerfCounter used = PerfCounters.findByName(ns + ".used");
+
+ long before = used.longValue();
+ fooClass = compileAndLoad("Foo", "public class Foo { }");
+ System.gc();
+ long after = used.longValue();
+
+ assertGT(after, before);
+ }
+
+ private static List<PerfCounter> countersInNamespace(String ns) throws Exception {
+ List<PerfCounter> counters = new ArrayList<>();
+ for (String name : counterNames) {
+ counters.add(PerfCounters.findByName(ns + "." + name));
+ }
+ return counters;
+ }
+
+ private static Class<?> compileAndLoad(String name, String source) throws Exception {
+ byte[] byteCode = InMemoryJavaCompiler.compile(name, source);
+ return ByteCodeLoader.load(name, byteCode);
+ }
+
+ private static boolean isUsingCompressedClassPointers() {
+ return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedKlassPointers");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8003424
+ * @summary Testing UseCompressedKlassPointers with CDS
+ * @library /testlibrary
+ * @run main CDSCompressedKPtrs
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CDSCompressedKPtrs {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb;
+ if (Platform.is64bit()) {
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops",
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("Loading classes to share");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops",
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("sharing");
+ output.shouldHaveExitValue(0);
+
+ } catch (RuntimeException e) {
+ // Report 'passed' if CDS was turned off because we could not allocate
+ // the klass metaspace at an address that would work with CDS.
+ output.shouldContain("Could not allocate metaspace at a compatible address");
+ output.shouldHaveExitValue(1);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8003424
+ * @summary Test that cannot use CDS if UseCompressedKlassPointers is turned off.
+ * @library /testlibrary
+ * @run main CDSCompressedKPtrsError
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CDSCompressedKPtrsError {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb;
+ if (Platform.is64bit()) {
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("Loading classes to share");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:-UseCompressedKlassPointers", "-XX:-UseCompressedOops",
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Unable to use shared archive");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:-UseCompressedKlassPointers", "-XX:+UseCompressedOops",
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Unable to use shared archive");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UseCompressedKlassPointers", "-XX:-UseCompressedOops",
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Unable to use shared archive");
+ output.shouldHaveExitValue(0);
+
+ } catch (RuntimeException e) {
+ output.shouldContain("Unable to use shared archive");
+ output.shouldHaveExitValue(1);
+ }
+
+ // Test bad options with -Xshare:dump.
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:-UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Cannot dump shared archive");
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Cannot dump shared archive");
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:-UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Cannot dump shared archive");
+
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8005933
+ * @summary Test that -Xshare:auto uses CDS when explicitly specified with -server.
+ * @library /testlibrary
+ * @run main XShareAuto
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class XShareAuto {
+ public static void main(String[] args) throws Exception {
+ if (!Platform.is64bit()) {
+ System.out.println("ObjectAlignmentInBytes for CDS is only " +
+ "supported on 64bit platforms; this plaform is " +
+ System.getProperty("sun.arch.data.model"));
+ System.out.println("Skipping the test");
+ return;
+ }
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
+ "-Xshare:dump");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Loading classes to share");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-server", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("sharing");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-server", "-Xshare:auto", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa", "-version");
+ output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("sharing");
+ output.shouldHaveExitValue(0);
+ } catch (RuntimeException e) {
+ // If this failed then check that it would also be unable
+ // to share even if -Xshare:on is specified. If so, then
+ // return a success status.
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-server", "-Xshare:on", "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Could not allocate metaspace at a compatible address");
+ output.shouldHaveExitValue(1);
+ }
+ }
+}
--- a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java Wed Jul 05 19:09:26 2017 +0200
@@ -84,8 +84,7 @@
// there is a chance such reservation will fail
// If it does, it is NOT considered a failure of the feature,
// rather a possible expected outcome, though not likely
- output.shouldContain(
- "Unable to reserve shared space at required address");
+ output.shouldContain("Could not allocate metaspace at a compatible address");
output.shouldHaveExitValue(1);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/AssertsTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import static com.oracle.java.testlibrary.Asserts.*;
+
+/* @test
+ * @summary Tests the different assertions in the Assert class
+ * @library /testlibrary
+ */
+public class AssertsTest {
+ private static class Foo implements Comparable<Foo> {
+ final int id;
+ public Foo(int id) {
+ this.id = id;
+ }
+
+ public int compareTo(Foo f) {
+ return new Integer(id).compareTo(new Integer(f.id));
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ testLessThan();
+ testLessThanOrEqual();
+ testEquals();
+ testGreaterThanOrEqual();
+ testGreaterThan();
+ testNotEquals();
+ testNull();
+ testNotNull();
+ testTrue();
+ testFalse();
+ }
+
+ private static void testLessThan() throws Exception {
+ expectPass(Assertion.LT, 1, 2);
+
+ expectFail(Assertion.LT, 2, 2);
+ expectFail(Assertion.LT, 2, 1);
+ expectFail(Assertion.LT, null, 2);
+ expectFail(Assertion.LT, 2, null);
+ }
+
+ private static void testLessThanOrEqual() throws Exception {
+ expectPass(Assertion.LTE, 1, 2);
+ expectPass(Assertion.LTE, 2, 2);
+
+ expectFail(Assertion.LTE, 3, 2);
+ expectFail(Assertion.LTE, null, 2);
+ expectFail(Assertion.LTE, 2, null);
+ }
+
+ private static void testEquals() throws Exception {
+ expectPass(Assertion.EQ, 1, 1);
+ expectPass(Assertion.EQ, null, null);
+
+ Foo f1 = new Foo(1);
+ expectPass(Assertion.EQ, f1, f1);
+
+ Foo f2 = new Foo(1);
+ expectFail(Assertion.EQ, f1, f2);
+ expectFail(Assertion.LTE, null, 2);
+ expectFail(Assertion.LTE, 2, null);
+ }
+
+ private static void testGreaterThanOrEqual() throws Exception {
+ expectPass(Assertion.GTE, 1, 1);
+ expectPass(Assertion.GTE, 2, 1);
+
+ expectFail(Assertion.GTE, 1, 2);
+ expectFail(Assertion.GTE, null, 2);
+ expectFail(Assertion.GTE, 2, null);
+ }
+
+ private static void testGreaterThan() throws Exception {
+ expectPass(Assertion.GT, 2, 1);
+
+ expectFail(Assertion.GT, 1, 1);
+ expectFail(Assertion.GT, 1, 2);
+ expectFail(Assertion.GT, null, 2);
+ expectFail(Assertion.GT, 2, null);
+ }
+
+ private static void testNotEquals() throws Exception {
+ expectPass(Assertion.NE, null, 1);
+ expectPass(Assertion.NE, 1, null);
+
+ Foo f1 = new Foo(1);
+ Foo f2 = new Foo(1);
+ expectPass(Assertion.NE, f1, f2);
+
+ expectFail(Assertion.NE, null, null);
+ expectFail(Assertion.NE, f1, f1);
+ expectFail(Assertion.NE, 1, 1);
+ }
+
+ private static void testNull() throws Exception {
+ expectPass(Assertion.NULL, null);
+
+ expectFail(Assertion.NULL, 1);
+ }
+
+ private static void testNotNull() throws Exception {
+ expectPass(Assertion.NOTNULL, 1);
+
+ expectFail(Assertion.NOTNULL, null);
+ }
+
+ private static void testTrue() throws Exception {
+ expectPass(Assertion.TRUE, true);
+
+ expectFail(Assertion.TRUE, false);
+ }
+
+ private static void testFalse() throws Exception {
+ expectPass(Assertion.FALSE, false);
+
+ expectFail(Assertion.FALSE, true);
+ }
+
+ private static <T extends Comparable<T>> void expectPass(Assertion assertion, T ... args)
+ throws Exception {
+ Assertion.run(assertion, args);
+ }
+
+ private static <T extends Comparable<T>> void expectFail(Assertion assertion, T ... args)
+ throws Exception {
+ try {
+ Assertion.run(assertion, args);
+ } catch (RuntimeException e) {
+ return;
+ }
+ throw new Exception("Expected " + Assertion.format(assertion, (Object[]) args) +
+ " to throw a RuntimeException");
+ }
+
+}
+
+enum Assertion {
+ LT, LTE, EQ, GTE, GT, NE, NULL, NOTNULL, FALSE, TRUE;
+
+ public static <T extends Comparable<T>> void run(Assertion assertion, T ... args) {
+ String msg = "Expected " + format(assertion, args) + " to pass";
+ switch (assertion) {
+ case LT:
+ assertLessThan(args[0], args[1], msg);
+ break;
+ case LTE:
+ assertLessThanOrEqual(args[0], args[1], msg);
+ break;
+ case EQ:
+ assertEquals(args[0], args[1], msg);
+ break;
+ case GTE:
+ assertGreaterThanOrEqual(args[0], args[1], msg);
+ break;
+ case GT:
+ assertGreaterThan(args[0], args[1], msg);
+ break;
+ case NE:
+ assertNotEquals(args[0], args[1], msg);
+ break;
+ case NULL:
+ assertNull(args == null ? args : args[0], msg);
+ break;
+ case NOTNULL:
+ assertNotNull(args == null ? args : args[0], msg);
+ break;
+ case FALSE:
+ assertFalse((Boolean) args[0], msg);
+ break;
+ case TRUE:
+ assertTrue((Boolean) args[0], msg);
+ break;
+ default:
+ // do nothing
+ }
+ }
+
+ public static String format(Assertion assertion, Object ... args) {
+ switch (assertion) {
+ case LT:
+ return asString("assertLessThan", args);
+ case LTE:
+ return asString("assertLessThanOrEqual", args);
+ case EQ:
+ return asString("assertEquals", args);
+ case GTE:
+ return asString("assertGreaterThanOrEquals", args);
+ case GT:
+ return asString("assertGreaterThan", args);
+ case NE:
+ return asString("assertNotEquals", args);
+ case NULL:
+ return asString("assertNull", args);
+ case NOTNULL:
+ return asString("assertNotNull", args);
+ case FALSE:
+ return asString("assertFalse", args);
+ case TRUE:
+ return asString("assertTrue", args);
+ default:
+ return "";
+ }
+ }
+
+ private static String asString(String assertion, Object ... args) {
+ if (args == null) {
+ return String.format("%s(null)", assertion);
+ }
+ if (args.length == 1) {
+ return String.format("%s(%s)", assertion, args[0]);
+ } else {
+ return String.format("%s(%s, %s)", assertion, args[0], args[1]);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Asserts.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary;
+
+/**
+ * Asserts that can be used for verifying assumptions in tests.
+ *
+ * An assertion will throw a {@link RuntimeException} if the assertion isn't
+ * valid. All the asserts can be imported into a test by using a static
+ * import:
+ *
+ * <pre>
+ * {@code
+ * import static com.oracle.java.testlibrary.Asserts.*;
+ * }
+ *
+ * Always provide a message describing the assumption if the line number of the
+ * failing assertion isn't enough to understand why the assumption failed. For
+ * example, if the assertion is in a loop or in a method that is called
+ * multiple times, then the line number won't provide enough context to
+ * understand the failure.
+ * </pre>
+ */
+public class Asserts {
+
+ /**
+ * Shorthand for {@link #assertLessThan(T, T)}.
+ *
+ * @see #assertLessThan(T, T)
+ */
+ public static <T extends Comparable<T>> void assertLT(T lhs, T rhs) {
+ assertLessThan(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertLessThan(T, T, String)}.
+ *
+ * @see #assertLessThan(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertLT(T lhs, T rhs, String msg) {
+ assertLessThan(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertLessThan(T, T, String)} with a default message.
+ *
+ * @see #assertLessThan(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertLessThan(T lhs, T rhs) {
+ String msg = "Expected that " + format(lhs) + " < " + format(rhs);
+ assertLessThan(lhs, rhs, msg);
+ }
+
+ /**
+ * Asserts that {@code lhs} is less than {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static <T extends Comparable<T>>void assertLessThan(T lhs, T rhs, String msg) {
+ assertTrue(compare(lhs, rhs, msg) < 0, msg);
+ }
+
+ /**
+ * Shorthand for {@link #assertLessThanOrEqual(T, T)}.
+ *
+ * @see #assertLessThanOrEqual(T, T)
+ */
+ public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs) {
+ assertLessThanOrEqual(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertLessThanOrEqual(T, T, String)}.
+ *
+ * @see #assertLessThanOrEqual(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs, String msg) {
+ assertLessThanOrEqual(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertLessThanOrEqual(T, T, String)} with a default message.
+ *
+ * @see #assertLessThanOrEqual(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs) {
+ String msg = "Expected that " + format(lhs) + " <= " + format(rhs);
+ assertLessThanOrEqual(lhs, rhs, msg);
+ }
+
+ /**
+ * Asserts that {@code lhs} is less than or equal to {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs, String msg) {
+ assertTrue(compare(lhs, rhs, msg) <= 0, msg);
+ }
+
+ /**
+ * Shorthand for {@link #assertEquals(T, T)}.
+ *
+ * @see #assertEquals(T, T)
+ */
+ public static void assertEQ(Object lhs, Object rhs) {
+ assertEquals(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertEquals(T, T, String)}.
+ *
+ * @see #assertEquals(T, T, String)
+ */
+ public static void assertEQ(Object lhs, Object rhs, String msg) {
+ assertEquals(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertEquals(T, T, String)} with a default message.
+ *
+ * @see #assertEquals(T, T, String)
+ */
+ public static void assertEquals(Object lhs, Object rhs) {
+ String msg = "Expected " + format(lhs) + " to equal " + format(rhs);
+ assertEquals(lhs, rhs, msg);
+ }
+
+ /**
+ * Asserts that {@code lhs} is equal to {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static void assertEquals(Object lhs, Object rhs, String msg) {
+ if (lhs == null) {
+ if (rhs != null) {
+ error(msg);
+ }
+ } else {
+ assertTrue(lhs.equals(rhs), msg);
+ }
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThanOrEqual(T, T)}.
+ *
+ * @see #assertGreaterThanOrEqual(T, T)
+ */
+ public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs) {
+ assertGreaterThanOrEqual(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThanOrEqual(T, T, String)}.
+ *
+ * @see #assertGreaterThanOrEqual(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs, String msg) {
+ assertGreaterThanOrEqual(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertGreaterThanOrEqual(T, T, String)} with a default message.
+ *
+ * @see #assertGreaterThanOrEqual(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs) {
+ String msg = "Expected that " + format(lhs) + " >= " + format(rhs);
+ assertGreaterThanOrEqual(lhs, rhs, msg);
+ }
+
+ /**
+ * Asserts that {@code lhs} is greater than or equal to {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs, String msg) {
+ assertTrue(compare(lhs, rhs, msg) >= 0, msg);
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThan(T, T)}.
+ *
+ * @see #assertGreaterThan(T, T)
+ */
+ public static <T extends Comparable<T>> void assertGT(T lhs, T rhs) {
+ assertGreaterThan(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertGreaterThan(T, T, String)}.
+ *
+ * @see #assertGreaterThan(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertGT(T lhs, T rhs, String msg) {
+ assertGreaterThan(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertGreaterThan(T, T, String)} with a default message.
+ *
+ * @see #assertGreaterThan(T, T, String)
+ */
+ public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs) {
+ String msg = "Expected that " + format(lhs) + " > " + format(rhs);
+ assertGreaterThan(lhs, rhs, msg);
+ }
+
+ /**
+ * Asserts that {@code lhs} is greater than {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs, String msg) {
+ assertTrue(compare(lhs, rhs, msg) > 0, msg);
+ }
+
+ /**
+ * Shorthand for {@link #assertNotEquals(T, T)}.
+ *
+ * @see #assertNotEquals(T, T)
+ */
+ public static void assertNE(Object lhs, Object rhs) {
+ assertNotEquals(lhs, rhs);
+ }
+
+ /**
+ * Shorthand for {@link #assertNotEquals(T, T, String)}.
+ *
+ * @see #assertNotEquals(T, T, String)
+ */
+ public static void assertNE(Object lhs, Object rhs, String msg) {
+ assertNotEquals(lhs, rhs, msg);
+ }
+
+ /**
+ * Calls {@link #assertNotEquals(T, T, String)} with a default message.
+ *
+ * @see #assertNotEquals(T, T, String)
+ */
+ public static void assertNotEquals(Object lhs, Object rhs) {
+ String msg = "Expected " + format(lhs) + " to not equal " + format(rhs);
+ assertNotEquals(lhs, rhs, msg);
+ }
+
+ /**
+ * Asserts that {@code lhs} is not equal to {@code rhs}.
+ *
+ * @param lhs The left hand side of the comparison.
+ * @param rhs The right hand side of the comparison.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static void assertNotEquals(Object lhs, Object rhs, String msg) {
+ if (lhs == null) {
+ if (rhs == null) {
+ error(msg);
+ }
+ } else {
+ assertFalse(lhs.equals(rhs), msg);
+ }
+ }
+
+ /**
+ * Calls {@link #assertNull(Object, String)} with a default message.
+ *
+ * @see #assertNull(Object, String)
+ */
+ public static void assertNull(Object o) {
+ assertNull(o, "Expected " + format(o) + " to be null");
+ }
+
+ /**
+ * Asserts that {@code o} is null.
+ *
+ * @param o The reference assumed to be null.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static void assertNull(Object o, String msg) {
+ assertEquals(o, null, msg);
+ }
+
+ /**
+ * Calls {@link #assertNotNull(Object, String)} with a default message.
+ *
+ * @see #assertNotNull(Object, String)
+ */
+ public static void assertNotNull(Object o) {
+ assertNotNull(o, "Expected non null reference");
+ }
+
+ /**
+ * Asserts that {@code o} is <i>not</i> null.
+ *
+ * @param o The reference assumed <i>not</i> to be null,
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static void assertNotNull(Object o, String msg) {
+ assertNotEquals(o, null, msg);
+ }
+
+ /**
+ * Calls {@link #assertFalse(boolean, String)} with a default message.
+ *
+ * @see #assertFalse(boolean, String)
+ */
+ public static void assertFalse(boolean value) {
+ assertFalse(value, "Expected value to be false");
+ }
+
+ /**
+ * Asserts that {@code value} is {@code false}.
+ *
+ * @param value The value assumed to be false.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static void assertFalse(boolean value, String msg) {
+ assertTrue(!value, msg);
+ }
+
+ /**
+ * Calls {@link #assertTrue(boolean, String)} with a default message.
+ *
+ * @see #assertTrue(boolean, String)
+ */
+ public static void assertTrue(boolean value) {
+ assertTrue(value, "Expected value to be true");
+ }
+
+ /**
+ * Asserts that {@code value} is {@code true}.
+ *
+ * @param value The value assumed to be true.
+ * @param msg A description of the assumption.
+ * @throws RuntimeException if the assertion isn't valid.
+ */
+ public static void assertTrue(boolean value, String msg) {
+ if (!value) {
+ error(msg);
+ }
+ }
+
+ private static <T extends Comparable<T>> int compare(T lhs, T rhs, String msg) {
+ assertNotNull(lhs, msg);
+ assertNotNull(rhs, msg);
+ return lhs.compareTo(rhs);
+ }
+
+ private static String format(Object o) {
+ return o == null? "null" : o.toString();
+ }
+
+ private static void error(String msg) {
+ throw new RuntimeException(msg);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.security.SecureClassLoader;
+
+/**
+ * {@code ByteCodeLoader} can be used for easy loading of byte code already
+ * present in memory.
+ *
+ * {@code InMemoryCompiler} can be used for compiling source code in a string
+ * into byte code, which then can be loaded with {@code ByteCodeLoader}.
+ *
+ * @see InMemoryCompiler
+ */
+public class ByteCodeLoader extends SecureClassLoader {
+ private final String className;
+ private final byte[] byteCode;
+
+ /**
+ * Creates a new {@code ByteCodeLoader} ready to load a class with the
+ * given name and the given byte code.
+ *
+ * @param className The name of the class
+ * @param byteCode The byte code of the class
+ */
+ public ByteCodeLoader(String className, byte[] byteCode) {
+ this.className = className;
+ this.byteCode = byteCode;
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (!name.equals(className)) {
+ throw new ClassNotFoundException(name);
+ }
+
+ return defineClass(name, byteCode, 0, byteCode.length);
+ }
+
+ /**
+ * Utility method for creating a new {@code ByteCodeLoader} and then
+ * directly load the given byte code.
+ *
+ * @param className The name of the class
+ * @param byteCode The byte code for the class
+ * @throws ClassNotFoundException if the class can't be loaded
+ * @return A {@see Class} object representing the class
+ */
+ public static Class<?> load(String className, byte[] byteCode) throws ClassNotFoundException {
+ return new ByteCodeLoader(className, byteCode).loadClass(className);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InMemoryJavaCompiler.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.net.URI;
+import java.util.Arrays;
+
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.FileObject;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+/**
+ * {@code InMemoryJavaCompiler} can be used for compiling a {@link
+ * CharSequence} to a {@code byte[]}.
+ *
+ * The compiler will not use the file system at all, instead using a {@link
+ * ByteArrayOutputStream} for storing the byte code. For the source code, any
+ * kind of {@link CharSequence} can be used, e.g. {@link String}, {@link
+ * StringBuffer} or {@link StringBuilder}.
+ *
+ * The {@code InMemoryCompiler} can easily be used together with a {@code
+ * ByteClassLoader} to easily compile and load source code in a {@link String}:
+ *
+ * <pre>
+ * {@code
+ * import com.oracle.java.testlibrary.InMemoryJavaCompiler;
+ * import com.oracle.java.testlibrary.ByteClassLoader;
+ *
+ * class Example {
+ * public static void main(String[] args) {
+ * String className = "Foo";
+ * String sourceCode = "public class " + className + " {" +
+ * " public void bar() {" +
+ * " System.out.println("Hello from bar!");" +
+ * " }" +
+ * "}";
+ * byte[] byteCode = InMemoryJavaCompiler.compile(className, sourceCode);
+ * Class fooClass = ByteClassLoader.load(className, byteCode);
+ * }
+ * }
+ * }
+ * </pre>
+ */
+public class InMemoryJavaCompiler {
+ private static class MemoryJavaFileObject extends SimpleJavaFileObject {
+ private final String className;
+ private final CharSequence sourceCode;
+ private final ByteArrayOutputStream byteCode;
+
+ public MemoryJavaFileObject(String className, CharSequence sourceCode) {
+ super(URI.create("string:///" + className.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
+ this.className = className;
+ this.sourceCode = sourceCode;
+ this.byteCode = new ByteArrayOutputStream();
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return sourceCode;
+ }
+
+ @Override
+ public OutputStream openOutputStream() throws IOException {
+ return byteCode;
+ }
+
+ public byte[] getByteCode() {
+ return byteCode.toByteArray();
+ }
+
+ public String getClassName() {
+ return className;
+ }
+ }
+
+ private static class FileManagerWrapper extends ForwardingJavaFileManager {
+ private MemoryJavaFileObject file;
+
+ public FileManagerWrapper(MemoryJavaFileObject file) {
+ super(getCompiler().getStandardFileManager(null, null, null));
+ this.file = file;
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForOutput(Location location, String className,
+ Kind kind, FileObject sibling)
+ throws IOException {
+ if (!file.getClassName().equals(className)) {
+ throw new IOException("Expected class with name " + file.getClassName() +
+ ", but got " + className);
+ }
+ return file;
+ }
+ }
+
+ /**
+ * Compiles the class with the given name and source code.
+ *
+ * @param className The name of the class
+ * @param sourceCode The source code for the class with name {@code className}
+ * @throws RuntimeException if the compilation did not succeed
+ * @return The resulting byte code from the compilation
+ */
+ public static byte[] compile(String className, CharSequence sourceCode) {
+ MemoryJavaFileObject file = new MemoryJavaFileObject(className, sourceCode);
+ CompilationTask task = getCompilationTask(file);
+
+ if(!task.call()) {
+ throw new RuntimeException("Could not compile " + className + " with source code " + sourceCode);
+ }
+
+ return file.getByteCode();
+ }
+
+ private static JavaCompiler getCompiler() {
+ return ToolProvider.getSystemJavaCompiler();
+ }
+
+ private static CompilationTask getCompilationTask(MemoryJavaFileObject file) {
+ return getCompiler().getTask(null, new FileManagerWrapper(file), null, null, null, Arrays.asList(file));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+
+/**
+ * This class provides access to the input arguments to the VM.
+ */
+public class InputArguments {
+ private static final List<String> args;
+
+ static {
+ RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+ args = runtimeMxBean.getInputArguments();
+ }
+
+ /**
+ * Returns true if {@code arg} is an input argument to the VM.
+ *
+ * @param arg The name of the argument.
+ * @return {@code true} if the given argument is an input argument,
+ * otherwise {@code false}.
+ */
+ public static boolean contains(String arg) {
+ return args.contains(arg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/PerfCounter.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary;
+
+import sun.jvmstat.monitor.Monitor;
+
+/**
+ * Represents a performance counter in the JVM.
+ *
+ * See http://openjdk.java.net/groups/hotspot/docs/Serviceability.html#bjvmstat
+ * for more details about performance counters.
+ */
+public class PerfCounter {
+ private final Monitor monitor;
+ private final String name;
+
+ PerfCounter(Monitor monitor, String name) {
+ this.monitor = monitor;
+ this.name = name;
+ }
+
+ /**
+ * Returns the value of this performance counter as a long.
+ *
+ * @return The long value of this performance counter
+ * @throws RuntimeException If the value of the performance counter isn't a long
+ */
+ public long longValue() {
+ Object value = monitor.getValue();
+ if (value instanceof Long) {
+ return ((Long) value).longValue();
+ }
+ throw new RuntimeException("Expected " + monitor.getName() + " to have a long value");
+ }
+
+ /**
+ * Returns the name of the performance counter.
+ *
+ * @return The name of the performance counter.
+ */
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/PerfCounters.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary;
+
+import sun.jvmstat.monitor.Monitor;
+import sun.jvmstat.monitor.MonitorException;
+import sun.jvmstat.monitor.MonitoredHost;
+import sun.jvmstat.monitor.MonitoredVm;
+import sun.jvmstat.monitor.VmIdentifier;
+
+/**
+ * PerfCounters can be used to get a performance counter from the currently
+ * executing VM.
+ *
+ * Throws a runtime exception if an error occurs while communicating with the
+ * currently executing VM.
+ */
+public class PerfCounters {
+ private final static MonitoredVm vm;
+
+ static {
+ try {
+ String pid = Integer.toString(ProcessTools.getProcessId());
+ VmIdentifier vmId = new VmIdentifier(pid);
+ MonitoredHost host = MonitoredHost.getMonitoredHost(vmId);
+ vm = host.getMonitoredVm(vmId);
+ } catch (Exception e) {
+ throw new RuntimeException("Could not connect to the VM");
+ }
+ }
+
+ /**
+ * Returns the performance counter with the given name.
+ *
+ * @param name The name of the performance counter.
+ * @throws IllegalArgumentException If no counter with the given name exists.
+ * @throws MonitorException If an error occurs while communicating with the VM.
+ * @return The performance counter with the given name.
+ */
+ public static PerfCounter findByName(String name)
+ throws MonitorException, IllegalArgumentException {
+ Monitor m = vm.findByName(name);
+ if (m == null) {
+ throw new IllegalArgumentException("Did not find a performance counter with name " + name);
+ }
+ return new PerfCounter(m, name);
+ }
+}
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Fri Aug 23 14:17:49 2013 -0700
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Jul 05 19:09:26 2017 +0200
@@ -93,23 +93,45 @@
// Compiler
public native void deoptimizeAll();
- public native boolean isMethodCompiled(Executable method);
- public boolean isMethodCompilable(Executable method) {
- return isMethodCompilable(method, -1 /*any*/);
+ public boolean isMethodCompiled(Executable method) {
+ return isMethodCompiled(method, false /*not osr*/);
}
- public native boolean isMethodCompilable(Executable method, int compLevel);
+ public native boolean isMethodCompiled(Executable method, boolean isOsr);
+ public boolean isMethodCompilable(Executable method) {
+ return isMethodCompilable(method, -1 /*any*/);
+ }
+ public boolean isMethodCompilable(Executable method, int compLevel) {
+ return isMethodCompilable(method, compLevel, false /*not osr*/);
+ }
+ public native boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr);
public native boolean isMethodQueuedForCompilation(Executable method);
- public native int deoptimizeMethod(Executable method);
- public void makeMethodNotCompilable(Executable method) {
- makeMethodNotCompilable(method, -1 /*any*/);
+ public int deoptimizeMethod(Executable method) {
+ return deoptimizeMethod(method, false /*not osr*/);
+ }
+ public native int deoptimizeMethod(Executable method, boolean isOsr);
+ public void makeMethodNotCompilable(Executable method) {
+ makeMethodNotCompilable(method, -1 /*any*/);
+ }
+ public void makeMethodNotCompilable(Executable method, int compLevel) {
+ makeMethodNotCompilable(method, compLevel, false /*not osr*/);
+ }
+ public native void makeMethodNotCompilable(Executable method, int compLevel, boolean isOsr);
+ public int getMethodCompilationLevel(Executable method) {
+ return getMethodCompilationLevel(method, false /*not ost*/);
}
- public native void makeMethodNotCompilable(Executable method, int compLevel);
- public native int getMethodCompilationLevel(Executable method);
+ public native int getMethodCompilationLevel(Executable method, boolean isOsr);
public native boolean testSetDontInlineMethod(Executable method, boolean value);
- public native int getCompileQueuesSize();
+ public int getCompileQueuesSize() {
+ return getCompileQueueSize(-1 /*any*/);
+ }
+ public native int getCompileQueueSize(int compLevel);
public native boolean testSetForceInlineMethod(Executable method, boolean value);
- public native boolean enqueueMethodForCompilation(Executable method, int compLevel);
+ public boolean enqueueMethodForCompilation(Executable method, int compLevel) {
+ return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/);
+ }
+ public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci);
public native void clearMethodState(Executable method);
+ public native int getMethodEntryBci(Executable method);
// Intered strings
public native boolean isInStringTable(String str);
--- a/jaxp/.hgtags Fri Aug 23 14:17:49 2013 -0700
+++ b/jaxp/.hgtags Wed Jul 05 19:09:26 2017 +0200
@@ -225,3 +225,4 @@
0a7432f898e579ea35e8c51e3edab37f949168e4 jdk8-b101
7cffafa606e9fb865e7b5e6a56e0a681ce5cf617 jdk8-b102
b1ceab582fc6d795b20aaa8a3fde2eba34af9399 jdk8-b103
+a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java Wed Jul 05 19:09:26 2017 +0200
@@ -38,6 +38,7 @@
import com.sun.org.apache.xerces.internal.util.PropertyState;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
@@ -184,6 +185,10 @@
protected static final String LOCALE =
Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
+ /** Property identifier: Security property manager. */
+ protected static final String XML_SECURITY_PROPERTY_MANAGER =
+ Constants.XML_SECURITY_PROPERTY_MANAGER;
+
// debugging
/** Set to true and recompile to print exception stack trace. */
@@ -328,7 +333,8 @@
VALIDATION_MANAGER,
JAXP_SCHEMA_SOURCE,
JAXP_SCHEMA_LANGUAGE,
- LOCALE
+ LOCALE,
+ XML_SECURITY_PROPERTY_MANAGER
};
addRecognizedProperties(recognizedProperties);
@@ -406,6 +412,7 @@
// REVISIT: What is the right thing to do? -Ac
}
+ setProperty(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager());
} // <init>(SymbolTable,XMLGrammarPool)
//
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java Wed Jul 05 19:09:26 2017 +0200
@@ -36,6 +36,7 @@
import com.sun.org.apache.xerces.internal.util.PropertyState;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
@@ -157,6 +158,10 @@
protected static final String LOCALE =
Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
+ /** Property identifier: Security property manager. */
+ protected static final String XML_SECURITY_PROPERTY_MANAGER =
+ Constants.XML_SECURITY_PROPERTY_MANAGER;
+
// debugging
/** Set to true and recompile to print exception stack trace. */
@@ -310,7 +315,8 @@
XMLGRAMMAR_POOL,
DATATYPE_VALIDATOR_FACTORY,
VALIDATION_MANAGER,
- LOCALE
+ LOCALE,
+ XML_SECURITY_PROPERTY_MANAGER
};
addRecognizedProperties(recognizedProperties);
@@ -367,6 +373,7 @@
// REVISIT: What is the right thing to do? -Ac
}
+ setProperty(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager());
} // <init>(SymbolTable,XMLGrammarPool)
//
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Wed Jul 05 19:09:26 2017 +0200
@@ -76,6 +76,7 @@
XMLGRAMMAR_POOL,
};
+ XMLSecurityPropertyManager securityPropertyManager;
//
// Constructors
//
@@ -129,16 +130,19 @@
*/
public void setProperty(String name, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException {
- XMLSecurityPropertyManager spm = new XMLSecurityPropertyManager();
- int index = spm.getIndex(name);
+ if (securityPropertyManager == null) {
+ securityPropertyManager = new XMLSecurityPropertyManager();
+ }
+ int index = securityPropertyManager.getIndex(name);
+
if (index > -1) {
/**
* this is a direct call to this parser, not a subclass since
* internally the support of this property is done through
* XMLSecurityPropertyManager
*/
- spm.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
- super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, spm);
+ securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
+ super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
} else {
super.setProperty(name, value);
}
--- a/jaxws/.hgtags Fri Aug 23 14:17:49 2013 -0700
+++ b/jaxws/.hgtags Wed Jul 05 19:09:26 2017 +0200
@@ -225,3 +225,4 @@
60b623a361642a0f5aef5f06dad9e5f279b9d9a9 jdk8-b101
988a5f2ac559dcab05698b8a8633aa453e012260 jdk8-b102
6cdc6ed987801c175a1217d0d3e53c3bd69ba52e jdk8-b103
+42211ab0ab1cca51a050d184634cf1db7ef81fbf jdk8-b104
--- a/jdk/.hgtags Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/.hgtags Wed Jul 05 19:09:26 2017 +0200
@@ -225,3 +225,4 @@
6901612328239fbd471d20823113c1cf3fdaebee jdk8-b101
8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102
e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103
+f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104
--- a/jdk/make/java/java/Exportedfiles.gmk Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/java/java/Exportedfiles.gmk Wed Jul 05 19:09:26 2017 +0200
@@ -50,6 +50,7 @@
java/lang/SecurityManager.java \
java/lang/Shutdown.java \
java/lang/Package.java \
+ java/lang/UNIXProcess.java \
java/lang/ref/Finalizer.java \
java/lang/reflect/AccessibleObject.java \
java/lang/reflect/Field.java \
--- a/jdk/make/java/java/Makefile Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/java/java/Makefile Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2013, 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
@@ -87,6 +87,7 @@
java/util/prefs/FileSystemPreferencesFactory.java \
FILES_c += UNIXProcess_md.c \
+ childproc.c \
UnixFileSystem_md.c \
canonicalize_md.c \
TimeZone.c \
@@ -468,3 +469,36 @@
clean::
$(RM) $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java
+
+HELPER_EXE = $(LIBDIR)/$(LIBARCH)/jspawnhelper
+BUILDHELPER =
+ifeq ($(PLATFORM), solaris)
+ BUILDHELPER = 1
+endif
+ifeq ($(PLATFORM), macosx)
+ HELPER_EXE = $(LIBDIR)/jspawnhelper
+ BUILDHELPER = 1
+endif
+
+ARCHFLAG =
+ifeq ($(ARCH_DATA_MODEL), 64)
+ARCHFLAG = -m64
+endif
+
+ifdef BUILDHELPER
+
+HELPER_EXE_FILES_c = jspawnhelper.c
+HELPER_EXE_FILES_o = $(OBJDIR)/jspawnhelper.o \
+ $(OBJDIR)/childproc.o
+
+$(HELPER_EXE): $(HELPER_EXE_FILES_o)
+ $(CC) $(ARCHFLAG) $(HELPER_EXE_FILES_o) \
+ -o $(TEMPDIR)/jspawnhelper
+ $(CP) $(TEMPDIR)/jspawnhelper $(HELPER_EXE)
+
+build: $(HELPER_EXE)
+
+clean clobber::
+ $(RM) $(HELPER_EXE_FILES_o) $(HELPER_EXE)
+
+endif #BUILDHELPER
--- a/jdk/make/java/java/mapfile-vers Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/java/java/mapfile-vers Wed Jul 05 19:09:26 2017 +0200
@@ -100,7 +100,7 @@
Java_java_io_RandomAccessFile_open;
Java_java_io_RandomAccessFile_read;
Java_java_io_RandomAccessFile_readBytes;
- Java_java_io_RandomAccessFile_seek;
+ Java_java_io_RandomAccessFile_seek0;
Java_java_io_RandomAccessFile_setLength;
Java_java_io_RandomAccessFile_write;
Java_java_io_RandomAccessFile_writeBytes;
--- a/jdk/make/sun/javazic/tzdata/VERSION Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/VERSION Wed Jul 05 19:09:26 2017 +0200
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2013c
+tzdata2013d
--- a/jdk/make/sun/javazic/tzdata/africa Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/africa Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -875,12 +875,18 @@
# announced that year's Ramadan daylight-saving transitions would be
# 2012-07-20 and 2012-08-20; see
# <http://www.mmsp.gov.ma/fr/actualites.aspx?id=288>.
-#
+
+# From Andrew Paprocki (2013-07-02):
+# Morocco announced that the year's Ramadan daylight-savings
+# transitions would be 2013-07-07 and 2013-08-10; see:
+# http://www.maroc.ma/en/news/morocco-suspends-daylight-saving-time-july-7-aug10
+
+# From Paul Eggert (2013-07-03):
# To estimate what the Moroccan government will do in future years,
-# transition dates for 2013 through 2021 were determined by running
+# transition dates for 2014 through 2021 were determined by running
# the following program under GNU Emacs 24.3:
#
-# (let ((islamic-year 1434))
+# (let ((islamic-year 1435))
# (while (< islamic-year 1444)
# (let ((a
# (calendar-gregorian-from-absolute
@@ -933,8 +939,8 @@
Rule Morocco 2012 max - Sep lastSun 3:00 0 -
Rule Morocco 2012 only - Jul 20 3:00 0 -
Rule Morocco 2012 only - Aug 20 2:00 1:00 S
-Rule Morocco 2013 only - Jul 9 3:00 0 -
-Rule Morocco 2013 only - Aug 8 2:00 1:00 S
+Rule Morocco 2013 only - Jul 7 3:00 0 -
+Rule Morocco 2013 only - Aug 10 2:00 1:00 S
Rule Morocco 2014 only - Jun 29 3:00 0 -
Rule Morocco 2014 only - Jul 29 2:00 1:00 S
Rule Morocco 2015 only - Jun 18 3:00 0 -
--- a/jdk/make/sun/javazic/tzdata/antarctica Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/antarctica Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/asia Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/asia Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -1235,39 +1235,21 @@
Rule Zion 2012 only - Mar Fri>=26 2:00 1:00 D
Rule Zion 2012 only - Sep 23 2:00 0 S
-# From Ephraim Silverberg (2012-10-18):
-# Yesterday, the Interior Ministry Committee, after more than a year
-# past, approved sending the proposed June 2011 changes to the Time
-# Decree Law back to the Knesset for second and third (final) votes
-# before the upcoming elections on Jan. 22, 2013. Hence, although the
-# changes are not yet law, they are expected to be so before February 2013.
+# From Ephraim Silverberg (2013-06-27):
+# On June 23, 2013, the Israeli government approved changes to the
+# Time Decree Law. The next day, the changes passed the First Reading
+# in the Knesset. The law is expected to pass the Second and Third
+# (final) Readings by the beginning of September 2013.
#
-# As of 2013, DST starts at 02:00 on the Friday before the last Sunday in March.
-# DST ends at 02:00 on the first Sunday after October 1, unless it occurs on the
-# second day of the Jewish Rosh Hashana holiday, in which case DST ends a day
-# later (i.e. at 02:00 the first Monday after October 2).
-# [Rosh Hashana holidays are factored in until 2100.]
-
-# From Ephraim Silverberg (2012-11-05):
-# The Knesset passed today (in second and final readings) the amendment to the
-# Time Decree Law making the changes ... law.
+# As of 2013, DST starts at 02:00 on the Friday before the last Sunday
+# in March. DST ends at 02:00 on the last Sunday of October.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Zion 2013 max - Mar Fri>=23 2:00 1:00 D
-Rule Zion 2013 2026 - Oct Sun>=2 2:00 0 S
-Rule Zion 2027 only - Oct Mon>=3 2:00 0 S
-Rule Zion 2028 max - Oct Sun>=2 2:00 0 S
-# The following rules are commented out for now, as they break older
-# versions of zic that support only signed 32-bit timestamps, i.e.,
-# through 2038-01-19 03:14:07 UTC.
-#Rule Zion 2028 2053 - Oct Sun>=2 2:00 0 S
-#Rule Zion 2054 only - Oct Mon>=3 2:00 0 S
-#Rule Zion 2055 2080 - Oct Sun>=2 2:00 0 S
-#Rule Zion 2081 only - Oct Mon>=3 2:00 0 S
-#Rule Zion 2082 max - Oct Sun>=2 2:00 0 S
+Rule Zion 2013 max - Oct lastSun 2:00 0 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Jerusalem 2:20:56 - LMT 1880
+Zone Asia/Jerusalem 2:20:54 - LMT 1880
2:20:40 - JMT 1918 # Jerusalem Mean Time?
2:00 Zion I%sT
@@ -2570,8 +2552,8 @@
Rule Syria 2007 only - Mar lastFri 0:00 1:00 S
# From Jesper Norgard (2007-10-27):
# The sister center ICARDA of my work CIMMYT is confirming that Syria DST will
-# not take place 1.st November at 0:00 o'clock but 1.st November at 24:00 or
-# rather Midnight between Thursday and Friday. This does make more sence than
+# not take place 1st November at 0:00 o'clock but 1st November at 24:00 or
+# rather Midnight between Thursday and Friday. This does make more sense than
# having it between Wednesday and Thursday (two workdays in Syria) since the
# weekend in Syria is not Saturday and Sunday, but Friday and Saturday. So now
# it is implemented at midnight of the last workday before weekend...
--- a/jdk/make/sun/javazic/tzdata/australasia Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/australasia Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -253,10 +253,16 @@
# - Macquarie Island will stay on UTC+11 for winter and therefore not
# switch back from daylight savings time when other parts of Australia do
# on 4 April.
+#
+# From Arthur David Olson (2013-05-23):
+# The 1919 transition is overspecified below so pre-2013 zics
+# will produce a binary file with an EST-type as the first 32-bit type;
+# this is required for correct handling of times before 1916 by
+# pre-2013 versions of localtime.
Zone Antarctica/Macquarie 0 - zzz 1899 Nov
10:00 - EST 1916 Oct 1 2:00
10:00 1:00 EST 1917 Feb
- 10:00 Aus EST 1919 Apr
+ 10:00 Aus EST 1919 Apr 1 0:00s
0 - zzz 1948 Mar 25
10:00 Aus EST 1967
10:00 AT EST 2010 Apr 4 3:00
@@ -1498,12 +1504,12 @@
# From Paul Eggert (2000-01-08):
# IATA SSIM (1999-09) says DST ends 0100 local time. Go with McDow.
-# From the BBC World Service (1998-10-31 11:32 UTC):
+# From the BBC World Service in
+# http://news.bbc.co.uk/2/hi/asia-pacific/205226.stm (1998-10-31 16:03 UTC):
# The Fijiian government says the main reasons for the time change is to
-# improve productivity and reduce road accidents. But correspondents say it
-# also hopes the move will boost Fiji's ability to compete with other pacific
-# islands in the effort to attract tourists to witness the dawning of the new
-# millenium.
+# improve productivity and reduce road accidents.... [T]he move is also
+# intended to boost Fiji's ability to attract tourists to witness the dawning
+# of the new millennium.
# http://www.fiji.gov.fj/press/2000_09/2000_09_13-05.shtml (2000-09-13)
# reports that Fiji has discontinued DST.
@@ -1648,7 +1654,7 @@
# Shanks & Pottenger say the transition was on 1968-10-01; go with Mundell.
# From Eric Ulevik (1999-05-03):
-# Tonga's director of tourism, who is also secretary of the National Millenium
+# Tonga's director of tourism, who is also secretary of the National Millennium
# Committee, has a plan to get Tonga back in front.
# He has proposed a one-off move to tropical daylight saving for Tonga from
# October to March, which has won approval in principle from the Tongan
--- a/jdk/make/sun/javazic/tzdata/backward Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/backward Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/etcetera Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/etcetera Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/europe Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/europe Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -546,7 +546,7 @@
# It seems that Paris, Monaco, Rule France, Rule Belgium all agree on
# 2:00 standard time, e.g. 3:00 local time. However there are no
# countries that use C-Eur rules in September 1945, so the only items
-# affected are apparently these ficticious zones that translates acronyms
+# affected are apparently these fictitious zones that translate acronyms
# CET and MET:
#
# Zone CET 1:00 C-Eur CE%sT
@@ -2802,9 +2802,9 @@
# Ukraine
#
-# From Igor Karpov, who works for the Ukranian Ministry of Justice,
+# From Igor Karpov, who works for the Ukrainian Ministry of Justice,
# via Garrett Wollman (2003-01-27):
-# BTW, I've found the official document on this matter. It's goverment
+# BTW, I've found the official document on this matter. It's government
# regulations number 509, May 13, 1996. In my poor translation it says:
# "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday
# of March at 3am the time is changing to 4am and each last Sunday of
@@ -2838,7 +2838,7 @@
# time this year after all.
#
# From Udo Schwedt (2011-10-18):
-# As far as I understand, the recent change to the Ukranian time zone
+# As far as I understand, the recent change to the Ukrainian time zone
# (Europe/Kiev) to introduce permanent daylight saving time (similar
# to Russia) was reverted today:
#
--- a/jdk/make/sun/javazic/tzdata/factory Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/factory Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/iso3166.tab Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/iso3166.tab Wed Jul 05 19:09:26 2017 +0200
@@ -1,39 +1,37 @@
#
# 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.
#
-# <pre>
+# ISO 3166 alpha-2 country codes
+#
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
-# ISO 3166 alpha-2 country codes
#
-# From Paul Eggert (2006-09-27):
+# From Paul Eggert (2013-05-27):
#
# This file contains a table with the following columns:
# 1. ISO 3166-1 alpha-2 country code, current as of
-# ISO 3166-1 Newsletter VI-1 (2007-09-21). See:
-# <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
-# ISO 3166 Maintenance agency (ISO 3166/MA)
-# </a>.
+# ISO 3166-1 Newsletter VI-15 (2013-05-10). See: Updates on ISO 3166
+# http://www.iso.org/iso/home/standards/country_codes/updates_on_iso_3166.htm
# 2. The usual English name for the country,
# chosen so that alphabetic sorting of subsets produces helpful lists.
# This is not the same as the English name in the ISO 3166 tables.
@@ -43,8 +41,9 @@
#
# Lines beginning with `#' are comments.
#
-# From Arthur David Olson (2011-08-17):
-# Resynchronized today with the ISO 3166 site (adding SS for South Sudan).
+# This table is intended as an aid for users, to help them select time
+# zone data appropriate for their practical needs. It is not intended
+# to take or endorse any position on legal or territorial claims.
#
#country-
#code country name
@@ -77,7 +76,7 @@
BM Bermuda
BN Brunei
BO Bolivia
-BQ Bonaire Sint Eustatius & Saba
+BQ Bonaire, St Eustatius & Saba
BR Brazil
BS Bahamas
BT Bhutan
@@ -258,7 +257,7 @@
SS South Sudan
ST Sao Tome & Principe
SV El Salvador
-SX Sint Maarten
+SX St Maarten (Dutch part)
SY Syria
SZ Swaziland
TC Turks & Caicos Is
--- a/jdk/make/sun/javazic/tzdata/leapseconds Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/leapseconds Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/northamerica Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/northamerica Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/pacificnew Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/pacificnew Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/solar87 Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/solar87 Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/solar88 Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/solar88 Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/solar89 Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/solar89 Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/southamerica Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/southamerica Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -994,7 +994,7 @@
# adopted by the same states as before.
Rule Brazil 2007 only - Oct Sun>=8 0:00 1:00 S
# From Frederico A. C. Neves (2008-09-10):
-# Acording to this decree
+# According to this decree
# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm">
# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm
# </a>
@@ -1226,7 +1226,7 @@
# http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651
# </a>
#
-# This is not yet reflected in the offical "cambio de hora" site, but
+# This is not yet reflected in the official "cambio de hora" site, but
# probably will be soon:
# <a href="http://www.horaoficial.cl/cambio.htm">
# http://www.horaoficial.cl/cambio.htm
--- a/jdk/make/sun/javazic/tzdata/systemv Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/systemv Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/make/sun/javazic/tzdata/zone.tab Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/javazic/tzdata/zone.tab Wed Jul 05 19:09:26 2017 +0200
@@ -1,41 +1,44 @@
#
# 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.
#
-# <pre>
+# TZ zone descriptions
+#
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
#
-# TZ zone descriptions
-#
-# From Paul Eggert (1996-08-05):
+# From Paul Eggert (2013-05-27):
#
# This file contains a table with the following columns:
# 1. ISO 3166 2-character country code. See the file `iso3166.tab'.
+# This identifies a country that overlaps the zone. The country may
+# overlap other zones and the zone may overlap other countries.
# 2. Latitude and longitude of the zone's principal location
# in ISO 6709 sign-degrees-minutes-seconds format,
# either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
# first latitude (+ is north), then longitude (+ is east).
+# This location need not lie within the column-1 country.
# 3. Zone name used in value of TZ environment variable.
+# Please see the 'Theory' file for how zone names are chosen.
# 4. Comments; present if and only if the country has multiple rows.
#
# Columns are separated by a single tab.
@@ -45,6 +48,10 @@
#
# Lines beginning with `#' are comments.
#
+# This table is intended as an aid for users, to help them select time
+# zone data appropriate for their practical needs. It is not intended
+# to take or endorse any position on legal or territorial claims.
+#
#country-
#code coordinates TZ comments
AD +4230+00131 Europe/Andorra
@@ -239,7 +246,7 @@
ID -0507+11924 Asia/Makassar east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor
ID -0232+14042 Asia/Jayapura west New Guinea (Irian Jaya) & Malukus (Moluccas)
IE +5320-00615 Europe/Dublin
-IL +3146+03514 Asia/Jerusalem
+IL +314650+0351326 Asia/Jerusalem
IM +5409-00428 Europe/Isle_of_Man
IN +2232+08822 Asia/Kolkata
IO -0720+07225 Indian/Chagos
--- a/jdk/make/sun/jconsole/Makefile Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/sun/jconsole/Makefile Wed Jul 05 19:09:26 2017 +0200
@@ -94,4 +94,5 @@
clean clobber::
$(RM) $(TEMPDIR)/manifest $(JARFILE)
+ $(RM) $(GENSRCDIR)/sun/tools/jconsole/Version.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM290.c2b Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,100 @@
+#
+# Diff of
+# b2c: cdctables.zip/Package2.zip/IBM-290.zip/012234B0.TPMAP100
+# c2b: cdctables.zip/Package2.zip/IBM-290.zip/012234B0.UPMAP100
+#
+# fullwidth form
+0x4B U+FF0E
+0x4C U+FF1C
+0x4D U+FF08
+0x4E U+FF0B
+0x4F U+FF5C
+0x50 U+FF06
+0x5A U+FF01
+0x5C U+FF0A
+0x5D U+FF09
+0x5E U+FF1B
+0x60 U+FF0D
+0x61 U+FF0F
+0x62 U+FF41
+0x63 U+FF42
+0x64 U+FF43
+0x65 U+FF44
+0x66 U+FF45
+0x67 U+FF46
+0x68 U+FF47
+0x69 U+FF48
+0x6B U+FF0C
+0x6C U+FF05
+0x6D U+FF3F
+0x6E U+FF1E
+0x6F U+FF1F
+0x70 U+FF3B
+0x71 U+FF49
+0x72 U+FF4A
+0x73 U+FF4B
+0x74 U+FF4C
+0x75 U+FF4D
+0x76 U+FF4E
+0x77 U+FF4F
+0x78 U+FF50
+0x79 U+FF40
+0x7A U+FF1A
+0x7B U+FF03
+0x7C U+FF20
+0x7D U+FF07
+0x7E U+FF1D
+0x7F U+FF02
+0x80 U+FF3D
+0x8B U+FF51
+0x9B U+FF52
+0xA0 U+FF5E
+0xAB U+FF53
+0xB0 U+FF3E
+0xB2 U+FF3C
+0xB3 U+FF54
+0xB4 U+FF55
+0xB5 U+FF56
+0xB6 U+FF57
+0xB7 U+FF58
+0xB8 U+FF59
+0xB9 U+FF5A
+0xC0 U+FF5B
+0xC1 U+FF21
+0xC2 U+FF22
+0xC3 U+FF23
+0xC4 U+FF24
+0xC5 U+FF25
+0xC6 U+FF26
+0xC7 U+FF27
+0xC8 U+FF28
+0xC9 U+FF29
+0xD0 U+FF5D
+0xD1 U+FF2A
+0xD2 U+FF2B
+0xD3 U+FF2C
+0xD4 U+FF2D
+0xD5 U+FF2E
+0xD6 U+FF2F
+0xD7 U+FF30
+0xD8 U+FF31
+0xD9 U+FF32
+0xE0 U+FF04
+0xE2 U+FF33
+0xE3 U+FF34
+0xE4 U+FF35
+0xE5 U+FF36
+0xE6 U+FF37
+0xE7 U+FF38
+0xE8 U+FF39
+0xE9 U+FF3A
+0xF0 U+FF10
+0xF1 U+FF11
+0xF2 U+FF12
+0xF3 U+FF13
+0xF4 U+FF14
+0xF5 U+FF15
+0xF6 U+FF16
+0xF7 U+FF17
+0xF8 U+FF18
+0xF9 U+FF19
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM290.map Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,232 @@
+#
+# b2c mapping for IBM290, generated from
+# cdctables.zip/Package2.zip/IBM-290.zip/012234B0.TPMAP100
+#
+0x00 U+0000
+0x01 U+0001
+0x02 U+0002
+0x03 U+0003
+0x04 U+009C
+0x05 U+0009
+0x06 U+0086
+0x07 U+007F
+0x08 U+0097
+0x09 U+008D
+0x0A U+008E
+0x0B U+000B
+0x0C U+000C
+0x0D U+000D
+0x0E U+000E
+0x0F U+000F
+0x10 U+0010
+0x11 U+0011
+0x12 U+0012
+0x13 U+0013
+0x14 U+009D
+0x15 U+0085
+0x16 U+0008
+0x17 U+0087
+0x18 U+0018
+0x19 U+0019
+0x1A U+0092
+0x1B U+008F
+0x1C U+001C
+0x1D U+001D
+0x1E U+001E
+0x1F U+001F
+0x20 U+0080
+0x21 U+0081
+0x22 U+0082
+0x23 U+0083
+0x24 U+0084
+0x25 U+000A
+0x26 U+0017
+0x27 U+001B
+0x28 U+0088
+0x29 U+0089
+0x2A U+008A
+0x2B U+008B
+0x2C U+008C
+0x2D U+0005
+0x2E U+0006
+0x2F U+0007
+0x30 U+0090
+0x31 U+0091
+0x32 U+0016
+0x33 U+0093
+0x34 U+0094
+0x35 U+0095
+0x36 U+0096
+0x37 U+0004
+0x38 U+0098
+0x39 U+0099
+0x3A U+009A
+0x3B U+009B
+0x3C U+0014
+0x3D U+0015
+0x3E U+009E
+0x3F U+001A
+0x40 U+0020
+0x41 U+FF61
+0x42 U+FF62
+0x43 U+FF63
+0x44 U+FF64
+0x45 U+FF65
+0x46 U+FF66
+0x47 U+FF67
+0x48 U+FF68
+0x49 U+FF69
+0x4A U+00A3
+0x4B U+002E
+0x4C U+003C
+0x4D U+0028
+0x4E U+002B
+0x4F U+007C
+0x50 U+0026
+0x51 U+FF6A
+0x52 U+FF6B
+0x53 U+FF6C
+0x54 U+FF6D
+0x55 U+FF6E
+0x56 U+FF6F
+0x58 U+FF70
+0x5A U+0021
+0x5B U+00A5
+0x5C U+002A
+0x5D U+0029
+0x5E U+003B
+0x5F U+00AC
+0x60 U+002D
+0x61 U+002F
+0x62 U+0061
+0x63 U+0062
+0x64 U+0063
+0x65 U+0064
+0x66 U+0065
+0x67 U+0066
+0x68 U+0067
+0x69 U+0068
+0x6B U+002C
+0x6C U+0025
+0x6D U+005F
+0x6E U+003E
+0x6F U+003F
+0x70 U+005B
+0x71 U+0069
+0x72 U+006A
+0x73 U+006B
+0x74 U+006C
+0x75 U+006D
+0x76 U+006E
+0x77 U+006F
+0x78 U+0070
+0x79 U+0060
+0x7A U+003A
+0x7B U+0023
+0x7C U+0040
+0x7D U+0027
+0x7E U+003D
+0x7F U+0022
+0x80 U+005D
+0x81 U+FF71
+0x82 U+FF72
+0x83 U+FF73
+0x84 U+FF74
+0x85 U+FF75
+0x86 U+FF76
+0x87 U+FF77
+0x88 U+FF78
+0x89 U+FF79
+0x8A U+FF7A
+0x8B U+0071
+0x8C U+FF7B
+0x8D U+FF7C
+0x8E U+FF7D
+0x8F U+FF7E
+0x90 U+FF7F
+0x91 U+FF80
+0x92 U+FF81
+0x93 U+FF82
+0x94 U+FF83
+0x95 U+FF84
+0x96 U+FF85
+0x97 U+FF86
+0x98 U+FF87
+0x99 U+FF88
+0x9A U+FF89
+0x9B U+0072
+0x9D U+FF8A
+0x9E U+FF8B
+0x9F U+FF8C
+0xA0 U+007E
+0xA1 U+203E
+0xA2 U+FF8D
+0xA3 U+FF8E
+0xA4 U+FF8F
+0xA5 U+FF90
+0xA6 U+FF91
+0xA7 U+FF92
+0xA8 U+FF93
+0xA9 U+FF94
+0xAA U+FF95
+0xAB U+0073
+0xAC U+FF96
+0xAD U+FF97
+0xAE U+FF98
+0xAF U+FF99
+0xB0 U+005E
+0xB1 U+00A2
+0xB2 U+005C
+0xB3 U+0074
+0xB4 U+0075
+0xB5 U+0076
+0xB6 U+0077
+0xB7 U+0078
+0xB8 U+0079
+0xB9 U+007A
+0xBA U+FF9A
+0xBB U+FF9B
+0xBC U+FF9C
+0xBD U+FF9D
+0xBE U+FF9E
+0xBF U+FF9F
+0xC0 U+007B
+0xC1 U+0041
+0xC2 U+0042
+0xC3 U+0043
+0xC4 U+0044
+0xC5 U+0045
+0xC6 U+0046
+0xC7 U+0047
+0xC8 U+0048
+0xC9 U+0049
+0xD0 U+007D
+0xD1 U+004A
+0xD2 U+004B
+0xD3 U+004C
+0xD4 U+004D
+0xD5 U+004E
+0xD6 U+004F
+0xD7 U+0050
+0xD8 U+0051
+0xD9 U+0052
+0xE0 U+0024
+0xE2 U+0053
+0xE3 U+0054
+0xE4 U+0055
+0xE5 U+0056
+0xE6 U+0057
+0xE7 U+0058
+0xE8 U+0059
+0xE9 U+005A
+0xF0 U+0030
+0xF1 U+0031
+0xF2 U+0032
+0xF3 U+0033
+0xF4 U+0034
+0xF5 U+0035
+0xF6 U+0036
+0xF7 U+0037
+0xF8 U+0038
+0xF9 U+0039
+0xFF U+009F
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM300.c2b Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,50 @@
+#
+# Diff of
+# b2c: cdctables.zip/Package2.zip/IBM-300.zip/012C34B0.TPMAP120
+# c2b: cdctables.zip/Package2.zip/IBM-300.zip/012C34B0.UPMAP120
+#
+4260 2212
+426A 00A6
+43A1 301C
+444A 2014
+446E F86F
+447C 2016
+4C7D 9E7C
+4EB3 9830
+4F5E 5861
+507F 91AC
+5190 56CA
+51F1 6805
+51FA 91B1
+5261 9EB4
+52A1 881F
+52C9 840A
+52DA 7E61
+52EC 4FE0
+5353 8EC0
+5373 7E6B
+53B3 8346
+53DA 9A52
+53E8 87EC
+53EE 7130
+53F8 8523
+5443 5C5B
+5464 9DD7
+547D 5699
+5481 525D
+54A3 6414
+54A4 7626
+54CA 7C1E
+54CD 6451
+54D4 555E
+54FA 6F51
+5550 7006
+5553 79B1
+555F 9EB5
+55C0 5C62
+55C1 985A
+5B72 6522
+5BFE 688E
+60F1 7E48
+61B0 8141
+66C8 9839
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM300.map Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,11644 @@
+#
+# b2c mapping for IBM300, generated from
+# cdctables.zip/Package2.zip/IBM-300.zip/012C34B0.TPMAP120
+#
+# <subchar> FEFE
+# Note: subchar FEFE itself is not a defined character in
+# 300 character set, we use fullwidth question mark
+# <0x426f U+FF1F> instead
+#
+4040 3000
+4141 03B1
+4142 03B2
+4143 03B3
+4144 03B4
+4145 03B5
+4146 03B6
+4147 03B7
+4148 03B8
+4149 03B9
+414A 03BA
+414B 03BB
+414C 03BC
+414D 03BD
+414E 03BE
+414F 03BF
+4150 03C0
+4151 03C1
+4152 03C3
+4153 03C4
+4154 03C5
+4155 03C6
+4156 03C7
+4157 03C8
+4158 03C9
+4161 0391
+4162 0392
+4163 0393
+4164 0394
+4165 0395
+4166 0396
+4167 0397
+4168 0398
+4169 0399
+416A 039A
+416B 039B
+416C 039C
+416D 039D
+416E 039E
+416F 039F
+4170 03A0
+4171 03A1
+4172 03A3
+4173 03A4
+4174 03A5
+4175 03A6
+4176 03A7
+4177 03A8
+4178 03A9
+4180 0430
+4181 0431
+4182 0432
+4183 0433
+4184 0434
+4185 0435
+4186 0451
+4187 0436
+4188 0437
+4189 0438
+418A 0439
+418B 043A
+418C 043B
+418D 043C
+418E 043D
+418F 043E
+4190 043F
+4191 0440
+4192 0441
+4193 0442
+4194 0443
+4195 0444
+4196 0445
+4197 0446
+4198 0447
+4199 0448
+419A 0449
+419B 044A
+419C 044B
+419D 044C
+419E 044D
+419F 044E
+41A0 044F
+41B1 2170
+41B2 2171
+41B3 2172
+41B4 2173
+41B5 2174
+41B6 2175
+41B7 2176
+41B8 2177
+41B9 2178
+41BA 2179
+41C0 0410
+41C1 0411
+41C2 0412
+41C3 0413
+41C4 0414
+41C5 0415
+41C6 0401
+41C7 0416
+41C8 0417
+41C9 0418
+41CA 0419
+41CB 041A
+41CC 041B
+41CD 041C
+41CE 041D
+41CF 041E
+41D0 041F
+41D1 0420
+41D2 0421
+41D3 0422
+41D4 0423
+41D5 0424
+41D6 0425
+41D7 0426
+41D8 0427
+41D9 0428
+41DA 0429
+41DB 042A
+41DC 042B
+41DD 042C
+41DE 042D
+41DF 042E
+41E0 042F
+41F1 2160
+41F2 2161
+41F3 2162
+41F4 2163
+41F5 2164
+41F6 2165
+41F7 2166
+41F8 2167
+41F9 2168
+41FA 2169
+424A FFE1
+424B FF0E
+424C FF1C
+424D FF08
+424E FF0B
+424F FF5C
+4250 FF06
+425A FF01
+425B FFE5
+425C FF0A
+425D FF09
+425E FF1B
+425F FFE2
+4260 FF0D
+4261 FF0F
+426A FFE4
+426B FF0C
+426C FF05
+426D FF3F
+426E FF1E
+426F FF1F
+4279 FF40
+427A FF1A
+427B FF03
+427C FF20
+427D FF07
+427E FF1D
+427F FF02
+4281 FF41
+4282 FF42
+4283 FF43
+4284 FF44
+4285 FF45
+4286 FF46
+4287 FF47
+4288 FF48
+4289 FF49
+4291 FF4A
+4292 FF4B
+4293 FF4C
+4294 FF4D
+4295 FF4E
+4296 FF4F
+4297 FF50
+4298 FF51
+4299 FF52
+42A1 FFE3
+42A2 FF53
+42A3 FF54
+42A4 FF55
+42A5 FF56
+42A6 FF57
+42A7 FF58
+42A8 FF59
+42A9 FF5A
+42C0 FF5B
+42C1 FF21
+42C2 FF22
+42C3 FF23
+42C4 FF24
+42C5 FF25
+42C6 FF26
+42C7 FF27
+42C8 FF28
+42C9 FF29
+42D0 FF5D
+42D1 FF2A
+42D2 FF2B
+42D3 FF2C
+42D4 FF2D
+42D5 FF2E
+42D6 FF2F
+42D7 FF30
+42D8 FF31
+42D9 FF32
+42E0 FF04
+42E2 FF33
+42E3 FF34
+42E4 FF35
+42E5 FF36
+42E6 FF37
+42E7 FF38
+42E8 FF39
+42E9 FF3A
+42F0 FF10
+42F1 FF11
+42F2 FF12
+42F3 FF13
+42F4 FF14
+42F5 FF15
+42F6 FF16
+42F7 FF17
+42F8 FF18
+42F9 FF19
+4341 3002
+4342 300C
+4343 300D
+4344 3001
+4345 30FB
+4346 30F2
+4347 30A1
+4348 30A3
+4349 30A5
+434A FFE0
+434B 2220
+434C 22A5
+434D 2312
+434E 2202
+434F 2207
+4351 30A7
+4352 30A9
+4353 30E3
+4354 30E5
+4355 30E7
+4356 30C3
+4357 30EE
+4358 30FC
+4359 30F5
+435A 30F6
+435B 2261
+435C 2252
+435D 226A
+435E 226B
+435F 221A
+4360 223D
+4361 221D
+4362 222B
+4363 222C
+4364 2208
+4365 220B
+4366 2286
+4367 2287
+4368 2282
+4369 2283
+436A 222A
+436B 2229
+436C 2227
+436D 2228
+436E 21D2
+436F 21D4
+4370 2200
+4371 2203
+4372 212B
+4373 2030
+4374 266F
+4375 266D
+4376 266A
+4377 2020
+4378 2021
+4379 00B6
+437A 25EF
+437C 2500
+437D 2502
+437E 250C
+437F 2510
+4381 30A2
+4382 30A4
+4383 30A6
+4384 30A8
+4385 30AA
+4386 30AB
+4387 30AD
+4388 30AF
+4389 30B1
+438A 30B3
+438C 30B5
+438D 30B7
+438E 30B9
+438F 30BB
+4390 30BD
+4391 30BF
+4392 30C1
+4393 30C4
+4394 30C6
+4395 30C8
+4396 30CA
+4397 30CB
+4398 30CC
+4399 30CD
+439A 30CE
+439D 30CF
+439E 30D2
+439F 30D5
+43A1 FF5E
+43A2 30D8
+43A3 30DB
+43A4 30DE
+43A5 30DF
+43A6 30E0
+43A7 30E1
+43A8 30E2
+43A9 30E4
+43AA 30E6
+43AC 30E8
+43AD 30E9
+43AE 30EA
+43AF 30EB
+43B0 2518
+43B1 2514
+43B2 251C
+43B3 252C
+43B4 2524
+43B5 2534
+43B6 253C
+43B7 2501
+43B8 2503
+43B9 250F
+43BA 30EC
+43BB 30ED
+43BC 30EF
+43BD 30F3
+43BE 309B
+43BF 309C
+43C0 30AC
+43C1 30AE
+43C2 30B0
+43C3 30B2
+43C4 30B4
+43C5 30B6
+43C6 30B8
+43C7 30BA
+43C8 30BC
+43C9 30BE
+43CA 30C0
+43CB 30C2
+43CC 30C5
+43CD 30C7
+43CE 30C9
+43CF 30D0
+43D0 30D3
+43D1 30D6
+43D2 30D9
+43D3 30DC
+43D4 30F4
+43D5 30D1
+43D6 30D4
+43D7 30D7
+43D8 30DA
+43D9 30DD
+43DA 30F0
+43DB 30F1
+43DC 30FD
+43DD 30FE
+43E0 FF3C
+43E1 2513
+43E2 251B
+43E3 2517
+43E4 2523
+43E5 2533
+43E6 252B
+43E7 253B
+43E8 254B
+43E9 2520
+43EA 252F
+43EB 2528
+43EC 2537
+43ED 253F
+43EE 251D
+43EF 2530
+43F0 2525
+43F1 2538
+43F2 2542
+4442 300E
+4443 300F
+4444 FF3B
+4445 FF3D
+4446 3092
+4447 3041
+4448 3043
+4449 3045
+444A 2015
+444B 00B1
+444C 2260
+444D 221E
+444E 2103
+4450 00B4
+4451 3047
+4452 3049
+4453 3083
+4454 3085
+4455 3087
+4456 3063
+4457 308E
+445A 2010
+445B 3003
+445C 4EDD
+445D 3005
+445E 3006
+445F 3007
+4460 00A8
+4461 2018
+4462 201C
+4463 3014
+4464 3008
+4465 300A
+4466 3010
+4467 2266
+4468 2234
+4469 2642
+446A 00A7
+446B 203B
+446C 3012
+446D 3231
+446E 2116
+446F 2121
+4470 FF3E
+4471 2019
+4472 201D
+4473 3015
+4474 3009
+4475 300B
+4476 3011
+4477 2267
+4478 2235
+4479 2640
+447A 00D7
+447B 00F7
+447C 2225
+447D 3013
+447E 2025
+447F 2026
+4481 3042
+4482 3044
+4483 3046
+4484 3048
+4485 304A
+4486 304B
+4487 304D
+4488 304F
+4489 3051
+448A 3053
+448C 3055
+448D 3057
+448E 3059
+448F 305B
+4490 305D
+4491 305F
+4492 3061
+4493 3064
+4494 3066
+4495 3068
+4496 306A
+4497 306B
+4498 306C
+4499 306D
+449A 306E
+449D 306F
+449E 3072
+449F 3075
+44A2 3078
+44A3 307B
+44A4 307E
+44A5 307F
+44A6 3080
+44A7 3081
+44A8 3082
+44A9 3084
+44AA 3086
+44AC 3088
+44AD 3089
+44AE 308A
+44AF 308B
+44BA 308C
+44BB 308D
+44BC 308F
+44BD 3093
+44C0 304C
+44C1 304E
+44C2 3050
+44C3 3052
+44C4 3054
+44C5 3056
+44C6 3058
+44C7 305A
+44C8 305C
+44C9 305E
+44CA 3060
+44CB 3062
+44CC 3065
+44CD 3067
+44CE 3069
+44CF 3070
+44D0 3073
+44D1 3076
+44D2 3079
+44D3 307C
+44D5 3071
+44D6 3074
+44D7 3077
+44D8 307A
+44D9 307D
+44DA 3090
+44DB 3091
+44DC 309D
+44DD 309E
+44E0 25CB
+44E1 25CF
+44E2 25B3
+44E3 25B2
+44E4 25CE
+44E5 2606
+44E6 2605
+44E7 25C7
+44E8 25C6
+44E9 25A1
+44EA 25A0
+44EB 25BD
+44EC 25BC
+44ED 00B0
+44EE 2032
+44EF 2033
+44F0 2192
+44F1 2190
+44F2 2191
+44F3 2193
+4541 4E00
+4542 4E8C
+4543 4E09
+4544 56DB
+4545 4E94
+4546 516D
+4547 4E03
+4548 516B
+4549 4E5D
+454A 5341
+454B 767E
+454C 5343
+454D 4E07
+454E 5104
+454F 90FD
+4550 9053
+4551 5E9C
+4552 770C
+4553 5E02
+4554 533A
+4555 753A
+4556 6751
+4557 6771
+4558 897F
+4559 5357
+455A 5317
+455B 5927
+455C 4E2D
+455D 5C0F
+455E 4E0A
+455F 4E0B
+4560 5E74
+4561 6708
+4562 65E5
+4563 7530
+4564 5B50
+4565 5C71
+4566 672C
+4567 5DDD
+4568 85E4
+4569 91CE
+456A 5DE5
+456B 696D
+456C 6728
+456D 4E95
+456E 90CE
+456F 5CF6
+4570 96C4
+4571 9AD8
+4572 5CA1
+4573 592B
+4574 539F
+4575 4EAC
+4576 4F50
+4577 6B63
+4578 677E
+4579 6A5F
+457A 548C
+457B 88FD
+457C 7537
+457D 7F8E
+457E 5409
+457F 5D0E
+4580 77F3
+4581 8C37
+4582 96FB
+4583 9577
+4584 6CBB
+4585 6CA2
+4586 91D1
+4587 65B0
+4588 53E3
+4589 6A4B
+458A 4E45
+458B 798F
+458C 6240
+458D 5E73
+458E 5185
+458F 56FD
+4590 5316
+4591 962A
+4592 5BAE
+4593 4EBA
+4594 4F5C
+4595 90E8
+4596 6E05
+4597 6B21
+4598 7FA9
+4599 751F
+459A 4EE3
+459B 51FA
+459C 6C34
+459D 68EE
+459E 5149
+459F 52A0
+45A0 5408
+45A1 795E
+45A2 6797
+45A3 91CD
+45A4 884C
+45A5 4FE1
+45A6 660E
+45A7 6D77
+45A8 5B89
+45A9 5E78
+45AA 4FDD
+45AB 592A
+45AC 5BCC
+45AD 6C5F
+45AE 9234
+45AF 524D
+45B0 77E5
+45B1 6B66
+45B2 4F0A
+45B3 662D
+45B4 5206
+45B5 52DD
+45B6 7528
+45B7 5E83
+45B8 9020
+45B9 6C17
+45BA 6210
+45BB 898B
+45BC 5229
+45BD 4F1A
+45BE 5B66
+45BF 5CA9
+45C0 7523
+45C1 9593
+45C2 5730
+45C3 81EA
+45C4 826F
+45C5 95A2
+45C6 611B
+45C7 653F
+45C8 5C3E
+45C9 8A08
+45CA 6587
+45CB 624B
+45CC 7236
+45CD 65B9
+45CE 4E8B
+45CF 6238
+45D0 54C1
+45D1 559C
+45D2 6E21
+45D3 5F18
+45D4 53E4
+45D5 8FBA
+45D6 5009
+45D7 9244
+45D8 4E4B
+45D9 5834
+45DA 6D0B
+45DB 57CE
+45DC 6D25
+45DD 7ACB
+45DE 5EA6
+45DF 5348
+45E0 4ECA
+45E1 5F66
+45E2 8A2D
+45E3 901A
+45E4 52D5
+45E5 5F8C
+45E6 5948
+45E7 5B9A
+45E8 6C60
+45E9 5C4B
+45EA 6D5C
+45EB 7406
+45EC 5742
+45ED 5B9F
+45EE 82F1
+45EF 7684
+45F0 53F8
+45F1 79C0
+45F2 6A2A
+45F3 540D
+45F4 5B5D
+45F5 7AF9
+45F6 535A
+45F7 529B
+45F8 5EAB
+45F9 8449
+45FA 6804
+45FB 6C38
+45FC 5668
+45FD 7389
+45FE 591A
+4641 8CC0
+4642 771F
+4643 6075
+4644 9759
+4645 5186
+4646 8302
+4647 654F
+4648 8C4A
+4649 5175
+464A 6CD5
+464B 767A
+464C 9752
+464D 5897
+464E 6599
+464F 5FE0
+4650 8CC7
+4651 6642
+4652 7269
+4653 8ECA
+4654 5FB3
+4655 8981
+4656 5BFE
+4657 585A
+4658 79CB
+4659 767D
+465A 6CB3
+465B 702C
+465C 6CB9
+465D 9686
+465E 8535
+465F 5F53
+4660 4FCA
+4661 5FD7
+4662 6625
+4663 793E
+4664 99AC
+4665 5165
+4666 5EFA
+4667 6839
+4668 6749
+4669 9032
+466A 8208
+466B 6D66
+466C 7CBE
+466D 540C
+466E 6027
+466F 7C73
+4670 8005
+4671 52A9
+4672 679D
+4673 8FD1
+4674 76F4
+4675 76EE
+4676 6765
+4677 753B
+4678 76F8
+4679 9ED2
+467A 4E38
+467B 8239
+467C 7531
+467D 58EB
+467E 7B2C
+467F 718A
+4680 7D19
+4681 5065
+4682 68B0
+4683 82B3
+4684 571F
+4685 6709
+4686 5BB6
+4687 7DDA
+4688 7D4C
+4689 8ABF
+468A 5929
+468B 671F
+468C 7F6E
+468D 6D45
+468E 6589
+468F 5F0F
+4690 5F62
+4691 9762
+4692 7A2E
+4693 8F38
+4694 5916
+4695 5143
+4696 4F53
+4697 9E7F
+4698 5FA1
+4699 5973
+469A 5EB7
+469B 4E16
+469C 52C7
+469D 5800
+469E 597D
+469F 5150
+46A0 5BFA
+46A1 92FC
+46A2 7279
+46A3 57FC
+46A4 9054
+46A5 5411
+46A6 53D6
+46A7 7B49
+46A8 667A
+46A9 56DE
+46AA 9580
+46AB 904B
+46AC 5099
+46AD 601D
+46AE 963F
+46AF 4E0D
+46B0 9808
+46B1 5168
+46B2 5BFF
+46B3 5584
+46B4 677F
+46B5 98EF
+46B6 8C9E
+46B7 73FE
+46B8 98DF
+46B9 7D44
+46BA 985E
+46BB 516C
+46BC 6750
+46BD 9999
+46BE 5546
+46BF 7D50
+46C0 8868
+46C1 77E2
+46C2 6F5F
+46C3 79C1
+46C4 5236
+46C5 90A6
+46C6 6CBC
+46C7 7CF8
+46C8 5B8F
+46C9 7B56
+46CA 6CE2
+46CB 54E1
+46CC 6570
+46CD 958B
+46CE 6E96
+46CF 6A39
+46D0 8CBB
+46D1 660C
+46D2 5F37
+46D3 7814
+46D4 53CB
+46D5 5B87
+46D6 82E5
+46D7 83CA
+46D8 6301
+46D9 82B1
+46DA 5F15
+46DB 7D00
+46DC 8352
+46DD 5225
+46DE 4FEE
+46DF 8D8A
+46E0 4F4F
+46E1 85AC
+46E2 6BDB
+46E3 9060
+46E4 554F
+46E5 5965
+46E6 578B
+46E7 5FC3
+46E8 767B
+46E9 65E9
+46EA 67F3
+46EB 6D69
+46EC 8CEA
+46ED 52D9
+46EE 6CC9
+46EF 5E38
+46F0 5B88
+46F1 57FA
+46F2 7BA1
+46F3 6CF0
+46F4 4F38
+46F5 6700
+46F6 4EE5
+46F7 6B4C
+46F8 88D5
+46F9 8D64
+46FA 8DB3
+46FB 898F
+46FC 6D41
+46FD 8AA0
+46FE 6607
+4741 5DDE
+4742 7167
+4743 5869
+4744 9001
+4745 96C5
+4746 672B
+4747 54F2
+4748 5CB8
+4749 4E5F
+474A 5C90
+474B 521D
+474C 8328
+474D 5247
+474E 6BD4
+474F 80FD
+4750 8A71
+4751 6295
+4752 8EE2
+4753 83C5
+4754 9023
+4755 4ED6
+4756 6C11
+4757 7D66
+4758 9152
+4759 7E41
+475A 4FA1
+475B 6E80
+475C 671D
+475D 4ED8
+475E 6761
+475F 7121
+4760 8003
+4761 697D
+4762 4E3B
+4763 610F
+4764 6226
+4765 5207
+4766 5264
+4767 7247
+4768 7D30
+4769 6E08
+476A 7A32
+476B 5E03
+476C 91CC
+476D 5C5E
+476E 7AE0
+476F 5909
+4770 4F55
+4771 685C
+4772 5F7C
+4773 67FB
+4774 76CA
+4775 58F2
+4776 4EC1
+4777 6DF1
+4778 53F0
+4779 9CE5
+477A 9DB4
+477B 652F
+477C 6574
+477D 89D2
+477E 5609
+477F 5473
+4780 885B
+4781 8B70
+4782 5727
+4783 7387
+4784 8DEF
+4785 706B
+4786 961C
+4787 8F1D
+4788 70B9
+4789 4E0E
+478A 6E1B
+478B 7551
+478C 9280
+478D 7A7A
+478E 4EA4
+478F 7FBD
+4790 534A
+4791 53CE
+4792 592E
+4793 7DCF
+4794 8A18
+4795 6674
+4796 69CB
+4797 969B
+4798 6885
+4799 5370
+479A 8A00
+479B 6817
+479C 8EAB
+479D 66F8
+479E 514B
+479F 7D20
+47A0 96C6
+47A1 7BC0
+47A2 5148
+47A3 6EDD
+47A4 6C7A
+47A5 6559
+47A6 7D14
+47A7 67F4
+47A8 63A5
+47A9 661F
+47AA 7740
+47AB 7559
+47AC 6620
+47AD 5DF1
+47AE 754C
+47AF 5177
+47B0 656C
+47B1 7FA4
+47B2 9806
+47B3 5171
+47B4 6D3B
+47B5 91CF
+47B6 6307
+47B7 89E3
+47B8 5BA4
+47B9 679C
+47BA 5404
+47BB 671B
+47BC 9632
+47BD 7D04
+47BE 61B2
+47BF 967D
+47C0 4E80
+47C1 56F3
+47C2 4E88
+47C3 8272
+47C4 7A0E
+47C5 690D
+47C6 53EF
+47C7 6052
+47C8 4F4D
+47C9 5178
+47CA 5FC5
+47CB 7D9A
+47CC 6025
+47CD 5728
+47CE 57A3
+47CF 541B
+47D0 5EF6
+47D1 5D8B
+47D2 4F01
+47D3 6803
+47D4 670D
+47D5 71B1
+47D6 5272
+47D7 5354
+47D8 6B69
+47D9 53F2
+47DA 512A
+47DB 658E
+47DC 623F
+47DD 5B97
+47DE 683C
+47DF 8FB0
+47E0 7B20
+47E1 5712
+47E2 8AF8
+47E3 8107
+47E4 5553
+47E5 8CE2
+47E6 5F25
+47E7 98A8
+47E8 5F97
+47E9 6613
+47EA 6253
+47EB 982D
+47EC 65ED
+47ED 6BB5
+47EE 52E2
+47EF 7136
+47F0 56E3
+47F1 984D
+47F2 843D
+47F3 914D
+47F4 7A0B
+47F5 8FBB
+47F6 543E
+47F7 611F
+47F8 5BDB
+47F9 53CD
+47FA 7A14
+47FB 9700
+47FC 6E90
+47FD 6C96
+47FE 984C
+4841 8FBC
+4842 8349
+4843 7B97
+4844 76DB
+4845 8FB2
+4846 90A3
+4847 7701
+4848 69D8
+4849 6BBF
+484A 5C11
+484B 4ECB
+484C 53D7
+484D 97F3
+484E 7DE8
+484F 59D4
+4850 5E84
+4851 4FC2
+4852 72B6
+4853 793A
+4854 5E97
+4855 5A9B
+4856 682A
+4857 6ECB
+4858 68A8
+4859 7E04
+485A 53F3
+485B 5DE6
+485C 53CA
+485D 9078
+485E 5C45
+485F 60C5
+4860 7DF4
+4861 70AD
+4862 9928
+4863 9271
+4864 6A21
+4865 6B8A
+4866 7E3E
+4867 4E9C
+4868 7E4A
+4869 4EF2
+486A 5857
+486B 6D88
+486C 8853
+486D 691C
+486E 6717
+486F 5B85
+4870 529F
+4871 5C1A
+4872 8CBF
+4873 60A6
+4874 8102
+4875 7BE0
+4876 4F73
+4877 7D21
+4878 51A8
+4879 6851
+487A 78BA
+487B 7267
+487C 4E26
+487D 5024
+487E 89B3
+487F 8CB4
+4880 7DAD
+4881 7D71
+4882 5BBF
+4883 4E21
+4884 7CD6
+4885 89AA
+4886 9332
+4887 6F84
+4888 65BD
+4889 5BB9
+488A 98DB
+488B 5C40
+488C 7950
+488D 904E
+488E 6C0F
+488F 6539
+4890 76E4
+4891 7A4D
+4892 6E0B
+4893 5DFB
+4894 6DF3
+4895 5FDC
+4896 4E89
+4897 8ECD
+4898 88C5
+4899 9178
+489A 7E54
+489B 67D3
+489C 5E1D
+489D 7DBF
+489E 7C89
+489F 822A
+48A0 7532
+48A1 5468
+48A2 4ED9
+48A3 5F85
+48A4 4F4E
+48A5 7DD1
+48A6 8EFD
+48A7 9EBB
+48A8 6176
+48A9 52B4
+48AA 78EF
+48AB 4E39
+48AC 80B2
+48AD 9650
+48AE 5C0E
+48AF 653E
+48B0 6643
+48B1 5EA7
+48B2 4EF6
+48B3 60F3
+48B4 9A13
+48B5 4ED5
+48B6 4F7F
+48B7 8F2A
+48B8 9854
+48B9 756A
+48BA 5F35
+48BB 805E
+48BC 4F9B
+48BD 6E6F
+48BE 6EB6
+48BF 6821
+48C0 9285
+48C1 92F3
+48C2 878D
+48C3 9756
+48C4 5199
+48C5 5B8C
+48C6 6E2F
+48C7 935B
+48C8 591C
+48C9 5145
+48CA 9F8D
+48CB 7DB1
+48CC 83F1
+48CD 901F
+48CE 52C9
+48CF 5237
+48D0 8D77
+48D1 6469
+48D2 53C2
+48D3 55B6
+48D4 7A42
+48D5 63A8
+48D6 8FD4
+48D7 8077
+48D8 6B62
+48D9 4F1D
+48DA 5E79
+48DB 7403
+48DC 6A29
+48DD 5C55
+48DE 5E61
+48DF 845B
+48E0 5EAD
+48E1 975E
+48E2 53F7
+48E3 5358
+48E4 6B73
+48E5 62E1
+48E6 51E6
+48E7 8A9E
+48E8 6628
+48E9 57DF
+48EA 6DF5
+48EB 518D
+48EC 50CD
+48ED 79D1
+48EE 9B5A
+48EF 7AEF
+48F0 9014
+48F1 6848
+48F2 5B57
+48F3 8AD6
+48F4 517C
+48F5 53C8
+48F6 632F
+48F7 6280
+48F8 5FB9
+48F9 672D
+48FA 7CFB
+48FB 5F93
+48FC 51B7
+48FD 614B
+48FE 5CF0
+4941 5931
+4942 539A
+4943 5074
+4944 6CE8
+4945 6E2C
+4946 9803
+4947 4E57
+4948 8A66
+4949 576A
+494A 8429
+494B 515A
+494C 6C7D
+494D 5B9D
+494E 606D
+494F 6A0B
+4950 6E29
+4951 6577
+4952 8AAC
+4953 82B8
+4954 544A
+4955 6B74
+4956 822C
+4957 98FE
+4958 793C
+4959 5C06
+495A 96E3
+495B 7802
+495C 5224
+495D 5F79
+495E 5F71
+495F 66FD
+4960 5E2F
+4961 9678
+4962 938C
+4963 8AC7
+4964 5F70
+4965 60AA
+4966 6A19
+4967 7533
+4968 5BB3
+4969 6BCD
+496A 88DC
+496B 5E4C
+496C 58F0
+496D 9664
+496E 7B39
+496F 5A66
+4970 4E7E
+4971 7AF6
+4972 829D
+4973 725B
+4974 8CB7
+4975 79FB
+4976 785D
+4977 8336
+4978 52B9
+4979 990A
+497A 52F2
+497B 80A5
+497C 8B19
+497D 7089
+497E 590F
+497F 5802
+4980 67CF
+4981 6255
+4982 5E30
+4983 713C
+4984 786B
+4985 8001
+4986 7A76
+4987 5BE9
+4988 91DD
+4989 65AD
+498A 5C04
+498B 5DEE
+498C 5D50
+498D 6298
+498E 8010
+498F 5BA3
+4990 59CB
+4991 5F8B
+4992 6B8B
+4993 666F
+4994 8C61
+4995 90F7
+4996 5353
+4997 96E2
+4998 85AB
+4999 6B7B
+499A 8015
+499B 64CD
+499C 4EAE
+499D 4E91
+499E 90E1
+499F 52E4
+49A0 6C42
+49A1 8CAB
+49A2 5B98
+49A3 59BB
+49A4 88CF
+49A5 773C
+49A6 4F2F
+49A7 7AAF
+49A8 7BC9
+49A9 968E
+49AA 63DB
+49AB 6842
+49AC 99C5
+49AD 68B6
+49AE 5747
+49AF 8CA1
+49B0 547D
+49B1 738B
+49B2 84B2
+49B3 90C1
+49B4 78E8
+49B5 7B11
+49B6 66F2
+49B7 6975
+49B8 5831
+49B9 63D0
+49BA 8A3C
+49BB 96EA
+49BC 9055
+49BD 88C1
+49BE 9996
+49BF 75C5
+49C0 6850
+49C1 4F59
+49C2 74E6
+49C3 4EE4
+49C4 5439
+49C5 732A
+49C6 672A
+49C7 525B
+49C8 8CA0
+49C9 4F34
+49CA 5100
+49CB 542B
+49CC 9069
+49CD 8FC4
+49CE 5C3B
+49CF 5DCC
+49D0 7B54
+49D1 8FFD
+49D2 8A0E
+49D3 4E08
+49D4 925B
+49D5 71C3
+49D6 8AB2
+49D7 70BA
+49D8 9662
+49D9 679A
+49DA 76AE
+49DB 8B77
+49DC 7DBE
+49DD 96E8
+49DE 6211
+49DF 5BC4
+49E0 837B
+49E1 62BC
+49E2 7D0D
+49E3 76E3
+49E4 7E2B
+49E5 964D
+49E6 572D
+49E7 7ADC
+49E8 7BC4
+49E9 6BBA
+49EA 8C9D
+49EB 698E
+49EC 9047
+49ED 6F14
+49EE 5360
+49EF 8FEB
+49F0 5287
+49F1 624D
+49F2 6566
+49F3 7D1A
+49F4 7D42
+49F5 6BCE
+49F6 7D79
+49F7 7E2E
+49F8 666E
+49F9 7965
+49FA 500B
+49FB 5C02
+49FC 99D2
+49FD 8A55
+49FE 7560
+4A41 5B58
+4A42 8089
+4A43 50BE
+4A44 5E2B
+4A45 6DB2
+4A46 4F8B
+4A47 81E3
+4A48 81F3
+4A49 56E0
+4A4A 7D99
+4A4B 5DF2
+4A4C 899A
+4A4D 6E9D
+4A4E 6D17
+4A4F 8AAD
+4A50 8996
+4A51 731B
+4A52 5DE8
+4A53 7DB2
+4A54 888B
+4A55 4EFB
+4A56 5BC6
+4A57 8896
+4A58 6CC1
+4A59 8457
+4A5A 8F03
+4A5B 6BC5
+4A5C 97FF
+4A5D 8CA9
+4A5E 5E45
+4A5F 82E6
+4A60 63AA
+4A61 5F81
+4A62 78C1
+4A63 821E
+4A64 52AA
+4A65 7AAA
+4A66 5999
+4A67 6297
+4A68 8F14
+4A69 7FD2
+4A6A 4FC3
+4A6B 54C9
+4A6C 967A
+4A6D 66F4
+4A6E 8B1B
+4A6F 5E72
+4A70 5FA9
+4A71 8A2A
+4A72 6D3E
+4A73 7763
+4A74 6483
+4A75 8B58
+4A76 614E
+4A77 5A5A
+4A78 8D85
+4A79 71D0
+4A7A 983C
+4A7B 72E9
+4A7C 583A
+4A7D 5DFE
+4A7E 8A8D
+4A7F 67C4
+4A80 7DE0
+4A81 4F11
+4A82 77ED
+4A83 4F0F
+4A84 5BC5
+4A85 629C
+4A86 5C3C
+4A87 533B
+4A88 6DC0
+4A89 81FC
+4A8A 96D1
+4A8B 904A
+4A8C 6D6E
+4A8D 93E1
+4A8E 5C64
+4A8F 98FC
+4A90 524A
+4A91 6DFB
+4A92 8584
+4A93 968A
+4A94 56FA
+4A95 5883
+4A96 7766
+4A97 9805
+4A98 4E73
+4A99 8C46
+4A9A 8A31
+4A9B 7DD2
+4A9C 8FF0
+4A9D 6D6A
+4A9E 4F9D
+4A9F 6B6F
+4AA0 6B27
+4AA1 62C5
+4AA2 511F
+4AA3 9769
+4AA4 5374
+4AA5 9AA8
+4AA6 6775
+4AA7 887F
+4AA8 5305
+4AA9 7570
+4AAA 8D70
+4AAB 864E
+4AAC 5CEF
+4AAD 8CDE
+4AAE 5FF5
+4AAF 725F
+4AB0 7686
+4AB1 609F
+4AB2 80CC
+4AB3 59EB
+4AB4 8131
+4AB5 5E0C
+4AB6 8A17
+4AB7 9676
+4AB8 82D7
+4AB9 74B0
+4ABA 84B8
+4ABB 50D5
+4ABC 96F2
+4ABD 7248
+4ABE 7834
+4ABF 6DD1
+4AC0 6E09
+4AC1 67FF
+4AC2 6F54
+4AC3 5915
+4AC4 500D
+4AC5 72AC
+4AC6 9EC4
+4AC7 7B46
+4AC8 9B3C
+4AC9 6563
+4ACA 53BB
+4ACB 8A98
+4ACC 91DC
+4ACD 9818
+4ACE 6FC3
+4ACF 65C5
+4AD0 501F
+4AD1 7F8A
+4AD2 6F64
+4AD3 9031
+4AD4 5F3E
+4AD5 63F4
+4AD6 9038
+4AD7 8B66
+4AD8 7BE4
+4AD9 7206
+4ADA 6843
+4ADB 72EC
+4ADC 65CF
+4ADD 82A6
+4ADE 5BA2
+4ADF 6960
+4AE0 9EA6
+4AE1 52DF
+4AE2 6790
+4AE3 639B
+4AE4 7D75
+4AE5 9855
+4AE6 5DF3
+4AE7 5805
+4AE8 8ACB
+4AE9 95A3
+4AEA 8863
+4AEB 8CA8
+4AEC 5B63
+4AED 5E8A
+4AEE 5449
+4AEF 786C
+4AF0 7D2B
+4AF1 8CA2
+4AF2 5352
+4AF3 7D76
+4AF4 8CB8
+4AF5 7070
+4AF6 547C
+4AF7 6545
+4AF8 6676
+4AF9 73B2
+4AFA 56F2
+4AFB 7BB1
+4AFC 58A8
+4AFD 7A81
+4AFE 66AE
+4B41 8087
+4B42 59FF
+4B43 8840
+4B44 56F0
+4B45 7B51
+4B46 6DF7
+4B47 5F01
+4B48 934B
+4B49 9000
+4B4A 4FE3
+4B4B 675F
+4B4C 4FBF
+4B4D 8CC3
+4B4E 526F
+4B4F 63A1
+4B50 5442
+4B51 8907
+4B52 698A
+4B53 5E2D
+4B54 5A18
+4B55 7518
+4B56 514D
+4B57 5E7E
+4B58 50B5
+4B59 5BDD
+4B5A 68D2
+4B5B 745E
+4B5C 69FB
+4B5D 5FAE
+4B5E 55E3
+4B5F 8A70
+4B60 5BF8
+4B61 5824
+4B62 8358
+4B63 5F13
+4B64 5E95
+4B65 706F
+4B66 751A
+4B67 7D05
+4B68 60E3
+4B69 7E70
+4B6A 5012
+4B6B 5238
+4B6C 83EF
+4B6D 5373
+4B6E 5F31
+4B6F 6A2B
+4B70 9CF4
+4B71 53CC
+4B72 6D32
+4B73 4EAB
+4B74 4E92
+4B75 842C
+4B76 8A8C
+4B77 65E2
+4B78 6F01
+4B79 80A9
+4B7A 9DF9
+4B7B 8B72
+4B7C 7B52
+4B7D 9589
+4B7E 6D74
+4B7F 63A2
+4B80 6590
+4B81 5BD2
+4B82 6319
+4B83 8AB0
+4B84 76DF
+4B85 99A8
+4B86 7A74
+4B87 8236
+4B88 8846
+4B89 8061
+4B8A 6557
+4B8B 5922
+4B8C 9644
+4B8D 88AB
+4B8E 9326
+4B8F 7B4B
+4B90 62B5
+4B91 5371
+4B92 5E81
+4B93 5BDF
+4B94 4F75
+4B95 58C1
+4B96 7058
+4B97 7DCA
+4B98 5438
+4B99 73E0
+4B9A 52D8
+4B9B 5208
+4B9C 78D0
+4B9D 6B23
+4B9E 6838
+4B9F 4E43
+4BA0 690E
+4BA1 8377
+4BA2 6ED1
+4BA3 98F2
+4BA4 8170
+4BA5 8857
+4BA6 8EF8
+4BA7 798E
+4BA8 83DC
+4BA9 8FCE
+4BAA 7E01
+4BAB 5510
+4BAC 4EA8
+4BAD 8A33
+4BAE 9162
+4BAF 5EFB
+4BB0 606F
+4BB1 4E86
+4BB2 664B
+4BB3 6368
+4BB4 5217
+4BB5 8056
+4BB6 51FD
+4BB7 7642
+4BB8 821F
+4BB9 9685
+4BBA 50CF
+4BBB 662F
+4BBC 4F3C
+4BBD 4E59
+4BBE 6A3D
+4BBF 4E71
+4BC0 523A
+4BC1 8ACF
+4BC2 6A58
+4BC3 66FF
+4BC4 670B
+4BC5 653B
+4BC6 9732
+4BC7 5EC3
+4BC8 8A13
+4BC9 5782
+4BCA 604B
+4BCB 866B
+4BCC 95D8
+4BCD 60A9
+4BCE 4E01
+4BCF 63CF
+4BD0 6FC0
+4BD1 659C
+4BD2 8CAC
+4BD3 8305
+4BD4 7CA7
+4BD5 6050
+4BD6 96F7
+4BD7 5FCD
+4BD8 640D
+4BD9 5B54
+4BDA 900F
+4BDB 62D3
+4BDC 59B9
+4BDD 7159
+4BDE 51AC
+4BDF 79F0
+4BE0 552F
+4BE1 5275
+4BE2 6697
+4BE3 80F8
+4BE4 4E98
+4BE5 4ECF
+4BE6 51CD
+4BE7 9D5C
+4BE8 5144
+4BE9 7A93
+4BEA 67F1
+4BEB 5841
+4BEC 7C21
+4BED 8861
+4BEE 5C31
+4BEF 68DA
+4BF0 91E7
+4BF1 9DF2
+4BF2 63EE
+4BF3 6575
+4BF4 84EE
+4BF5 523B
+4BF6 6B32
+4BF7 7C98
+4BF8 5982
+4BF9 969C
+4BFA 8987
+4BFB 7C9F
+4BFC 9006
+4BFD 62DB
+4BFE 66DC
+4C41 6355
+4C42 6982
+4C43 50AC
+4C44 623B
+4C45 5FD8
+4C46 63DA
+4C47 75DB
+4C48 627F
+4C49 616E
+4C4A 8266
+4C4B 7C95
+4C4C 716E
+4C4D 96C7
+4C4E 7F6A
+4C4F 5426
+4C50 5200
+4C51 83D3
+4C52 5211
+4C53 594F
+4C54 9D28
+4C55 574A
+4C56 66C7
+4C57 9858
+4C58 820E
+4C59 6614
+4C5A 733F
+4C5B 50B7
+4C5C 6551
+4C5D 5EB8
+4C5E 5B6B
+4C5F 55AC
+4C60 5FEB
+4C61 6388
+4C62 8CAF
+4C63 676F
+4C64 5951
+4C65 5A01
+4C66 71E5
+4C67 5DE3
+4C68 8C6A
+4C69 6271
+4C6A 81F4
+4C6B 5C3A
+4C6C 5F92
+4C6D 9045
+4C6E 7384
+4C6F 7149
+4C70 79D8
+4C71 796D
+4C72 9003
+4C73 83CC
+4C74 5FB4
+4C75 5B8D
+4C76 6279
+4C77 64AE
+4C78 7D18
+4C79 723E
+4C7A 5BEE
+4C7B 65E7
+4C7C 8D08
+4C7D 9E78
+4C7E 52E7
+4C7F 5D07
+4C80 9F62
+4C81 6069
+4C82 536F
+4C83 6681
+4C84 9663
+4C85 5E3D
+4C86 62B1
+4C87 722A
+4C88 6E4A
+4C89 93AE
+4C8A 79E6
+4C8B 53E5
+4C8C 809D
+4C8D 88FE
+4C8E 53B3
+4C8F 6C88
+4C90 6E7F
+4C91 5141
+4C92 9091
+4C93 6F6E
+4C94 84C4
+4C95 85EA
+4C96 8129
+4C97 6BD2
+4C98 663C
+4C99 7F72
+4C9A 73C2
+4C9B 5F1F
+4C9C 790E
+4C9D 60B2
+4C9E 72ED
+4C9F 58EE
+4CA0 8179
+4CA1 8E8D
+4CA2 5C65
+4CA3 5DE7
+4CA4 6C37
+4CA5 6DE1
+4CA6 862D
+4CA7 72AF
+4CA8 8E0A
+4CA9 7C92
+4CAA 8218
+4CAB 8033
+4CAC 63A7
+4CAD 9291
+4CAE 5019
+4CAF 8155
+4CB0 8A69
+4CB1 8EDF
+4CB2 66B4
+4CB3 8133
+4CB4 7591
+4CB5 6B20
+4CB6 6669
+4CB7 90F5
+4CB8 4E32
+4CB9 73EA
+4CBA 693F
+4CBB 7687
+4CBC 707D
+4CBD 7D3A
+4CBE 6148
+4CBF 8607
+4CC0 99FF
+4CC1 59C9
+4CC2 7832
+4CC3 7815
+4CC4 907F
+4CC5 80A1
+4CC6 5C3F
+4CC7 66A2
+4CC8 9418
+4CC9 6D44
+4CCA 5E55
+4CCB 5854
+4CCC 7B95
+4CCD 8DE1
+4CCE 4EA1
+4CCF 8C5A
+4CD0 81E8
+4CD1 89E6
+4CD2 9670
+4CD3 5263
+4CD4 74F6
+4CD5 9A5A
+4CD6 6012
+4CD7 520A
+4CD8 7434
+4CD9 9801
+4CDA 907A
+4CDB 5504
+4CDC 7956
+4CDD 5230
+4CDE 54B2
+4CDF 8A34
+4CE0 96A3
+4CE1 4FF3
+4CE2 9283
+4CE3 91E3
+4CE4 7D39
+4CE5 9688
+4CE6 4F51
+4CE7 7D61
+4CE8 5DBA
+4CE9 9BAE
+4CEA 5F80
+4CEB 795D
+4CEC 8597
+4CED 8DA3
+4CEE 7C60
+4CEF 5C0A
+4CF0 7565
+4CF1 85A9
+4CF2 63D6
+4CF3 9E97
+4CF4 7D22
+4CF5 5375
+4CF6 9AEA
+4CF7 9042
+4CF8 6B3D
+4CF9 7D0B
+4CFA 6392
+4CFB 80AA
+4CFC 7DE9
+4CFD 9F3B
+4CFE 99C6
+4D41 6D78
+4D42 6731
+4D43 5531
+4D44 6398
+4D45 7825
+4D46 5CB3
+4D47 5DE1
+4D48 92AD
+4D49 98FD
+4D4A 9810
+4D4B 6CE3
+4D4C 6B64
+4D4D 5321
+4D4E 6B53
+4D4F 5E8F
+4D50 7AE5
+4D51 502B
+4D52 6E56
+4D53 62BD
+4D54 8276
+4D55 6A9C
+4D56 4E18
+4D57 57F7
+4D58 752B
+4D59 7C97
+4D5A 82EB
+4D5B 9802
+4D5C 811A
+4D5D 73CD
+4D5E 8F9B
+4D5F 5C0B
+4D60 63E1
+4D61 7372
+4D62 8150
+4D63 80E1
+4D64 5B99
+4D65 76D7
+4D66 6291
+4D67 65EC
+4D68 8A3A
+4D69 5947
+4D6A 65E8
+4D6B 6E7E
+4D6C 6696
+4D6D 55AB
+4D6E 8F09
+4D6F 92ED
+4D70 9396
+4D71 4EEE
+4D72 755C
+4D73 6F38
+4D74 8F9E
+4D75 7981
+4D76 5C01
+4D77 62E0
+4D78 9BE8
+4D79 91C8
+4D7A 6276
+4D7B 65CB
+4D7C 8E0F
+4D7D 8B21
+4D7E 699B
+4D7F 6216
+4D80 5A92
+4D81 90B8
+4D82 50DA
+4D83 79DF
+4D84 6C41
+4D85 5270
+4D86 9175
+4D87 8B39
+4D88 685D
+4D89 5875
+4D8A 819C
+4D8B 5B9C
+4D8C 8A89
+4D8D 8A72
+4D8E 9D8F
+4D8F 6377
+4D90 5974
+4D91 8AA4
+4D92 52B1
+4D93 6962
+4D94 5C48
+4D95 9CE9
+4D96 673A
+4D97 75B2
+4D98 6D1E
+4D99 4F0D
+4D9A 7E6D
+4D9B 7B48
+4D9C 7FCC
+4D9D 65E6
+4D9E 59A5
+4D9F 79E9
+4DA0 6212
+4DA1 6EDE
+4DA2 770B
+4DA3 8CA7
+4DA4 65BC
+4DA5 885D
+4DA6 6ADB
+4DA7 5C4A
+4DA8 8074
+4DA9 9084
+4DAA 8ECC
+4DAB 65D7
+4DAC 57F9
+4DAD 708E
+4DAE 6F06
+4DAF 5E7C
+4DB0 77AC
+4DB1 4FF5
+4DB2 5949
+4DB3 81ED
+4DB4 9B45
+4DB5 7FFC
+4DB6 8178
+4DB7 69FD
+4DB8 6CCA
+4DB9 69C7
+4DBA 79D2
+4DBB 8B1D
+4DBC 9ED9
+4DBD 81D3
+4DBE 7A3C
+4DBF 7968
+4DC0 6F5C
+4DC1 63B2
+4DC2 8DDD
+4DC3 6383
+4DC4 6E9C
+4DC5 5E33
+4DC6 61F8
+4DC7 76BF
+4DC8 642C
+4DC9 7DB4
+4DCA 6247
+4DCB 6458
+4DCC 6816
+4DCD 5F69
+4DCE 9022
+4DCF 7A1A
+4DD0 82B9
+4DD1 70C8
+4DD2 9A12
+4DD3 6163
+4DD4 6FEF
+4DD5 53EB
+4DD6 9D3B
+4DD7 62FE
+4DD8 60A0
+4DD9 9591
+4DDA 6D99
+4DDB 6162
+4DDC 9298
+4DDD 635C
+4DDE 9707
+4DDF 8972
+4DE0 683D
+4DE1 51E1
+4DE2 9B54
+4DE3 608C
+4DE4 5B22
+4DE5 99C4
+4DE6 7126
+4DE7 8A73
+4DE8 971C
+4DE9 7396
+4DEA 67D4
+4DEB 60A3
+4DEC 4E11
+4DED 4EF0
+4DEE 8CDB
+4DEF 8CB0
+4DF0 7912
+4DF1 9774
+4DF2 8986
+4DF3 5146
+4DF4 57DC
+4DF5 99D0
+4DF6 80C3
+4DF7 8338
+4DF8 78A7
+4DF9 86CD
+4DFA 7F85
+4DFB 5049
+4DFC 8247
+4DFD 690B
+4DFE 7C4D
+4E41 53EA
+4E42 5F26
+4E43 6E25
+4E44 6881
+4E45 9375
+4E46 5DFD
+4E47 5347
+4E48 9727
+4E49 643A
+4E4A 75C7
+4E4B 6FA4
+4E4C 73A9
+4E4D 77E9
+4E4E 9451
+4E4F 8B5C
+4E50 808C
+4E51 674E
+4E52 4EAD
+4E53 582F
+4E54 7573
+4E55 8ED2
+4E56 6CE5
+4E57 9320
+4E58 8FF7
+4E59 7D33
+4E5A 72C2
+4E5B 8217
+4E5C 7422
+4E5D 82C5
+4E5E 9A30
+4E5F 773A
+4E60 5F84
+4E61 9673
+4E62 64AD
+4E63 920D
+4E64 74DC
+4E65 60C7
+4E66 86ED
+4E67 4FFA
+4E68 52A3
+4E69 6A3A
+4E6A 7720
+4E6B 5320
+4E6C 61B6
+4E6D 5674
+4E6E 8776
+4E6F 6CBF
+4E70 505C
+4E71 602A
+4E72 8466
+4E73 6B96
+4E74 6DBC
+4E75 97D3
+4E76 968F
+4E77 6876
+4E78 60D1
+4E79 5378
+4E7A 64A4
+4E7B 51A0
+4E7C 9154
+4E7D 5DF4
+4E7E 629E
+4E7F 5E63
+4E80 929A
+4E81 7693
+4E82 6C5A
+4E83 6597
+4E84 50E7
+4E85 7C82
+4E86 5F6B
+4E87 6CE1
+4E88 5F6C
+4E89 5AC1
+4E8A 6F2C
+4E8B 852D
+4E8C 6442
+4E8D 5750
+4E8E 58C7
+4E8F 8CFC
+4E90 8A5E
+4E91 7A7F
+4E92 689D
+4E93 7E26
+4E94 7A40
+4E95 7344
+4E96 8AEB
+4E97 4FD7
+4E98 7A63
+4E99 8036
+4E9A 7DEF
+4E9B 80C6
+4E9C 8AED
+4E9D 731F
+4E9E 8FEA
+4E9F 4F0E
+4EA0 758B
+4EA1 518A
+4EA2 6734
+4EA3 5FD9
+4EA4 61C7
+4EA5 65AF
+4EA6 9CF3
+4EA7 5ECA
+4EA8 9262
+4EA9 68DF
+4EAA 6CB8
+4EAB 80F4
+4EAC 57CB
+4EAD 6C99
+4EAE 96A0
+4EAF 5B64
+4EB0 58F1
+4EB1 68C4
+4EB2 5410
+4EB3 982C
+4EB4 8A87
+4EB5 4E5E
+4EB6 6167
+4EB7 9BAB
+4EB8 90AA
+4EB9 55B0
+4EBA 82BD
+4EBB 596A
+4EBC 66F3
+4EBD 8299
+4EBE 5893
+4EBF 719F
+4EC0 6284
+4EC1 67D1
+4EC2 9063
+4EC3 5ACC
+4EC4 6C57
+4EC5 7CE7
+4EC6 5851
+4EC7 64B2
+4EC8 58CA
+4EC9 830E
+4ECA 5968
+4ECB 5302
+4ECC 5A46
+4ECD 8702
+4ECE 6065
+4ECF 72D9
+4ED0 89A7
+4ED1 6689
+4ED2 66F9
+4ED3 5D6F
+4ED4 5BB0
+4ED5 96BC
+4ED6 636E
+4ED7 60DC
+4ED8 7948
+4ED9 51DD
+4EDA 8606
+4EDB 5EC9
+4EDC 7554
+4EDD 596E
+4EDE 6B04
+4EDF 4F43
+4EE0 7B94
+4EE1 67DA
+4EE2 62DD
+4EE3 628A
+4EE4 971E
+4EE5 62ED
+4EE6 6EC5
+4EE7 508D
+4EE8 67B6
+4EE9 80E4
+4EEA 9EBF
+4EEB 5EB5
+4EEC 638C
+4EED 85CD
+4EEE 9867
+4EEF 52C5
+4EF0 6016
+4EF1 68CB
+4EF2 61D0
+4EF3 5751
+4EF4 8F29
+4EF5 5FAA
+4EF6 81A8
+4EF7 7D62
+4EF8 71C8
+4EF9 54C0
+4EFA 69CC
+4EFB 6B3E
+4EFC 65AC
+4EFD 63C3
+4EFE 4F46
+4F41 7B1B
+4F42 6B86
+4F43 88F8
+4F44 5203
+4F45 732E
+4F46 6687
+4F47 7D17
+4F48 57F4
+4F49 570F
+4F4A 618E
+4F4B 970A
+4F4C 7C3F
+4F4D 8B00
+4F4E 7881
+4F4F 8CE0
+4F50 548B
+4F51 7B87
+4F52 745B
+4F53 7C11
+4F54 8870
+4F55 5398
+4F56 5448
+4F57 6CF3
+4F58 6F22
+4F59 53F6
+4F5A 88B4
+4F5B 5301
+4F5C 7A6B
+4F5D 8695
+4F5E 586B
+4F5F 5D29
+4F60 88C2
+4F61 62D2
+4F62 4E1E
+4F63 5036
+4F64 96C0
+4F65 7363
+4F66 8A3B
+4F67 5176
+4F68 7199
+4F69 7FE0
+4F6A 8888
+4F6B 7E1E
+4F6C 4E4F
+4F6D 84CB
+4F6E 6F2B
+4F6F 5859
+4F70 936C
+4F71 53E9
+4F72 865A
+4F73 9149
+4F74 86EF
+4F75 5E06
+4F76 5507
+4F77 902E
+4F78 6795
+4F79 846C
+4F7A 5BA5
+4F7B 82A5
+4F7C 8431
+4F7D 6D8C
+4F7E 63FA
+4F7F 4EA5
+4F80 51C6
+4F81 6328
+4F82 7F70
+4F83 5B5F
+4F84 5DBD
+4F85 99C8
+4F86 53EC
+4F87 7985
+4F88 8A54
+4F89 7962
+4F8A 88DF
+4F8B 5B09
+4F8C 4FB5
+4F8D 4F91
+4F8E 9B8E
+4F8F 5192
+4F90 96F0
+4F91 6DAF
+4F92 622F
+4F93 8490
+4F94 8CDC
+4F95 5075
+4F96 5CE0
+4F97 4E14
+4F98 4F83
+4F99 7C54
+4F9A 84D1
+4F9B 77B3
+4F9C 8AEE
+4F9D 5CE8
+4F9E 62F6
+4F9F 663B
+4FA0 8A93
+4FA1 8526
+4FA2 8A95
+4FA3 65FA
+4FA4 6714
+4FA5 53D4
+4FA6 62AB
+4FA7 8CE6
+4FA8 88F3
+4FA9 5BE7
+4FAA 868A
+4FAB 668E
+4FAC 582A
+4FAD 6170
+4FAE 696F
+4FAF 9F13
+4FB0 7A92
+4FB1 7893
+4FB2 6A7F
+4FB3 9017
+4FB4 9266
+4FB5 7D10
+4FB6 7BC7
+4FB7 6EF4
+4FB8 821C
+4FB9 5C3D
+4FBA 62CD
+4FBB 85C1
+4FBC 6F02
+4FBD 6E67
+4FBE 6691
+4FBF 85A6
+4FC0 637A
+4FC1 821B
+4FC2 4F8D
+4FC3 5091
+4FC4 8A02
+4FC5 62EC
+4FC6 9BC9
+4FC7 7A3D
+4FC8 7C9B
+4FC9 50C5
+4FCA 9019
+4FCB 708A
+4FCC 7C8B
+4FCD 64EC
+4FCE 665F
+4FCF 6562
+4FD0 732B
+4FD1 5339
+4FD2 67A0
+4FD3 55A7
+4FD4 6D2A
+4FD5 7A3F
+4FD6 64E6
+4FD7 79A7
+4FD8 67D8
+4FD9 7B26
+4FDA 96BB
+4FDB 6311
+4FDC 72A0
+4FDD 5C6F
+4FDE 7026
+4FDF 97EE
+4FE0 60DF
+4FE1 8AFE
+4FE2 8B04
+4FE3 8494
+4FE4 9BD6
+4FE5 82AF
+4FE6 932C
+4FE7 6606
+4FE8 9640
+4FE9 5BC2
+4FEA 86C7
+4FEB 7949
+4FEC 8017
+4FED 6919
+4FEE 7092
+4FEF 963B
+4FF0 7C7E
+4FF1 59D3
+4FF2 5B5C
+4FF3 7D1B
+4FF4 91D8
+4FF5 6A80
+4FF6 85E9
+4FF7 6905
+4FF8 6C93
+4FF9 502D
+4FFA 4EA6
+4FFB 7FC1
+4FFC 61A4
+4FFD 8CCA
+4FFE 9665
+5041 93D1
+5042 53F1
+5043 598A
+5044 8EAC
+5045 62D8
+5046 6867
+5047 71D5
+5048 7B67
+5049 504F
+504A 67D0
+504B 82D1
+504C 978D
+504D 748B
+504E 80BA
+504F 7336
+5050 514E
+5051 8105
+5052 90CA
+5053 584A
+5054 67FE
+5055 6FF1
+5056 5FFD
+5057 76C6
+5058 9A0E
+5059 507D
+505A 9694
+505B 5EF7
+505C 7BB8
+505D 904D
+505E 6C4E
+505F 85FB
+5060 819D
+5061 67AF
+5062 564C
+5063 5606
+5064 8C8C
+5065 56DA
+5066 73ED
+5067 8CC4
+5068 8FC5
+5069 96F6
+506A 6C50
+506B 8944
+506C 8F3F
+506D 7D5E
+506E 60E8
+506F 72FC
+5070 7D9C
+5071 8463
+5072 5CFB
+5073 5446
+5074 5D16
+5075 6CA1
+5076 81B3
+5077 58FA
+5078 5BB4
+5079 8108
+507A 541F
+507B 8CBC
+507C 6182
+507D 78A9
+507E 6FE1
+507F 91A4
+5080 76F2
+5081 6020
+5082 76FE
+5083 84C9
+5084 7F36
+5085 4EC7
+5086 755D
+5087 7A17
+5088 84EC
+5089 75F4
+508A 4F3A
+508B 676D
+508C 7460
+508D 62F3
+508E 6F20
+508F 79E4
+5090 87F9
+5091 6094
+5092 6234
+5093 66AB
+5094 820C
+5095 8499
+5096 723A
+5097 5FCC
+5098 6109
+5099 70CF
+509A 7261
+509B 7A50
+509C 5098
+509D 9AED
+509E 5D69
+509F 601C
+50A0 6667
+50A1 99B4
+50A2 5E7B
+50A3 643E
+50A4 5830
+50A5 53C9
+50A6 7A9F
+50A7 990C
+50A8 9B42
+50A9 8F5F
+50AA 7AAE
+50AB 5B9B
+50AC 68A2
+50AD 6249
+50AE 7984
+50AF 9DFA
+50B0 5451
+50B1 932F
+50B2 8AC4
+50B3 5F90
+50B4 8DF3
+50B5 5A2F
+50B6 80DE
+50B7 6D29
+50B8 7A4F
+50B9 84BC
+50BA 9D2B
+50BB 9010
+50BC 6D38
+50BD 916A
+50BE 6FC1
+50BF 9905
+50C0 6BBB
+50C1 5EB6
+50C2 91B8
+50C3 5076
+50C4 6F0F
+50C5 4E19
+50C6 540F
+50C7 9675
+50C8 6C72
+50C9 51B4
+50CA 5631
+50CB 9F20
+50CC 66A6
+50CD 5F0A
+50CE 75AB
+50CF 51F8
+50D0 674F
+50D1 8DF5
+50D2 6C70
+50D3 8A6B
+50D4 757F
+50D5 5CAC
+50D6 6841
+50D7 8CD3
+50D8 9BDB
+50D9 8475
+50DA 6893
+50DB 840C
+50DC 72DB
+50DD 7577
+50DE 8568
+50DF 783A
+50E0 847A
+50E1 5F10
+50E2 831C
+50E3 6813
+50E4 6E1A
+50E5 9DAF
+50E6 51F9
+50E7 7980
+50E8 4E99
+50E9 5EE3
+50EA 908A
+50EB 80AF
+50EC 59A8
+50ED 77DB
+50EE 8D74
+50EF 8A1F
+50F0 673D
+50F1 533F
+50F2 8A0A
+50F3 5618
+50F4 6756
+50F5 53D9
+50F6 4F10
+50F7 7409
+50F8 5A41
+50F9 4FF8
+50FA 79B0
+50FB 9838
+50FC 8E2A
+50FD 9D60
+50FE 8F44
+5141 65A5
+5142 75BE
+5143 906D
+5144 867B
+5145 60BC
+5146 51B6
+5147 5937
+5148 7D2F
+5149 916C
+514A 69AE
+514B 7CE0
+514C 792A
+514D 5D14
+514E 64C1
+514F 58EC
+5150 589C
+5151 8D66
+5152 66D9
+5153 61F2
+5154 912D
+5155 6E58
+5156 9435
+5157 965B
+5158 7272
+5159 5F6A
+515A 5E9A
+515B 8F1B
+515C 5B95
+515D 5C39
+515E 9013
+515F 834F
+5160 7CCE
+5161 620A
+5162 90ED
+5163 691B
+5164 6E15
+5165 65DB
+5166 66FE
+5167 4E9F
+5168 55AA
+5169 7A83
+516A 83E9
+516B 8B83
+516C 846D
+516D 83F0
+516E 7F50
+516F 918D
+5170 9190
+5171 758E
+5172 95A5
+5173 81E7
+5174 75E2
+5175 61A9
+5176 8A50
+5177 95B2
+5178 53A8
+5179 59F6
+517A 9813
+517B 7891
+517C 7C17
+517D 6B3A
+517E 57E0
+517F 620E
+5180 83D6
+5181 8AD2
+5182 75D4
+5183 927E
+5184 59DC
+5185 5289
+5186 9087
+5187 6FFE
+5188 7473
+5189 5C09
+518A 9D6C
+518B 84FC
+518C 7CDF
+518D 7BAD
+518E 8A6E
+518F 594E
+5190 56A2
+5191 819A
+5192 7947
+5193 6636
+5194 53E1
+5195 7887
+5196 58CC
+5197 9397
+5198 6E13
+5199 5256
+519A 828B
+519B 9E9F
+519C 9583
+519D 658C
+519E 9E93
+519F 7345
+51A0 6E26
+51A1 9D07
+51A2 5983
+51A3 7DAC
+51A4 96C1
+51A5 61BE
+51A6 6762
+51A7 9ECE
+51A8 90A8
+51A9 9187
+51AA 9F0E
+51AB 7C38
+51AC 51F1
+51AD 8599
+51AE 524C
+51AF 540E
+51B0 7901
+51B1 655E
+51B2 6668
+51B3 5CE1
+51B4 7566
+51B5 76C8
+51B6 8679
+51B7 531D
+51B8 5506
+51B9 7926
+51BA 8912
+51BB 77EF
+51BC 7CC0
+51BD 570B
+51BE 515C
+51BF 7E8A
+51C0 535C
+51C1 8A60
+51C2 65A7
+51C3 8766
+51C4 5766
+51C5 6AE8
+51C6 87FB
+51C7 5E16
+51C8 7AEA
+51C9 8D73
+51CA 771E
+51CB 737A
+51CC 66E0
+51CD 9410
+51CE 816B
+51CF 7B08
+51D0 91FC
+51D1 5737
+51D2 6FE4
+51D3 856A
+51D4 7E55
+51D5 9957
+51D6 87BA
+51D7 694A
+51D8 818F
+51D9 5EFF
+51DA 891C
+51DB 72D0
+51DC 9846
+51DD 9EDB
+51DE 8D99
+51DF 5DD6
+51E0 62B9
+51E1 64AB
+51E2 4F76
+51E3 613F
+51E4 68AF
+51E5 5F14
+51E6 800C
+51E7 92F8
+51E8 7BC1
+51E9 52FE
+51EA 664F
+51EB 9177
+51EC 51F6
+51ED 97A0
+51EE 839E
+51EF 647A
+51F0 9C3A
+51F1 67F5
+51F2 7C4F
+51F3 685F
+51F4 9B6F
+51F5 9F4B
+51F6 7FFB
+51F7 9348
+51F8 4FF6
+51F9 9E92
+51FA 9197
+51FB 96DB
+51FC 5BE6
+51FD 6CCC
+51FE 7CFE
+5241 9453
+5242 6822
+5243 66B9
+5244 5BD4
+5245 98F4
+5246 8AE6
+5247 8154
+5248 7827
+5249 74BD
+524A 6ED3
+524B 9288
+524C 5A20
+524D 5B8B
+524E 86F8
+524F 760D
+5250 865C
+5251 6641
+5252 91C9
+5253 5589
+5254 7A4E
+5255 59E5
+5256 6042
+5257 932B
+5258 5B5A
+5259 849C
+525A 5C91
+525B 96CD
+525C 62D9
+525D 675C
+525E 6787
+525F 5E7D
+5260 8650
+5261 9EB9
+5262 5CB1
+5263 80CE
+5264 7A00
+5265 8ABC
+5266 5700
+5267 8096
+5268 7D72
+5269 9211
+526A 8098
+526B 907C
+526C 7761
+526D 8737
+526E 9075
+526F 817A
+5270 7C3E
+5271 6EA2
+5272 965E
+5273 7E90
+5274 72D7
+5275 58FD
+5276 60B3
+5277 9786
+5278 7E88
+5279 587E
+527A 6E20
+527B 84DC
+527C 6961
+527D 77AD
+527E 5197
+527F 652A
+5280 6777
+5281 5DCD
+5282 6101
+5283 932E
+5284 5954
+5285 6367
+5286 798D
+5287 7AFF
+5288 80D6
+5289 58B3
+528A 6168
+528B 6AC3
+528C 7483
+528D 9B92
+528E 660A
+528F 642D
+5290 5118
+5291 6763
+5292 809B
+5293 9C10
+5294 4FC9
+5295 6953
+5296 7A1C
+5297 52FF
+5298 6055
+5299 768E
+529A 817F
+529B 5642
+529C 5F6D
+529D 7194
+529E 70BB
+529F 7436
+52A0 8000
+52A1 874B
+52A2 55DA
+52A3 7435
+52A4 7690
+52A5 96EB
+52A6 66DD
+52A7 751C
+52A8 633D
+52A9 6EC9
+52AA 7C64
+52AB 7CA5
+52AC 6D35
+52AD 935C
+52AE 7027
+52AF 5E25
+52B0 701D
+52B1 54BD
+52B2 611A
+52B3 6973
+52B4 6C6A
+52B5 559A
+52B6 6D19
+52B7 96CC
+52B8 5BE1
+52B9 59FB
+52BA 697C
+52BB 914C
+52BC 7709
+52BD 8500
+52BE 7A46
+52BF 7872
+52C0 92E4
+52C1 8CED
+52C2 7CFA
+52C3 9D1B
+52C4 814E
+52C5 9AC4
+52C6 68A0
+52C7 6DCB
+52C8 5918
+52C9 83B1
+52CA 5629
+52CB 9B41
+52CC 6897
+52CD 70B3
+52CE 9771
+52CF 9419
+52D0 67A2
+52D1 6802
+52D2 7895
+52D3 68A7
+52D4 50D6
+52D5 80B1
+52D6 5EF8
+52D7 82D4
+52D8 797A
+52D9 67CA
+52DA 7E4D
+52DB 69CD
+52DC 51C4
+52DD 723D
+52DE 6829
+52DF 99B3
+52E0 5F3C
+52E1 8F61
+52E2 682B
+52E3 6155
+52E4 6591
+52E5 8FB1
+52E6 7E1B
+52E7 9798
+52E8 9952
+52E9 8877
+52EA 5B2C
+52EB 6631
+52EC 4FA0
+52ED 6939
+52EE 6AFB
+52EF 5BB5
+52F0 7AC8
+52F1 5026
+52F2 5944
+52F3 9059
+52F4 7B25
+52F5 7B4F
+52F6 8E74
+52F7 8543
+52F8 5858
+52F9 8B0E
+52FA 5039
+52FB 8654
+52FC 97F6
+52FD 7569
+52FE 72F8
+5341 4EF7
+5342 9D89
+5343 5016
+5344 51CC
+5345 62CC
+5346 91C6
+5347 8755
+5348 649A
+5349 88F4
+534A 91E6
+534B 6854
+534C 695A
+534D 6C40
+534E 7B6C
+534F 6741
+5350 77D7
+5351 8823
+5352 5384
+5353 8EAF
+5354 7280
+5355 8C6B
+5356 788D
+5357 7165
+5358 8207
+5359 68B1
+535A 8D04
+535B 9077
+535C 701E
+535D 8FE6
+535E 810A
+535F 81BF
+5360 89DC
+5361 68B3
+5362 6ADF
+5363 92EA
+5364 95C7
+5365 7957
+5366 7A20
+5367 53A9
+5368 8E5F
+5369 786F
+536A 79B9
+536B 5F27
+536C 5ED6
+536D 6853
+536E 93AC
+536F 919C
+5370 691A
+5371 5806
+5372 64B0
+5373 7E4B
+5374 7D8F
+5375 68F2
+5376 6EA5
+5377 82DB
+5378 9192
+5379 5243
+537A 8EB0
+537B 9081
+537C 721B
+537D 7DCB
+537E 7656
+537F 59AC
+5380 6FE0
+5381 8B28
+5382 80A2
+5383 5544
+5384 6070
+5385 5F4A
+5386 68C8
+5387 633A
+5388 9438
+5389 9B4F
+538A 81E5
+538B 6A17
+538C 70DD
+538D 69A7
+538E 614C
+538F 920E
+5390 9310
+5391 9BAD
+5392 52D7
+5393 925E
+5394 92F9
+5395 5993
+5396 7696
+5397 66FB
+5398 5769
+5399 73CA
+539A 7678
+539B 6A1F
+539C 7E9C
+539D 9811
+539E 8CD1
+539F 5840
+53A0 6349
+53A1 871C
+53A2 62D0
+53A3 60B4
+53A4 6B89
+53A5 86EE
+53A6 5764
+53A7 581D
+53A8 8549
+53A9 7235
+53AA 7652
+53AB 983B
+53AC 8237
+53AD 5351
+53AE 5C24
+53AF 59BE
+53B0 5815
+53B1 901D
+53B2 69B4
+53B3 834A
+53B4 9EA9
+53B5 976B
+53B6 8086
+53B7 53AD
+53B8 6068
+53B9 4FAE
+53BA 76C3
+53BB 6A05
+53BC 689B
+53BD 937E
+53BE 99D5
+53BF 91C7
+53C0 5C16
+53C1 585E
+53C2 61A7
+53C3 9699
+53C4 4FDF
+53C5 8278
+53C6 9C52
+53C7 5F45
+53C8 6108
+53C9 7C8D
+53CA 806F
+53CB 5DF7
+53CC 8D6B
+53CD 57B0
+53CE 98E2
+53CF 5703
+53D0 79BF
+53D1 5996
+53D2 7941
+53D3 540A
+53D4 83DF
+53D5 9C39
+53D6 52D2
+53D7 6BD8
+53D8 86CB
+53D9 4EC0
+53DA 9A28
+53DB 5366
+53DC 8006
+53DD 7337
+53DE 6492
+53DF 8FED
+53E0 5AC9
+53E1 5420
+53E2 537F
+53E3 4FAF
+53E4 807E
+53E5 543B
+53E6 7515
+53E7 7B18
+53E8 8749
+53E9 54B3
+53EA 704C
+53EB 8997
+53EC 6CAB
+53ED 85FA
+53EE 7114
+53EF 696E
+53F0 9328
+53F1 745A
+53F2 59D1
+53F3 6E5B
+53F4 617E
+53F5 53E2
+53F6 8317
+53F7 76E7
+53F8 848B
+53F9 85AF
+53FA 6925
+53FB 5C60
+53FC 7259
+53FD 75D5
+53FE 8B90
+5441 6E07
+5442 82AD
+5443 5C4F
+5444 7BED
+5445 9784
+5446 6F70
+5447 764C
+5448 88B7
+5449 92D2
+544A 4F36
+544B 5EFE
+544C 9061
+544D 88E1
+544E 8471
+544F 711A
+5450 6D1B
+5451 80B4
+5452 74E2
+5453 7433
+5454 5A7F
+5455 905C
+5456 980C
+5457 5319
+5458 906E
+5459 6BB4
+545A 85AA
+545B 7897
+545C 7AFA
+545D 6AAE
+545E 8910
+545F 958F
+5460 620C
+5461 4F3D
+5462 4F7C
+5463 79BE
+5464 9D0E
+5465 4ED4
+5466 57A2
+5467 51A5
+5468 6900
+5469 6089
+546A 707C
+546B 7AE3
+546C 8956
+546D 93A7
+546E 9C2D
+546F 5112
+5470 52FA
+5471 7CCA
+5472 60F9
+5473 7078
+5474 81C6
+5475 559D
+5476 6991
+5477 96C9
+5478 553E
+5479 805A
+547A 8304
+547B 8332
+547C 54FA
+547D 565B
+547E 8FBF
+547F 5634
+5480 6760
+5481 5265
+5482 840E
+5483 5E5F
+5484 7B65
+5485 9035
+5486 8387
+5487 6B4E
+5488 58BE
+5489 6309
+548A 727D
+548B 97AD
+548C 69D0
+548D 546A
+548E 984E
+548F 632B
+5490 714E
+5491 8557
+5492 7CDE
+5493 6372
+5494 68F9
+5495 7511
+5496 8602
+5497 6EBA
+5498 5A3C
+5499 7A84
+549A 851A
+549B 95A4
+549C 59D0
+549D 60DA
+549E 51EA
+549F 5A29
+54A0 7169
+54A1 6F15
+54A2 696B
+54A3 63BB
+54A4 75E9
+54A5 4E4E
+54A6 7DBB
+54A7 6934
+54A8 8521
+54A9 8FFA
+54AA 9354
+54AB 9C3B
+54AC 5F17
+54AD 5ED3
+54AE 8258
+54AF 895F
+54B0 82E7
+54B1 52C3
+54B2 5C51
+54B3 83AB
+54B4 7826
+54B5 79E1
+54B6 7FF0
+54B7 626E
+54B8 60F0
+54B9 5CA8
+54BA 6F97
+54BB 71A8
+54BC 9909
+54BD 5132
+54BE 5E37
+54BF 5F04
+54C0 637B
+54C1 6753
+54C2 68D7
+54C3 6652
+54C4 9CF6
+54C5 88B0
+54C6 52AB
+54C7 4FC4
+54C8 4E3C
+54C9 67B3
+54CA 7BAA
+54CB 7F4D
+54CC 8A23
+54CD 63B4
+54CE 71E6
+54CF 65A4
+54D0 6F09
+54D1 853D
+54D2 5072
+54D3 7DBA
+54D4 5516
+54D5 7B04
+54D6 72FD
+54D7 6CD3
+54D8 8422
+54D9 621F
+54DA 50AD
+54DB 8235
+54DC 8718
+54DD 5919
+54DE 6028
+54DF 677C
+54E0 6F23
+54E1 75B9
+54E2 695C
+54E3 520E
+54E4 8018
+54E5 8B01
+54E6 71ED
+54E7 5713
+54E8 660F
+54E9 83EB
+54EA 7164
+54EB 7D9B
+54EC 5617
+54ED 7D7D
+54EE 8F4D
+54EF 9318
+54F0 8569
+54F1 5D17
+54F2 678C
+54F3 67DE
+54F4 87C7
+54F5 79AE
+54F6 5835
+54F7 8404
+54F8 9041
+54F9 7FD4
+54FA 6E8C
+54FB 8A63
+54FC 9D08
+54FD 670F
+54FE 939A
+5541 63AC
+5542 602F
+5543 64E2
+5544 608D
+5545 96B7
+5546 6357
+5547 8461
+5548 914B
+5549 75D8
+554A 60E7
+554B 9913
+554C 9C57
+554D 5984
+554E 6DEB
+554F 5E96
+5550 6D9C
+5551 9BF0
+5552 58BB
+5553 7977
+5554 60B6
+5555 633F
+5556 5BF5
+5557 9812
+5558 558B
+5559 82D3
+555A 5147
+555B 6190
+555C 7953
+555D 79BD
+555E 6C5D
+555F 9EBA
+5560 9C48
+5561 8DA8
+5562 5EE0
+5563 7D43
+5564 5EFC
+5565 854E
+5566 8CE4
+5567 5AE1
+5568 54E8
+5569 5023
+556A 52BE
+556B 7DEC
+556C 8511
+556D 6666
+556E 6C3E
+556F 724C
+5570 8ADC
+5571 9C0D
+5572 77A5
+5573 8B02
+5574 8D05
+5575 6F11
+5576 9834
+5577 97FB
+5578 50FB
+5579 7F75
+557A 5A03
+557B 8513
+557C 4FB6
+557D 634C
+557E 9D61
+557F 808B
+5580 5294
+5581 65A1
+5582 567A
+5583 5957
+5584 8D0B
+5585 6A35
+5586 6AD3
+5587 70F9
+5588 865E
+5589 6FB1
+558A 51E7
+558B 7FEB
+558C 59EA
+558D 5E87
+558E 6B6A
+558F 754F
+5590 717D
+5591 914E
+5592 7D2C
+5593 8C79
+5594 6062
+5595 621A
+5596 7FA8
+5597 5F1B
+5598 6C8C
+5599 86FE
+559A 7562
+559B 7B86
+559C 9AB8
+559D 6627
+559E 7ABA
+559F 844E
+55A0 6F81
+55A1 8B2C
+55A2 86A4
+55A3 6FEB
+55A4 7B8B
+55A5 7F77
+55A6 8F2F
+55A7 8E44
+55A8 7E23
+55A9 4E4D
+55AA 79A6
+55AB 8AFA
+55AC 903C
+55AD 50D1
+55AE 9ECD
+55AF 5EDF
+55B0 758F
+55B1 631F
+55B2 53DB
+55B3 9910
+55B4 826E
+55B5 62F7
+55B6 68FA
+55B7 725D
+55B8 803D
+55B9 58D5
+55BA 5C4D
+55BB 86D9
+55BC 540B
+55BD 8805
+55BE 92F2
+55BF 9237
+55C0 5C61
+55C1 985B
+55C2 86E4
+55C3 966A
+55C4 7262
+55C5 6955
+55C6 6CD7
+55C7 6994
+55C8 9C2F
+55C9 77E7
+55CA 68C9
+55CB 8DE8
+55CC 6D6C
+55CD 67C1
+55CE 9BAA
+55CF 619A
+55D0 63A9
+55D1 7015
+55D2 9306
+55D3 934D
+55D4 6A61
+55D5 6258
+55D6 5283
+55D7 7525
+55D8 5687
+55D9 6C83
+55DA 6834
+55DB 649E
+55DC 4E9B
+55DD 7252
+55DE 59E6
+55DF 8FC2
+55E0 5FBD
+55E1 6DD8
+55E2 85F7
+55E3 8A51
+55E4 9817
+55E5 99C1
+55E6 63A0
+55E7 7C81
+55E8 5B30
+55E9 8139
+55EA 5403
+55EB 7E82
+55EC 8106
+55ED 532A
+55EE 6A8E
+55EF 7F6B
+55F0 54E9
+55F1 5678
+55F2 8AB9
+55F3 6715
+55F4 5BD3
+55F5 6478
+55F6 64FE
+55F7 6B1D
+55F8 8CC2
+55F9 51CB
+55FA 7E8F
+5641 5F0C
+5642 4E10
+5643 4E15
+5644 4E28
+5645 4E2A
+5646 4E31
+5647 4E36
+5648 4E3F
+5649 4E42
+564A 4E56
+564B 4E58
+564C 4E62
+564D 4E82
+564E 4E85
+564F 4E8A
+5650 4E8E
+5651 5F0D
+5652 4E9E
+5653 4EA0
+5654 4EA2
+5655 4EB0
+5656 4EB3
+5657 4EB6
+5658 4ECE
+5659 4ECD
+565A 4EC4
+565B 4EC6
+565C 4EC2
+565D 4EE1
+565E 4ED7
+565F 4EDE
+5660 4EED
+5661 4EDF
+5662 4EFC
+5663 4F09
+5664 4F1C
+5665 4F00
+5666 4F03
+5667 4F5A
+5668 4F30
+5669 4F5D
+566A 4F39
+566B 4F57
+566C 4F47
+566D 4F5E
+566E 4F56
+566F 4F5B
+5670 4F92
+5671 4F8A
+5672 4F88
+5673 4F8F
+5674 4F9A
+5675 4FAD
+5676 4F98
+5677 4F7B
+5678 4FAB
+5679 4F69
+567A 4F70
+567B 4F94
+567C 4F6F
+567D 4F86
+567E 4F96
+567F 4FD4
+5680 4FCE
+5681 4FD8
+5682 4FDB
+5683 4FD1
+5684 4FDA
+5685 4FD0
+5686 4FCD
+5687 4FE4
+5688 4FE5
+5689 501A
+568A 5040
+568B 5028
+568C 5014
+568D 502A
+568E 5025
+568F 5005
+5690 5021
+5691 5022
+5692 5029
+5693 502C
+5694 4FFF
+5695 4FFE
+5696 4FEF
+5697 5011
+5698 501E
+5699 5006
+569A 5043
+569B 5047
+569C 5055
+569D 5050
+569E 5048
+569F 505A
+56A0 5056
+56A1 500F
+56A2 5046
+56A3 5070
+56A4 5042
+56A5 506C
+56A6 5078
+56A7 5080
+56A8 5094
+56A9 509A
+56AA 5085
+56AB 50B4
+56AC 6703
+56AD 50B2
+56AE 50C9
+56AF 50CA
+56B0 50B3
+56B1 50C2
+56B2 50F4
+56B3 50DE
+56B4 50E5
+56B5 50D8
+56B6 50ED
+56B7 50E3
+56B8 50EE
+56B9 50F9
+56BA 50F5
+56BB 5109
+56BC 5101
+56BD 5102
+56BE 511A
+56BF 5115
+56C0 5114
+56C1 5116
+56C2 5121
+56C3 513A
+56C4 5137
+56C5 513C
+56C6 513B
+56C7 513F
+56C8 5140
+56C9 514A
+56CA 514C
+56CB 5152
+56CC 5154
+56CD 5162
+56CE 5164
+56CF 5169
+56D0 516A
+56D1 516E
+56D2 5180
+56D3 5182
+56D4 56D8
+56D5 518C
+56D6 5189
+56D7 518F
+56D8 5191
+56D9 5193
+56DA 5195
+56DB 5196
+56DC 519D
+56DD 51A4
+56DE 51A6
+56DF 51A2
+56E0 51A9
+56E1 51AA
+56E2 51AB
+56E3 51B3
+56E4 51B1
+56E5 51B2
+56E6 51B0
+56E7 51B5
+56E8 51BE
+56E9 51BD
+56EA 51C5
+56EB 51C9
+56EC 51DB
+56ED 51E0
+56EE 51E9
+56EF 51EC
+56F0 51ED
+56F1 51F0
+56F2 51F5
+56F3 51FE
+56F4 5204
+56F5 520B
+56F6 5214
+56F7 5215
+56F8 5227
+56F9 522A
+56FA 522E
+56FB 5233
+56FC 5239
+56FD 5244
+56FE 524B
+5741 524F
+5742 525E
+5743 5254
+5744 5271
+5745 526A
+5746 5273
+5747 5274
+5748 5269
+5749 527F
+574A 527D
+574B 528D
+574C 5288
+574D 5292
+574E 5291
+574F 529C
+5750 52A6
+5751 52AC
+5752 52AD
+5753 52BC
+5754 52B5
+5755 52C1
+5756 52C0
+5757 52CD
+5758 52DB
+5759 52DE
+575A 52E3
+575B 52E6
+575C 52E0
+575D 52F3
+575E 52F5
+575F 52F8
+5760 52F9
+5761 5300
+5762 5306
+5763 5307
+5764 5308
+5765 7538
+5766 530D
+5767 5310
+5768 530F
+5769 5315
+576A 531A
+576B 5324
+576C 5323
+576D 532F
+576E 5331
+576F 5333
+5770 5338
+5771 5340
+5772 5345
+5773 5346
+5774 5349
+5775 4E17
+5776 534D
+5777 51D6
+5778 8209
+5779 535E
+577A 5369
+577B 536E
+577C 5372
+577D 5377
+577E 537B
+577F 5382
+5780 5393
+5781 5396
+5782 53A0
+5783 53A6
+5784 53A5
+5785 53AE
+5786 53B0
+5787 53B2
+5788 53B6
+5789 53C3
+578A 7C12
+578B 53DD
+578C 53DF
+578D 66FC
+578E FA0E
+578F 71EE
+5790 53EE
+5791 53E8
+5792 53ED
+5793 53FA
+5794 5401
+5795 543D
+5796 5440
+5797 542C
+5798 542D
+5799 543C
+579A 542E
+579B 5436
+579C 5429
+579D 541D
+579E 544E
+579F 548F
+57A0 5475
+57A1 548E
+57A2 545F
+57A3 5471
+57A4 5477
+57A5 5470
+57A6 5492
+57A7 547B
+57A8 5480
+57A9 549C
+57AA 5476
+57AB 5484
+57AC 5490
+57AD 5486
+57AE 548A
+57AF 54C7
+57B0 54BC
+57B1 54AF
+57B2 54A2
+57B3 54B8
+57B4 54A5
+57B5 54AC
+57B6 54C4
+57B7 54D8
+57B8 54C8
+57B9 54A8
+57BA 54AB
+57BB 54C2
+57BC 54A4
+57BD 54A9
+57BE 54BE
+57BF 54E5
+57C0 54FF
+57C1 54E6
+57C2 550F
+57C3 5514
+57C4 54FD
+57C5 54EE
+57C6 54ED
+57C7 54E2
+57C8 5539
+57C9 5540
+57CA 5563
+57CB 554C
+57CC 552E
+57CD 555C
+57CE 5545
+57CF 5556
+57D0 5557
+57D1 5538
+57D2 5533
+57D3 555D
+57D4 5599
+57D5 5580
+57D6 558A
+57D7 559F
+57D8 557B
+57D9 557E
+57DA 5598
+57DB 559E
+57DC 55AE
+57DD 557C
+57DE 5586
+57DF 5583
+57E0 55A9
+57E1 5587
+57E2 55A8
+57E3 55C5
+57E4 55DF
+57E5 55C4
+57E6 55DC
+57E7 55E4
+57E8 55D4
+57E9 55F9
+57EA 5614
+57EB 55F7
+57EC 5616
+57ED 55FE
+57EE 55FD
+57EF 561B
+57F0 564E
+57F1 5650
+57F2 5636
+57F3 5632
+57F4 5638
+57F5 566B
+57F6 5664
+57F7 5686
+57F8 562F
+57F9 566C
+57FA 566A
+57FB 71DF
+57FC 5694
+57FD 568F
+57FE 5680
+5841 568A
+5842 56A0
+5843 56A5
+5844 56AE
+5845 56B6
+5846 56B4
+5847 56C8
+5848 56C2
+5849 56BC
+584A 56C1
+584B 56C3
+584C 56C0
+584D 56CE
+584E 56D3
+584F 56D1
+5850 56D7
+5851 56EE
+5852 56F9
+5853 56FF
+5854 5704
+5855 5709
+5856 5708
+5857 570D
+5858 55C7
+5859 5718
+585A 5716
+585B 571C
+585C 5726
+585D 5738
+585E 574E
+585F 573B
+5860 5759
+5861 5740
+5862 574F
+5863 5765
+5864 5788
+5865 5761
+5866 577F
+5867 5789
+5868 5793
+5869 57A0
+586A 57A4
+586B 57B3
+586C 57AC
+586D 57AA
+586E 57C3
+586F 57C6
+5870 57C8
+5871 57C0
+5872 57D4
+5873 57C7
+5874 57D2
+5875 57D3
+5876 57D6
+5877 FA0F
+5878 580A
+5879 57E3
+587A 580B
+587B 5819
+587C 5821
+587D 584B
+587E 5862
+587F 6BC0
+5880 583D
+5881 5852
+5882 FA10
+5883 5870
+5884 5879
+5885 5885
+5886 5872
+5887 589F
+5888 58AB
+5889 58B8
+588A 589E
+588B 58AE
+588C 58B2
+588D 58B9
+588E 58BA
+588F 58C5
+5890 58D3
+5891 58D1
+5892 58D7
+5893 58D9
+5894 58D8
+5895 58DE
+5896 58DC
+5897 58DF
+5898 58E4
+5899 58E5
+589A 58EF
+589B 58F7
+589C 58F9
+589D 58FB
+589E 58FC
+589F 5902
+58A0 590A
+58A1 590B
+58A2 5910
+58A3 591B
+58A4 68A6
+58A5 5925
+58A6 592C
+58A7 592D
+58A8 5932
+58A9 5938
+58AA 593E
+58AB 5955
+58AC 5950
+58AD 5953
+58AE 595A
+58AF 5958
+58B0 595B
+58B1 595D
+58B2 5963
+58B3 5962
+58B4 5960
+58B5 5967
+58B6 596C
+58B7 5969
+58B8 5978
+58B9 5981
+58BA 598D
+58BB 599B
+58BC 599D
+58BD 59A3
+58BE 59A4
+58BF 59B2
+58C0 59BA
+58C1 59C6
+58C2 59E8
+58C3 59D9
+58C4 59DA
+58C5 5A25
+58C6 5A1F
+58C7 5A11
+58C8 5A1C
+58C9 5A1A
+58CA 5A09
+58CB 5A40
+58CC 5A6C
+58CD 5A49
+58CE 5A35
+58CF 5A36
+58D0 5A62
+58D1 5A6A
+58D2 5A9A
+58D3 5ABC
+58D4 5ABE
+58D5 5AD0
+58D6 5ACB
+58D7 5AC2
+58D8 5ABD
+58D9 5AE3
+58DA 5AD7
+58DB 5AE6
+58DC 5AE9
+58DD 5AD6
+58DE 5AFA
+58DF 5AFB
+58E0 5B0C
+58E1 5B0B
+58E2 5B16
+58E3 5B32
+58E4 5B2A
+58E5 5B36
+58E6 5B3E
+58E7 5B43
+58E8 5B45
+58E9 5B40
+58EA 5B51
+58EB 5B55
+58EC 5B56
+58ED 6588
+58EE 5B5B
+58EF 5B65
+58F0 5B69
+58F1 5B70
+58F2 5B73
+58F3 5B75
+58F4 5B78
+58F5 5B7A
+58F6 5B80
+58F7 5B83
+58F8 5BA6
+58F9 5BB8
+58FA 5BC3
+58FB 5BC7
+58FC 5BC0
+58FD 5BC9
+58FE 752F
+5941 5BD0
+5942 5BD8
+5943 5BDE
+5944 5BEC
+5945 5BE4
+5946 5BE2
+5947 5BE5
+5948 5BEB
+5949 5BF0
+594A 5BF3
+594B 5BF6
+594C 5C05
+594D 5C07
+594E 5C08
+594F 5C0D
+5950 5C13
+5951 5C1E
+5952 5C20
+5953 5C22
+5954 5C28
+5955 5C38
+5956 5C41
+5957 5C46
+5958 5C4E
+5959 5C53
+595A 5C50
+595B 5B71
+595C 5C6C
+595D 5C6E
+595E 5C76
+595F 5C79
+5960 5C8C
+5961 5C94
+5962 5CBE
+5963 5CAB
+5964 5CBB
+5965 5CB6
+5966 5CB7
+5967 5CA6
+5968 5CBA
+5969 5CC5
+596A 5CBC
+596B 5CC7
+596C 5CD9
+596D 5CE9
+596E 5CFD
+596F 5CFA
+5970 5CF5
+5971 5CED
+5972 5CEA
+5973 5D0B
+5974 5D15
+5975 5D1F
+5976 5D1B
+5977 5D11
+5978 5D27
+5979 5D22
+597A 5D1A
+597B 5D19
+597C 5D18
+597D 5D4C
+597E 5D52
+597F 5D53
+5980 FA11
+5981 5D5C
+5982 5D4E
+5983 5D4B
+5984 5D42
+5985 5D6C
+5986 5D73
+5987 5D6D
+5988 5D76
+5989 5D87
+598A 5D84
+598B 5D82
+598C 5D8C
+598D 5DA2
+598E 5D9D
+598F 5D90
+5990 5DAC
+5991 5DAE
+5992 5DB7
+5993 5DB8
+5994 5DBC
+5995 5DB9
+5996 5DC9
+5997 5DD0
+5998 5DD3
+5999 5DD2
+599A 5DDB
+599B 5DEB
+599C 5DF5
+599D 5E0B
+599E 5E1A
+599F 5E19
+59A0 5E11
+59A1 5E1B
+59A2 5E36
+59A3 5E44
+59A4 5E43
+59A5 5E40
+59A6 5E47
+59A7 5E4E
+59A8 5E57
+59A9 5E54
+59AA 5E62
+59AB 5E64
+59AC 5E75
+59AD 5E76
+59AE 5E7A
+59AF 5E7F
+59B0 5EA0
+59B1 5EC1
+59B2 5EC2
+59B3 5EC8
+59B4 5ED0
+59B5 5ECF
+59B6 5EDD
+59B7 5EDA
+59B8 5EDB
+59B9 5EE2
+59BA 5EE1
+59BB 5EE8
+59BC 5EE9
+59BD 5EEC
+59BE 5EF0
+59BF 5EF1
+59C0 5EF3
+59C1 5EF4
+59C2 5F03
+59C3 5F09
+59C4 5F0B
+59C5 5F11
+59C6 5F16
+59C7 5F21
+59C8 5F29
+59C9 5F2D
+59CA 5F2F
+59CB 5F34
+59CC 5F38
+59CD 5F41
+59CE 5F48
+59CF 5F4C
+59D0 5F4E
+59D1 5F51
+59D2 5F56
+59D3 5F57
+59D4 5F59
+59D5 5F5C
+59D6 5F5D
+59D7 5F61
+59D8 5F67
+59D9 5F73
+59DA 5F77
+59DB 5F83
+59DC 5F82
+59DD 5F7F
+59DE 5F8A
+59DF 5F88
+59E0 5F87
+59E1 5F91
+59E2 5F99
+59E3 5F9E
+59E4 5F98
+59E5 5FA0
+59E6 5FA8
+59E7 5FAD
+59E8 5FB7
+59E9 5FBC
+59EA 5FD6
+59EB 5FFB
+59EC 5FE4
+59ED 5FF8
+59EE 5FF1
+59EF 5FF0
+59F0 5FDD
+59F1 5FDE
+59F2 5FFF
+59F3 6021
+59F4 6019
+59F5 6010
+59F6 6029
+59F7 600E
+59F8 6031
+59F9 601B
+59FA 6015
+59FB 602B
+59FC 6026
+59FD 600F
+59FE 603A
+5A41 605A
+5A42 6041
+5A43 6060
+5A44 605D
+5A45 606A
+5A46 6077
+5A47 605F
+5A48 604A
+5A49 6046
+5A4A 604D
+5A4B 6063
+5A4C 6043
+5A4D 6064
+5A4E 606C
+5A4F 606B
+5A50 6059
+5A51 6085
+5A52 6081
+5A53 6083
+5A54 609A
+5A55 6084
+5A56 609B
+5A57 608A
+5A58 6096
+5A59 6097
+5A5A 6092
+5A5B 60A7
+5A5C 608B
+5A5D 60E1
+5A5E 60B8
+5A5F 60DE
+5A60 60E0
+5A61 60D3
+5A62 60BD
+5A63 60C6
+5A64 60B5
+5A65 60D5
+5A66 60D8
+5A67 6120
+5A68 60F2
+5A69 6115
+5A6A 6106
+5A6B 60F6
+5A6C 60F7
+5A6D 6100
+5A6E 60F4
+5A6F 60FA
+5A70 6103
+5A71 6121
+5A72 60FB
+5A73 60F1
+5A74 610D
+5A75 610E
+5A76 6111
+5A77 6147
+5A78 614D
+5A79 6137
+5A7A 6128
+5A7B 6127
+5A7C 613E
+5A7D 614A
+5A7E 6130
+5A7F 613C
+5A80 612C
+5A81 6134
+5A82 6165
+5A83 615D
+5A84 613D
+5A85 6142
+5A86 6144
+5A87 6173
+5A88 6187
+5A89 6177
+5A8A 6158
+5A8B 6159
+5A8C 615A
+5A8D 616B
+5A8E 6174
+5A8F 616F
+5A90 6171
+5A91 615F
+5A92 6153
+5A93 6175
+5A94 6198
+5A95 6199
+5A96 6196
+5A97 61AC
+5A98 6194
+5A99 618A
+5A9A 6191
+5A9B 61AB
+5A9C 61AE
+5A9D 61CC
+5A9E 61CA
+5A9F 61C9
+5AA0 61C8
+5AA1 61C3
+5AA2 61C6
+5AA3 61BA
+5AA4 61CB
+5AA5 7F79
+5AA6 61CD
+5AA7 61E6
+5AA8 61E3
+5AA9 61F4
+5AAA 61F7
+5AAB 61F6
+5AAC 61FD
+5AAD 61FA
+5AAE 61FF
+5AAF 61FC
+5AB0 61FE
+5AB1 6200
+5AB2 6208
+5AB3 6209
+5AB4 620D
+5AB5 6213
+5AB6 6214
+5AB7 621B
+5AB8 621E
+5AB9 6221
+5ABA 622A
+5ABB 622E
+5ABC 6230
+5ABD 6232
+5ABE 6233
+5ABF 6241
+5AC0 624E
+5AC1 625E
+5AC2 6263
+5AC3 625B
+5AC4 6260
+5AC5 6268
+5AC6 627C
+5AC7 6282
+5AC8 6289
+5AC9 6292
+5ACA 627E
+5ACB 6293
+5ACC 6296
+5ACD 6283
+5ACE 6294
+5ACF 62D7
+5AD0 62D1
+5AD1 62BB
+5AD2 62CF
+5AD3 62AC
+5AD4 62C6
+5AD5 62C8
+5AD6 62DC
+5AD7 62D4
+5AD8 62CA
+5AD9 62C2
+5ADA 62A6
+5ADB 62C7
+5ADC 629B
+5ADD 62C9
+5ADE 630C
+5ADF 62EE
+5AE0 62F1
+5AE1 6327
+5AE2 6302
+5AE3 6308
+5AE4 62EF
+5AE5 62F5
+5AE6 62FF
+5AE7 6350
+5AE8 634D
+5AE9 633E
+5AEA 634F
+5AEB 6396
+5AEC 638E
+5AED 6380
+5AEE 63AB
+5AEF 6376
+5AF0 63A3
+5AF1 638F
+5AF2 6389
+5AF3 639F
+5AF4 636B
+5AF5 6369
+5AF6 63B5
+5AF7 63BE
+5AF8 63E9
+5AF9 63C0
+5AFA 63C6
+5AFB 63F5
+5AFC 63E3
+5AFD 63C9
+5AFE 63D2
+5B41 63F6
+5B42 63C4
+5B43 6434
+5B44 6406
+5B45 6413
+5B46 6426
+5B47 6436
+5B48 641C
+5B49 6417
+5B4A 6428
+5B4B 640F
+5B4C 6416
+5B4D 644E
+5B4E 6467
+5B4F 646F
+5B50 6460
+5B51 6476
+5B52 64B9
+5B53 649D
+5B54 64CE
+5B55 6495
+5B56 64BB
+5B57 6493
+5B58 64A5
+5B59 64A9
+5B5A 6488
+5B5B 64BC
+5B5C 64DA
+5B5D 64D2
+5B5E 64C5
+5B5F 64C7
+5B60 64D4
+5B61 64D8
+5B62 64C2
+5B63 64F1
+5B64 64E7
+5B65 64E0
+5B66 64E1
+5B67 64E3
+5B68 64EF
+5B69 64F4
+5B6A 64F6
+5B6B 64F2
+5B6C 64FA
+5B6D 6500
+5B6E 64FD
+5B6F 6518
+5B70 651C
+5B71 651D
+5B72 6505
+5B73 6524
+5B74 6523
+5B75 652B
+5B76 652C
+5B77 6534
+5B78 6535
+5B79 6537
+5B7A 6536
+5B7B 6538
+5B7C 754B
+5B7D 6548
+5B7E 654E
+5B7F 6556
+5B80 654D
+5B81 6558
+5B82 6555
+5B83 655D
+5B84 6572
+5B85 6578
+5B86 6582
+5B87 6583
+5B88 8B8A
+5B89 659B
+5B8A 659F
+5B8B 65AB
+5B8C 65B7
+5B8D 65C3
+5B8E 65C6
+5B8F 65C1
+5B90 65C4
+5B91 65CC
+5B92 65D2
+5B93 65D9
+5B94 65E1
+5B95 65E0
+5B96 65F1
+5B97 6600
+5B98 6615
+5B99 6602
+5B9A 6772
+5B9B 6603
+5B9C 65FB
+5B9D 6609
+5B9E 663F
+5B9F 6635
+5BA0 662E
+5BA1 661E
+5BA2 6634
+5BA3 661C
+5BA4 6624
+5BA5 6644
+5BA6 6649
+5BA7 6665
+5BA8 6657
+5BA9 665E
+5BAA 6664
+5BAB 6659
+5BAC 6662
+5BAD 665D
+5BAE FA12
+5BAF 6673
+5BB0 6670
+5BB1 6683
+5BB2 6688
+5BB3 6684
+5BB4 6699
+5BB5 6698
+5BB6 66A0
+5BB7 669D
+5BB8 66B2
+5BB9 66C4
+5BBA 66C1
+5BBB 66BF
+5BBC 66C9
+5BBD 66BE
+5BBE 66BC
+5BBF 66B8
+5BC0 66D6
+5BC1 66DA
+5BC2 66E6
+5BC3 66E9
+5BC4 66F0
+5BC5 66F5
+5BC6 66F7
+5BC7 66FA
+5BC8 670E
+5BC9 F929
+5BCA 6716
+5BCB 671E
+5BCC 7E22
+5BCD 6726
+5BCE 6727
+5BCF 9738
+5BD0 672E
+5BD1 673F
+5BD2 6736
+5BD3 6737
+5BD4 6738
+5BD5 6746
+5BD6 675E
+5BD7 6759
+5BD8 6766
+5BD9 6764
+5BDA 6789
+5BDB 6785
+5BDC 6770
+5BDD 67A9
+5BDE 676A
+5BDF 678B
+5BE0 6773
+5BE1 67A6
+5BE2 67A1
+5BE3 67BB
+5BE4 67B7
+5BE5 67EF
+5BE6 67B4
+5BE7 67EC
+5BE8 67E9
+5BE9 67B8
+5BEA 67E7
+5BEB 67E4
+5BEC 6852
+5BED 67DD
+5BEE 67E2
+5BEF 67EE
+5BF0 67C0
+5BF1 67CE
+5BF2 67B9
+5BF3 6801
+5BF4 67C6
+5BF5 681E
+5BF6 6846
+5BF7 684D
+5BF8 6840
+5BF9 6844
+5BFA 6832
+5BFB 684E
+5BFC 6863
+5BFD 6859
+5BFE 688D
+5C41 6877
+5C42 687F
+5C43 689F
+5C44 687E
+5C45 688F
+5C46 68AD
+5C47 6894
+5C48 6883
+5C49 68BC
+5C4A 68B9
+5C4B 6874
+5C4C 68B5
+5C4D 68BA
+5C4E 690F
+5C4F 6901
+5C50 68CA
+5C51 6908
+5C52 68D8
+5C53 6926
+5C54 68E1
+5C55 690C
+5C56 68CD
+5C57 68D4
+5C58 68E7
+5C59 68D5
+5C5A 6912
+5C5B 68EF
+5C5C 6904
+5C5D 68E3
+5C5E 68E0
+5C5F 68CF
+5C60 68C6
+5C61 6922
+5C62 692A
+5C63 6921
+5C64 6923
+5C65 6928
+5C66 FA13
+5C67 6979
+5C68 6977
+5C69 6936
+5C6A 6978
+5C6B 6954
+5C6C 696A
+5C6D 6974
+5C6E 6968
+5C6F 693D
+5C70 6959
+5C71 6930
+5C72 695E
+5C73 695D
+5C74 697E
+5C75 6981
+5C76 69B2
+5C77 69BF
+5C78 FA14
+5C79 6998
+5C7A 69C1
+5C7B 69D3
+5C7C 69BE
+5C7D 69CE
+5C7E 5BE8
+5C7F 69CA
+5C80 69B1
+5C81 69DD
+5C82 69BB
+5C83 69C3
+5C84 69A0
+5C85 699C
+5C86 6995
+5C87 69DE
+5C88 6A2E
+5C89 69E8
+5C8A 6A02
+5C8B 6A1B
+5C8C 69FF
+5C8D 69F9
+5C8E 69F2
+5C8F 69E7
+5C90 69E2
+5C91 6A1E
+5C92 69ED
+5C93 6A14
+5C94 69EB
+5C95 6A0A
+5C96 6A22
+5C97 6A12
+5C98 6A23
+5C99 6A13
+5C9A 6A30
+5C9B 6A6B
+5C9C 6A44
+5C9D 6A0C
+5C9E 6AA0
+5C9F 6A36
+5CA0 6A78
+5CA1 6A47
+5CA2 6A62
+5CA3 6A59
+5CA4 6A66
+5CA5 6A48
+5CA6 6A46
+5CA7 6A38
+5CA8 6A72
+5CA9 6A73
+5CAA 6A90
+5CAB 6A8D
+5CAC 6A84
+5CAD 6AA2
+5CAE 6AA3
+5CAF 6A7E
+5CB0 6A97
+5CB1 6AAC
+5CB2 6AAA
+5CB3 6ABB
+5CB4 6AC2
+5CB5 6AB8
+5CB6 6AB3
+5CB7 6AC1
+5CB8 6ADE
+5CB9 6AE2
+5CBA 6AD1
+5CBB 6ADA
+5CBC 6AE4
+5CBD 8616
+5CBE 8617
+5CBF 6AEA
+5CC0 6B05
+5CC1 6B0A
+5CC2 6AFA
+5CC3 6B12
+5CC4 6B16
+5CC5 6B1F
+5CC6 6B38
+5CC7 6B37
+5CC8 6B39
+5CC9 76DC
+5CCA 98EE
+5CCB 6B47
+5CCC 6B43
+5CCD 6B49
+5CCE 6B50
+5CCF 6B59
+5CD0 6B54
+5CD1 6B5B
+5CD2 6B5F
+5CD3 6B61
+5CD4 6B78
+5CD5 6B79
+5CD6 6B7F
+5CD7 6B80
+5CD8 6B84
+5CD9 6B83
+5CDA 6B8D
+5CDB 6B98
+5CDC 6B95
+5CDD 6B9E
+5CDE 6BA4
+5CDF 6BAA
+5CE0 6BAB
+5CE1 6BAF
+5CE2 6BB1
+5CE3 6BB2
+5CE4 6BB3
+5CE5 6BB7
+5CE6 6BBC
+5CE7 6BC6
+5CE8 6BCB
+5CE9 6BD3
+5CEA 6BD6
+5CEB 6BDF
+5CEC 6BEC
+5CED 6BEB
+5CEE 6BF3
+5CEF 6BEF
+5CF0 6C08
+5CF1 6C13
+5CF2 6C14
+5CF3 6C1B
+5CF4 6C24
+5CF5 6C23
+5CF6 6C3F
+5CF7 6C5E
+5CF8 6C55
+5CF9 6C5C
+5CFA 6C62
+5CFB 6C82
+5CFC 6C8D
+5CFD 6C86
+5CFE 6C6F
+5D41 6C9A
+5D42 6C81
+5D43 6C9B
+5D44 6C7E
+5D45 6C68
+5D46 6C73
+5D47 6C92
+5D48 6C90
+5D49 6CC4
+5D4A 6CF1
+5D4B 6CBD
+5D4C 6CC5
+5D4D 6CAE
+5D4E 6CDA
+5D4F 6CDD
+5D50 6CB1
+5D51 6CBE
+5D52 6CBA
+5D53 6CDB
+5D54 6CEF
+5D55 6CD9
+5D56 6CEA
+5D57 6D1F
+5D58 6D04
+5D59 6D36
+5D5A 6D2B
+5D5B 6D3D
+5D5C 6D33
+5D5D 6D12
+5D5E 6D0C
+5D5F 6D63
+5D60 6D87
+5D61 6D93
+5D62 6D6F
+5D63 6D64
+5D64 6D5A
+5D65 6D79
+5D66 6D59
+5D67 6D8E
+5D68 6D95
+5D69 6D9B
+5D6A 6D85
+5D6B 6D96
+5D6C 6DF9
+5D6D 6E0A
+5D6E 6E2E
+5D6F 6DB5
+5D70 6DE6
+5D71 6DC7
+5D72 6DAC
+5D73 6DB8
+5D74 6DCF
+5D75 6DC6
+5D76 6DEC
+5D77 6DDE
+5D78 6DCC
+5D79 6DE8
+5D7A 6DF8
+5D7B 6DD2
+5D7C 6DC5
+5D7D 6DFA
+5D7E 6DD9
+5D7F 6DF2
+5D80 6DFC
+5D81 6DE4
+5D82 6DD5
+5D83 6DEA
+5D84 6DEE
+5D85 6E2D
+5D86 6E6E
+5D87 6E19
+5D88 6E72
+5D89 6E5F
+5D8A 6E39
+5D8B 6E3E
+5D8C 6E23
+5D8D 6E6B
+5D8E 6E5C
+5D8F 6E2B
+5D90 6E76
+5D91 6E4D
+5D92 6E1F
+5D93 6E27
+5D94 6E43
+5D95 6E3C
+5D96 6E3A
+5D97 6E4E
+5D98 6E24
+5D99 6E1D
+5D9A 6E38
+5D9B 6E82
+5D9C 6EAA
+5D9D 6E98
+5D9E 6EB7
+5D9F 6EBD
+5DA0 6EAF
+5DA1 6EC4
+5DA2 6EB2
+5DA3 6ED4
+5DA4 6ED5
+5DA5 6E8F
+5DA6 6EBF
+5DA7 6EC2
+5DA8 6E9F
+5DA9 6F41
+5DAA 6F45
+5DAB 6EEC
+5DAC 6EF8
+5DAD 6EFE
+5DAE 6F3F
+5DAF 6EF2
+5DB0 6F31
+5DB1 6EEF
+5DB2 6F32
+5DB3 6ECC
+5DB4 6EFF
+5DB5 6F3E
+5DB6 6F13
+5DB7 6EF7
+5DB8 6F86
+5DB9 6F7A
+5DBA 6F78
+5DBB 6F80
+5DBC 6F6F
+5DBD 6F5B
+5DBE 6F6D
+5DBF 6F74
+5DC0 6F82
+5DC1 6F88
+5DC2 6F7C
+5DC3 6F58
+5DC4 6FC6
+5DC5 6F8E
+5DC6 6F91
+5DC7 6F66
+5DC8 6FB3
+5DC9 6FA3
+5DCA 6FB5
+5DCB 6FA1
+5DCC 6FB9
+5DCD 6FDB
+5DCE 6FAA
+5DCF 6FC2
+5DD0 6FDF
+5DD1 6FD5
+5DD2 6FEC
+5DD3 6FD8
+5DD4 6FD4
+5DD5 6FF5
+5DD6 6FEE
+5DD7 7005
+5DD8 7007
+5DD9 7009
+5DDA 700B
+5DDB 6FFA
+5DDC 7011
+5DDD 7001
+5DDE 700F
+5DDF 701B
+5DE0 701A
+5DE1 701F
+5DE2 6FF3
+5DE3 7028
+5DE4 7018
+5DE5 7030
+5DE6 703E
+5DE7 7032
+5DE8 7051
+5DE9 7063
+5DEA 7085
+5DEB 7099
+5DEC 70AF
+5DED 70AB
+5DEE 70AC
+5DEF 70B8
+5DF0 70AE
+5DF1 70DF
+5DF2 70CB
+5DF3 70D9
+5DF4 7109
+5DF5 710F
+5DF6 7104
+5DF7 70F1
+5DF8 70FD
+5DF9 711C
+5DFA 7119
+5DFB 715C
+5DFC 7146
+5DFD 7147
+5DFE 7166
+5E41 7162
+5E42 714C
+5E43 7156
+5E44 716C
+5E45 7188
+5E46 718F
+5E47 7184
+5E48 7195
+5E49 FA15
+5E4A 71AC
+5E4B 71C1
+5E4C 71B9
+5E4D 71BE
+5E4E 71D2
+5E4F 71E7
+5E50 71C9
+5E51 71D4
+5E52 71D7
+5E53 71CE
+5E54 71F5
+5E55 71E0
+5E56 71EC
+5E57 71FB
+5E58 71FC
+5E59 71F9
+5E5A 71FE
+5E5B 71FF
+5E5C 720D
+5E5D 7210
+5E5E 7228
+5E5F 722D
+5E60 722C
+5E61 7230
+5E62 7232
+5E63 723B
+5E64 723C
+5E65 723F
+5E66 7240
+5E67 7246
+5E68 724B
+5E69 7258
+5E6A 7274
+5E6B 727E
+5E6C 7281
+5E6D 7287
+5E6E 7282
+5E6F 7292
+5E70 7296
+5E71 72A2
+5E72 72A7
+5E73 72B1
+5E74 72B2
+5E75 72BE
+5E76 72C3
+5E77 72C6
+5E78 72C4
+5E79 72B9
+5E7A 72CE
+5E7B 72D2
+5E7C 72E2
+5E7D 72E0
+5E7E 72E1
+5E7F 72F9
+5E80 72F7
+5E81 7317
+5E82 730A
+5E83 731C
+5E84 7316
+5E85 731D
+5E86 7324
+5E87 7334
+5E88 7329
+5E89 732F
+5E8A FA16
+5E8B 7325
+5E8C 733E
+5E8D 734F
+5E8E 734E
+5E8F 7357
+5E90 9ED8
+5E91 736A
+5E92 7368
+5E93 7370
+5E94 7377
+5E95 7378
+5E96 7375
+5E97 737B
+5E98 73C8
+5E99 73BD
+5E9A 73B3
+5E9B 73CE
+5E9C 73BB
+5E9D 73C0
+5E9E 73C9
+5E9F 73D6
+5EA0 73E5
+5EA1 73E3
+5EA2 73D2
+5EA3 73EE
+5EA4 73F1
+5EA5 73DE
+5EA6 73F8
+5EA7 7407
+5EA8 73F5
+5EA9 7405
+5EAA 7426
+5EAB 742A
+5EAC 7425
+5EAD 7429
+5EAE 742E
+5EAF 7432
+5EB0 743A
+5EB1 7455
+5EB2 743F
+5EB3 745F
+5EB4 7459
+5EB5 7441
+5EB6 745C
+5EB7 7469
+5EB8 7470
+5EB9 7463
+5EBA 746A
+5EBB 7464
+5EBC 7462
+5EBD 7489
+5EBE 746F
+5EBF 747E
+5EC0 749F
+5EC1 749E
+5EC2 74A2
+5EC3 74A7
+5EC4 74CA
+5EC5 74CF
+5EC6 74D4
+5EC7 74E0
+5EC8 74E3
+5EC9 74E7
+5ECA 74E9
+5ECB 74EE
+5ECC 74F0
+5ECD 74F2
+5ECE 74F1
+5ECF 74F7
+5ED0 74F8
+5ED1 7501
+5ED2 7504
+5ED3 7503
+5ED4 7505
+5ED5 750D
+5ED6 750C
+5ED7 750E
+5ED8 7513
+5ED9 751E
+5EDA 7526
+5EDB 752C
+5EDC 753C
+5EDD 7544
+5EDE 754D
+5EDF 754A
+5EE0 7549
+5EE1 7546
+5EE2 755B
+5EE3 755A
+5EE4 7564
+5EE5 7567
+5EE6 756B
+5EE7 756F
+5EE8 7574
+5EE9 756D
+5EEA 7578
+5EEB 7576
+5EEC 7582
+5EED 7586
+5EEE 7587
+5EEF 758A
+5EF0 7589
+5EF1 7594
+5EF2 759A
+5EF3 759D
+5EF4 75A5
+5EF5 75A3
+5EF6 75C2
+5EF7 75B3
+5EF8 75C3
+5EF9 75B5
+5EFA 75BD
+5EFB 75B8
+5EFC 75BC
+5EFD 75B1
+5EFE 75CD
+5F41 75CA
+5F42 75D2
+5F43 75D9
+5F44 75E3
+5F45 75DE
+5F46 75FE
+5F47 75FF
+5F48 75FC
+5F49 7601
+5F4A 75F0
+5F4B 75FA
+5F4C 75F2
+5F4D 75F3
+5F4E 760B
+5F4F 7609
+5F50 761F
+5F51 7627
+5F52 7620
+5F53 7621
+5F54 7622
+5F55 7624
+5F56 7634
+5F57 7630
+5F58 763B
+5F59 7647
+5F5A 7648
+5F5B 7658
+5F5C 7646
+5F5D 765C
+5F5E 7661
+5F5F 7662
+5F60 7668
+5F61 7669
+5F62 7667
+5F63 766A
+5F64 766C
+5F65 7670
+5F66 7672
+5F67 7676
+5F68 767C
+5F69 7682
+5F6A 7680
+5F6B 7683
+5F6C 7688
+5F6D 768B
+5F6E 7699
+5F6F 769A
+5F70 769C
+5F71 769E
+5F72 769B
+5F73 76A6
+5F74 76B0
+5F75 76B4
+5F76 76B8
+5F77 76B9
+5F78 76BA
+5F79 76C2
+5F7A FA17
+5F7B 76CD
+5F7C 76D6
+5F7D 76D2
+5F7E 76DE
+5F7F 76E1
+5F80 76E5
+5F81 76EA
+5F82 862F
+5F83 76FB
+5F84 7708
+5F85 7707
+5F86 7704
+5F87 7724
+5F88 7729
+5F89 7725
+5F8A 7726
+5F8B 771B
+5F8C 7737
+5F8D 7738
+5F8E 7746
+5F8F 7747
+5F90 775A
+5F91 7768
+5F92 776B
+5F93 775B
+5F94 7765
+5F95 777F
+5F96 777E
+5F97 7779
+5F98 778E
+5F99 778B
+5F9A 7791
+5F9B 77A0
+5F9C 779E
+5F9D 77B0
+5F9E 77B6
+5F9F 77B9
+5FA0 77BF
+5FA1 77BC
+5FA2 77BD
+5FA3 77BB
+5FA4 77C7
+5FA5 77CD
+5FA6 77DA
+5FA7 77DC
+5FA8 77E3
+5FA9 77EE
+5FAA 52AF
+5FAB 77FC
+5FAC 780C
+5FAD 7812
+5FAE 7821
+5FAF 783F
+5FB0 7820
+5FB1 7845
+5FB2 784E
+5FB3 7864
+5FB4 7874
+5FB5 788E
+5FB6 787A
+5FB7 7886
+5FB8 789A
+5FB9 787C
+5FBA 788C
+5FBB 78A3
+5FBC 78B5
+5FBD 78AA
+5FBE 78AF
+5FBF 78D1
+5FC0 78C6
+5FC1 78CB
+5FC2 78D4
+5FC3 78BE
+5FC4 78BC
+5FC5 78C5
+5FC6 78CA
+5FC7 78EC
+5FC8 78E7
+5FC9 78DA
+5FCA 78FD
+5FCB 78F4
+5FCC 7907
+5FCD 7911
+5FCE 7919
+5FCF 792C
+5FD0 792B
+5FD1 7930
+5FD2 FA18
+5FD3 7940
+5FD4 7960
+5FD5 FA19
+5FD6 795F
+5FD7 795A
+5FD8 7955
+5FD9 FA1A
+5FDA 797F
+5FDB 798A
+5FDC 7994
+5FDD FA1B
+5FDE 799D
+5FDF 799B
+5FE0 79AA
+5FE1 79B3
+5FE2 79BA
+5FE3 79C9
+5FE4 79D5
+5FE5 79E7
+5FE6 79EC
+5FE7 79E3
+5FE8 7A08
+5FE9 7A0D
+5FEA 7A18
+5FEB 7A19
+5FEC 7A1F
+5FED 7A31
+5FEE 7A3E
+5FEF 7A37
+5FF0 7A3B
+5FF1 7A43
+5FF2 7A57
+5FF3 7A49
+5FF4 7A62
+5FF5 7A61
+5FF6 7A69
+5FF7 9F9D
+5FF8 7A70
+5FF9 7A79
+5FFA 7A7D
+5FFB 7A88
+5FFC 7A95
+5FFD 7A98
+5FFE 7A96
+6041 7A97
+6042 7AA9
+6043 7AB0
+6044 7AB6
+6045 9083
+6046 7AC3
+6047 7ABF
+6048 7AC5
+6049 7AC4
+604A 7AC7
+604B 7ACA
+604C 7ACD
+604D 7ACF
+604E 7AD2
+604F 7AD1
+6050 7AD5
+6051 7AD3
+6052 7AD9
+6053 7ADA
+6054 7ADD
+6055 7AE1
+6056 7AE2
+6057 7AE6
+6058 7AE7
+6059 FA1C
+605A 7AEB
+605B 7AED
+605C 7AF0
+605D 7AF8
+605E 7B02
+605F 7B0F
+6060 7B0B
+6061 7B0A
+6062 7B06
+6063 7B33
+6064 7B36
+6065 7B19
+6066 7B1E
+6067 7B35
+6068 7B28
+6069 7B50
+606A 7B4D
+606B 7B4C
+606C 7B45
+606D 7B5D
+606E 7B75
+606F 7B7A
+6070 7B74
+6071 7B70
+6072 7B71
+6073 7B6E
+6074 7B9D
+6075 7B98
+6076 7B9F
+6077 7B8D
+6078 7B9C
+6079 7B9A
+607A 7B92
+607B 7B8F
+607C 7B99
+607D 7BCF
+607E 7BCB
+607F 7BCC
+6080 7BB4
+6081 7BC6
+6082 7B9E
+6083 7BDD
+6084 7BE9
+6085 7BE6
+6086 7BF7
+6087 7BE5
+6088 7C14
+6089 7C00
+608A 7C13
+608B 7C07
+608C 7BF3
+608D 7C0D
+608E 7BF6
+608F 7C23
+6090 7C27
+6091 7C2A
+6092 7C1F
+6093 7C37
+6094 7C2B
+6095 7C3D
+6096 7C40
+6097 7C4C
+6098 7C43
+6099 7C56
+609A 7C50
+609B 7C58
+609C 7C5F
+609D 7C65
+609E 7C6C
+609F 7C75
+60A0 7C83
+60A1 7C90
+60A2 7CA4
+60A3 7CA2
+60A4 7CAB
+60A5 7CA1
+60A6 7CAD
+60A7 7CA8
+60A8 7CB3
+60A9 7CB2
+60AA 7CB1
+60AB 7CAE
+60AC 7CB9
+60AD FA1D
+60AE 7CBD
+60AF 7CC5
+60B0 7CC2
+60B1 7CD2
+60B2 7CE2
+60B3 7CD8
+60B4 7CDC
+60B5 7CEF
+60B6 7CF2
+60B7 7CF4
+60B8 7CF6
+60B9 7D06
+60BA 7D02
+60BB 7D1C
+60BC 7D15
+60BD 7D0A
+60BE 7D45
+60BF 7D4B
+60C0 7D2E
+60C1 7D32
+60C2 7D3F
+60C3 7D35
+60C4 7D48
+60C5 7D46
+60C6 7D5C
+60C7 7D73
+60C8 7D56
+60C9 7D4E
+60CA 7D68
+60CB 7D6E
+60CC 7D4F
+60CD 7D63
+60CE 7D93
+60CF 7D89
+60D0 7D5B
+60D1 7DAE
+60D2 7DA3
+60D3 7DB5
+60D4 7DB7
+60D5 7DC7
+60D6 7DBD
+60D7 7DAB
+60D8 7DA2
+60D9 7DAF
+60DA 7DA0
+60DB 7DB8
+60DC 7D9F
+60DD 7DB0
+60DE 7DD5
+60DF 7DD8
+60E0 7DDD
+60E1 7DD6
+60E2 7DE4
+60E3 7DDE
+60E4 7DFB
+60E5 7E0B
+60E6 7DF2
+60E7 7DE1
+60E8 7DDC
+60E9 7E05
+60EA 7E0A
+60EB 7E21
+60EC 7E12
+60ED 7E1F
+60EE 7E09
+60EF 7E3A
+60F0 7E46
+60F1 7E66
+60F2 7E31
+60F3 7E3D
+60F4 7E35
+60F5 7E3B
+60F6 7E39
+60F7 7E43
+60F8 7E37
+60F9 7E32
+60FA 7E5D
+60FB 7E56
+60FC 7E5E
+60FD 7E52
+60FE 7E59
+6141 7E5A
+6142 7E67
+6143 7E79
+6144 7E6A
+6145 7E69
+6146 7E7C
+6147 7E7B
+6148 7E7D
+6149 8FAE
+614A 7E7F
+614B 7E83
+614C 7E89
+614D 7E8E
+614E 7E8C
+614F 7E92
+6150 7E93
+6151 7E94
+6152 7E96
+6153 7E9B
+6154 7F38
+6155 7F3A
+6156 7F45
+6157 7F47
+6158 7F4C
+6159 7F4E
+615A 7F51
+615B 7F55
+615C 7F54
+615D 7F58
+615E 7F5F
+615F 7F60
+6160 7F68
+6161 7F67
+6162 7F69
+6163 7F78
+6164 7F82
+6165 7F86
+6166 7F83
+6167 7F87
+6168 7F88
+6169 7F8C
+616A 7F94
+616B 7F9E
+616C 7F9D
+616D 7F9A
+616E 7FA1
+616F 7FA3
+6170 7FAF
+6171 7FAE
+6172 7FB2
+6173 7FB9
+6174 7FB6
+6175 7FB8
+6176 8B71
+6177 FA1E
+6178 7FC5
+6179 7FC6
+617A 7FCA
+617B 7FD5
+617C 7FE1
+617D 7FE6
+617E 7FE9
+617F 7FF3
+6180 7FF9
+6181 8004
+6182 800B
+6183 8012
+6184 8019
+6185 801C
+6186 8021
+6187 8028
+6188 803F
+6189 803B
+618A 804A
+618B 8046
+618C 8052
+618D 8058
+618E 805F
+618F 8062
+6190 8068
+6191 8073
+6192 8072
+6193 8070
+6194 8076
+6195 8079
+6196 807D
+6197 807F
+6198 8084
+6199 8085
+619A 8093
+619B 809A
+619C 80AD
+619D 5190
+619E 80AC
+619F 80DB
+61A0 80E5
+61A1 80D9
+61A2 80DD
+61A3 80C4
+61A4 80DA
+61A5 8109
+61A6 80EF
+61A7 80F1
+61A8 811B
+61A9 8123
+61AA 812F
+61AB 814B
+61AC 8146
+61AD 813E
+61AE 8153
+61AF 8151
+61B0 80FC
+61B1 8171
+61B2 816E
+61B3 8165
+61B4 815F
+61B5 8166
+61B6 8174
+61B7 8183
+61B8 8188
+61B9 818A
+61BA 8180
+61BB 8182
+61BC 81A0
+61BD 8195
+61BE 81A3
+61BF 8193
+61C0 81B5
+61C1 81A4
+61C2 81A9
+61C3 81B8
+61C4 81B0
+61C5 81C8
+61C6 81BE
+61C7 81BD
+61C8 81C0
+61C9 81C2
+61CA 81BA
+61CB 81C9
+61CC 81CD
+61CD 81D1
+61CE 81D8
+61CF 81D9
+61D0 81DA
+61D1 81DF
+61D2 81E0
+61D3 81FA
+61D4 81FB
+61D5 81FE
+61D6 8201
+61D7 8202
+61D8 8205
+61D9 820D
+61DA 8210
+61DB 8212
+61DC 8216
+61DD 8229
+61DE 822B
+61DF 822E
+61E0 8238
+61E1 8233
+61E2 8240
+61E3 8259
+61E4 825A
+61E5 825D
+61E6 825F
+61E7 8264
+61E8 8262
+61E9 8268
+61EA 826A
+61EB 826B
+61EC 8271
+61ED 8277
+61EE 827E
+61EF 828D
+61F0 8292
+61F1 82AB
+61F2 829F
+61F3 82BB
+61F4 82AC
+61F5 82E1
+61F6 82E3
+61F7 82DF
+61F8 8301
+61F9 82D2
+61FA 82F4
+61FB 82F3
+61FC 8303
+61FD 82FB
+61FE 82F9
+6241 82DE
+6242 8306
+6243 82DC
+6244 82FA
+6245 8309
+6246 82D9
+6247 8335
+6248 8362
+6249 8334
+624A 8316
+624B 8331
+624C 8340
+624D 8339
+624E 8350
+624F 8345
+6250 832F
+6251 832B
+6252 8318
+6253 839A
+6254 83AA
+6255 839F
+6256 83A2
+6257 8396
+6258 8323
+6259 838E
+625A 8375
+625B 837F
+625C 838A
+625D 837C
+625E 83B5
+625F 8373
+6260 8393
+6261 83A0
+6262 8385
+6263 8389
+6264 83A8
+6265 83F4
+6266 8413
+6267 83C7
+6268 83CE
+6269 83F7
+626A 83FD
+626B 8403
+626C 83D8
+626D 840B
+626E 83C1
+626F 8407
+6270 83E0
+6271 83F2
+6272 840D
+6273 8420
+6274 83F6
+6275 83BD
+6276 83FB
+6277 842A
+6278 8462
+6279 843C
+627A 8484
+627B 8477
+627C 846B
+627D 8479
+627E 8448
+627F 846E
+6280 8482
+6281 8469
+6282 8446
+6283 846F
+6284 8438
+6285 8435
+6286 84CA
+6287 84B9
+6288 84BF
+6289 849F
+628A 84B4
+628B 84CD
+628C 84BB
+628D 84DA
+628E 84D0
+628F 84C1
+6290 84AD
+6291 84C6
+6292 84D6
+6293 84A1
+6294 84D9
+6295 84FF
+6296 84F4
+6297 8517
+6298 8518
+6299 852C
+629A 851F
+629B 8515
+629C 8514
+629D 8506
+629E 8553
+629F 855A
+62A0 8540
+62A1 8559
+62A2 8563
+62A3 8558
+62A4 8548
+62A5 8541
+62A6 854A
+62A7 854B
+62A8 856B
+62A9 8555
+62AA 8580
+62AB 85A4
+62AC 8588
+62AD 8591
+62AE 858A
+62AF 85A8
+62B0 856D
+62B1 8594
+62B2 859B
+62B3 85AE
+62B4 8587
+62B5 859C
+62B6 8577
+62B7 857E
+62B8 8590
+62B9 FA1F
+62BA 820A
+62BB 85B0
+62BC 85C9
+62BD 85BA
+62BE 85CF
+62BF 85B9
+62C0 85D0
+62C1 85D5
+62C2 85DD
+62C3 85E5
+62C4 85DC
+62C5 85F9
+62C6 860A
+62C7 8613
+62C8 860B
+62C9 85FE
+62CA 8622
+62CB 861A
+62CC 8630
+62CD 863F
+62CE FA20
+62CF 864D
+62D0 4E55
+62D1 8655
+62D2 865F
+62D3 8667
+62D4 8671
+62D5 8693
+62D6 86A3
+62D7 86A9
+62D8 868B
+62D9 86AA
+62DA 868C
+62DB 86B6
+62DC 86AF
+62DD 86C4
+62DE 86C6
+62DF 86B0
+62E0 86C9
+62E1 86CE
+62E2 FA21
+62E3 86AB
+62E4 86D4
+62E5 86DE
+62E6 86E9
+62E7 86EC
+62E8 86DF
+62E9 86DB
+62EA 8712
+62EB 8706
+62EC 8708
+62ED 8700
+62EE 8703
+62EF 86FB
+62F0 8711
+62F1 8709
+62F2 870D
+62F3 86F9
+62F4 870A
+62F5 8734
+62F6 873F
+62F7 873B
+62F8 8725
+62F9 8729
+62FA 871A
+62FB 875F
+62FC 8778
+62FD 874C
+62FE 874E
+6341 8774
+6342 8757
+6343 8768
+6344 8782
+6345 876A
+6346 8760
+6347 876E
+6348 8759
+6349 8753
+634A 8763
+634B 877F
+634C 87A2
+634D 87C6
+634E 879F
+634F 87AF
+6350 87CB
+6351 87BD
+6352 87C0
+6353 87D0
+6354 96D6
+6355 87AB
+6356 87C4
+6357 87B3
+6358 87D2
+6359 87BB
+635A 87EF
+635B 87F2
+635C 87E0
+635D 880E
+635E 8807
+635F 880F
+6360 8816
+6361 880D
+6362 87FE
+6363 87F6
+6364 87F7
+6365 8811
+6366 8815
+6367 8822
+6368 8821
+6369 8827
+636A 8831
+636B 8836
+636C 8839
+636D 883B
+636E 8842
+636F 8844
+6370 884D
+6371 8852
+6372 8859
+6373 885E
+6374 8862
+6375 886B
+6376 8881
+6377 887E
+6378 8875
+6379 887D
+637A 8872
+637B 8882
+637C 889E
+637D 8897
+637E 8892
+637F 88AE
+6380 8899
+6381 88A2
+6382 888D
+6383 88A4
+6384 88BF
+6385 88B5
+6386 88B1
+6387 88C3
+6388 88C4
+6389 88D4
+638A 88D8
+638B 88D9
+638C 88DD
+638D 88F9
+638E 8902
+638F 88FC
+6390 88F5
+6391 88E8
+6392 88F2
+6393 8904
+6394 890C
+6395 892A
+6396 891D
+6397 890A
+6398 8913
+6399 891E
+639A 8925
+639B 892B
+639C 8941
+639D 893B
+639E 8936
+639F 8943
+63A0 8938
+63A1 894D
+63A2 894C
+63A3 8960
+63A4 895E
+63A5 8966
+63A6 896A
+63A7 8964
+63A8 896D
+63A9 896F
+63AA 8974
+63AB 8977
+63AC 897E
+63AD 8983
+63AE 8988
+63AF 898A
+63B0 8993
+63B1 8998
+63B2 89A1
+63B3 89A9
+63B4 89A6
+63B5 89AC
+63B6 89AF
+63B7 89B2
+63B8 89BA
+63B9 89BF
+63BA 89BD
+63BB 89C0
+63BC 89DA
+63BD 89DD
+63BE 89E7
+63BF 89F4
+63C0 89F8
+63C1 8A03
+63C2 8A16
+63C3 8A10
+63C4 8A0C
+63C5 8A12
+63C6 8A1B
+63C7 8A1D
+63C8 8A25
+63C9 8A36
+63CA 8A41
+63CB 8A37
+63CC 8A5B
+63CD 8A52
+63CE 8A46
+63CF 8A48
+63D0 8A7C
+63D1 8A6D
+63D2 8A6C
+63D3 8A62
+63D4 8A79
+63D5 8A85
+63D6 8A82
+63D7 8A84
+63D8 8AA8
+63D9 8AA1
+63DA 8A91
+63DB 8AA5
+63DC 8AA6
+63DD 8A9A
+63DE 8AA3
+63DF 8AA7
+63E0 8ACC
+63E1 8ABE
+63E2 8ACD
+63E3 8AC2
+63E4 8ADA
+63E5 8AF3
+63E6 8AE7
+63E7 8AE4
+63E8 8AF1
+63E9 8B14
+63EA 8AE0
+63EB 8AE2
+63EC 8AE1
+63ED 8ADF
+63EE FA22
+63EF 8AF6
+63F0 8AF7
+63F1 8ADE
+63F2 8ADB
+63F3 8B0C
+63F4 8B07
+63F5 8B1A
+63F6 8B16
+63F7 8B10
+63F8 8B17
+63F9 8B20
+63FA 8B33
+63FB 8B41
+63FC 97AB
+63FD 8B26
+63FE 8B2B
+6441 8B3E
+6442 8B4C
+6443 8B4F
+6444 8B4E
+6445 8B53
+6446 8B49
+6447 8B56
+6448 8B5B
+6449 8B5A
+644A 8B74
+644B 8B6B
+644C 8B5F
+644D 8B6C
+644E 8B6F
+644F 8B7D
+6450 8B7F
+6451 8B80
+6452 8B8C
+6453 8B8E
+6454 8B99
+6455 8B92
+6456 8B93
+6457 8B96
+6458 8B9A
+6459 8C3A
+645A 8C41
+645B 8C3F
+645C 8C48
+645D 8C4C
+645E 8C4E
+645F 8C50
+6460 8C55
+6461 8C62
+6462 8C6C
+6463 8C78
+6464 8C7A
+6465 8C7C
+6466 8C82
+6467 8C89
+6468 8C85
+6469 8C8A
+646A 8C8D
+646B 8C8E
+646C 8C98
+646D 8C94
+646E 621D
+646F 8CAD
+6470 8CAA
+6471 8CAE
+6472 8CBD
+6473 8CB2
+6474 8CB3
+6475 8CC1
+6476 8CB6
+6477 8CC8
+6478 8CCE
+6479 8CCD
+647A 8CE3
+647B 8CDA
+647C 8CF0
+647D 8CF4
+647E 8CFD
+647F 8CFA
+6480 8CFB
+6481 8D07
+6482 8D0A
+6483 8D0F
+6484 8D0D
+6485 8D12
+6486 8D10
+6487 8D13
+6488 8D14
+6489 8D16
+648A 8D67
+648B 8D6D
+648C 8D71
+648D 8D76
+648E FA23
+648F 8D81
+6490 8DC2
+6491 8DBE
+6492 8DBA
+6493 8DCF
+6494 8DDA
+6495 8DD6
+6496 8DCC
+6497 8DDB
+6498 8DCB
+6499 8DEA
+649A 8DEB
+649B 8DDF
+649C 8DE3
+649D 8DFC
+649E 8E08
+649F 8DFF
+64A0 8E09
+64A1 8E1D
+64A2 8E1E
+64A3 8E10
+64A4 8E1F
+64A5 8E42
+64A6 8E35
+64A7 8E30
+64A8 8E34
+64A9 8E4A
+64AA 8E47
+64AB 8E49
+64AC 8E4C
+64AD 8E50
+64AE 8E48
+64AF 8E59
+64B0 8E64
+64B1 8E60
+64B2 8E55
+64B3 8E63
+64B4 8E76
+64B5 8E72
+64B6 8E87
+64B7 8E7C
+64B8 8E81
+64B9 8E85
+64BA 8E84
+64BB 8E8B
+64BC 8E8A
+64BD 8E93
+64BE 8E91
+64BF 8E94
+64C0 8E99
+64C1 8EA1
+64C2 8EAA
+64C3 8EB1
+64C4 8EBE
+64C5 8EC6
+64C6 8EC5
+64C7 8EC8
+64C8 8ECB
+64C9 8ECF
+64CA 8EDB
+64CB 8EE3
+64CC 8EFC
+64CD 8EFB
+64CE 8EEB
+64CF 8EFE
+64D0 8F0A
+64D1 8F0C
+64D2 8F05
+64D3 8F15
+64D4 8F12
+64D5 8F13
+64D6 8F1C
+64D7 8F19
+64D8 8F1F
+64D9 8F26
+64DA 8F33
+64DB 8F3B
+64DC 8F39
+64DD 8F45
+64DE 8F42
+64DF 8F3E
+64E0 8F49
+64E1 8F46
+64E2 8F4C
+64E3 8F4E
+64E4 8F57
+64E5 8F5C
+64E6 8F62
+64E7 8F63
+64E8 8F64
+64E9 8F9C
+64EA 8F9F
+64EB 8FA3
+64EC 8FA8
+64ED 8FA7
+64EE 8FAD
+64EF 8FAF
+64F0 8FB7
+64F1 FA24
+64F2 8FDA
+64F3 8FE5
+64F4 8FE2
+64F5 8FEF
+64F6 8FE9
+64F7 8FF4
+64F8 9005
+64F9 8FF9
+64FA 8FF8
+64FB 9011
+64FC 9015
+64FD 900E
+64FE 9021
+6541 900D
+6542 901E
+6543 9016
+6544 900B
+6545 9027
+6546 9036
+6547 9039
+6548 904F
+6549 FA25
+654A 9050
+654B 9051
+654C 9052
+654D 9049
+654E 903E
+654F 9056
+6550 9058
+6551 905E
+6552 9068
+6553 9067
+6554 906F
+6555 9076
+6556 96A8
+6557 9072
+6558 9082
+6559 907D
+655A 9089
+655B 9080
+655C 908F
+655D 6248
+655E 90AF
+655F 90B1
+6560 90B5
+6561 90E2
+6562 90E4
+6563 90DB
+6564 90DE
+6565 9102
+6566 FA26
+6567 9115
+6568 9112
+6569 9119
+656A 9132
+656B 9127
+656C 9130
+656D 914A
+656E 9156
+656F 9158
+6570 9163
+6571 9165
+6572 9169
+6573 9173
+6574 9172
+6575 918B
+6576 9189
+6577 9182
+6578 91A2
+6579 91AB
+657A 91AF
+657B 91AA
+657C 91B5
+657D 91B4
+657E 91BA
+657F 91C0
+6580 91C1
+6581 91CB
+6582 91D0
+6583 91DA
+6584 91DB
+6585 91D7
+6586 91DE
+6587 91D6
+6588 91DF
+6589 91E1
+658A 91ED
+658B 91F5
+658C 91EE
+658D 91E4
+658E 91F6
+658F 91E5
+6590 9206
+6591 921E
+6592 91FF
+6593 9210
+6594 9214
+6595 920A
+6596 922C
+6597 9215
+6598 9229
+6599 9257
+659A 9245
+659B 923A
+659C 9249
+659D 9264
+659E 9240
+659F 923C
+65A0 9248
+65A1 924E
+65A2 9250
+65A3 9259
+65A4 923F
+65A5 9251
+65A6 9239
+65A7 924B
+65A8 9267
+65A9 925A
+65AA 929C
+65AB 92A7
+65AC 9277
+65AD 9278
+65AE 9296
+65AF 9293
+65B0 929B
+65B1 9295
+65B2 92E9
+65B3 92CF
+65B4 92E7
+65B5 92D7
+65B6 92D9
+65B7 92D0
+65B8 FA27
+65B9 92D5
+65BA 92B9
+65BB 92B7
+65BC 92E0
+65BD 92D3
+65BE 933A
+65BF 9335
+65C0 930F
+65C1 9325
+65C2 92FA
+65C3 9321
+65C4 9344
+65C5 92FB
+65C6 FA28
+65C7 9319
+65C8 931E
+65C9 92FF
+65CA 9322
+65CB 931A
+65CC 931D
+65CD 9323
+65CE 9302
+65CF 933B
+65D0 9370
+65D1 9360
+65D2 937C
+65D3 936E
+65D4 9356
+65D5 9357
+65D6 93B9
+65D7 93B0
+65D8 93A4
+65D9 93AD
+65DA 9394
+65DB 93C8
+65DC 93D6
+65DD 93C6
+65DE 93D7
+65DF 93E8
+65E0 93E5
+65E1 93D8
+65E2 93C3
+65E3 93DD
+65E4 93DE
+65E5 93D0
+65E6 93E4
+65E7 941A
+65E8 93F8
+65E9 9414
+65EA 9413
+65EB 9421
+65EC 9403
+65ED 9407
+65EE 9436
+65EF 942B
+65F0 9431
+65F1 943A
+65F2 9441
+65F3 9452
+65F4 9445
+65F5 9444
+65F6 9448
+65F7 945B
+65F8 945A
+65F9 9460
+65FA 9462
+65FB 945E
+65FC 946A
+65FD 9475
+65FE 9470
+6641 9477
+6642 947F
+6643 947D
+6644 947C
+6645 947E
+6646 9481
+6647 9582
+6648 9587
+6649 958A
+664A 9592
+664B 9594
+664C 9596
+664D 9598
+664E 9599
+664F 95A0
+6650 95A8
+6651 95A7
+6652 95AD
+6653 95BC
+6654 95BB
+6655 95B9
+6656 95BE
+6657 95CA
+6658 6FF6
+6659 95C3
+665A 95CD
+665B 95CC
+665C 95D5
+665D 95D4
+665E 95D6
+665F 95DC
+6660 95E1
+6661 95E5
+6662 95E2
+6663 9621
+6664 9628
+6665 962E
+6666 962F
+6667 9642
+6668 964F
+6669 964C
+666A 964B
+666B 965C
+666C 965D
+666D 965F
+666E 9666
+666F 9677
+6670 9672
+6671 966C
+6672 968D
+6673 968B
+6674 F9DC
+6675 9698
+6676 9695
+6677 9697
+6678 FA29
+6679 969D
+667A 96A7
+667B 96AA
+667C 96B1
+667D 96B2
+667E 96B0
+667F 96AF
+6680 96B4
+6681 96B6
+6682 96B8
+6683 96B9
+6684 96CE
+6685 96CB
+6686 96D5
+6687 96DC
+6688 96D9
+6689 96F9
+668A 9704
+668B 9706
+668C 9708
+668D 9719
+668E 970D
+668F 9713
+6690 970E
+6691 9711
+6692 970F
+6693 9716
+6694 9724
+6695 972A
+6696 9730
+6697 9733
+6698 9739
+6699 973B
+669A 973D
+669B 973E
+669C 9746
+669D 9744
+669E 9743
+669F 9748
+66A0 9742
+66A1 9749
+66A2 974D
+66A3 974F
+66A4 9751
+66A5 9755
+66A6 975C
+66A7 9760
+66A8 9764
+66A9 9766
+66AA 9768
+66AB 976D
+66AC 9779
+66AD 9785
+66AE 977C
+66AF 9781
+66B0 977A
+66B1 978B
+66B2 978F
+66B3 9790
+66B4 979C
+66B5 97A8
+66B6 97A6
+66B7 97A3
+66B8 97B3
+66B9 97B4
+66BA 97C3
+66BB 97C6
+66BC 97C8
+66BD 97CB
+66BE 97DC
+66BF 97ED
+66C0 97F2
+66C1 7ADF
+66C2 97F5
+66C3 980F
+66C4 981A
+66C5 9824
+66C6 9821
+66C7 9837
+66C8 983D
+66C9 984F
+66CA 984B
+66CB 9857
+66CC 9865
+66CD 986B
+66CE 986F
+66CF 9870
+66D0 9871
+66D1 9874
+66D2 9873
+66D3 98AA
+66D4 98AF
+66D5 98B1
+66D6 98B6
+66D7 98C4
+66D8 98C3
+66D9 98C6
+66DA 98DC
+66DB 98ED
+66DC 98E9
+66DD FA2A
+66DE 98EB
+66DF FA2B
+66E0 9903
+66E1 991D
+66E2 9912
+66E3 9914
+66E4 9918
+66E5 9927
+66E6 FA2C
+66E7 9921
+66E8 991E
+66E9 9924
+66EA 9920
+66EB 992C
+66EC 992E
+66ED 993D
+66EE 993E
+66EF 9942
+66F0 9949
+66F1 9945
+66F2 9950
+66F3 994B
+66F4 9951
+66F5 994C
+66F6 9955
+66F7 9997
+66F8 9998
+66F9 999E
+66FA 99A5
+66FB 99AD
+66FC 99AE
+66FD 99BC
+66FE 99DF
+6741 99DB
+6742 99DD
+6743 99D8
+6744 99D1
+6745 99ED
+6746 99EE
+6747 99E2
+6748 99F1
+6749 99F2
+674A 99FB
+674B 99F8
+674C 9A01
+674D 9A0F
+674E 9A05
+674F 9A19
+6750 9A2B
+6751 9A37
+6752 9A40
+6753 9A45
+6754 9A42
+6755 9A43
+6756 9A3E
+6757 9A55
+6758 9A4D
+6759 9A4E
+675A 9A5B
+675B 9A57
+675C 9A5F
+675D 9A62
+675E 9A69
+675F 9A65
+6760 9A64
+6761 9A6A
+6762 9A6B
+6763 9AAD
+6764 9AB0
+6765 9ABC
+6766 9AC0
+6767 9ACF
+6768 9AD3
+6769 9AD4
+676A 9AD1
+676B 9AD9
+676C 9ADC
+676D 9ADE
+676E 9ADF
+676F 9AE2
+6770 9AE3
+6771 9AE6
+6772 9AEF
+6773 9AEB
+6774 9AEE
+6775 9AF4
+6776 9AF1
+6777 9AF7
+6778 9AFB
+6779 9B06
+677A 9B18
+677B 9B1A
+677C 9B1F
+677D 9B22
+677E 9B23
+677F 9B25
+6780 9B27
+6781 9B28
+6782 9B29
+6783 9B2A
+6784 9B2E
+6785 9B2F
+6786 9B31
+6787 9B32
+6788 9B3B
+6789 9B44
+678A 9B43
+678B 9B4D
+678C 9B4E
+678D 9B51
+678E 9B58
+678F 9B75
+6790 9B74
+6791 9B72
+6792 9B93
+6793 9B8F
+6794 9B83
+6795 9B91
+6796 9B96
+6797 9B97
+6798 9B9F
+6799 9BA0
+679A 9BA8
+679B 9BB1
+679C 9BB4
+679D 9BC0
+679E 9BCA
+679F 9BBB
+67A0 9BB9
+67A1 9BC6
+67A2 9BCF
+67A3 9BD1
+67A4 9BD2
+67A5 9BE3
+67A6 9BE2
+67A7 9BE4
+67A8 9BD4
+67A9 9BE1
+67AA 9BF5
+67AB 9BF1
+67AC 9BF2
+67AD 9C04
+67AE 9C1B
+67AF 9C15
+67B0 9C14
+67B1 9C00
+67B2 9C09
+67B3 9C13
+67B4 9C0C
+67B5 9C06
+67B6 9C08
+67B7 9C12
+67B8 9C0A
+67B9 9C2E
+67BA 9C25
+67BB 9C24
+67BC 9C21
+67BD 9C30
+67BE 9C47
+67BF 9C32
+67C0 9C46
+67C1 9C3E
+67C2 9C5A
+67C3 9C60
+67C4 9C67
+67C5 9C76
+67C6 9C78
+67C7 9CEB
+67C8 9CE7
+67C9 9CEC
+67CA 9CF0
+67CB 9D09
+67CC 9D03
+67CD 9D06
+67CE 9D2A
+67CF 9D26
+67D0 9D2C
+67D1 9D23
+67D2 9D1F
+67D3 9D15
+67D4 9D12
+67D5 9D41
+67D6 9D3F
+67D7 9D44
+67D8 9D3E
+67D9 9D46
+67DA 9D48
+67DB 9D5D
+67DC 9D5E
+67DD 9D59
+67DE 9D51
+67DF 9D50
+67E0 9D64
+67E1 9D72
+67E2 9D70
+67E3 9D87
+67E4 9D6B
+67E5 9D6F
+67E6 9D7A
+67E7 9D9A
+67E8 9DA4
+67E9 9DA9
+67EA 9DAB
+67EB 9DB2
+67EC 9DC4
+67ED 9DC1
+67EE 9DBB
+67EF 9DB8
+67F0 9DBA
+67F1 9DC6
+67F2 9DCF
+67F3 9DC2
+67F4 FA2D
+67F5 9DD9
+67F6 9DD3
+67F7 9DF8
+67F8 9DE6
+67F9 9DED
+67FA 9DEF
+67FB 9DFD
+67FC 9E1A
+67FD 9E1B
+67FE 9E19
+6841 9E1E
+6842 9E75
+6843 9E79
+6844 9E7D
+6845 9E81
+6846 9E88
+6847 9E8B
+6848 9E8C
+6849 9E95
+684A 9E91
+684B 9E9D
+684C 9EA5
+684D 9EB8
+684E 9EAA
+684F 9EAD
+6850 9EBC
+6851 9EBE
+6852 9761
+6853 9ECC
+6854 9ECF
+6855 9ED0
+6856 9ED1
+6857 9ED4
+6858 9EDC
+6859 9EDE
+685A 9EDD
+685B 9EE0
+685C 9EE5
+685D 9EE8
+685E 9EEF
+685F 9EF4
+6860 9EF6
+6861 9EF7
+6862 9EF9
+6863 9EFB
+6864 9EFC
+6865 9EFD
+6866 9F07
+6867 9F08
+6868 76B7
+6869 9F15
+686A 9F21
+686B 9F2C
+686C 9F3E
+686D 9F4A
+686E 9F4E
+686F 9F4F
+6870 9F52
+6871 9F54
+6872 9F63
+6873 9F5F
+6874 9F60
+6875 9F61
+6876 9F66
+6877 9F67
+6878 9F6C
+6879 9F6A
+687A 9F77
+687B 9F72
+687C 9F76
+687D 9F95
+687E 9F9C
+687F 9FA0
+6880 5C2D
+6881 69D9
+6882 9065
+6883 7476
+6884 51DC
+6885 7155
+6941 E000
+6942 E001
+6943 E002
+6944 E003
+6945 E004
+6946 E005
+6947 E006
+6948 E007
+6949 E008
+694A E009
+694B E00A
+694C E00B
+694D E00C
+694E E00D
+694F E00E
+6950 E00F
+6951 E010
+6952 E011
+6953 E012
+6954 E013
+6955 E014
+6956 E015
+6957 E016
+6958 E017
+6959 E018
+695A E019
+695B E01A
+695C E01B
+695D E01C
+695E E01D
+695F E01E
+6960 E01F
+6961 E020
+6962 E021
+6963 E022
+6964 E023
+6965 E024
+6966 E025
+6967 E026
+6968 E027
+6969 E028
+696A E029
+696B E02A
+696C E02B
+696D E02C
+696E E02D
+696F E02E
+6970 E02F
+6971 E030
+6972 E031
+6973 E032
+6974 E033
+6975 E034
+6976 E035
+6977 E036
+6978 E037
+6979 E038
+697A E039
+697B E03A
+697C E03B
+697D E03C
+697E E03D
+697F E03E
+6980 E03F
+6981 E040
+6982 E041
+6983 E042
+6984 E043
+6985 E044
+6986 E045
+6987 E046
+6988 E047
+6989 E048
+698A E049
+698B E04A
+698C E04B
+698D E04C
+698E E04D
+698F E04E
+6990 E04F
+6991 E050
+6992 E051
+6993 E052
+6994 E053
+6995 E054
+6996 E055
+6997 E056
+6998 E057
+6999 E058
+699A E059
+699B E05A
+699C E05B
+699D E05C
+699E E05D
+699F E05E
+69A0 E05F
+69A1 E060
+69A2 E061
+69A3 E062
+69A4 E063
+69A5 E064
+69A6 E065
+69A7 E066
+69A8 E067
+69A9 E068
+69AA E069
+69AB E06A
+69AC E06B
+69AD E06C
+69AE E06D
+69AF E06E
+69B0 E06F
+69B1 E070
+69B2 E071
+69B3 E072
+69B4 E073
+69B5 E074
+69B6 E075
+69B7 E076
+69B8 E077
+69B9 E078
+69BA E079
+69BB E07A
+69BC E07B
+69BD E07C
+69BE E07D
+69BF E07E
+69C0 E07F
+69C1 E080
+69C2 E081
+69C3 E082
+69C4 E083
+69C5 E084
+69C6 E085
+69C7 E086
+69C8 E087
+69C9 E088
+69CA E089
+69CB E08A
+69CC E08B
+69CD E08C
+69CE E08D
+69CF E08E
+69D0 E08F
+69D1 E090
+69D2 E091
+69D3 E092
+69D4 E093
+69D5 E094
+69D6 E095
+69D7 E096
+69D8 E097
+69D9 E098
+69DA E099
+69DB E09A
+69DC E09B
+69DD E09C
+69DE E09D
+69DF E09E
+69E0 E09F
+69E1 E0A0
+69E2 E0A1
+69E3 E0A2
+69E4 E0A3
+69E5 E0A4
+69E6 E0A5
+69E7 E0A6
+69E8 E0A7
+69E9 E0A8
+69EA E0A9
+69EB E0AA
+69EC E0AB
+69ED E0AC
+69EE E0AD
+69EF E0AE
+69F0 E0AF
+69F1 E0B0
+69F2 E0B1
+69F3 E0B2
+69F4 E0B3
+69F5 E0B4
+69F6 E0B5
+69F7 E0B6
+69F8 E0B7
+69F9 E0B8
+69FA E0B9
+69FB E0BA
+69FC E0BB
+69FD E0BC
+69FE E0BD
+6A41 E0BE
+6A42 E0BF
+6A43 E0C0
+6A44 E0C1
+6A45 E0C2
+6A46 E0C3
+6A47 E0C4
+6A48 E0C5
+6A49 E0C6
+6A4A E0C7
+6A4B E0C8
+6A4C E0C9
+6A4D E0CA
+6A4E E0CB
+6A4F E0CC
+6A50 E0CD
+6A51 E0CE
+6A52 E0CF
+6A53 E0D0
+6A54 E0D1
+6A55 E0D2
+6A56 E0D3
+6A57 E0D4
+6A58 E0D5
+6A59 E0D6
+6A5A E0D7
+6A5B E0D8
+6A5C E0D9
+6A5D E0DA
+6A5E E0DB
+6A5F E0DC
+6A60 E0DD
+6A61 E0DE
+6A62 E0DF
+6A63 E0E0
+6A64 E0E1
+6A65 E0E2
+6A66 E0E3
+6A67 E0E4
+6A68 E0E5
+6A69 E0E6
+6A6A E0E7
+6A6B E0E8
+6A6C E0E9
+6A6D E0EA
+6A6E E0EB
+6A6F E0EC
+6A70 E0ED
+6A71 E0EE
+6A72 E0EF
+6A73 E0F0
+6A74 E0F1
+6A75 E0F2
+6A76 E0F3
+6A77 E0F4
+6A78 E0F5
+6A79 E0F6
+6A7A E0F7
+6A7B E0F8
+6A7C E0F9
+6A7D E0FA
+6A7E E0FB
+6A7F E0FC
+6A80 E0FD
+6A81 E0FE
+6A82 E0FF
+6A83 E100
+6A84 E101
+6A85 E102
+6A86 E103
+6A87 E104
+6A88 E105
+6A89 E106
+6A8A E107
+6A8B E108
+6A8C E109
+6A8D E10A
+6A8E E10B
+6A8F E10C
+6A90 E10D
+6A91 E10E
+6A92 E10F
+6A93 E110
+6A94 E111
+6A95 E112
+6A96 E113
+6A97 E114
+6A98 E115
+6A99 E116
+6A9A E117
+6A9B E118
+6A9C E119
+6A9D E11A
+6A9E E11B
+6A9F E11C
+6AA0 E11D
+6AA1 E11E
+6AA2 E11F
+6AA3 E120
+6AA4 E121
+6AA5 E122
+6AA6 E123
+6AA7 E124
+6AA8 E125
+6AA9 E126
+6AAA E127
+6AAB E128
+6AAC E129
+6AAD E12A
+6AAE E12B
+6AAF E12C
+6AB0 E12D
+6AB1 E12E
+6AB2 E12F
+6AB3 E130
+6AB4 E131
+6AB5 E132
+6AB6 E133
+6AB7 E134
+6AB8 E135
+6AB9 E136
+6ABA E137
+6ABB E138
+6ABC E139
+6ABD E13A
+6ABE E13B
+6ABF E13C
+6AC0 E13D
+6AC1 E13E
+6AC2 E13F
+6AC3 E140
+6AC4 E141
+6AC5 E142
+6AC6 E143
+6AC7 E144
+6AC8 E145
+6AC9 E146
+6ACA E147
+6ACB E148
+6ACC E149
+6ACD E14A
+6ACE E14B
+6ACF E14C
+6AD0 E14D
+6AD1 E14E
+6AD2 E14F
+6AD3 E150
+6AD4 E151
+6AD5 E152
+6AD6 E153
+6AD7 E154
+6AD8 E155
+6AD9 E156
+6ADA E157
+6ADB E158
+6ADC E159
+6ADD E15A
+6ADE E15B
+6ADF E15C
+6AE0 E15D
+6AE1 E15E
+6AE2 E15F
+6AE3 E160
+6AE4 E161
+6AE5 E162
+6AE6 E163
+6AE7 E164
+6AE8 E165
+6AE9 E166
+6AEA E167
+6AEB E168
+6AEC E169
+6AED E16A
+6AEE E16B
+6AEF E16C
+6AF0 E16D
+6AF1 E16E
+6AF2 E16F
+6AF3 E170
+6AF4 E171
+6AF5 E172
+6AF6 E173
+6AF7 E174
+6AF8 E175
+6AF9 E176
+6AFA E177
+6AFB E178
+6AFC E179
+6AFD E17A
+6AFE E17B
+6B41 E17C
+6B42 E17D
+6B43 E17E
+6B44 E17F
+6B45 E180
+6B46 E181
+6B47 E182
+6B48 E183
+6B49 E184
+6B4A E185
+6B4B E186
+6B4C E187
+6B4D E188
+6B4E E189
+6B4F E18A
+6B50 E18B
+6B51 E18C
+6B52 E18D
+6B53 E18E
+6B54 E18F
+6B55 E190
+6B56 E191
+6B57 E192
+6B58 E193
+6B59 E194
+6B5A E195
+6B5B E196
+6B5C E197
+6B5D E198
+6B5E E199
+6B5F E19A
+6B60 E19B
+6B61 E19C
+6B62 E19D
+6B63 E19E
+6B64 E19F
+6B65 E1A0
+6B66 E1A1
+6B67 E1A2
+6B68 E1A3
+6B69 E1A4
+6B6A E1A5
+6B6B E1A6
+6B6C E1A7
+6B6D E1A8
+6B6E E1A9
+6B6F E1AA
+6B70 E1AB
+6B71 E1AC
+6B72 E1AD
+6B73 E1AE
+6B74 E1AF
+6B75 E1B0
+6B76 E1B1
+6B77 E1B2
+6B78 E1B3
+6B79 E1B4
+6B7A E1B5
+6B7B E1B6
+6B7C E1B7
+6B7D E1B8
+6B7E E1B9
+6B7F E1BA
+6B80 E1BB
+6B81 E1BC
+6B82 E1BD
+6B83 E1BE
+6B84 E1BF
+6B85 E1C0
+6B86 E1C1
+6B87 E1C2
+6B88 E1C3
+6B89 E1C4
+6B8A E1C5
+6B8B E1C6
+6B8C E1C7
+6B8D E1C8
+6B8E E1C9
+6B8F E1CA
+6B90 E1CB
+6B91 E1CC
+6B92 E1CD
+6B93 E1CE
+6B94 E1CF
+6B95 E1D0
+6B96 E1D1
+6B97 E1D2
+6B98 E1D3
+6B99 E1D4
+6B9A E1D5
+6B9B E1D6
+6B9C E1D7
+6B9D E1D8
+6B9E E1D9
+6B9F E1DA
+6BA0 E1DB
+6BA1 E1DC
+6BA2 E1DD
+6BA3 E1DE
+6BA4 E1DF
+6BA5 E1E0
+6BA6 E1E1
+6BA7 E1E2
+6BA8 E1E3
+6BA9 E1E4
+6BAA E1E5
+6BAB E1E6
+6BAC E1E7
+6BAD E1E8
+6BAE E1E9
+6BAF E1EA
+6BB0 E1EB
+6BB1 E1EC
+6BB2 E1ED
+6BB3 E1EE
+6BB4 E1EF
+6BB5 E1F0
+6BB6 E1F1
+6BB7 E1F2
+6BB8 E1F3
+6BB9 E1F4
+6BBA E1F5
+6BBB E1F6
+6BBC E1F7
+6BBD E1F8
+6BBE E1F9
+6BBF E1FA
+6BC0 E1FB
+6BC1 E1FC
+6BC2 E1FD
+6BC3 E1FE
+6BC4 E1FF
+6BC5 E200
+6BC6 E201
+6BC7 E202
+6BC8 E203
+6BC9 E204
+6BCA E205
+6BCB E206
+6BCC E207
+6BCD E208
+6BCE E209
+6BCF E20A
+6BD0 E20B
+6BD1 E20C
+6BD2 E20D
+6BD3 E20E
+6BD4 E20F
+6BD5 E210
+6BD6 E211
+6BD7 E212
+6BD8 E213
+6BD9 E214
+6BDA E215
+6BDB E216
+6BDC E217
+6BDD E218
+6BDE E219
+6BDF E21A
+6BE0 E21B
+6BE1 E21C
+6BE2 E21D
+6BE3 E21E
+6BE4 E21F
+6BE5 E220
+6BE6 E221
+6BE7 E222
+6BE8 E223
+6BE9 E224
+6BEA E225
+6BEB E226
+6BEC E227
+6BED E228
+6BEE E229
+6BEF E22A
+6BF0 E22B
+6BF1 E22C
+6BF2 E22D
+6BF3 E22E
+6BF4 E22F
+6BF5 E230
+6BF6 E231
+6BF7 E232
+6BF8 E233
+6BF9 E234
+6BFA E235
+6BFB E236
+6BFC E237
+6BFD E238
+6BFE E239
+6C41 E23A
+6C42 E23B
+6C43 E23C
+6C44 E23D
+6C45 E23E
+6C46 E23F
+6C47 E240
+6C48 E241
+6C49 E242
+6C4A E243
+6C4B E244
+6C4C E245
+6C4D E246
+6C4E E247
+6C4F E248
+6C50 E249
+6C51 E24A
+6C52 E24B
+6C53 E24C
+6C54 E24D
+6C55 E24E
+6C56 E24F
+6C57 E250
+6C58 E251
+6C59 E252
+6C5A E253
+6C5B E254
+6C5C E255
+6C5D E256
+6C5E E257
+6C5F E258
+6C60 E259
+6C61 E25A
+6C62 E25B
+6C63 E25C
+6C64 E25D
+6C65 E25E
+6C66 E25F
+6C67 E260
+6C68 E261
+6C69 E262
+6C6A E263
+6C6B E264
+6C6C E265
+6C6D E266
+6C6E E267
+6C6F E268
+6C70 E269
+6C71 E26A
+6C72 E26B
+6C73 E26C
+6C74 E26D
+6C75 E26E
+6C76 E26F
+6C77 E270
+6C78 E271
+6C79 E272
+6C7A E273
+6C7B E274
+6C7C E275
+6C7D E276
+6C7E E277
+6C7F E278
+6C80 E279
+6C81 E27A
+6C82 E27B
+6C83 E27C
+6C84 E27D
+6C85 E27E
+6C86 E27F
+6C87 E280
+6C88 E281
+6C89 E282
+6C8A E283
+6C8B E284
+6C8C E285
+6C8D E286
+6C8E E287
+6C8F E288
+6C90 E289
+6C91 E28A
+6C92 E28B
+6C93 E28C
+6C94 E28D
+6C95 E28E
+6C96 E28F
+6C97 E290
+6C98 E291
+6C99 E292
+6C9A E293
+6C9B E294
+6C9C E295
+6C9D E296
+6C9E E297
+6C9F E298
+6CA0 E299
+6CA1 E29A
+6CA2 E29B
+6CA3 E29C
+6CA4 E29D
+6CA5 E29E
+6CA6 E29F
+6CA7 E2A0
+6CA8 E2A1
+6CA9 E2A2
+6CAA E2A3
+6CAB E2A4
+6CAC E2A5
+6CAD E2A6
+6CAE E2A7
+6CAF E2A8
+6CB0 E2A9
+6CB1 E2AA
+6CB2 E2AB
+6CB3 E2AC
+6CB4 E2AD
+6CB5 E2AE
+6CB6 E2AF
+6CB7 E2B0
+6CB8 E2B1
+6CB9 E2B2
+6CBA E2B3
+6CBB E2B4
+6CBC E2B5
+6CBD E2B6
+6CBE E2B7
+6CBF E2B8
+6CC0 E2B9
+6CC1 E2BA
+6CC2 E2BB
+6CC3 E2BC
+6CC4 E2BD
+6CC5 E2BE
+6CC6 E2BF
+6CC7 E2C0
+6CC8 E2C1
+6CC9 E2C2
+6CCA E2C3
+6CCB E2C4
+6CCC E2C5
+6CCD E2C6
+6CCE E2C7
+6CCF E2C8
+6CD0 E2C9
+6CD1 E2CA
+6CD2 E2CB
+6CD3 E2CC
+6CD4 E2CD
+6CD5 E2CE
+6CD6 E2CF
+6CD7 E2D0
+6CD8 E2D1
+6CD9 E2D2
+6CDA E2D3
+6CDB E2D4
+6CDC E2D5
+6CDD E2D6
+6CDE E2D7
+6CDF E2D8
+6CE0 E2D9
+6CE1 E2DA
+6CE2 E2DB
+6CE3 E2DC
+6CE4 E2DD
+6CE5 E2DE
+6CE6 E2DF
+6CE7 E2E0
+6CE8 E2E1
+6CE9 E2E2
+6CEA E2E3
+6CEB E2E4
+6CEC E2E5
+6CED E2E6
+6CEE E2E7
+6CEF E2E8
+6CF0 E2E9
+6CF1 E2EA
+6CF2 E2EB
+6CF3 E2EC
+6CF4 E2ED
+6CF5 E2EE
+6CF6 E2EF
+6CF7 E2F0
+6CF8 E2F1
+6CF9 E2F2
+6CFA E2F3
+6CFB E2F4
+6CFC E2F5
+6CFD E2F6
+6CFE E2F7
+6D41 E2F8
+6D42 E2F9
+6D43 E2FA
+6D44 E2FB
+6D45 E2FC
+6D46 E2FD
+6D47 E2FE
+6D48 E2FF
+6D49 E300
+6D4A E301
+6D4B E302
+6D4C E303
+6D4D E304
+6D4E E305
+6D4F E306
+6D50 E307
+6D51 E308
+6D52 E309
+6D53 E30A
+6D54 E30B
+6D55 E30C
+6D56 E30D
+6D57 E30E
+6D58 E30F
+6D59 E310
+6D5A E311
+6D5B E312
+6D5C E313
+6D5D E314
+6D5E E315
+6D5F E316
+6D60 E317
+6D61 E318
+6D62 E319
+6D63 E31A
+6D64 E31B
+6D65 E31C
+6D66 E31D
+6D67 E31E
+6D68 E31F
+6D69 E320
+6D6A E321
+6D6B E322
+6D6C E323
+6D6D E324
+6D6E E325
+6D6F E326
+6D70 E327
+6D71 E328
+6D72 E329
+6D73 E32A
+6D74 E32B
+6D75 E32C
+6D76 E32D
+6D77 E32E
+6D78 E32F
+6D79 E330
+6D7A E331
+6D7B E332
+6D7C E333
+6D7D E334
+6D7E E335
+6D7F E336
+6D80 E337
+6D81 E338
+6D82 E339
+6D83 E33A
+6D84 E33B
+6D85 E33C
+6D86 E33D
+6D87 E33E
+6D88 E33F
+6D89 E340
+6D8A E341
+6D8B E342
+6D8C E343
+6D8D E344
+6D8E E345
+6D8F E346
+6D90 E347
+6D91 E348
+6D92 E349
+6D93 E34A
+6D94 E34B
+6D95 E34C
+6D96 E34D
+6D97 E34E
+6D98 E34F
+6D99 E350
+6D9A E351
+6D9B E352
+6D9C E353
+6D9D E354
+6D9E E355
+6D9F E356
+6DA0 E357
+6DA1 E358
+6DA2 E359
+6DA3 E35A
+6DA4 E35B
+6DA5 E35C
+6DA6 E35D
+6DA7 E35E
+6DA8 E35F
+6DA9 E360
+6DAA E361
+6DAB E362
+6DAC E363
+6DAD E364
+6DAE E365
+6DAF E366
+6DB0 E367
+6DB1 E368
+6DB2 E369
+6DB3 E36A
+6DB4 E36B
+6DB5 E36C
+6DB6 E36D
+6DB7 E36E
+6DB8 E36F
+6DB9 E370
+6DBA E371
+6DBB E372
+6DBC E373
+6DBD E374
+6DBE E375
+6DBF E376
+6DC0 E377
+6DC1 E378
+6DC2 E379
+6DC3 E37A
+6DC4 E37B
+6DC5 E37C
+6DC6 E37D
+6DC7 E37E
+6DC8 E37F
+6DC9 E380
+6DCA E381
+6DCB E382
+6DCC E383
+6DCD E384
+6DCE E385
+6DCF E386
+6DD0 E387
+6DD1 E388
+6DD2 E389
+6DD3 E38A
+6DD4 E38B
+6DD5 E38C
+6DD6 E38D
+6DD7 E38E
+6DD8 E38F
+6DD9 E390
+6DDA E391
+6DDB E392
+6DDC E393
+6DDD E394
+6DDE E395
+6DDF E396
+6DE0 E397
+6DE1 E398
+6DE2 E399
+6DE3 E39A
+6DE4 E39B
+6DE5 E39C
+6DE6 E39D
+6DE7 E39E
+6DE8 E39F
+6DE9 E3A0
+6DEA E3A1
+6DEB E3A2
+6DEC E3A3
+6DED E3A4
+6DEE E3A5
+6DEF E3A6
+6DF0 E3A7
+6DF1 E3A8
+6DF2 E3A9
+6DF3 E3AA
+6DF4 E3AB
+6DF5 E3AC
+6DF6 E3AD
+6DF7 E3AE
+6DF8 E3AF
+6DF9 E3B0
+6DFA E3B1
+6DFB E3B2
+6DFC E3B3
+6DFD E3B4
+6DFE E3B5
+6E41 E3B6
+6E42 E3B7
+6E43 E3B8
+6E44 E3B9
+6E45 E3BA
+6E46 E3BB
+6E47 E3BC
+6E48 E3BD
+6E49 E3BE
+6E4A E3BF
+6E4B E3C0
+6E4C E3C1
+6E4D E3C2
+6E4E E3C3
+6E4F E3C4
+6E50 E3C5
+6E51 E3C6
+6E52 E3C7
+6E53 E3C8
+6E54 E3C9
+6E55 E3CA
+6E56 E3CB
+6E57 E3CC
+6E58 E3CD
+6E59 E3CE
+6E5A E3CF
+6E5B E3D0
+6E5C E3D1
+6E5D E3D2
+6E5E E3D3
+6E5F E3D4
+6E60 E3D5
+6E61 E3D6
+6E62 E3D7
+6E63 E3D8
+6E64 E3D9
+6E65 E3DA
+6E66 E3DB
+6E67 E3DC
+6E68 E3DD
+6E69 E3DE
+6E6A E3DF
+6E6B E3E0
+6E6C E3E1
+6E6D E3E2
+6E6E E3E3
+6E6F E3E4
+6E70 E3E5
+6E71 E3E6
+6E72 E3E7
+6E73 E3E8
+6E74 E3E9
+6E75 E3EA
+6E76 E3EB
+6E77 E3EC
+6E78 E3ED
+6E79 E3EE
+6E7A E3EF
+6E7B E3F0
+6E7C E3F1
+6E7D E3F2
+6E7E E3F3
+6E7F E3F4
+6E80 E3F5
+6E81 E3F6
+6E82 E3F7
+6E83 E3F8
+6E84 E3F9
+6E85 E3FA
+6E86 E3FB
+6E87 E3FC
+6E88 E3FD
+6E89 E3FE
+6E8A E3FF
+6E8B E400
+6E8C E401
+6E8D E402
+6E8E E403
+6E8F E404
+6E90 E405
+6E91 E406
+6E92 E407
+6E93 E408
+6E94 E409
+6E95 E40A
+6E96 E40B
+6E97 E40C
+6E98 E40D
+6E99 E40E
+6E9A E40F
+6E9B E410
+6E9C E411
+6E9D E412
+6E9E E413
+6E9F E414
+6EA0 E415
+6EA1 E416
+6EA2 E417
+6EA3 E418
+6EA4 E419
+6EA5 E41A
+6EA6 E41B
+6EA7 E41C
+6EA8 E41D
+6EA9 E41E
+6EAA E41F
+6EAB E420
+6EAC E421
+6EAD E422
+6EAE E423
+6EAF E424
+6EB0 E425
+6EB1 E426
+6EB2 E427
+6EB3 E428
+6EB4 E429
+6EB5 E42A
+6EB6 E42B
+6EB7 E42C
+6EB8 E42D
+6EB9 E42E
+6EBA E42F
+6EBB E430
+6EBC E431
+6EBD E432
+6EBE E433
+6EBF E434
+6EC0 E435
+6EC1 E436
+6EC2 E437
+6EC3 E438
+6EC4 E439
+6EC5 E43A
+6EC6 E43B
+6EC7 E43C
+6EC8 E43D
+6EC9 E43E
+6ECA E43F
+6ECB E440
+6ECC E441
+6ECD E442
+6ECE E443
+6ECF E444
+6ED0 E445
+6ED1 E446
+6ED2 E447
+6ED3 E448
+6ED4 E449
+6ED5 E44A
+6ED6 E44B
+6ED7 E44C
+6ED8 E44D
+6ED9 E44E
+6EDA E44F
+6EDB E450
+6EDC E451
+6EDD E452
+6EDE E453
+6EDF E454
+6EE0 E455
+6EE1 E456
+6EE2 E457
+6EE3 E458
+6EE4 E459
+6EE5 E45A
+6EE6 E45B
+6EE7 E45C
+6EE8 E45D
+6EE9 E45E
+6EEA E45F
+6EEB E460
+6EEC E461
+6EED E462
+6EEE E463
+6EEF E464
+6EF0 E465
+6EF1 E466
+6EF2 E467
+6EF3 E468
+6EF4 E469
+6EF5 E46A
+6EF6 E46B
+6EF7 E46C
+6EF8 E46D
+6EF9 E46E
+6EFA E46F
+6EFB E470
+6EFC E471
+6EFD E472
+6EFE E473
+6F41 E474
+6F42 E475
+6F43 E476
+6F44 E477
+6F45 E478
+6F46 E479
+6F47 E47A
+6F48 E47B
+6F49 E47C
+6F4A E47D
+6F4B E47E
+6F4C E47F
+6F4D E480
+6F4E E481
+6F4F E482
+6F50 E483
+6F51 E484
+6F52 E485
+6F53 E486
+6F54 E487
+6F55 E488
+6F56 E489
+6F57 E48A
+6F58 E48B
+6F59 E48C
+6F5A E48D
+6F5B E48E
+6F5C E48F
+6F5D E490
+6F5E E491
+6F5F E492
+6F60 E493
+6F61 E494
+6F62 E495
+6F63 E496
+6F64 E497
+6F65 E498
+6F66 E499
+6F67 E49A
+6F68 E49B
+6F69 E49C
+6F6A E49D
+6F6B E49E
+6F6C E49F
+6F6D E4A0
+6F6E E4A1
+6F6F E4A2
+6F70 E4A3
+6F71 E4A4
+6F72 E4A5
+6F73 E4A6
+6F74 E4A7
+6F75 E4A8
+6F76 E4A9
+6F77 E4AA
+6F78 E4AB
+6F79 E4AC
+6F7A E4AD
+6F7B E4AE
+6F7C E4AF
+6F7D E4B0
+6F7E E4B1
+6F7F E4B2
+6F80 E4B3
+6F81 E4B4
+6F82 E4B5
+6F83 E4B6
+6F84 E4B7
+6F85 E4B8
+6F86 E4B9
+6F87 E4BA
+6F88 E4BB
+6F89 E4BC
+6F8A E4BD
+6F8B E4BE
+6F8C E4BF
+6F8D E4C0
+6F8E E4C1
+6F8F E4C2
+6F90 E4C3
+6F91 E4C4
+6F92 E4C5
+6F93 E4C6
+6F94 E4C7
+6F95 E4C8
+6F96 E4C9
+6F97 E4CA
+6F98 E4CB
+6F99 E4CC
+6F9A E4CD
+6F9B E4CE
+6F9C E4CF
+6F9D E4D0
+6F9E E4D1
+6F9F E4D2
+6FA0 E4D3
+6FA1 E4D4
+6FA2 E4D5
+6FA3 E4D6
+6FA4 E4D7
+6FA5 E4D8
+6FA6 E4D9
+6FA7 E4DA
+6FA8 E4DB
+6FA9 E4DC
+6FAA E4DD
+6FAB E4DE
+6FAC E4DF
+6FAD E4E0
+6FAE E4E1
+6FAF E4E2
+6FB0 E4E3
+6FB1 E4E4
+6FB2 E4E5
+6FB3 E4E6
+6FB4 E4E7
+6FB5 E4E8
+6FB6 E4E9
+6FB7 E4EA
+6FB8 E4EB
+6FB9 E4EC
+6FBA E4ED
+6FBB E4EE
+6FBC E4EF
+6FBD E4F0
+6FBE E4F1
+6FBF E4F2
+6FC0 E4F3
+6FC1 E4F4
+6FC2 E4F5
+6FC3 E4F6
+6FC4 E4F7
+6FC5 E4F8
+6FC6 E4F9
+6FC7 E4FA
+6FC8 E4FB
+6FC9 E4FC
+6FCA E4FD
+6FCB E4FE
+6FCC E4FF
+6FCD E500
+6FCE E501
+6FCF E502
+6FD0 E503
+6FD1 E504
+6FD2 E505
+6FD3 E506
+6FD4 E507
+6FD5 E508
+6FD6 E509
+6FD7 E50A
+6FD8 E50B
+6FD9 E50C
+6FDA E50D
+6FDB E50E
+6FDC E50F
+6FDD E510
+6FDE E511
+6FDF E512
+6FE0 E513
+6FE1 E514
+6FE2 E515
+6FE3 E516
+6FE4 E517
+6FE5 E518
+6FE6 E519
+6FE7 E51A
+6FE8 E51B
+6FE9 E51C
+6FEA E51D
+6FEB E51E
+6FEC E51F
+6FED E520
+6FEE E521
+6FEF E522
+6FF0 E523
+6FF1 E524
+6FF2 E525
+6FF3 E526
+6FF4 E527
+6FF5 E528
+6FF6 E529
+6FF7 E52A
+6FF8 E52B
+6FF9 E52C
+6FFA E52D
+6FFB E52E
+6FFC E52F
+6FFD E530
+6FFE E531
+7041 E532
+7042 E533
+7043 E534
+7044 E535
+7045 E536
+7046 E537
+7047 E538
+7048 E539
+7049 E53A
+704A E53B
+704B E53C
+704C E53D
+704D E53E
+704E E53F
+704F E540
+7050 E541
+7051 E542
+7052 E543
+7053 E544
+7054 E545
+7055 E546
+7056 E547
+7057 E548
+7058 E549
+7059 E54A
+705A E54B
+705B E54C
+705C E54D
+705D E54E
+705E E54F
+705F E550
+7060 E551
+7061 E552
+7062 E553
+7063 E554
+7064 E555
+7065 E556
+7066 E557
+7067 E558
+7068 E559
+7069 E55A
+706A E55B
+706B E55C
+706C E55D
+706D E55E
+706E E55F
+706F E560
+7070 E561
+7071 E562
+7072 E563
+7073 E564
+7074 E565
+7075 E566
+7076 E567
+7077 E568
+7078 E569
+7079 E56A
+707A E56B
+707B E56C
+707C E56D
+707D E56E
+707E E56F
+707F E570
+7080 E571
+7081 E572
+7082 E573
+7083 E574
+7084 E575
+7085 E576
+7086 E577
+7087 E578
+7088 E579
+7089 E57A
+708A E57B
+708B E57C
+708C E57D
+708D E57E
+708E E57F
+708F E580
+7090 E581
+7091 E582
+7092 E583
+7093 E584
+7094 E585
+7095 E586
+7096 E587
+7097 E588
+7098 E589
+7099 E58A
+709A E58B
+709B E58C
+709C E58D
+709D E58E
+709E E58F
+709F E590
+70A0 E591
+70A1 E592
+70A2 E593
+70A3 E594
+70A4 E595
+70A5 E596
+70A6 E597
+70A7 E598
+70A8 E599
+70A9 E59A
+70AA E59B
+70AB E59C
+70AC E59D
+70AD E59E
+70AE E59F
+70AF E5A0
+70B0 E5A1
+70B1 E5A2
+70B2 E5A3
+70B3 E5A4
+70B4 E5A5
+70B5 E5A6
+70B6 E5A7
+70B7 E5A8
+70B8 E5A9
+70B9 E5AA
+70BA E5AB
+70BB E5AC
+70BC E5AD
+70BD E5AE
+70BE E5AF
+70BF E5B0
+70C0 E5B1
+70C1 E5B2
+70C2 E5B3
+70C3 E5B4
+70C4 E5B5
+70C5 E5B6
+70C6 E5B7
+70C7 E5B8
+70C8 E5B9
+70C9 E5BA
+70CA E5BB
+70CB E5BC
+70CC E5BD
+70CD E5BE
+70CE E5BF
+70CF E5C0
+70D0 E5C1
+70D1 E5C2
+70D2 E5C3
+70D3 E5C4
+70D4 E5C5
+70D5 E5C6
+70D6 E5C7
+70D7 E5C8
+70D8 E5C9
+70D9 E5CA
+70DA E5CB
+70DB E5CC
+70DC E5CD
+70DD E5CE
+70DE E5CF
+70DF E5D0
+70E0 E5D1
+70E1 E5D2
+70E2 E5D3
+70E3 E5D4
+70E4 E5D5
+70E5 E5D6
+70E6 E5D7
+70E7 E5D8
+70E8 E5D9
+70E9 E5DA
+70EA E5DB
+70EB E5DC
+70EC E5DD
+70ED E5DE
+70EE E5DF
+70EF E5E0
+70F0 E5E1
+70F1 E5E2
+70F2 E5E3
+70F3 E5E4
+70F4 E5E5
+70F5 E5E6
+70F6 E5E7
+70F7 E5E8
+70F8 E5E9
+70F9 E5EA
+70FA E5EB
+70FB E5EC
+70FC E5ED
+70FD E5EE
+70FE E5EF
+7141 E5F0
+7142 E5F1
+7143 E5F2
+7144 E5F3
+7145 E5F4
+7146 E5F5
+7147 E5F6
+7148 E5F7
+7149 E5F8
+714A E5F9
+714B E5FA
+714C E5FB
+714D E5FC
+714E E5FD
+714F E5FE
+7150 E5FF
+7151 E600
+7152 E601
+7153 E602
+7154 E603
+7155 E604
+7156 E605
+7157 E606
+7158 E607
+7159 E608
+715A E609
+715B E60A
+715C E60B
+715D E60C
+715E E60D
+715F E60E
+7160 E60F
+7161 E610
+7162 E611
+7163 E612
+7164 E613
+7165 E614
+7166 E615
+7167 E616
+7168 E617
+7169 E618
+716A E619
+716B E61A
+716C E61B
+716D E61C
+716E E61D
+716F E61E
+7170 E61F
+7171 E620
+7172 E621
+7173 E622
+7174 E623
+7175 E624
+7176 E625
+7177 E626
+7178 E627
+7179 E628
+717A E629
+717B E62A
+717C E62B
+717D E62C
+717E E62D
+717F E62E
+7180 E62F
+7181 E630
+7182 E631
+7183 E632
+7184 E633
+7185 E634
+7186 E635
+7187 E636
+7188 E637
+7189 E638
+718A E639
+718B E63A
+718C E63B
+718D E63C
+718E E63D
+718F E63E
+7190 E63F
+7191 E640
+7192 E641
+7193 E642
+7194 E643
+7195 E644
+7196 E645
+7197 E646
+7198 E647
+7199 E648
+719A E649
+719B E64A
+719C E64B
+719D E64C
+719E E64D
+719F E64E
+71A0 E64F
+71A1 E650
+71A2 E651
+71A3 E652
+71A4 E653
+71A5 E654
+71A6 E655
+71A7 E656
+71A8 E657
+71A9 E658
+71AA E659
+71AB E65A
+71AC E65B
+71AD E65C
+71AE E65D
+71AF E65E
+71B0 E65F
+71B1 E660
+71B2 E661
+71B3 E662
+71B4 E663
+71B5 E664
+71B6 E665
+71B7 E666
+71B8 E667
+71B9 E668
+71BA E669
+71BB E66A
+71BC E66B
+71BD E66C
+71BE E66D
+71BF E66E
+71C0 E66F
+71C1 E670
+71C2 E671
+71C3 E672
+71C4 E673
+71C5 E674
+71C6 E675
+71C7 E676
+71C8 E677
+71C9 E678
+71CA E679
+71CB E67A
+71CC E67B
+71CD E67C
+71CE E67D
+71CF E67E
+71D0 E67F
+71D1 E680
+71D2 E681
+71D3 E682
+71D4 E683
+71D5 E684
+71D6 E685
+71D7 E686
+71D8 E687
+71D9 E688
+71DA E689
+71DB E68A
+71DC E68B
+71DD E68C
+71DE E68D
+71DF E68E
+71E0 E68F
+71E1 E690
+71E2 E691
+71E3 E692
+71E4 E693
+71E5 E694
+71E6 E695
+71E7 E696
+71E8 E697
+71E9 E698
+71EA E699
+71EB E69A
+71EC E69B
+71ED E69C
+71EE E69D
+71EF E69E
+71F0 E69F
+71F1 E6A0
+71F2 E6A1
+71F3 E6A2
+71F4 E6A3
+71F5 E6A4
+71F6 E6A5
+71F7 E6A6
+71F8 E6A7
+71F9 E6A8
+71FA E6A9
+71FB E6AA
+71FC E6AB
+71FD E6AC
+71FE E6AD
+7241 E6AE
+7242 E6AF
+7243 E6B0
+7244 E6B1
+7245 E6B2
+7246 E6B3
+7247 E6B4
+7248 E6B5
+7249 E6B6
+724A E6B7
+724B E6B8
+724C E6B9
+724D E6BA
+724E E6BB
+724F E6BC
+7250 E6BD
+7251 E6BE
+7252 E6BF
+7253 E6C0
+7254 E6C1
+7255 E6C2
+7256 E6C3
+7257 E6C4
+7258 E6C5
+7259 E6C6
+725A E6C7
+725B E6C8
+725C E6C9
+725D E6CA
+725E E6CB
+725F E6CC
+7260 E6CD
+7261 E6CE
+7262 E6CF
+7263 E6D0
+7264 E6D1
+7265 E6D2
+7266 E6D3
+7267 E6D4
+7268 E6D5
+7269 E6D6
+726A E6D7
+726B E6D8
+726C E6D9
+726D E6DA
+726E E6DB
+726F E6DC
+7270 E6DD
+7271 E6DE
+7272 E6DF
+7273 E6E0
+7274 E6E1
+7275 E6E2
+7276 E6E3
+7277 E6E4
+7278 E6E5
+7279 E6E6
+727A E6E7
+727B E6E8
+727C E6E9
+727D E6EA
+727E E6EB
+727F E6EC
+7280 E6ED
+7281 E6EE
+7282 E6EF
+7283 E6F0
+7284 E6F1
+7285 E6F2
+7286 E6F3
+7287 E6F4
+7288 E6F5
+7289 E6F6
+728A E6F7
+728B E6F8
+728C E6F9
+728D E6FA
+728E E6FB
+728F E6FC
+7290 E6FD
+7291 E6FE
+7292 E6FF
+7293 E700
+7294 E701
+7295 E702
+7296 E703
+7297 E704
+7298 E705
+7299 E706
+729A E707
+729B E708
+729C E709
+729D E70A
+729E E70B
+729F E70C
+72A0 E70D
+72A1 E70E
+72A2 E70F
+72A3 E710
+72A4 E711
+72A5 E712
+72A6 E713
+72A7 E714
+72A8 E715
+72A9 E716
+72AA E717
+72AB E718
+72AC E719
+72AD E71A
+72AE E71B
+72AF E71C
+72B0 E71D
+72B1 E71E
+72B2 E71F
+72B3 E720
+72B4 E721
+72B5 E722
+72B6 E723
+72B7 E724
+72B8 E725
+72B9 E726
+72BA E727
+72BB E728
+72BC E729
+72BD E72A
+72BE E72B
+72BF E72C
+72C0 E72D
+72C1 E72E
+72C2 E72F
+72C3 E730
+72C4 E731
+72C5 E732
+72C6 E733
+72C7 E734
+72C8 E735
+72C9 E736
+72CA E737
+72CB E738
+72CC E739
+72CD E73A
+72CE E73B
+72CF E73C
+72D0 E73D
+72D1 E73E
+72D2 E73F
+72D3 E740
+72D4 E741
+72D5 E742
+72D6 E743
+72D7 E744
+72D8 E745
+72D9 E746
+72DA E747
+72DB E748
+72DC E749
+72DD E74A
+72DE E74B
+72DF E74C
+72E0 E74D
+72E1 E74E
+72E2 E74F
+72E3 E750
+72E4 E751
+72E5 E752
+72E6 E753
+72E7 E754
+72E8 E755
+72E9 E756
+72EA E757
+72EB E758
+72EC E759
+72ED E75A
+72EE E75B
+72EF E75C
+72F0 E75D
+72F1 E75E
+72F2 E75F
+72F3 E760
+72F4 E761
+72F5 E762
+72F6 E763
+72F7 E764
+72F8 E765
+72F9 E766
+72FA E767
+72FB E768
+72FC E769
+72FD E76A
+72FE E76B
+7341 E76C
+7342 E76D
+7343 E76E
+7344 E76F
+7345 E770
+7346 E771
+7347 E772
+7348 E773
+7349 E774
+734A E775
+734B E776
+734C E777
+734D E778
+734E E779
+734F E77A
+7350 E77B
+7351 E77C
+7352 E77D
+7353 E77E
+7354 E77F
+7355 E780
+7356 E781
+7357 E782
+7358 E783
+7359 E784
+735A E785
+735B E786
+735C E787
+735D E788
+735E E789
+735F E78A
+7360 E78B
+7361 E78C
+7362 E78D
+7363 E78E
+7364 E78F
+7365 E790
+7366 E791
+7367 E792
+7368 E793
+7369 E794
+736A E795
+736B E796
+736C E797
+736D E798
+736E E799
+736F E79A
+7370 E79B
+7371 E79C
+7372 E79D
+7373 E79E
+7374 E79F
+7375 E7A0
+7376 E7A1
+7377 E7A2
+7378 E7A3
+7379 E7A4
+737A E7A5
+737B E7A6
+737C E7A7
+737D E7A8
+737E E7A9
+737F E7AA
+7380 E7AB
+7381 E7AC
+7382 E7AD
+7383 E7AE
+7384 E7AF
+7385 E7B0
+7386 E7B1
+7387 E7B2
+7388 E7B3
+7389 E7B4
+738A E7B5
+738B E7B6
+738C E7B7
+738D E7B8
+738E E7B9
+738F E7BA
+7390 E7BB
+7391 E7BC
+7392 E7BD
+7393 E7BE
+7394 E7BF
+7395 E7C0
+7396 E7C1
+7397 E7C2
+7398 E7C3
+7399 E7C4
+739A E7C5
+739B E7C6
+739C E7C7
+739D E7C8
+739E E7C9
+739F E7CA
+73A0 E7CB
+73A1 E7CC
+73A2 E7CD
+73A3 E7CE
+73A4 E7CF
+73A5 E7D0
+73A6 E7D1
+73A7 E7D2
+73A8 E7D3
+73A9 E7D4
+73AA E7D5
+73AB E7D6
+73AC E7D7
+73AD E7D8
+73AE E7D9
+73AF E7DA
+73B0 E7DB
+73B1 E7DC
+73B2 E7DD
+73B3 E7DE
+73B4 E7DF
+73B5 E7E0
+73B6 E7E1
+73B7 E7E2
+73B8 E7E3
+73B9 E7E4
+73BA E7E5
+73BB E7E6
+73BC E7E7
+73BD E7E8
+73BE E7E9
+73BF E7EA
+73C0 E7EB
+73C1 E7EC
+73C2 E7ED
+73C3 E7EE
+73C4 E7EF
+73C5 E7F0
+73C6 E7F1
+73C7 E7F2
+73C8 E7F3
+73C9 E7F4
+73CA E7F5
+73CB E7F6
+73CC E7F7
+73CD E7F8
+73CE E7F9
+73CF E7FA
+73D0 E7FB
+73D1 E7FC
+73D2 E7FD
+73D3 E7FE
+73D4 E7FF
+73D5 E800
+73D6 E801
+73D7 E802
+73D8 E803
+73D9 E804
+73DA E805
+73DB E806
+73DC E807
+73DD E808
+73DE E809
+73DF E80A
+73E0 E80B
+73E1 E80C
+73E2 E80D
+73E3 E80E
+73E4 E80F
+73E5 E810
+73E6 E811
+73E7 E812
+73E8 E813
+73E9 E814
+73EA E815
+73EB E816
+73EC E817
+73ED E818
+73EE E819
+73EF E81A
+73F0 E81B
+73F1 E81C
+73F2 E81D
+73F3 E81E
+73F4 E81F
+73F5 E820
+73F6 E821
+73F7 E822
+73F8 E823
+73F9 E824
+73FA E825
+73FB E826
+73FC E827
+73FD E828
+73FE E829
+7441 E82A
+7442 E82B
+7443 E82C
+7444 E82D
+7445 E82E
+7446 E82F
+7447 E830
+7448 E831
+7449 E832
+744A E833
+744B E834
+744C E835
+744D E836
+744E E837
+744F E838
+7450 E839
+7451 E83A
+7452 E83B
+7453 E83C
+7454 E83D
+7455 E83E
+7456 E83F
+7457 E840
+7458 E841
+7459 E842
+745A E843
+745B E844
+745C E845
+745D E846
+745E E847
+745F E848
+7460 E849
+7461 E84A
+7462 E84B
+7463 E84C
+7464 E84D
+7465 E84E
+7466 E84F
+7467 E850
+7468 E851
+7469 E852
+746A E853
+746B E854
+746C E855
+746D E856
+746E E857
+746F E858
+7470 E859
+7471 E85A
+7472 E85B
+7473 E85C
+7474 E85D
+7475 E85E
+7476 E85F
+7477 E860
+7478 E861
+7479 E862
+747A E863
+747B E864
+747C E865
+747D E866
+747E E867
+747F E868
+7480 E869
+7481 E86A
+7482 E86B
+7483 E86C
+7484 E86D
+7485 E86E
+7486 E86F
+7487 E870
+7488 E871
+7489 E872
+748A E873
+748B E874
+748C E875
+748D E876
+748E E877
+748F E878
+7490 E879
+7491 E87A
+7492 E87B
+7493 E87C
+7494 E87D
+7495 E87E
+7496 E87F
+7497 E880
+7498 E881
+7499 E882
+749A E883
+749B E884
+749C E885
+749D E886
+749E E887
+749F E888
+74A0 E889
+74A1 E88A
+74A2 E88B
+74A3 E88C
+74A4 E88D
+74A5 E88E
+74A6 E88F
+74A7 E890
+74A8 E891
+74A9 E892
+74AA E893
+74AB E894
+74AC E895
+74AD E896
+74AE E897
+74AF E898
+74B0 E899
+74B1 E89A
+74B2 E89B
+74B3 E89C
+74B4 E89D
+74B5 E89E
+74B6 E89F
+74B7 E8A0
+74B8 E8A1
+74B9 E8A2
+74BA E8A3
+74BB E8A4
+74BC E8A5
+74BD E8A6
+74BE E8A7
+74BF E8A8
+74C0 E8A9
+74C1 E8AA
+74C2 E8AB
+74C3 E8AC
+74C4 E8AD
+74C5 E8AE
+74C6 E8AF
+74C7 E8B0
+74C8 E8B1
+74C9 E8B2
+74CA E8B3
+74CB E8B4
+74CC E8B5
+74CD E8B6
+74CE E8B7
+74CF E8B8
+74D0 E8B9
+74D1 E8BA
+74D2 E8BB
+74D3 E8BC
+74D4 E8BD
+74D5 E8BE
+74D6 E8BF
+74D7 E8C0
+74D8 E8C1
+74D9 E8C2
+74DA E8C3
+74DB E8C4
+74DC E8C5
+74DD E8C6
+74DE E8C7
+74DF E8C8
+74E0 E8C9
+74E1 E8CA
+74E2 E8CB
+74E3 E8CC
+74E4 E8CD
+74E5 E8CE
+74E6 E8CF
+74E7 E8D0
+74E8 E8D1
+74E9 E8D2
+74EA E8D3
+74EB E8D4
+74EC E8D5
+74ED E8D6
+74EE E8D7
+74EF E8D8
+74F0 E8D9
+74F1 E8DA
+74F2 E8DB
+74F3 E8DC
+74F4 E8DD
+74F5 E8DE
+74F6 E8DF
+74F7 E8E0
+74F8 E8E1
+74F9 E8E2
+74FA E8E3
+74FB E8E4
+74FC E8E5
+74FD E8E6
+74FE E8E7
+7541 E8E8
+7542 E8E9
+7543 E8EA
+7544 E8EB
+7545 E8EC
+7546 E8ED
+7547 E8EE
+7548 E8EF
+7549 E8F0
+754A E8F1
+754B E8F2
+754C E8F3
+754D E8F4
+754E E8F5
+754F E8F6
+7550 E8F7
+7551 E8F8
+7552 E8F9
+7553 E8FA
+7554 E8FB
+7555 E8FC
+7556 E8FD
+7557 E8FE
+7558 E8FF
+7559 E900
+755A E901
+755B E902
+755C E903
+755D E904
+755E E905
+755F E906
+7560 E907
+7561 E908
+7562 E909
+7563 E90A
+7564 E90B
+7565 E90C
+7566 E90D
+7567 E90E
+7568 E90F
+7569 E910
+756A E911
+756B E912
+756C E913
+756D E914
+756E E915
+756F E916
+7570 E917
+7571 E918
+7572 E919
+7573 E91A
+7574 E91B
+7575 E91C
+7576 E91D
+7577 E91E
+7578 E91F
+7579 E920
+757A E921
+757B E922
+757C E923
+757D E924
+757E E925
+757F E926
+7580 E927
+7581 E928
+7582 E929
+7583 E92A
+7584 E92B
+7585 E92C
+7586 E92D
+7587 E92E
+7588 E92F
+7589 E930
+758A E931
+758B E932
+758C E933
+758D E934
+758E E935
+758F E936
+7590 E937
+7591 E938
+7592 E939
+7593 E93A
+7594 E93B
+7595 E93C
+7596 E93D
+7597 E93E
+7598 E93F
+7599 E940
+759A E941
+759B E942
+759C E943
+759D E944
+759E E945
+759F E946
+75A0 E947
+75A1 E948
+75A2 E949
+75A3 E94A
+75A4 E94B
+75A5 E94C
+75A6 E94D
+75A7 E94E
+75A8 E94F
+75A9 E950
+75AA E951
+75AB E952
+75AC E953
+75AD E954
+75AE E955
+75AF E956
+75B0 E957
+75B1 E958
+75B2 E959
+75B3 E95A
+75B4 E95B
+75B5 E95C
+75B6 E95D
+75B7 E95E
+75B8 E95F
+75B9 E960
+75BA E961
+75BB E962
+75BC E963
+75BD E964
+75BE E965
+75BF E966
+75C0 E967
+75C1 E968
+75C2 E969
+75C3 E96A
+75C4 E96B
+75C5 E96C
+75C6 E96D
+75C7 E96E
+75C8 E96F
+75C9 E970
+75CA E971
+75CB E972
+75CC E973
+75CD E974
+75CE E975
+75CF E976
+75D0 E977
+75D1 E978
+75D2 E979
+75D3 E97A
+75D4 E97B
+75D5 E97C
+75D6 E97D
+75D7 E97E
+75D8 E97F
+75D9 E980
+75DA E981
+75DB E982
+75DC E983
+75DD E984
+75DE E985
+75DF E986
+75E0 E987
+75E1 E988
+75E2 E989
+75E3 E98A
+75E4 E98B
+75E5 E98C
+75E6 E98D
+75E7 E98E
+75E8 E98F
+75E9 E990
+75EA E991
+75EB E992
+75EC E993
+75ED E994
+75EE E995
+75EF E996
+75F0 E997
+75F1 E998
+75F2 E999
+75F3 E99A
+75F4 E99B
+75F5 E99C
+75F6 E99D
+75F7 E99E
+75F8 E99F
+75F9 E9A0
+75FA E9A1
+75FB E9A2
+75FC E9A3
+75FD E9A4
+75FE E9A5
+7641 E9A6
+7642 E9A7
+7643 E9A8
+7644 E9A9
+7645 E9AA
+7646 E9AB
+7647 E9AC
+7648 E9AD
+7649 E9AE
+764A E9AF
+764B E9B0
+764C E9B1
+764D E9B2
+764E E9B3
+764F E9B4
+7650 E9B5
+7651 E9B6
+7652 E9B7
+7653 E9B8
+7654 E9B9
+7655 E9BA
+7656 E9BB
+7657 E9BC
+7658 E9BD
+7659 E9BE
+765A E9BF
+765B E9C0
+765C E9C1
+765D E9C2
+765E E9C3
+765F E9C4
+7660 E9C5
+7661 E9C6
+7662 E9C7
+7663 E9C8
+7664 E9C9
+7665 E9CA
+7666 E9CB
+7667 E9CC
+7668 E9CD
+7669 E9CE
+766A E9CF
+766B E9D0
+766C E9D1
+766D E9D2
+766E E9D3
+766F E9D4
+7670 E9D5
+7671 E9D6
+7672 E9D7
+7673 E9D8
+7674 E9D9
+7675 E9DA
+7676 E9DB
+7677 E9DC
+7678 E9DD
+7679 E9DE
+767A E9DF
+767B E9E0
+767C E9E1
+767D E9E2
+767E E9E3
+767F E9E4
+7680 E9E5
+7681 E9E6
+7682 E9E7
+7683 E9E8
+7684 E9E9
+7685 E9EA
+7686 E9EB
+7687 E9EC
+7688 E9ED
+7689 E9EE
+768A E9EF
+768B E9F0
+768C E9F1
+768D E9F2
+768E E9F3
+768F E9F4
+7690 E9F5
+7691 E9F6
+7692 E9F7
+7693 E9F8
+7694 E9F9
+7695 E9FA
+7696 E9FB
+7697 E9FC
+7698 E9FD
+7699 E9FE
+769A E9FF
+769B EA00
+769C EA01
+769D EA02
+769E EA03
+769F EA04
+76A0 EA05
+76A1 EA06
+76A2 EA07
+76A3 EA08
+76A4 EA09
+76A5 EA0A
+76A6 EA0B
+76A7 EA0C
+76A8 EA0D
+76A9 EA0E
+76AA EA0F
+76AB EA10
+76AC EA11
+76AD EA12
+76AE EA13
+76AF EA14
+76B0 EA15
+76B1 EA16
+76B2 EA17
+76B3 EA18
+76B4 EA19
+76B5 EA1A
+76B6 EA1B
+76B7 EA1C
+76B8 EA1D
+76B9 EA1E
+76BA EA1F
+76BB EA20
+76BC EA21
+76BD EA22
+76BE EA23
+76BF EA24
+76C0 EA25
+76C1 EA26
+76C2 EA27
+76C3 EA28
+76C4 EA29
+76C5 EA2A
+76C6 EA2B
+76C7 EA2C
+76C8 EA2D
+76C9 EA2E
+76CA EA2F
+76CB EA30
+76CC EA31
+76CD EA32
+76CE EA33
+76CF EA34
+76D0 EA35
+76D1 EA36
+76D2 EA37
+76D3 EA38
+76D4 EA39
+76D5 EA3A
+76D6 EA3B
+76D7 EA3C
+76D8 EA3D
+76D9 EA3E
+76DA EA3F
+76DB EA40
+76DC EA41
+76DD EA42
+76DE EA43
+76DF EA44
+76E0 EA45
+76E1 EA46
+76E2 EA47
+76E3 EA48
+76E4 EA49
+76E5 EA4A
+76E6 EA4B
+76E7 EA4C
+76E8 EA4D
+76E9 EA4E
+76EA EA4F
+76EB EA50
+76EC EA51
+76ED EA52
+76EE EA53
+76EF EA54
+76F0 EA55
+76F1 EA56
+76F2 EA57
+76F3 EA58
+76F4 EA59
+76F5 EA5A
+76F6 EA5B
+76F7 EA5C
+76F8 EA5D
+76F9 EA5E
+76FA EA5F
+76FB EA60
+76FC EA61
+76FD EA62
+76FE EA63
+7741 EA64
+7742 EA65
+7743 EA66
+7744 EA67
+7745 EA68
+7746 EA69
+7747 EA6A
+7748 EA6B
+7749 EA6C
+774A EA6D
+774B EA6E
+774C EA6F
+774D EA70
+774E EA71
+774F EA72
+7750 EA73
+7751 EA74
+7752 EA75
+7753 EA76
+7754 EA77
+7755 EA78
+7756 EA79
+7757 EA7A
+7758 EA7B
+7759 EA7C
+775A EA7D
+775B EA7E
+775C EA7F
+775D EA80
+775E EA81
+775F EA82
+7760 EA83
+7761 EA84
+7762 EA85
+7763 EA86
+7764 EA87
+7765 EA88
+7766 EA89
+7767 EA8A
+7768 EA8B
+7769 EA8C
+776A EA8D
+776B EA8E
+776C EA8F
+776D EA90
+776E EA91
+776F EA92
+7770 EA93
+7771 EA94
+7772 EA95
+7773 EA96
+7774 EA97
+7775 EA98
+7776 EA99
+7777 EA9A
+7778 EA9B
+7779 EA9C
+777A EA9D
+777B EA9E
+777C EA9F
+777D EAA0
+777E EAA1
+777F EAA2
+7780 EAA3
+7781 EAA4
+7782 EAA5
+7783 EAA6
+7784 EAA7
+7785 EAA8
+7786 EAA9
+7787 EAAA
+7788 EAAB
+7789 EAAC
+778A EAAD
+778B EAAE
+778C EAAF
+778D EAB0
+778E EAB1
+778F EAB2
+7790 EAB3
+7791 EAB4
+7792 EAB5
+7793 EAB6
+7794 EAB7
+7795 EAB8
+7796 EAB9
+7797 EABA
+7798 EABB
+7799 EABC
+779A EABD
+779B EABE
+779C EABF
+779D EAC0
+779E EAC1
+779F EAC2
+77A0 EAC3
+77A1 EAC4
+77A2 EAC5
+77A3 EAC6
+77A4 EAC7
+77A5 EAC8
+77A6 EAC9
+77A7 EACA
+77A8 EACB
+77A9 EACC
+77AA EACD
+77AB EACE
+77AC EACF
+77AD EAD0
+77AE EAD1
+77AF EAD2
+77B0 EAD3
+77B1 EAD4
+77B2 EAD5
+77B3 EAD6
+77B4 EAD7
+77B5 EAD8
+77B6 EAD9
+77B7 EADA
+77B8 EADB
+77B9 EADC
+77BA EADD
+77BB EADE
+77BC EADF
+77BD EAE0
+77BE EAE1
+77BF EAE2
+77C0 EAE3
+77C1 EAE4
+77C2 EAE5
+77C3 EAE6
+77C4 EAE7
+77C5 EAE8
+77C6 EAE9
+77C7 EAEA
+77C8 EAEB
+77C9 EAEC
+77CA EAED
+77CB EAEE
+77CC EAEF
+77CD EAF0
+77CE EAF1
+77CF EAF2
+77D0 EAF3
+77D1 EAF4
+77D2 EAF5
+77D3 EAF6
+77D4 EAF7
+77D5 EAF8
+77D6 EAF9
+77D7 EAFA
+77D8 EAFB
+77D9 EAFC
+77DA EAFD
+77DB EAFE
+77DC EAFF
+77DD EB00
+77DE EB01
+77DF EB02
+77E0 EB03
+77E1 EB04
+77E2 EB05
+77E3 EB06
+77E4 EB07
+77E5 EB08
+77E6 EB09
+77E7 EB0A
+77E8 EB0B
+77E9 EB0C
+77EA EB0D
+77EB EB0E
+77EC EB0F
+77ED EB10
+77EE EB11
+77EF EB12
+77F0 EB13
+77F1 EB14
+77F2 EB15
+77F3 EB16
+77F4 EB17
+77F5 EB18
+77F6 EB19
+77F7 EB1A
+77F8 EB1B
+77F9 EB1C
+77FA EB1D
+77FB EB1E
+77FC EB1F
+77FD EB20
+77FE EB21
+7841 EB22
+7842 EB23
+7843 EB24
+7844 EB25
+7845 EB26
+7846 EB27
+7847 EB28
+7848 EB29
+7849 EB2A
+784A EB2B
+784B EB2C
+784C EB2D
+784D EB2E
+784E EB2F
+784F EB30
+7850 EB31
+7851 EB32
+7852 EB33
+7853 EB34
+7854 EB35
+7855 EB36
+7856 EB37
+7857 EB38
+7858 EB39
+7859 EB3A
+785A EB3B
+785B EB3C
+785C EB3D
+785D EB3E
+785E EB3F
+785F EB40
+7860 EB41
+7861 EB42
+7862 EB43
+7863 EB44
+7864 EB45
+7865 EB46
+7866 EB47
+7867 EB48
+7868 EB49
+7869 EB4A
+786A EB4B
+786B EB4C
+786C EB4D
+786D EB4E
+786E EB4F
+786F EB50
+7870 EB51
+7871 EB52
+7872 EB53
+7873 EB54
+7874 EB55
+7875 EB56
+7876 EB57
+7877 EB58
+7878 EB59
+7879 EB5A
+787A EB5B
+787B EB5C
+787C EB5D
+787D EB5E
+787E EB5F
+787F EB60
+7880 EB61
+7881 EB62
+7882 EB63
+7883 EB64
+7884 EB65
+7885 EB66
+7886 EB67
+7887 EB68
+7888 EB69
+7889 EB6A
+788A EB6B
+788B EB6C
+788C EB6D
+788D EB6E
+788E EB6F
+788F EB70
+7890 EB71
+7891 EB72
+7892 EB73
+7893 EB74
+7894 EB75
+7895 EB76
+7896 EB77
+7897 EB78
+7898 EB79
+7899 EB7A
+789A EB7B
+789B EB7C
+789C EB7D
+789D EB7E
+789E EB7F
+789F EB80
+78A0 EB81
+78A1 EB82
+78A2 EB83
+78A3 EB84
+78A4 EB85
+78A5 EB86
+78A6 EB87
+78A7 EB88
+78A8 EB89
+78A9 EB8A
+78AA EB8B
+78AB EB8C
+78AC EB8D
+78AD EB8E
+78AE EB8F
+78AF EB90
+78B0 EB91
+78B1 EB92
+78B2 EB93
+78B3 EB94
+78B4 EB95
+78B5 EB96
+78B6 EB97
+78B7 EB98
+78B8 EB99
+78B9 EB9A
+78BA EB9B
+78BB EB9C
+78BC EB9D
+78BD EB9E
+78BE EB9F
+78BF EBA0
+78C0 EBA1
+78C1 EBA2
+78C2 EBA3
+78C3 EBA4
+78C4 EBA5
+78C5 EBA6
+78C6 EBA7
+78C7 EBA8
+78C8 EBA9
+78C9 EBAA
+78CA EBAB
+78CB EBAC
+78CC EBAD
+78CD EBAE
+78CE EBAF
+78CF EBB0
+78D0 EBB1
+78D1 EBB2
+78D2 EBB3
+78D3 EBB4
+78D4 EBB5
+78D5 EBB6
+78D6 EBB7
+78D7 EBB8
+78D8 EBB9
+78D9 EBBA
+78DA EBBB
+78DB EBBC
+78DC EBBD
+78DD EBBE
+78DE EBBF
+78DF EBC0
+78E0 EBC1
+78E1 EBC2
+78E2 EBC3
+78E3 EBC4
+78E4 EBC5
+78E5 EBC6
+78E6 EBC7
+78E7 EBC8
+78E8 EBC9
+78E9 EBCA
+78EA EBCB
+78EB EBCC
+78EC EBCD
+78ED EBCE
+78EE EBCF
+78EF EBD0
+78F0 EBD1
+78F1 EBD2
+78F2 EBD3
+78F3 EBD4
+78F4 EBD5
+78F5 EBD6
+78F6 EBD7
+78F7 EBD8
+78F8 EBD9
+78F9 EBDA
+78FA EBDB
+78FB EBDC
+78FC EBDD
+78FD EBDE
+78FE EBDF
+7941 EBE0
+7942 EBE1
+7943 EBE2
+7944 EBE3
+7945 EBE4
+7946 EBE5
+7947 EBE6
+7948 EBE7
+7949 EBE8
+794A EBE9
+794B EBEA
+794C EBEB
+794D EBEC
+794E EBED
+794F EBEE
+7950 EBEF
+7951 EBF0
+7952 EBF1
+7953 EBF2
+7954 EBF3
+7955 EBF4
+7956 EBF5
+7957 EBF6
+7958 EBF7
+7959 EBF8
+795A EBF9
+795B EBFA
+795C EBFB
+795D EBFC
+795E EBFD
+795F EBFE
+7960 EBFF
+7961 EC00
+7962 EC01
+7963 EC02
+7964 EC03
+7965 EC04
+7966 EC05
+7967 EC06
+7968 EC07
+7969 EC08
+796A EC09
+796B EC0A
+796C EC0B
+796D EC0C
+796E EC0D
+796F EC0E
+7970 EC0F
+7971 EC10
+7972 EC11
+7973 EC12
+7974 EC13
+7975 EC14
+7976 EC15
+7977 EC16
+7978 EC17
+7979 EC18
+797A EC19
+797B EC1A
+797C EC1B
+797D EC1C
+797E EC1D
+797F EC1E
+7980 EC1F
+7981 EC20
+7982 EC21
+7983 EC22
+7984 EC23
+7985 EC24
+7986 EC25
+7987 EC26
+7988 EC27
+7989 EC28
+798A EC29
+798B EC2A
+798C EC2B
+798D EC2C
+798E EC2D
+798F EC2E
+7990 EC2F
+7991 EC30
+7992 EC31
+7993 EC32
+7994 EC33
+7995 EC34
+7996 EC35
+7997 EC36
+7998 EC37
+7999 EC38
+799A EC39
+799B EC3A
+799C EC3B
+799D EC3C
+799E EC3D
+799F EC3E
+79A0 EC3F
+79A1 EC40
+79A2 EC41
+79A3 EC42
+79A4 EC43
+79A5 EC44
+79A6 EC45
+79A7 EC46
+79A8 EC47
+79A9 EC48
+79AA EC49
+79AB EC4A
+79AC EC4B
+79AD EC4C
+79AE EC4D
+79AF EC4E
+79B0 EC4F
+79B1 EC50
+79B2 EC51
+79B3 EC52
+79B4 EC53
+79B5 EC54
+79B6 EC55
+79B7 EC56
+79B8 EC57
+79B9 EC58
+79BA EC59
+79BB EC5A
+79BC EC5B
+79BD EC5C
+79BE EC5D
+79BF EC5E
+79C0 EC5F
+79C1 EC60
+79C2 EC61
+79C3 EC62
+79C4 EC63
+79C5 EC64
+79C6 EC65
+79C7 EC66
+79C8 EC67
+79C9 EC68
+79CA EC69
+79CB EC6A
+79CC EC6B
+79CD EC6C
+79CE EC6D
+79CF EC6E
+79D0 EC6F
+79D1 EC70
+79D2 EC71
+79D3 EC72
+79D4 EC73
+79D5 EC74
+79D6 EC75
+79D7 EC76
+79D8 EC77
+79D9 EC78
+79DA EC79
+79DB EC7A
+79DC EC7B
+79DD EC7C
+79DE EC7D
+79DF EC7E
+79E0 EC7F
+79E1 EC80
+79E2 EC81
+79E3 EC82
+79E4 EC83
+79E5 EC84
+79E6 EC85
+79E7 EC86
+79E8 EC87
+79E9 EC88
+79EA EC89
+79EB EC8A
+79EC EC8B
+79ED EC8C
+79EE EC8D
+79EF EC8E
+79F0 EC8F
+79F1 EC90
+79F2 EC91
+79F3 EC92
+79F4 EC93
+79F5 EC94
+79F6 EC95
+79F7 EC96
+79F8 EC97
+79F9 EC98
+79FA EC99
+79FB EC9A
+79FC EC9B
+79FD EC9C
+79FE EC9D
+7A41 EC9E
+7A42 EC9F
+7A43 ECA0
+7A44 ECA1
+7A45 ECA2
+7A46 ECA3
+7A47 ECA4
+7A48 ECA5
+7A49 ECA6
+7A4A ECA7
+7A4B ECA8
+7A4C ECA9
+7A4D ECAA
+7A4E ECAB
+7A4F ECAC
+7A50 ECAD
+7A51 ECAE
+7A52 ECAF
+7A53 ECB0
+7A54 ECB1
+7A55 ECB2
+7A56 ECB3
+7A57 ECB4
+7A58 ECB5
+7A59 ECB6
+7A5A ECB7
+7A5B ECB8
+7A5C ECB9
+7A5D ECBA
+7A5E ECBB
+7A5F ECBC
+7A60 ECBD
+7A61 ECBE
+7A62 ECBF
+7A63 ECC0
+7A64 ECC1
+7A65 ECC2
+7A66 ECC3
+7A67 ECC4
+7A68 ECC5
+7A69 ECC6
+7A6A ECC7
+7A6B ECC8
+7A6C ECC9
+7A6D ECCA
+7A6E ECCB
+7A6F ECCC
+7A70 ECCD
+7A71 ECCE
+7A72 ECCF
+7A73 ECD0
+7A74 ECD1
+7A75 ECD2
+7A76 ECD3
+7A77 ECD4
+7A78 ECD5
+7A79 ECD6
+7A7A ECD7
+7A7B ECD8
+7A7C ECD9
+7A7D ECDA
+7A7E ECDB
+7A7F ECDC
+7A80 ECDD
+7A81 ECDE
+7A82 ECDF
+7A83 ECE0
+7A84 ECE1
+7A85 ECE2
+7A86 ECE3
+7A87 ECE4
+7A88 ECE5
+7A89 ECE6
+7A8A ECE7
+7A8B ECE8
+7A8C ECE9
+7A8D ECEA
+7A8E ECEB
+7A8F ECEC
+7A90 ECED
+7A91 ECEE
+7A92 ECEF
+7A93 ECF0
+7A94 ECF1
+7A95 ECF2
+7A96 ECF3
+7A97 ECF4
+7A98 ECF5
+7A99 ECF6
+7A9A ECF7
+7A9B ECF8
+7A9C ECF9
+7A9D ECFA
+7A9E ECFB
+7A9F ECFC
+7AA0 ECFD
+7AA1 ECFE
+7AA2 ECFF
+7AA3 ED00
+7AA4 ED01
+7AA5 ED02
+7AA6 ED03
+7AA7 ED04
+7AA8 ED05
+7AA9 ED06
+7AAA ED07
+7AAB ED08
+7AAC ED09
+7AAD ED0A
+7AAE ED0B
+7AAF ED0C
+7AB0 ED0D
+7AB1 ED0E
+7AB2 ED0F
+7AB3 ED10
+7AB4 ED11
+7AB5 ED12
+7AB6 ED13
+7AB7 ED14
+7AB8 ED15
+7AB9 ED16
+7ABA ED17
+7ABB ED18
+7ABC ED19
+7ABD ED1A
+7ABE ED1B
+7ABF ED1C
+7AC0 ED1D
+7AC1 ED1E
+7AC2 ED1F
+7AC3 ED20
+7AC4 ED21
+7AC5 ED22
+7AC6 ED23
+7AC7 ED24
+7AC8 ED25
+7AC9 ED26
+7ACA ED27
+7ACB ED28
+7ACC ED29
+7ACD ED2A
+7ACE ED2B
+7ACF ED2C
+7AD0 ED2D
+7AD1 ED2E
+7AD2 ED2F
+7AD3 ED30
+7AD4 ED31
+7AD5 ED32
+7AD6 ED33
+7AD7 ED34
+7AD8 ED35
+7AD9 ED36
+7ADA ED37
+7ADB ED38
+7ADC ED39
+7ADD ED3A
+7ADE ED3B
+7ADF ED3C
+7AE0 ED3D
+7AE1 ED3E
+7AE2 ED3F
+7AE3 ED40
+7AE4 ED41
+7AE5 ED42
+7AE6 ED43
+7AE7 ED44
+7AE8 ED45
+7AE9 ED46
+7AEA ED47
+7AEB ED48
+7AEC ED49
+7AED ED4A
+7AEE ED4B
+7AEF ED4C
+7AF0 ED4D
+7AF1 ED4E
+7AF2 ED4F
+7AF3 ED50
+7AF4 ED51
+7AF5 ED52
+7AF6 ED53
+7AF7 ED54
+7AF8 ED55
+7AF9 ED56
+7AFA ED57
+7AFB ED58
+7AFC ED59
+7AFD ED5A
+7AFE ED5B
+7B41 ED5C
+7B42 ED5D
+7B43 ED5E
+7B44 ED5F
+7B45 ED60
+7B46 ED61
+7B47 ED62
+7B48 ED63
+7B49 ED64
+7B4A ED65
+7B4B ED66
+7B4C ED67
+7B4D ED68
+7B4E ED69
+7B4F ED6A
+7B50 ED6B
+7B51 ED6C
+7B52 ED6D
+7B53 ED6E
+7B54 ED6F
+7B55 ED70
+7B56 ED71
+7B57 ED72
+7B58 ED73
+7B59 ED74
+7B5A ED75
+7B5B ED76
+7B5C ED77
+7B5D ED78
+7B5E ED79
+7B5F ED7A
+7B60 ED7B
+7B61 ED7C
+7B62 ED7D
+7B63 ED7E
+7B64 ED7F
+7B65 ED80
+7B66 ED81
+7B67 ED82
+7B68 ED83
+7B69 ED84
+7B6A ED85
+7B6B ED86
+7B6C ED87
+7B6D ED88
+7B6E ED89
+7B6F ED8A
+7B70 ED8B
+7B71 ED8C
+7B72 ED8D
+7B73 ED8E
+7B74 ED8F
+7B75 ED90
+7B76 ED91
+7B77 ED92
+7B78 ED93
+7B79 ED94
+7B7A ED95
+7B7B ED96
+7B7C ED97
+7B7D ED98
+7B7E ED99
+7B7F ED9A
+7B80 ED9B
+7B81 ED9C
+7B82 ED9D
+7B83 ED9E
+7B84 ED9F
+7B85 EDA0
+7B86 EDA1
+7B87 EDA2
+7B88 EDA3
+7B89 EDA4
+7B8A EDA5
+7B8B EDA6
+7B8C EDA7
+7B8D EDA8
+7B8E EDA9
+7B8F EDAA
+7B90 EDAB
+7B91 EDAC
+7B92 EDAD
+7B93 EDAE
+7B94 EDAF
+7B95 EDB0
+7B96 EDB1
+7B97 EDB2
+7B98 EDB3
+7B99 EDB4
+7B9A EDB5
+7B9B EDB6
+7B9C EDB7
+7B9D EDB8
+7B9E EDB9
+7B9F EDBA
+7BA0 EDBB
+7BA1 EDBC
+7BA2 EDBD
+7BA3 EDBE
+7BA4 EDBF
+7BA5 EDC0
+7BA6 EDC1
+7BA7 EDC2
+7BA8 EDC3
+7BA9 EDC4
+7BAA EDC5
+7BAB EDC6
+7BAC EDC7
+7BAD EDC8
+7BAE EDC9
+7BAF EDCA
+7BB0 EDCB
+7BB1 EDCC
+7BB2 EDCD
+7BB3 EDCE
+7BB4 EDCF
+7BB5 EDD0
+7BB6 EDD1
+7BB7 EDD2
+7BB8 EDD3
+7BB9 EDD4
+7BBA EDD5
+7BBB EDD6
+7BBC EDD7
+7BBD EDD8
+7BBE EDD9
+7BBF EDDA
+7BC0 EDDB
+7BC1 EDDC
+7BC2 EDDD
+7BC3 EDDE
+7BC4 EDDF
+7BC5 EDE0
+7BC6 EDE1
+7BC7 EDE2
+7BC8 EDE3
+7BC9 EDE4
+7BCA EDE5
+7BCB EDE6
+7BCC EDE7
+7BCD EDE8
+7BCE EDE9
+7BCF EDEA
+7BD0 EDEB
+7BD1 EDEC
+7BD2 EDED
+7BD3 EDEE
+7BD4 EDEF
+7BD5 EDF0
+7BD6 EDF1
+7BD7 EDF2
+7BD8 EDF3
+7BD9 EDF4
+7BDA EDF5
+7BDB EDF6
+7BDC EDF7
+7BDD EDF8
+7BDE EDF9
+7BDF EDFA
+7BE0 EDFB
+7BE1 EDFC
+7BE2 EDFD
+7BE3 EDFE
+7BE4 EDFF
+7BE5 EE00
+7BE6 EE01
+7BE7 EE02
+7BE8 EE03
+7BE9 EE04
+7BEA EE05
+7BEB EE06
+7BEC EE07
+7BED EE08
+7BEE EE09
+7BEF EE0A
+7BF0 EE0B
+7BF1 EE0C
+7BF2 EE0D
+7BF3 EE0E
+7BF4 EE0F
+7BF5 EE10
+7BF6 EE11
+7BF7 EE12
+7BF8 EE13
+7BF9 EE14
+7BFA EE15
+7BFB EE16
+7BFC EE17
+7BFD EE18
+7BFE EE19
+7C41 EE1A
+7C42 EE1B
+7C43 EE1C
+7C44 EE1D
+7C45 EE1E
+7C46 EE1F
+7C47 EE20
+7C48 EE21
+7C49 EE22
+7C4A EE23
+7C4B EE24
+7C4C EE25
+7C4D EE26
+7C4E EE27
+7C4F EE28
+7C50 EE29
+7C51 EE2A
+7C52 EE2B
+7C53 EE2C
+7C54 EE2D
+7C55 EE2E
+7C56 EE2F
+7C57 EE30
+7C58 EE31
+7C59 EE32
+7C5A EE33
+7C5B EE34
+7C5C EE35
+7C5D EE36
+7C5E EE37
+7C5F EE38
+7C60 EE39
+7C61 EE3A
+7C62 EE3B
+7C63 EE3C
+7C64 EE3D
+7C65 EE3E
+7C66 EE3F
+7C67 EE40
+7C68 EE41
+7C69 EE42
+7C6A EE43
+7C6B EE44
+7C6C EE45
+7C6D EE46
+7C6E EE47
+7C6F EE48
+7C70 EE49
+7C71 EE4A
+7C72 EE4B
+7C73 EE4C
+7C74 EE4D
+7C75 EE4E
+7C76 EE4F
+7C77 EE50
+7C78 EE51
+7C79 EE52
+7C7A EE53
+7C7B EE54
+7C7C EE55
+7C7D EE56
+7C7E EE57
+7C7F EE58
+7C80 EE59
+7C81 EE5A
+7C82 EE5B
+7C83 EE5C
+7C84 EE5D
+7C85 EE5E
+7C86 EE5F
+7C87 EE60
+7C88 EE61
+7C89 EE62
+7C8A EE63
+7C8B EE64
+7C8C EE65
+7C8D EE66
+7C8E EE67
+7C8F EE68
+7C90 EE69
+7C91 EE6A
+7C92 EE6B
+7C93 EE6C
+7C94 EE6D
+7C95 EE6E
+7C96 EE6F
+7C97 EE70
+7C98 EE71
+7C99 EE72
+7C9A EE73
+7C9B EE74
+7C9C EE75
+7C9D EE76
+7C9E EE77
+7C9F EE78
+7CA0 EE79
+7CA1 EE7A
+7CA2 EE7B
+7CA3 EE7C
+7CA4 EE7D
+7CA5 EE7E
+7CA6 EE7F
+7CA7 EE80
+7CA8 EE81
+7CA9 EE82
+7CAA EE83
+7CAB EE84
+7CAC EE85
+7CAD EE86
+7CAE EE87
+7CAF EE88
+7CB0 EE89
+7CB1 EE8A
+7CB2 EE8B
+7CB3 EE8C
+7CB4 EE8D
+7CB5 EE8E
+7CB6 EE8F
+7CB7 EE90
+7CB8 EE91
+7CB9 EE92
+7CBA EE93
+7CBB EE94
+7CBC EE95
+7CBD EE96
+7CBE EE97
+7CBF EE98
+7CC0 EE99
+7CC1 EE9A
+7CC2 EE9B
+7CC3 EE9C
+7CC4 EE9D
+7CC5 EE9E
+7CC6 EE9F
+7CC7 EEA0
+7CC8 EEA1
+7CC9 EEA2
+7CCA EEA3
+7CCB EEA4
+7CCC EEA5
+7CCD EEA6
+7CCE EEA7
+7CCF EEA8
+7CD0 EEA9
+7CD1 EEAA
+7CD2 EEAB
+7CD3 EEAC
+7CD4 EEAD
+7CD5 EEAE
+7CD6 EEAF
+7CD7 EEB0
+7CD8 EEB1
+7CD9 EEB2
+7CDA EEB3
+7CDB EEB4
+7CDC EEB5
+7CDD EEB6
+7CDE EEB7
+7CDF EEB8
+7CE0 EEB9
+7CE1 EEBA
+7CE2 EEBB
+7CE3 EEBC
+7CE4 EEBD
+7CE5 EEBE
+7CE6 EEBF
+7CE7 EEC0
+7CE8 EEC1
+7CE9 EEC2
+7CEA EEC3
+7CEB EEC4
+7CEC EEC5
+7CED EEC6
+7CEE EEC7
+7CEF EEC8
+7CF0 EEC9
+7CF1 EECA
+7CF2 EECB
+7CF3 EECC
+7CF4 EECD
+7CF5 EECE
+7CF6 EECF
+7CF7 EED0
+7CF8 EED1
+7CF9 EED2
+7CFA EED3
+7CFB EED4
+7CFC EED5
+7CFD EED6
+7CFE EED7
+7D41 EED8
+7D42 EED9
+7D43 EEDA
+7D44 EEDB
+7D45 EEDC
+7D46 EEDD
+7D47 EEDE
+7D48 EEDF
+7D49 EEE0
+7D4A EEE1
+7D4B EEE2
+7D4C EEE3
+7D4D EEE4
+7D4E EEE5
+7D4F EEE6
+7D50 EEE7
+7D51 EEE8
+7D52 EEE9
+7D53 EEEA
+7D54 EEEB
+7D55 EEEC
+7D56 EEED
+7D57 EEEE
+7D58 EEEF
+7D59 EEF0
+7D5A EEF1
+7D5B EEF2
+7D5C EEF3
+7D5D EEF4
+7D5E EEF5
+7D5F EEF6
+7D60 EEF7
+7D61 EEF8
+7D62 EEF9
+7D63 EEFA
+7D64 EEFB
+7D65 EEFC
+7D66 EEFD
+7D67 EEFE
+7D68 EEFF
+7D69 EF00
+7D6A EF01
+7D6B EF02
+7D6C EF03
+7D6D EF04
+7D6E EF05
+7D6F EF06
+7D70 EF07
+7D71 EF08
+7D72 EF09
+7D73 EF0A
+7D74 EF0B
+7D75 EF0C
+7D76 EF0D
+7D77 EF0E
+7D78 EF0F
+7D79 EF10
+7D7A EF11
+7D7B EF12
+7D7C EF13
+7D7D EF14
+7D7E EF15
+7D7F EF16
+7D80 EF17
+7D81 EF18
+7D82 EF19
+7D83 EF1A
+7D84 EF1B
+7D85 EF1C
+7D86 EF1D
+7D87 EF1E
+7D88 EF1F
+7D89 EF20
+7D8A EF21
+7D8B EF22
+7D8C EF23
+7D8D EF24
+7D8E EF25
+7D8F EF26
+7D90 EF27
+7D91 EF28
+7D92 EF29
+7D93 EF2A
+7D94 EF2B
+7D95 EF2C
+7D96 EF2D
+7D97 EF2E
+7D98 EF2F
+7D99 EF30
+7D9A EF31
+7D9B EF32
+7D9C EF33
+7D9D EF34
+7D9E EF35
+7D9F EF36
+7DA0 EF37
+7DA1 EF38
+7DA2 EF39
+7DA3 EF3A
+7DA4 EF3B
+7DA5 EF3C
+7DA6 EF3D
+7DA7 EF3E
+7DA8 EF3F
+7DA9 EF40
+7DAA EF41
+7DAB EF42
+7DAC EF43
+7DAD EF44
+7DAE EF45
+7DAF EF46
+7DB0 EF47
+7DB1 EF48
+7DB2 EF49
+7DB3 EF4A
+7DB4 EF4B
+7DB5 EF4C
+7DB6 EF4D
+7DB7 EF4E
+7DB8 EF4F
+7DB9 EF50
+7DBA EF51
+7DBB EF52
+7DBC EF53
+7DBD EF54
+7DBE EF55
+7DBF EF56
+7DC0 EF57
+7DC1 EF58
+7DC2 EF59
+7DC3 EF5A
+7DC4 EF5B
+7DC5 EF5C
+7DC6 EF5D
+7DC7 EF5E
+7DC8 EF5F
+7DC9 EF60
+7DCA EF61
+7DCB EF62
+7DCC EF63
+7DCD EF64
+7DCE EF65
+7DCF EF66
+7DD0 EF67
+7DD1 EF68
+7DD2 EF69
+7DD3 EF6A
+7DD4 EF6B
+7DD5 EF6C
+7DD6 EF6D
+7DD7 EF6E
+7DD8 EF6F
+7DD9 EF70
+7DDA EF71
+7DDB EF72
+7DDC EF73
+7DDD EF74
+7DDE EF75
+7DDF EF76
+7DE0 EF77
+7DE1 EF78
+7DE2 EF79
+7DE3 EF7A
+7DE4 EF7B
+7DE5 EF7C
+7DE6 EF7D
+7DE7 EF7E
+7DE8 EF7F
+7DE9 EF80
+7DEA EF81
+7DEB EF82
+7DEC EF83
+7DED EF84
+7DEE EF85
+7DEF EF86
+7DF0 EF87
+7DF1 EF88
+7DF2 EF89
+7DF3 EF8A
+7DF4 EF8B
+7DF5 EF8C
+7DF6 EF8D
+7DF7 EF8E
+7DF8 EF8F
+7DF9 EF90
+7DFA EF91
+7DFB EF92
+7DFC EF93
+7DFD EF94
+7DFE EF95
+7E41 EF96
+7E42 EF97
+7E43 EF98
+7E44 EF99
+7E45 EF9A
+7E46 EF9B
+7E47 EF9C
+7E48 EF9D
+7E49 EF9E
+7E4A EF9F
+7E4B EFA0
+7E4C EFA1
+7E4D EFA2
+7E4E EFA3
+7E4F EFA4
+7E50 EFA5
+7E51 EFA6
+7E52 EFA7
+7E53 EFA8
+7E54 EFA9
+7E55 EFAA
+7E56 EFAB
+7E57 EFAC
+7E58 EFAD
+7E59 EFAE
+7E5A EFAF
+7E5B EFB0
+7E5C EFB1
+7E5D EFB2
+7E5E EFB3
+7E5F EFB4
+7E60 EFB5
+7E61 EFB6
+7E62 EFB7
+7E63 EFB8
+7E64 EFB9
+7E65 EFBA
+7E66 EFBB
+7E67 EFBC
+7E68 EFBD
+7E69 EFBE
+7E6A EFBF
+7E6B EFC0
+7E6C EFC1
+7E6D EFC2
+7E6E EFC3
+7E6F EFC4
+7E70 EFC5
+7E71 EFC6
+7E72 EFC7
+7E73 EFC8
+7E74 EFC9
+7E75 EFCA
+7E76 EFCB
+7E77 EFCC
+7E78 EFCD
+7E79 EFCE
+7E7A EFCF
+7E7B EFD0
+7E7C EFD1
+7E7D EFD2
+7E7E EFD3
+7E7F EFD4
+7E80 EFD5
+7E81 EFD6
+7E82 EFD7
+7E83 EFD8
+7E84 EFD9
+7E85 EFDA
+7E86 EFDB
+7E87 EFDC
+7E88 EFDD
+7E89 EFDE
+7E8A EFDF
+7E8B EFE0
+7E8C EFE1
+7E8D EFE2
+7E8E EFE3
+7E8F EFE4
+7E90 EFE5
+7E91 EFE6
+7E92 EFE7
+7E93 EFE8
+7E94 EFE9
+7E95 EFEA
+7E96 EFEB
+7E97 EFEC
+7E98 EFED
+7E99 EFEE
+7E9A EFEF
+7E9B EFF0
+7E9C EFF1
+7E9D EFF2
+7E9E EFF3
+7E9F EFF4
+7EA0 EFF5
+7EA1 EFF6
+7EA2 EFF7
+7EA3 EFF8
+7EA4 EFF9
+7EA5 EFFA
+7EA6 EFFB
+7EA7 EFFC
+7EA8 EFFD
+7EA9 EFFE
+7EAA EFFF
+7EAB F000
+7EAC F001
+7EAD F002
+7EAE F003
+7EAF F004
+7EB0 F005
+7EB1 F006
+7EB2 F007
+7EB3 F008
+7EB4 F009
+7EB5 F00A
+7EB6 F00B
+7EB7 F00C
+7EB8 F00D
+7EB9 F00E
+7EBA F00F
+7EBB F010
+7EBC F011
+7EBD F012
+7EBE F013
+7EBF F014
+7EC0 F015
+7EC1 F016
+7EC2 F017
+7EC3 F018
+7EC4 F019
+7EC5 F01A
+7EC6 F01B
+7EC7 F01C
+7EC8 F01D
+7EC9 F01E
+7ECA F01F
+7ECB F020
+7ECC F021
+7ECD F022
+7ECE F023
+7ECF F024
+7ED0 F025
+7ED1 F026
+7ED2 F027
+7ED3 F028
+7ED4 F029
+7ED5 F02A
+7ED6 F02B
+7ED7 F02C
+7ED8 F02D
+7ED9 F02E
+7EDA F02F
+7EDB F030
+7EDC F031
+7EDD F032
+7EDE F033
+7EDF F034
+7EE0 F035
+7EE1 F036
+7EE2 F037
+7EE3 F038
+7EE4 F039
+7EE5 F03A
+7EE6 F03B
+7EE7 F03C
+7EE8 F03D
+7EE9 F03E
+7EEA F03F
+7EEB F040
+7EEC F041
+7EED F042
+7EEE F043
+7EEF F044
+7EF0 F045
+7EF1 F046
+7EF2 F047
+7EF3 F048
+7EF4 F049
+7EF5 F04A
+7EF6 F04B
+7EF7 F04C
+7EF8 F04D
+7EF9 F04E
+7EFA F04F
+7EFB F050
+7EFC F051
+7EFD F052
+7EFE F053
+7F41 F054
+7F42 F055
+7F43 F056
+7F44 F057
+7F45 F058
+7F46 F059
+7F47 F05A
+7F48 F05B
+7F49 F05C
+7F4A F05D
+7F4B F05E
+7F4C F05F
+7F4D F060
+7F4E F061
+7F4F F062
+7F50 F063
+7F51 F064
+7F52 F065
+7F53 F066
+7F54 F067
+7F55 F068
+7F56 F069
+7F57 F06A
+7F58 F06B
+7F59 F06C
+7F5A F06D
+7F5B F06E
+7F5C F06F
+7F5D F070
+7F5E F071
+7F5F F072
+7F60 F073
+7F61 F074
+7F62 F075
+7F63 F076
+7F64 F077
+7F65 F078
+7F66 F079
+7F67 F07A
+7F68 F07B
+7F69 F07C
+7F6A F07D
+7F6B F07E
+7F6C F07F
+7F6D F080
+7F6E F081
+7F6F F082
+7F70 F083
+7F71 F084
+7F72 F085
+7F73 F086
+7F74 F087
+7F75 F088
+7F76 F089
+7F77 F08A
+7F78 F08B
+7F79 F08C
+7F7A F08D
+7F7B F08E
+7F7C F08F
+7F7D F090
+7F7E F091
+7F7F F092
+7F80 F093
+7F81 F094
+7F82 F095
+7F83 F096
+7F84 F097
+7F85 F098
+7F86 F099
+7F87 F09A
+7F88 F09B
+7F89 F09C
+7F8A F09D
+7F8B F09E
+7F8C F09F
+7F8D F0A0
+7F8E F0A1
+7F8F F0A2
+7F90 F0A3
+7F91 F0A4
+7F92 F0A5
+7F93 F0A6
+7F94 F0A7
+7F95 F0A8
+7F96 F0A9
+7F97 F0AA
+7F98 F0AB
+7F99 F0AC
+7F9A F0AD
+7F9B F0AE
+7F9C F0AF
+7F9D F0B0
+7F9E F0B1
+7F9F F0B2
+7FA0 F0B3
+7FA1 F0B4
+7FA2 F0B5
+7FA3 F0B6
+7FA4 F0B7
+7FA5 F0B8
+7FA6 F0B9
+7FA7 F0BA
+7FA8 F0BB
+7FA9 F0BC
+7FAA F0BD
+7FAB F0BE
+7FAC F0BF
+7FAD F0C0
+7FAE F0C1
+7FAF F0C2
+7FB0 F0C3
+7FB1 F0C4
+7FB2 F0C5
+7FB3 F0C6
+7FB4 F0C7
+7FB5 F0C8
+7FB6 F0C9
+7FB7 F0CA
+7FB8 F0CB
+7FB9 F0CC
+7FBA F0CD
+7FBB F0CE
+7FBC F0CF
+7FBD F0D0
+7FBE F0D1
+7FBF F0D2
+7FC0 F0D3
+7FC1 F0D4
+7FC2 F0D5
+7FC3 F0D6
+7FC4 F0D7
+7FC5 F0D8
+7FC6 F0D9
+7FC7 F0DA
+7FC8 F0DB
+7FC9 F0DC
+7FCA F0DD
+7FCB F0DE
+7FCC F0DF
+7FCD F0E0
+7FCE F0E1
+7FCF F0E2
+7FD0 F0E3
+7FD1 F0E4
+7FD2 F0E5
+7FD3 F0E6
+7FD4 F0E7
+7FD5 F0E8
+7FD6 F0E9
+7FD7 F0EA
+7FD8 F0EB
+7FD9 F0EC
+7FDA F0ED
+7FDB F0EE
+7FDC F0EF
+7FDD F0F0
+7FDE F0F1
+7FDF F0F2
+7FE0 F0F3
+7FE1 F0F4
+7FE2 F0F5
+7FE3 F0F6
+7FE4 F0F7
+7FE5 F0F8
+7FE6 F0F9
+7FE7 F0FA
+7FE8 F0FB
+7FE9 F0FC
+7FEA F0FD
+7FEB F0FE
+7FEC F0FF
+7FED F100
+7FEE F101
+7FEF F102
+7FF0 F103
+7FF1 F104
+7FF2 F105
+7FF3 F106
+7FF4 F107
+7FF5 F108
+7FF6 F109
+7FF7 F10A
+7FF8 F10B
+7FF9 F10C
+7FFA F10D
+7FFB F10E
+7FFC F10F
+7FFD F110
+7FFE F111
--- a/jdk/make/tools/CharsetMapping/dbcs Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/tools/CharsetMapping/dbcs Wed Jul 05 19:09:26 2017 +0200
@@ -15,6 +15,7 @@
IBM1364 x-IBM1364 Cp1364 ebcdic sun.nio.cs.ext false 0x40 0xde 0x40 0xfe
IBM1381 x-IBM1381 Cp1381 basic sun.nio.cs.ext true 0x8c 0xf7 0xa1 0xfe
IBM1383 x-IBM1383 Cp1383 euc_sim sun.nio.cs.ext true 0xa1 0xfe 0xa1 0xfe
+IBM300 x-IBM300 Cp300 dbcsonly sun.nio.cs.ext false 0x40 0x7f 0x40 0xfe
IBM930 x-IBM930 Cp930 ebcdic sun.nio.cs.ext false 0x40 0x7f 0x40 0xfe
IBM933 x-IBM933 Cp933 ebcdic sun.nio.cs.ext false 0x40 0xdd 0x40 0xfe
IBM935 x-IBM935 Cp935 ebcdic sun.nio.cs.ext false 0x40 0x7f 0x40 0xfe
--- a/jdk/make/tools/CharsetMapping/extsbcs Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/tools/CharsetMapping/extsbcs Wed Jul 05 19:09:26 2017 +0200
@@ -28,6 +28,7 @@
IBM280 IBM280 Cp280 false sun.nio.cs.ext
IBM284 IBM284 Cp284 false sun.nio.cs.ext
IBM285 IBM285 Cp285 false sun.nio.cs.ext
+IBM290 IBM290 Cp290 false sun.nio.cs.ext
IBM297 IBM297 Cp297 false sun.nio.cs.ext
IBM420 IBM420 Cp420 false sun.nio.cs.ext
IBM424 IBM424 Cp424 false sun.nio.cs.ext
--- a/jdk/make/tools/sharing/README.txt Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/tools/sharing/README.txt Wed Jul 05 19:09:26 2017 +0200
@@ -2,20 +2,20 @@
class list for class data sharing.
The class list is produced by running the refWorkload startup3 benchmark with
-the -verbose:class option. The -Xshare:off option must also be used so that
-bootclasspath classes are loaded from rt.jar. The MakeClasslist program
-should be built into the jar file makeclasslist.jar and is run
+the -XX:+TraceClassLoadingPreorder option. The -Xshare:off option must also be
+used so that bootclasspath classes are loaded from rt.jar. The MakeClasslist
+program should be built into the jar file makeclasslist.jar and is run
on one of the logs from each of the benchmarks in the following fashion:
-cd .../results.startup3
-$JAVA_HOME/bin/java -jar makeclasslist.jar results.Noop/results_1/log results.Framer/results_1/log results.XFramer/results_1/log results.JEdit/results_1/log results.LimeWire/results_1/log results.NetBeans/results_1/log
+cd .../<resultsdir>/results.startup3
+$JAVA_HOME/bin/java -jar makeclasslist.jar results.Noop/results_1/log results.Framer/results_1/log results.XFramer/results_1/log results.JEdit/results_1/log results.LimeWire/results_1/log results.NetBeans50/results_1/log
Presently, $JAVA_HOME must be the same path used to run the startup3 benchmark.
-The logs are deliberately concatenated in roughly smallest to largest
-order based on application size. The resulting output is redirected
-into a file and results in one of classlist.solaris, classlist.linux,
-or classlist.windows. These files are checked in to the workspace. A
+The logs are deliberately concatenated in roughly smallest to largest order
+based on application size. The resulting output is redirected into a file
+and results in one of classlist.solaris, classlist.linux, classlist.macosx,
+or classlist.windows. These files are checked in to the workspace. A
necessary checksum (AddJsum.java) is added to the final classlist
(installed in lib/ or jre/lib/) during the build process by the
makefiles in make/java/redist.
@@ -27,8 +27,8 @@
The properties file supplied to the refworkload is approximately the
following:
-javahome=/usr/java/j2sdk1.5.0
+javahome=/usr/java/j2sdk1.8.0
resultsdir=classlist-run
iterations=1
benchmarks=startup3
-globalvmoptions=-client -Xshare:off -verbose:class
+globalvmoptions=-client -Xshare:off -XX:+TraceClassLoadingPreorder
--- a/jdk/make/tools/src/build/tools/charsetmapping/DBCS.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/tools/src/build/tools/charsetmapping/DBCS.java Wed Jul 05 19:09:26 2017 +0200
@@ -196,11 +196,14 @@
// (5) c2b replacement, only used for JIs0208/0212, which
// are two pure db charsets so default '3f' does not work
+ // TBD: move this into configuration file
String c2bRepl = "";
if (clzName.startsWith("JIS_X_0208")) {
c2bRepl = "new byte[]{ (byte)0x21, (byte)0x29 },";
} else if (clzName.startsWith("JIS_X_0212")) {
c2bRepl = "new byte[]{ (byte)0x22, (byte)0x44 },";
+ } else if (clzName.startsWith("IBM300")) {
+ c2bRepl = "new byte[]{ (byte)0x42, (byte)0x6f },";
}
while (s.hasNextLine()) {
--- a/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/tools/src/build/tools/cldrconverter/CLDRConverter.java Wed Jul 05 19:09:26 2017 +0200
@@ -605,7 +605,23 @@
copyIfPresent(map, key, formatData);
}
}
-
+ // Workaround for islamic-umalqura name support (JDK-8015986)
+ switch (id) {
+ case "ar":
+ map.put(CLDRConverter.CALENDAR_NAME_PREFIX
+ + CalendarType.ISLAMIC_UMALQURA.lname(),
+ // derived from CLDR 24 draft
+ "\u0627\u0644\u062a\u0642\u0648\u064a\u0645 "
+ +"\u0627\u0644\u0625\u0633\u0644\u0627\u0645\u064a "
+ +"[\u0623\u0645 \u0627\u0644\u0642\u0631\u0649]");
+ break;
+ case "en":
+ map.put(CLDRConverter.CALENDAR_NAME_PREFIX
+ + CalendarType.ISLAMIC_UMALQURA.lname(),
+ // derived from CLDR 24 draft
+ "Islamic Calendar [Umm al-Qura]");
+ break;
+ }
// Copy available calendar names
for (String key : map.keySet()) {
if (key.startsWith(CLDRConverter.CALENDAR_NAME_PREFIX)) {
--- a/jdk/make/tools/src/build/tools/cldrconverter/CalendarType.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/tools/src/build/tools/cldrconverter/CalendarType.java Wed Jul 05 19:09:26 2017 +0200
@@ -31,7 +31,8 @@
* Constants for the Calendars supported by JRE.
*/
enum CalendarType {
- GREGORIAN("gregory"), BUDDHIST, JAPANESE, ROC, ISLAMIC, ISLAMIC_CIVIL("islamicc");
+ GREGORIAN("gregory"), BUDDHIST, JAPANESE, ROC,
+ ISLAMIC, ISLAMIC_CIVIL("islamicc"), ISLAMIC_UMALQURA("islamic-umalqura");
private static final int[][] ERA_DATA = {
// start index, array length
@@ -41,6 +42,7 @@
{0, 2}, // roc (Minguo)
{0, 1}, // islamic (Hijrah)
{0, 1}, // islamicc (same as islamic)
+ {0, 1}, // islamic-umalqura
};
private final String lname; // lowercase name
@@ -52,8 +54,8 @@
private CalendarType(String uname) {
String lname = name().toLowerCase(Locale.ROOT);
- if (lname.equals("islamic_civil")) {
- lname = "islamic-civil";
+ if (lname.startsWith("islamic_")) {
+ lname = lname.replace('_', '-');
}
this.lname = lname;
this.uname = (uname != null) ? uname : lname;
--- a/jdk/make/tools/src/build/tools/makeclasslist/MakeClasslist.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/make/tools/src/build/tools/makeclasslist/MakeClasslist.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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,11 +29,11 @@
import java.util.*;
import java.util.jar.*;
-/** Reads a set of files containing the output of java -verbose:class
- runs. Finds all classes that were loaded from the bootstrap class
- path by comparing the prefix of the load path to the current JRE's
- java.home system property. Prints the names of these classes to
- stdout.
+/** Reads a set of files containing the output of java
+ -XX:+TraceClassLoadingPreorder runs. Finds all classes that were
+ loaded from the bootstrap class path by comparing the prefix of
+ the load path to the current JRE's java.home system property.
+ Prints the names of these classes to stdout.
*/
public class MakeClasslist {
@@ -86,7 +86,7 @@
Set<String> seenClasses = new HashSet<>();
- for (String str : seenClasses) {
+ for (String str : classes) {
if (seenClasses.add(str)) {
System.out.println(str);
}
--- a/jdk/makefiles/CompileLaunchers.gmk Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/makefiles/CompileLaunchers.gmk Wed Jul 05 19:09:26 2017 +0200
@@ -40,7 +40,7 @@
BUILD_LAUNCHERS=
-# When building a legacy overlay image (on solaris 64 bit), the launchers
+# When building a legacy overlay image (on solaris 64 bit), the launchers
# need to be built with a different rpath and a different output dir.
ifeq ($(OVERLAY_IMAGES),true)
ORIGIN_ROOT:=/../..
@@ -63,7 +63,7 @@
#
ifneq ($(findstring $(OPENJDK_TARGET_OS), linux solaris),)
ORIGIN_ARG+=$(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/lib$(OPENJDK_TARGET_CPU_LIBDIR)) \
- $(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR))
+ $(call SET_EXECUTABLE_ORIGIN,$(ORIGIN_ROOT)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR))
endif
define SetupLauncher
@@ -189,7 +189,7 @@
ifeq ($(OPENJDK_TARGET_OS),windows)
$$(BUILD_LAUNCHER_$1) : $(JDK_OUTPUTDIR)/objs/libjava/java.lib \
$$($1_WINDOWS_JLI_LIB)
- endif
+ endif
endef
##########################################################################################
@@ -441,7 +441,7 @@
endif
# On windows, unpack200 is linked completely differently to all other
# executables, using the compiler with the compiler arguments.
-# It's also linked incrementally, producing a .ilk file that needs to
+# It's also linked incrementally, producing a .ilk file that needs to
# be kept away.
ifeq ($(OPENJDK_TARGET_OS),windows)
BUILD_UNPACKEXE_LDEXE:=$(CC)
@@ -490,7 +490,7 @@
endif
# Build into object dir and copy executable afterwards to avoid .ilk file in
-# image. The real fix would be clean up linking of unpack200 using
+# image. The real fix would be clean up linking of unpack200 using
# -link -incremental:no
# like all other launchers.
$(JDK_OUTPUTDIR)/bin$(OUTPUT_SUBDIR)/unpack200$(EXE_SUFFIX): $(BUILD_UNPACKEXE)
@@ -501,7 +501,7 @@
##########################################################################################
-BUILD_JEXEC :=
+BUILD_JEXEC :=
BUILD_JEXEC_SRC :=
BUILD_JEXEC_INC :=
BUILD_JEXEC_DST_DIR := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
@@ -581,11 +581,11 @@
endif
endif
-# TODO:
+# TODO:
# On windows java-rmi.cgi shouldn't be bundled since Java 1.2, but has been built all
# this time anyway. Since jdk6, it has been built from the wrong source and resulted
-# in a (almost) copy of the standard java launcher named "java-rmi.exe" ending up in
-# the final images bin dir. This weird behavior is mimicked here in the converted
+# in a (almost) copy of the standard java launcher named "java-rmi.exe" ending up in
+# the final images bin dir. This weird behavior is mimicked here in the converted
# makefiles for now. Should probably just be deleted.
# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6512052
ifeq ($(OPENJDK_TARGET_OS),windows)
@@ -598,6 +598,44 @@
endif
##########################################################################################
+
+BUILD_JSPAWNHELPER :=
+BUILD_JSPAWNHELPER_SRC := $(JDK_TOPDIR)/src/solaris/native/java/lang
+BUILD_JSPAWNHELPER_DST_DIR := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
+LINK_JSPAWNHELPER_OBJECTS := $(JDK_OUTPUTDIR)/objs/libjava/childproc.o
+LINK_JSPAWNHELPER_FLAGS :=
+
+ifneq ($(findstring $(OPENJDK_TARGET_OS), macosx solaris),)
+ BUILD_JSPAWNHELPER := 1
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ BUILD_JSPAWNHELPER_DST_DIR := $(JDK_OUTPUTDIR)/lib
+endif
+
+ifeq ($(OPENJDK_TARGET_CPU_BITS), 64)
+ LINK_JSPAWNHELPER_FLAGS += -m64
+endif
+
+ifeq ($(BUILD_JSPAWNHELPER), 1)
+ $(eval $(call SetupNativeCompilation,BUILD_JSPAWNHELPER,\
+ SRC:=$(BUILD_JSPAWNHELPER_SRC),\
+ INCLUDE_FILES:=jspawnhelper.c,\
+ LANG:=C,\
+ OPTIMIZATION := LOW, \
+ CFLAGS:=$(CFLAGS_JDKEXE), \
+ LDFLAGS:=$(LDFLAGS_JDKEXE) $(LINK_JSPAWNHELPER_FLAGS), \
+ LDFLAGS_SUFFIX:= $(LINK_JSPAWNHELPER_OBJECTS), \
+ OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/jspawnhelper,\
+ OUTPUT_DIR:=$(BUILD_JSPAWNHELPER_DST_DIR),\
+ PROGRAM:=jspawnhelper))
+
+ $(BUILD_JSPAWNHELPER): $(LINK_JSPAWNHELPER_OBJECTS)
+
+ BUILD_LAUNCHERS += $(BUILD_JSPAWNHELPER)
+endif
+
+##########################################################################################
# jabswitch
ifndef OPENJDK
--- a/jdk/makefiles/CompileNativeLibraries.gmk Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/makefiles/CompileNativeLibraries.gmk Wed Jul 05 19:09:26 2017 +0200
@@ -199,13 +199,13 @@
LIBJAVA_CFLAGS += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \
-DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' \
-DJDK_MICRO_VERSION='"$(JDK_MICRO_VERSION)"' \
- -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"'
+ -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"'
ifneq (,$(JDK_UPDATE_VERSION))
LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"'
endif
-LIBJAVA_EXCLUDE_FILES:=check_code.c check_format.c
+LIBJAVA_EXCLUDE_FILES:=check_code.c check_format.c jspawnhelper.c
ifneq ($(OPENJDK_TARGET_OS),macosx)
LIBJAVA_EXCLUDE_FILES += java_props_macosx.c
@@ -279,7 +279,7 @@
BUILD_LIBMLIB_SRC:=$(JDK_TOPDIR)/src/share/native/sun/awt/medialib
BUILD_LIBMLIB_CFLAGS:=-D__USE_J2D_NAMES -D__MEDIALIB_OLD_NAMES \
-I$(BUILD_LIBMLIB_SRC) \
- -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib
+ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib
BUILD_LIBMLIB_LDLIBS:=
BUILD_LIBMLIB_IMAGE_MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libmlib_image/mapfile-vers
@@ -1042,6 +1042,7 @@
LANG:=C,\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB),\
+ CFLAGS_windows:=/Gy,\
MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libattach/mapfile-$(OPENJDK_TARGET_OS), \
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS) \
@@ -1051,6 +1052,7 @@
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_solaris:=-ldoor,\
+ LDFLAGS_windows:=/ORDER:@$(JDK_TOPDIR)/makefiles/mapfiles/libattach/reorder-windows-$(OPENJDK_TARGET_CPU),\
LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\
LDFLAGS_SUFFIX_windows:=$(WIN_JAVA_LIB) advapi32.lib psapi.lib,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libattach,\
@@ -1413,10 +1415,10 @@
# ifeq ($(OPENJDK_TARGET_OS), linux)
# ifeq ("$(CC_VER_MAJOR)", "3")
# OTHER_LDLIBS += -Wl,-Bstatic -lgcc_eh -Wl,-Bdynamic
-# endif
+# endif
# endif
#
-# The resulting size of the t2k lib file is (at least on linux) dependant on the order of
+# The resulting size of the t2k lib file is (at least on linux) dependant on the order of
# the input .o files. Because of this the new build will differ in size to the old build.
BUILD_LIBT2K_CFLAGS_COMMON:=-I$(JDK_TOPDIR)/src/share/native/sun/font \
-I$(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k \
@@ -1590,8 +1592,8 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
LIBINSTRUMENT_LDFLAGS += $(JDK_OUTPUTDIR)/objs/jli_static.lib $(WIN_JAVA_LIB) \
-export:Agent_OnAttach advapi32.lib
- # Statically link the C runtime so that there are not dependencies on modules
- # not on the search patch when invoked from the Windows system directory
+ # Statically link the C runtime so that there are not dependencies on modules
+ # not on the search patch when invoked from the Windows system directory
# (or elsewhere).
LIBINSTRUMENT_CFLAGS := $(filter-out -MD,$(LIBINSTRUMENT_CFLAGS))
# equivalent of strcasecmp is stricmp on Windows
@@ -2065,13 +2067,13 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_LIBJLI_FILES += java_md.c \
- cmdtoargs.c
+ cmdtoargs.c
# Staticically link with c runtime on windows.
LIBJLI_CFLAGS:=$(filter-out -MD,$(LIBJLI_CFLAGS))
else ifneq ($(OPENJDK_TARGET_OS), macosx)
BUILD_LIBJLI_FILES += java_md_common.c
- BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c
+ BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c
ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c
@@ -2518,7 +2520,7 @@
BUILD_LIBRARIES += $(LIBSPLASHSCREEN)
ifeq ($(OPENJDK_TARGET_OS),macosx)
-$(LIBSPLASHSCREEN) : $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX)
+$(LIBSPLASHSCREEN) : $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX)
endif
endif
@@ -3246,7 +3248,7 @@
BUILD_LIBRARIES += $(BUILD_LIBAWT_LWAWT)
-$(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBAWT)
+$(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBAWT)
$(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBMLIB_IMAGE)
@@ -3287,7 +3289,7 @@
BUILD_LIBRARIES += $(BUILD_LIBOSXUI)
-$(BUILD_LIBOSXUI) : $(BUILD_LIBAWT)
+$(BUILD_LIBOSXUI) : $(BUILD_LIBAWT)
$(BUILD_LIBOSXUI) : $(BUILD_LIBOSXAPP)
--- a/jdk/makefiles/CopyFiles.gmk Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/makefiles/CopyFiles.gmk Wed Jul 05 19:09:26 2017 +0200
@@ -292,8 +292,11 @@
JVMCFG_DIR := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
JVMCFG := $(JVMCFG_DIR)/jvm.cfg
+# To do: should this also support -zeroshark?
-ifeq ($(OPENJDK_TARGET_CPU_BITS),32)
+ifeq ($(OPENJDK_TARGET_CPU_BITS),64)
+ COPY_JVM_CFG_FILE := true
+else
# On 32-bit machines we have three potential VMs: client, server and minimal.
# Historically we usually have both client and server and so that is what the
# committed jvm.cfg expects (including platform specific ergonomics switches
@@ -302,16 +305,21 @@
# The main problem is deciding whether to use aliases for the VMs that are not
# present and the current position is that we add aliases for client and server, but
# not for minimal.
- # To do: should this also support, -zero and -zeroshark?
-
CLIENT_AND_SERVER := $(and $(findstring true,$(JVM_VARIANT_SERVER)),$(findstring true,$(JVM_VARIANT_CLIENT)))
+ ifeq ($(CLIENT_AND_SERVER), true)
+ COPY_JVM_CFG_FILE := true
+ else
+ # For zero, the default jvm.cfg file is sufficient
+ ifeq ($(JVM_VARIANT_ZERO), true)
+ COPY_JVM_CFG_FILE := true
+ endif
+ endif
+endif
- ifeq ($(CLIENT_AND_SERVER), true)
- # Use the committed jvm.cfg for this 32 bit setup (the minimal
- # VM is already KNOWN on platforms that potentially support it)
+ifeq ($(COPY_JVM_CFG_FILE), true)
$(JVMCFG): $(JVMCFG_SRC)
$(call install-file)
- else
+else
$(JVMCFG):
$(MKDIR) -p $(@D)
$(RM) $(@)
@@ -338,12 +346,6 @@
endif
endif
endif
- endif
-
-else
- # Use the default jvm.cfg for this 64 bit setup.
- $(JVMCFG): $(JVMCFG_SRC)
- $(call install-file)
endif
COPY_FILES += $(JVMCFG)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/makefiles/mapfiles/libattach/reorder-windows-x86 Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,2 @@
+jvm_attach_thread_func@4
+jvm_attach_thread_func_end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/makefiles/mapfiles/libattach/reorder-windows-x86_64 Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,2 @@
+jvm_attach_thread_func
+jvm_attach_thread_func_end
--- a/jdk/makefiles/mapfiles/libjava/mapfile-vers Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers Wed Jul 05 19:09:26 2017 +0200
@@ -100,7 +100,7 @@
Java_java_io_RandomAccessFile_open;
Java_java_io_RandomAccessFile_read;
Java_java_io_RandomAccessFile_readBytes;
- Java_java_io_RandomAccessFile_seek;
+ Java_java_io_RandomAccessFile_seek0;
Java_java_io_RandomAccessFile_setLength;
Java_java_io_RandomAccessFile_write;
Java_java_io_RandomAccessFile_writeBytes;
--- a/jdk/makefiles/profile-includes.txt Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/makefiles/profile-includes.txt Wed Jul 05 19:09:26 2017 +0200
@@ -102,6 +102,7 @@
security/US_export_policy.jar \
security/local_policy.jar
+
PROFILE_2_JRE_BIN_FILES := \
rmid$(EXE_SUFFIX) \
rmiregistry$(EXE_SUFFIX)
@@ -140,7 +141,6 @@
PROFILE_3_JRE_OTHER_FILES :=
PROFILE_3_JRE_JAR_FILES := \
- jfr.jar \
management-agent.jar
@@ -253,6 +253,6 @@
ext/cldrdata.jar \
ext/dnsns.jar \
ext/nashorn.jar \
- ext/zipfs.jar
+ ext/zipfs.jar \
+ jfr.jar
-
--- a/jdk/src/macosx/native/sun/awt/CMenuItem.m Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/macosx/native/sun/awt/CMenuItem.m Wed Jul 05 19:09:26 2017 +0200
@@ -296,7 +296,7 @@
case java_awt_event_KeyEvent_VK_HELP : macKey = NSHelpFunctionKey; break;
case java_awt_event_KeyEvent_VK_TAB : macKey = NSTabCharacter; break;
- case java_awt_event_KeyEvent_VK_ENTER : macKey = NSCarriageReturnCharacter; break;
+ case java_awt_event_KeyEvent_VK_ENTER : macKey = NSNewlineCharacter; break;
case java_awt_event_KeyEvent_VK_BACK_SPACE : macKey = NSBackspaceCharacter; break;
case java_awt_event_KeyEvent_VK_DELETE : macKey = NSDeleteCharacter; break;
case java_awt_event_KeyEvent_VK_CLEAR : macKey = NSClearDisplayFunctionKey; break;
--- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Wed Jul 05 19:09:26 2017 +0200
@@ -124,7 +124,8 @@
put("Cipher.RSA", "com.sun.crypto.provider.RSACipher");
put("Cipher.RSA SupportedModes", "ECB");
put("Cipher.RSA SupportedPaddings",
- "NOPADDING|PKCS1PADDING|OAEPWITHMD5ANDMGF1PADDING"
+ "NOPADDING|PKCS1PADDING|OAEPPADDING"
+ + "|OAEPWITHMD5ANDMGF1PADDING"
+ "|OAEPWITHSHA1ANDMGF1PADDING"
+ "|OAEPWITHSHA-1ANDMGF1PADDING"
+ "|OAEPWITHSHA-224ANDMGF1PADDING"
--- a/jdk/src/share/classes/com/sun/java/swing/Painter.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/java/swing/Painter.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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,5 +29,6 @@
*
* @deprecated Use {@link javax.swing.Painter} instead.
*/
+@Deprecated
public interface Painter<T> extends javax.swing.Painter<T> {
}
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/AbstractRegionPainter.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/AbstractRegionPainter.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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,5 +29,6 @@
*
* @deprecated Use {@link javax.swing.plaf.nimbus.AbstractRegionPainter} instead.
*/
+@Deprecated
public abstract class AbstractRegionPainter extends javax.swing.plaf.nimbus.AbstractRegionPainter {
}
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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,5 +29,6 @@
*
* @deprecated Use {@link javax.swing.plaf.nimbus.NimbusLookAndFeel} instead.
*/
+@Deprecated
public class NimbusLookAndFeel extends javax.swing.plaf.nimbus.NimbusLookAndFeel {
}
--- a/jdk/src/share/classes/com/sun/media/sound/DataPusher.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/media/sound/DataPusher.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,6 +25,8 @@
package com.sun.media.sound;
+import java.util.Arrays;
+
import javax.sound.sampled.*;
/**
@@ -46,11 +48,11 @@
private final AudioFormat format;
// stream as source data
- private AudioInputStream ais = null;
+ private final AudioInputStream ais;
// byte array as source data
- private byte[] audioData = null;
- private int audioDataByteLength = 0;
+ private final byte[] audioData;
+ private final int audioDataByteLength;
private int pos;
private int newPos = -1;
private boolean looping;
@@ -67,16 +69,22 @@
private final int BUFFER_SIZE = 16384;
public DataPusher(SourceDataLine sourceLine, AudioFormat format, byte[] audioData, int byteLength) {
- this.audioData = audioData;
- this.audioDataByteLength = byteLength;
- this.format = format;
- this.source = sourceLine;
+ this(sourceLine, format, null, audioData, byteLength);
}
public DataPusher(SourceDataLine sourceLine, AudioInputStream ais) {
+ this(sourceLine, ais.getFormat(), ais, null, 0);
+ }
+
+ private DataPusher(final SourceDataLine source, final AudioFormat format,
+ final AudioInputStream ais, final byte[] audioData,
+ final int audioDataByteLength) {
+ this.source = source;
+ this.format = format;
this.ais = ais;
- this.format = ais.getFormat();
- this.source = sourceLine;
+ this.audioDataByteLength = audioDataByteLength;
+ this.audioData = audioData == null ? null : Arrays.copyOf(audioData,
+ audioData.length);
}
public synchronized void start() {
--- a/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java Wed Jul 05 19:09:26 2017 +0200
@@ -24,6 +24,8 @@
*/
package com.sun.media.sound;
+import java.util.Arrays;
+
/**
* A standard director who chooses performers
* by there keyfrom,keyto,velfrom,velto properties.
@@ -32,17 +34,16 @@
*/
public final class ModelStandardDirector implements ModelDirector {
- ModelPerformer[] performers;
- ModelDirectedPlayer player;
- boolean noteOnUsed = false;
- boolean noteOffUsed = false;
+ private final ModelPerformer[] performers;
+ private final ModelDirectedPlayer player;
+ private boolean noteOnUsed = false;
+ private boolean noteOffUsed = false;
- public ModelStandardDirector(ModelPerformer[] performers,
- ModelDirectedPlayer player) {
- this.performers = performers;
+ public ModelStandardDirector(final ModelPerformer[] performers,
+ final ModelDirectedPlayer player) {
+ this.performers = Arrays.copyOf(performers, performers.length);
this.player = player;
- for (int i = 0; i < performers.length; i++) {
- ModelPerformer p = performers[i];
+ for (final ModelPerformer p : this.performers) {
if (p.isReleaseTriggered()) {
noteOffUsed = true;
} else {
--- a/jdk/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java Wed Jul 05 19:09:26 2017 +0200
@@ -24,6 +24,8 @@
*/
package com.sun.media.sound;
+import java.util.Arrays;
+
/**
* A standard indexed director who chooses performers
* by there keyfrom,keyto,velfrom,velto properties.
@@ -32,22 +34,21 @@
*/
public final class ModelStandardIndexedDirector implements ModelDirector {
- ModelPerformer[] performers;
- ModelDirectedPlayer player;
- boolean noteOnUsed = false;
- boolean noteOffUsed = false;
+ private final ModelPerformer[] performers;
+ private final ModelDirectedPlayer player;
+ private boolean noteOnUsed = false;
+ private boolean noteOffUsed = false;
// Variables needed for index
- byte[][] trantables;
- int[] counters;
- int[][] mat;
+ private byte[][] trantables;
+ private int[] counters;
+ private int[][] mat;
- public ModelStandardIndexedDirector(ModelPerformer[] performers,
- ModelDirectedPlayer player) {
- this.performers = performers;
+ public ModelStandardIndexedDirector(final ModelPerformer[] performers,
+ final ModelDirectedPlayer player) {
+ this.performers = Arrays.copyOf(performers, performers.length);
this.player = player;
- for (int i = 0; i < performers.length; i++) {
- ModelPerformer p = performers[i];
+ for (final ModelPerformer p : this.performers) {
if (p.isReleaseTriggered()) {
noteOffUsed = true;
} else {
--- a/jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java Wed Jul 05 19:09:26 2017 +0200
@@ -38,7 +38,7 @@
import javax.sound.sampled.LineUnavailableException;
/**
- * Clip implemention for the SoftMixingMixer.
+ * Clip implementation for the SoftMixingMixer.
*
* @author Karl Helgason
*/
@@ -357,7 +357,9 @@
throw new IllegalArgumentException(
"Buffer size does not represent an integral number of sample frames!");
- this.data = data;
+ if (data != null) {
+ this.data = Arrays.copyOf(data, data.length);
+ }
this.offset = offset;
this.bufferSize = bufferSize;
this.format = format;
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java Wed Jul 05 19:09:26 2017 +0200
@@ -42,7 +42,7 @@
public class DEREncodedKeyValue extends Signature11ElementProxy implements KeyInfoContent {
/** JCA algorithm key types supported by this implementation. */
- public static final String supportedKeyTypes[] = { "RSA", "DSA", "EC"};
+ private static final String supportedKeyTypes[] = { "RSA", "DSA", "EC"};
/**
* Constructor DEREncodedKeyValue
--- a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,31 +25,9 @@
package com.sun.security.auth;
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.URL;
-import java.util.*;
-
import java.security.CodeSource;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.Permission;
-import java.security.Permissions;
import java.security.PermissionCollection;
-import java.security.Principal;
-import java.security.UnresolvedPermission;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-
import javax.security.auth.Subject;
-import javax.security.auth.PrivateCredentialPermission;
-
-import sun.security.util.PropertyExpander;
-
-import sun.security.provider.PolicyParser.PrincipalEntry;
-import sun.security.provider.PolicyParser.GrantEntry;
-import sun.security.provider.PolicyParser.PermissionEntry;
/**
* This class represents a default implementation for
@@ -240,61 +218,14 @@
@Deprecated
public class PolicyFile extends javax.security.auth.Policy {
- static final java.util.ResourceBundle rb =
- java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
- public java.util.ResourceBundle run() {
- return (java.util.ResourceBundle.getBundle
- ("sun.security.util.AuthResources"));
- }
- });
- // needs to be package private
-
- private static final sun.security.util.Debug debug =
- sun.security.util.Debug.getInstance("policy", "\t[Auth Policy]");
-
- private static final String AUTH_POLICY = "java.security.auth.policy";
- private static final String SECURITY_MANAGER = "java.security.manager";
- private static final String AUTH_POLICY_URL = "auth.policy.url.";
-
- private Vector<PolicyEntry> policyEntries;
- private Hashtable<Object, Object> aliasMapping;
-
- private boolean initialized = false;
-
- private boolean expandProperties = true;
- private boolean ignoreIdentityScope = true;
-
- // for use with the reflection API
-
- private static final Class[] PARAMS = { String.class, String.class};
+ private final sun.security.provider.AuthPolicyFile apf;
/**
* Initializes the Policy object and reads the default policy
* configuration file(s) into the Policy object.
*/
public PolicyFile() {
- // initialize Policy if either the AUTH_POLICY or
- // SECURITY_MANAGER properties are set
- String prop = System.getProperty(AUTH_POLICY);
-
- if (prop == null) {
- prop = System.getProperty(SECURITY_MANAGER);
- }
- if (prop != null)
- init();
- }
-
- private synchronized void init() {
-
- if (initialized)
- return;
-
- policyEntries = new Vector<PolicyEntry>();
- aliasMapping = new Hashtable<Object, Object>(11);
-
- initPolicyFile();
- initialized = true;
+ apf = new sun.security.provider.AuthPolicyFile();
}
/**
@@ -305,460 +236,9 @@
* @exception SecurityException if the caller doesn't have permission
* to refresh the <code>Policy</code>.
*/
- public synchronized void refresh()
- {
-
- java.lang.SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new javax.security.auth.AuthPermission
- ("refreshPolicy"));
- }
-
- // XXX
- //
- // 1) if code instantiates PolicyFile directly, then it will need
- // all the permissions required for the PolicyFile initialization
- // 2) if code calls Policy.getPolicy, then it simply needs
- // AuthPermission(getPolicy), and the javax.security.auth.Policy
- // implementation instantiates PolicyFile in a doPrivileged block
- // 3) if after instantiating a Policy (either via #1 or #2),
- // code calls refresh, it simply needs
- // AuthPermission(refreshPolicy). then PolicyFile wraps
- // the refresh in a doPrivileged block.
- initialized = false;
- java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction<Void>() {
- public Void run() {
- init();
- return null;
- }
- });
- }
-
- private KeyStore initKeyStore(URL policyUrl, String keyStoreName,
- String keyStoreType) {
- if (keyStoreName != null) {
- try {
- /*
- * location of keystore is specified as absolute URL in policy
- * file, or is relative to URL of policy file
- */
- URL keyStoreUrl = null;
- try {
- keyStoreUrl = new URL(keyStoreName);
- // absolute URL
- } catch (java.net.MalformedURLException e) {
- // relative URL
- keyStoreUrl = new URL(policyUrl, keyStoreName);
- }
-
- if (debug != null) {
- debug.println("reading keystore"+keyStoreUrl);
- }
-
- InputStream inStream =
- new BufferedInputStream(getInputStream(keyStoreUrl));
-
- KeyStore ks;
- if (keyStoreType != null)
- ks = KeyStore.getInstance(keyStoreType);
- else
- ks = KeyStore.getInstance(KeyStore.getDefaultType());
- ks.load(inStream, null);
- inStream.close();
- return ks;
- } catch (Exception e) {
- // ignore, treat it like we have no keystore
- if (debug != null) {
- e.printStackTrace();
- }
- return null;
- }
- }
- return null;
- }
-
- private void initPolicyFile() {
-
- String prop = Security.getProperty("policy.expandProperties");
-
- if (prop != null) expandProperties = prop.equalsIgnoreCase("true");
-
- String iscp = Security.getProperty("policy.ignoreIdentityScope");
-
- if (iscp != null) ignoreIdentityScope = iscp.equalsIgnoreCase("true");
-
- String allowSys = Security.getProperty("policy.allowSystemProperty");
-
- if ((allowSys!=null) && allowSys.equalsIgnoreCase("true")) {
-
- String extra_policy = System.getProperty(AUTH_POLICY);
- if (extra_policy != null) {
- boolean overrideAll = false;
- if (extra_policy.startsWith("=")) {
- overrideAll = true;
- extra_policy = extra_policy.substring(1);
- }
- try {
- extra_policy = PropertyExpander.expand(extra_policy);
- URL policyURL;
- File policyFile = new File(extra_policy);
- if (policyFile.exists()) {
- policyURL =
- new URL("file:" + policyFile.getCanonicalPath());
- } else {
- policyURL = new URL(extra_policy);
- }
- if (debug != null)
- debug.println("reading "+policyURL);
- init(policyURL);
- } catch (Exception e) {
- // ignore.
- if (debug != null) {
- debug.println("caught exception: "+e);
- }
-
- }
- if (overrideAll) {
- if (debug != null) {
- debug.println("overriding other policies!");
- }
- return;
- }
- }
- }
-
- int n = 1;
- boolean loaded_one = false;
- String policy_url;
-
- while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) {
- try {
- policy_url = PropertyExpander.expand(policy_url).replace
- (File.separatorChar, '/');
- if (debug != null)
- debug.println("reading "+policy_url);
- init(new URL(policy_url));
- loaded_one = true;
- } catch (Exception e) {
- if (debug != null) {
- debug.println("error reading policy "+e);
- e.printStackTrace();
- }
- // ignore that policy
- }
- n++;
- }
-
- if (loaded_one == false) {
- // do not load a static policy
- }
- }
-
- /**
- * Checks public key. If it is marked as trusted in
- * the identity database, add it to the policy
- * with the AllPermission.
- */
- private boolean checkForTrustedIdentity(final Certificate cert) {
- // XXX JAAS has no way to access the SUN package.
- // we'll add this back in when JAAS goes into core.
- return false;
- }
-
- /**
- * Reads a policy configuration into the Policy object using a
- * Reader object.
- *
- * @param policyFile the policy Reader object.
- */
- private void init(URL policy) {
- sun.security.provider.PolicyParser pp =
- new sun.security.provider.PolicyParser(expandProperties);
- try {
- InputStreamReader isr
- = new InputStreamReader(getInputStream(policy));
- pp.read(isr);
- isr.close();
- KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
- pp.getKeyStoreType());
- Enumeration<GrantEntry> enum_ = pp.grantElements();
- while (enum_.hasMoreElements()) {
- GrantEntry ge = enum_.nextElement();
- addGrantEntry(ge, keyStore);
- }
- } catch (sun.security.provider.PolicyParser.ParsingException pe) {
- System.err.println(AUTH_POLICY +
- rb.getString(".error.parsing.") + policy);
- System.err.println(AUTH_POLICY +
- rb.getString("COLON") +
- pe.getMessage());
- if (debug != null)
- pe.printStackTrace();
-
- } catch (Exception e) {
- if (debug != null) {
- debug.println("error parsing "+policy);
- debug.println(e.toString());
- e.printStackTrace();
- }
- }
- }
-
- /*
- * Fast path reading from file urls in order to avoid calling
- * FileURLConnection.connect() which can be quite slow the first time
- * it is called. We really should clean up FileURLConnection so that
- * this is not a problem but in the meantime this fix helps reduce
- * start up time noticeably for the new launcher. -- DAC
- */
- private InputStream getInputStream(URL url) throws IOException {
- if ("file".equals(url.getProtocol())) {
- String path = url.getFile().replace('/', File.separatorChar);
- return new FileInputStream(path);
- } else {
- return url.openStream();
- }
- }
-
- /**
- * Given a PermissionEntry, create a codeSource.
- *
- * @return null if signedBy alias is not recognized
- */
- CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore)
- throws java.net.MalformedURLException
- {
- Certificate[] certs = null;
- if (ge.signedBy != null) {
- certs = getCertificates(keyStore, ge.signedBy);
- if (certs == null) {
- // we don't have a key for this alias,
- // just return
- if (debug != null) {
- debug.println(" no certs for alias " +
- ge.signedBy + ", ignoring.");
- }
- return null;
- }
- }
-
- URL location;
-
- if (ge.codeBase != null)
- location = new URL(ge.codeBase);
- else
- location = null;
-
- if (ge.principals == null || ge.principals.size() == 0) {
- return (canonicalizeCodebase
- (new CodeSource(location, certs),
- false));
- } else {
- return (canonicalizeCodebase
- (new SubjectCodeSource(null, ge.principals, location, certs),
- false));
- }
- }
-
- /**
- * Add one policy entry to the vector.
- */
- private void addGrantEntry(GrantEntry ge, KeyStore keyStore) {
-
- if (debug != null) {
- debug.println("Adding policy entry: ");
- debug.println(" signedBy " + ge.signedBy);
- debug.println(" codeBase " + ge.codeBase);
- if (ge.principals != null && ge.principals.size() > 0) {
- ListIterator<PrincipalEntry> li = ge.principals.listIterator();
- while (li.hasNext()) {
- PrincipalEntry pppe = li.next();
- debug.println(" " + pppe.getPrincipalClass() +
- " " + pppe.getPrincipalName());
- }
- }
- debug.println();
- }
-
- try {
- CodeSource codesource = getCodeSource(ge, keyStore);
- // skip if signedBy alias was unknown...
- if (codesource == null) return;
-
- PolicyEntry entry = new PolicyEntry(codesource);
- Enumeration<PermissionEntry> enum_ = ge.permissionElements();
- while (enum_.hasMoreElements()) {
- PermissionEntry pe = enum_.nextElement();
- try {
- // XXX special case PrivateCredentialPermission-SELF
- Permission perm;
- if (pe.permission.equals
- ("javax.security.auth.PrivateCredentialPermission") &&
- pe.name.endsWith(" self")) {
- perm = getInstance(pe.permission,
- pe.name + " \"self\"",
- pe.action);
- } else {
- perm = getInstance(pe.permission,
- pe.name,
- pe.action);
- }
- entry.add(perm);
- if (debug != null) {
- debug.println(" "+perm);
- }
- } catch (ClassNotFoundException cnfe) {
- Certificate certs[];
- if (pe.signedBy != null)
- certs = getCertificates(keyStore, pe.signedBy);
- else
- certs = null;
-
- // only add if we had no signer or we had a
- // a signer and found the keys for it.
- if (certs != null || pe.signedBy == null) {
- Permission perm = new UnresolvedPermission(
- pe.permission,
- pe.name,
- pe.action,
- certs);
- entry.add(perm);
- if (debug != null) {
- debug.println(" "+perm);
- }
- }
- } catch (java.lang.reflect.InvocationTargetException ite) {
- System.err.println
- (AUTH_POLICY +
- rb.getString(".error.adding.Permission.") +
- pe.permission +
- rb.getString("SPACE") +
- ite.getTargetException());
- } catch (Exception e) {
- System.err.println
- (AUTH_POLICY +
- rb.getString(".error.adding.Permission.") +
- pe.permission +
- rb.getString("SPACE") +
- e);
- }
- }
- policyEntries.addElement(entry);
- } catch (Exception e) {
- System.err.println
- (AUTH_POLICY +
- rb.getString(".error.adding.Entry.") +
- ge +
- rb.getString("SPACE") +
- e);
- }
-
- if (debug != null)
- debug.println();
- }
-
- /**
- * Returns a new Permission object of the given Type. The Permission is
- * created by getting the
- * Class object using the <code>Class.forName</code> method, and using
- * the reflection API to invoke the (String name, String actions)
- * constructor on the
- * object.
- *
- * @param type the type of Permission being created.
- * @param name the name of the Permission being created.
- * @param actions the actions of the Permission being created.
- *
- * @exception ClassNotFoundException if the particular Permission
- * class could not be found.
- *
- * @exception IllegalAccessException if the class or initializer is
- * not accessible.
- *
- * @exception InstantiationException if getInstance tries to
- * instantiate an abstract class or an interface, or if the
- * instantiation fails for some other reason.
- *
- * @exception NoSuchMethodException if the (String, String) constructor
- * is not found.
- *
- * @exception InvocationTargetException if the underlying Permission
- * constructor throws an exception.
- *
- */
-
- private static final Permission getInstance(String type,
- String name,
- String actions)
- throws ClassNotFoundException,
- InstantiationException,
- IllegalAccessException,
- NoSuchMethodException,
- InvocationTargetException
- {
- //XXX we might want to keep a hash of created factories...
- Class<?> pc = Class.forName(type);
- Constructor<?> c = pc.getConstructor(PARAMS);
- return (Permission) c.newInstance(new Object[] { name, actions });
- }
-
- /**
- * Fetch all certs associated with this alias.
- */
- Certificate[] getCertificates(
- KeyStore keyStore, String aliases) {
-
- Vector<Certificate> vcerts = null;
-
- StringTokenizer st = new StringTokenizer(aliases, ",");
- int n = 0;
-
- while (st.hasMoreTokens()) {
- String alias = st.nextToken().trim();
- n++;
- Certificate cert = null;
- //See if this alias's cert has already been cached
- cert = (Certificate) aliasMapping.get(alias);
- if (cert == null && keyStore != null) {
-
- try {
- cert = keyStore.getCertificate(alias);
- } catch (KeyStoreException kse) {
- // never happens, because keystore has already been loaded
- // when we call this
- }
- if (cert != null) {
- aliasMapping.put(alias, cert);
- aliasMapping.put(cert, alias);
- }
- }
-
- if (cert != null) {
- if (vcerts == null)
- vcerts = new Vector<Certificate>();
- vcerts.addElement(cert);
- }
- }
-
- // make sure n == vcerts.size, since we are doing a logical *and*
- if (vcerts != null && n == vcerts.size()) {
- Certificate[] certs = new Certificate[vcerts.size()];
- vcerts.copyInto(certs);
- return certs;
- } else {
- return null;
- }
- }
-
- /**
- * Enumerate all the entries in the global policy object.
- * This method is used by policy admin tools. The tools
- * should use the Enumeration methods on the returned object
- * to fetch the elements sequentially.
- */
- private final synchronized Enumeration<PolicyEntry> elements(){
- return policyEntries.elements();
+ @Override
+ public void refresh() {
+ apf.refresh();
}
/**
@@ -816,646 +296,9 @@
* @return the Permissions granted to the provided <code>Subject</code>
* <code>CodeSource</code>.
*/
+ @Override
public PermissionCollection getPermissions(final Subject subject,
- final CodeSource codesource) {
-
- // XXX when JAAS goes into the JDK core,
- // we can remove this method and simply
- // rely on the getPermissions variant that takes a codesource,
- // which no one can use at this point in time.
- // at that time, we can also make SubjectCodeSource a public
- // class.
-
- // XXX
- //
- // 1) if code instantiates PolicyFile directly, then it will need
- // all the permissions required for the PolicyFile initialization
- // 2) if code calls Policy.getPolicy, then it simply needs
- // AuthPermission(getPolicy), and the javax.security.auth.Policy
- // implementation instantiates PolicyFile in a doPrivileged block
- // 3) if after instantiating a Policy (either via #1 or #2),
- // code calls getPermissions, PolicyFile wraps the call
- // in a doPrivileged block.
- return java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction<PermissionCollection>() {
- public PermissionCollection run() {
- SubjectCodeSource scs = new SubjectCodeSource
- (subject,
- null,
- codesource == null ? null : codesource.getLocation(),
- codesource == null ? null : codesource.getCertificates());
- if (initialized)
- return getPermissions(new Permissions(), scs);
- else
- return new PolicyPermissions(PolicyFile.this, scs);
- }
- });
- }
-
- /**
- * Examines the global policy for the specified CodeSource, and
- * creates a PermissionCollection object with
- * the set of permissions for that principal's protection domain.
- *
- * @param CodeSource the codesource associated with the caller.
- * This encapsulates the original location of the code (where the code
- * came from) and the public key(s) of its signer.
- *
- * @return the set of permissions according to the policy.
- */
- PermissionCollection getPermissions(CodeSource codesource) {
-
- if (initialized)
- return getPermissions(new Permissions(), codesource);
- else
- return new PolicyPermissions(this, codesource);
- }
-
- /**
- * Examines the global policy for the specified CodeSource, and
- * creates a PermissionCollection object with
- * the set of permissions for that principal's protection domain.
- *
- * @param permissions the permissions to populate
- * @param codesource the codesource associated with the caller.
- * This encapsulates the original location of the code (where the code
- * came from) and the public key(s) of its signer.
- *
- * @return the set of permissions according to the policy.
- */
- Permissions getPermissions(final Permissions perms,
- final CodeSource cs)
- {
- if (!initialized) {
- init();
- }
-
- final CodeSource codesource[] = {null};
-
- codesource[0] = canonicalizeCodebase(cs, true);
-
- if (debug != null) {
- debug.println("evaluate("+codesource[0]+")\n");
- }
-
- // needs to be in a begin/endPrivileged block because
- // codesource.implies calls URL.equals which does an
- // InetAddress lookup
-
- for (int i = 0; i < policyEntries.size(); i++) {
-
- PolicyEntry entry = policyEntries.elementAt(i);
-
- if (debug != null) {
- debug.println("PolicyFile CodeSource implies: " +
- entry.codesource.toString() + "\n\n" +
- "\t" + codesource[0].toString() + "\n\n");
- }
-
- if (entry.codesource.implies(codesource[0])) {
- for (int j = 0; j < entry.permissions.size(); j++) {
- Permission p = entry.permissions.elementAt(j);
- if (debug != null) {
- debug.println(" granting " + p);
- }
- if (!addSelfPermissions(p, entry.codesource,
- codesource[0], perms)) {
- // we could check for duplicates
- // before adding new permissions,
- // but the SubjectDomainCombiner
- // already checks for duplicates later
- perms.add(p);
- }
- }
- }
- }
-
- // now see if any of the keys are trusted ids.
-
- if (!ignoreIdentityScope) {
- Certificate certs[] = codesource[0].getCertificates();
- if (certs != null) {
- for (int k=0; k < certs.length; k++) {
- if ((aliasMapping.get(certs[k]) == null) &&
- checkForTrustedIdentity(certs[k])) {
- // checkForTrustedIdentity added it
- // to the policy for us. next time
- // around we'll find it. This time
- // around we need to add it.
- perms.add(new java.security.AllPermission());
- }
- }
- }
- }
- return perms;
- }
-
- /**
- * Returns true if 'Self' permissions were added to the provided
- * 'perms', and false otherwise.
- *
- * <p>
- *
- * @param p check to see if this Permission is a "SELF"
- * PrivateCredentialPermission. <p>
- *
- * @param entryCs the codesource for the Policy entry.
- *
- * @param accCs the codesource for from the current AccessControlContext.
- *
- * @param perms the PermissionCollection where the individual
- * PrivateCredentialPermissions will be added.
- */
- private boolean addSelfPermissions(final Permission p,
- CodeSource entryCs,
- CodeSource accCs,
- Permissions perms) {
-
- if (!(p instanceof PrivateCredentialPermission))
- return false;
-
- if (!(entryCs instanceof SubjectCodeSource))
- return false;
-
-
- PrivateCredentialPermission pcp = (PrivateCredentialPermission)p;
- SubjectCodeSource scs = (SubjectCodeSource)entryCs;
-
- // see if it is a SELF permission
- String[][] pPrincipals = pcp.getPrincipals();
- if (pPrincipals.length <= 0 ||
- !pPrincipals[0][0].equalsIgnoreCase("self") ||
- !pPrincipals[0][1].equalsIgnoreCase("self")) {
-
- // regular PrivateCredentialPermission
- return false;
- } else {
-
- // granted a SELF permission - create a
- // PrivateCredentialPermission for each
- // of the Policy entry's CodeSource Principals
-
- if (scs.getPrincipals() == null) {
- // XXX SubjectCodeSource has no Subject???
- return true;
- }
-
- ListIterator<PrincipalEntry> pli =
- scs.getPrincipals().listIterator();
- while (pli.hasNext()) {
-
- PrincipalEntry principal = pli.next();
-
- // XXX
- // if the Policy entry's Principal does not contain a
- // WILDCARD for the Principal name, then a
- // new PrivateCredentialPermission is created
- // for the Principal listed in the Policy entry.
- // if the Policy entry's Principal contains a WILDCARD
- // for the Principal name, then a new
- // PrivateCredentialPermission is created
- // for each Principal associated with the Subject
- // in the current ACC.
-
- String[][] principalInfo = getPrincipalInfo
- (principal, accCs);
-
- for (int i = 0; i < principalInfo.length; i++) {
-
- // here's the new PrivateCredentialPermission
-
- PrivateCredentialPermission newPcp =
- new PrivateCredentialPermission
- (pcp.getCredentialClass() +
- " " +
- principalInfo[i][0] +
- " " +
- "\"" + principalInfo[i][1] + "\"",
- "read");
-
- if (debug != null) {
- debug.println("adding SELF permission: " +
- newPcp.toString());
- }
-
- perms.add(newPcp);
- }
- }
- }
- return true;
- }
-
- /**
- * return the principal class/name pair in the 2D array.
- * array[x][y]: x corresponds to the array length.
- * if (y == 0), it's the principal class.
- * if (y == 1), it's the principal name.
- */
- private String[][] getPrincipalInfo
- (PrincipalEntry principal, final CodeSource accCs) {
-
- // there are 3 possibilities:
- // 1) the entry's Principal class and name are not wildcarded
- // 2) the entry's Principal name is wildcarded only
- // 3) the entry's Principal class and name are wildcarded
-
- if (!principal.getPrincipalClass().equals
- (PrincipalEntry.WILDCARD_CLASS) &&
- !principal.getPrincipalName().equals
- (PrincipalEntry.WILDCARD_NAME)) {
-
- // build a PrivateCredentialPermission for the principal
- // from the Policy entry
- String[][] info = new String[1][2];
- info[0][0] = principal.getPrincipalClass();
- info[0][1] = principal.getPrincipalName();
- return info;
-
- } else if (!principal.getPrincipalClass().equals
- (PrincipalEntry.WILDCARD_CLASS) &&
- principal.getPrincipalName().equals
- (PrincipalEntry.WILDCARD_NAME)) {
-
- // build a PrivateCredentialPermission for all
- // the Subject's principals that are instances of principalClass
-
- // the accCs is guaranteed to be a SubjectCodeSource
- // because the earlier CodeSource.implies succeeded
- SubjectCodeSource scs = (SubjectCodeSource)accCs;
-
- Set<? extends Principal> principalSet = null;
- try {
- // principal.principalClass should extend Principal
- // If it doesn't, we should stop here with a ClassCastException.
- @SuppressWarnings("unchecked")
- Class<? extends Principal> pClass = (Class<? extends Principal>)
- Class.forName(principal.getPrincipalClass(), false,
- ClassLoader.getSystemClassLoader());
- principalSet = scs.getSubject().getPrincipals(pClass);
- } catch (Exception e) {
- if (debug != null) {
- debug.println("problem finding Principal Class " +
- "when expanding SELF permission: " +
- e.toString());
- }
- }
-
- if (principalSet == null) {
- // error
- return new String[0][0];
- }
-
- String[][] info = new String[principalSet.size()][2];
-
- int i = 0;
- for (Principal p : principalSet) {
- info[i][0] = p.getClass().getName();
- info[i][1] = p.getName();
- i++;
- }
- return info;
-
- } else {
-
- // build a PrivateCredentialPermission for every
- // one of the current Subject's principals
-
- // the accCs is guaranteed to be a SubjectCodeSource
- // because the earlier CodeSource.implies succeeded
- SubjectCodeSource scs = (SubjectCodeSource)accCs;
- Set<Principal> principalSet = scs.getSubject().getPrincipals();
-
- String[][] info = new String[principalSet.size()][2];
- java.util.Iterator<Principal> pIterator = principalSet.iterator();
-
- int i = 0;
- while (pIterator.hasNext()) {
- Principal p = pIterator.next();
- info[i][0] = p.getClass().getName();
- info[i][1] = p.getName();
- i++;
- }
- return info;
- }
- }
-
- /*
- * Returns the signer certificates from the list of certificates associated
- * with the given code source.
- *
- * The signer certificates are those certificates that were used to verify
- * signed code originating from the codesource location.
- *
- * This method assumes that in the given code source, each signer
- * certificate is followed by its supporting certificate chain
- * (which may be empty), and that the signer certificate and its
- * supporting certificate chain are ordered bottom-to-top (i.e., with the
- * signer certificate first and the (root) certificate authority last).
- */
- Certificate[] getSignerCertificates(CodeSource cs) {
- Certificate[] certs = null;
- if ((certs = cs.getCertificates()) == null)
- return null;
- for (int i=0; i<certs.length; i++) {
- if (!(certs[i] instanceof X509Certificate))
- return cs.getCertificates();
- }
-
- // Do we have to do anything?
- int i = 0;
- int count = 0;
- while (i < certs.length) {
- count++;
- while (((i+1) < certs.length)
- && ((X509Certificate)certs[i]).getIssuerDN().equals(
- ((X509Certificate)certs[i+1]).getSubjectDN())) {
- i++;
- }
- i++;
- }
- if (count == certs.length)
- // Done
- return certs;
-
- ArrayList<Certificate> userCertList = new ArrayList<>();
- i = 0;
- while (i < certs.length) {
- userCertList.add(certs[i]);
- while (((i+1) < certs.length)
- && ((X509Certificate)certs[i]).getIssuerDN().equals(
- ((X509Certificate)certs[i+1]).getSubjectDN())) {
- i++;
- }
- i++;
- }
- Certificate[] userCerts = new Certificate[userCertList.size()];
- userCertList.toArray(userCerts);
- return userCerts;
- }
-
- private CodeSource canonicalizeCodebase(CodeSource cs,
- boolean extractSignerCerts) {
- CodeSource canonCs = cs;
- if (cs.getLocation() != null &&
- cs.getLocation().getProtocol().equalsIgnoreCase("file")) {
- try {
- String path = cs.getLocation().getFile().replace
- ('/',
- File.separatorChar);
- URL csUrl = null;
- if (path.endsWith("*")) {
- // remove trailing '*' because it causes canonicalization
- // to fail on win32
- path = path.substring(0, path.length()-1);
- boolean appendFileSep = false;
- if (path.endsWith(File.separator))
- appendFileSep = true;
- if (path.equals("")) {
- path = System.getProperty("user.dir");
- }
- File f = new File(path);
- path = f.getCanonicalPath();
- StringBuffer sb = new StringBuffer(path);
- // reappend '*' to canonicalized filename (note that
- // canonicalization may have removed trailing file
- // separator, so we have to check for that, too)
- if (!path.endsWith(File.separator) &&
- (appendFileSep || f.isDirectory()))
- sb.append(File.separatorChar);
- sb.append('*');
- path = sb.toString();
- } else {
- path = new File(path).getCanonicalPath();
- }
- csUrl = new File(path).toURL();
-
- if (cs instanceof SubjectCodeSource) {
- SubjectCodeSource scs = (SubjectCodeSource)cs;
- if (extractSignerCerts) {
- canonCs = new SubjectCodeSource
- (scs.getSubject(),
- scs.getPrincipals(),
- csUrl,
- getSignerCertificates(scs));
- } else {
- canonCs = new SubjectCodeSource
- (scs.getSubject(),
- scs.getPrincipals(),
- csUrl,
- scs.getCertificates());
- }
- } else {
- if (extractSignerCerts) {
- canonCs = new CodeSource(csUrl,
- getSignerCertificates(cs));
- } else {
- canonCs = new CodeSource(csUrl,
- cs.getCertificates());
- }
- }
- } catch (IOException ioe) {
- // leave codesource as it is, unless we have to extract its
- // signer certificates
- if (extractSignerCerts) {
- if (!(cs instanceof SubjectCodeSource)) {
- canonCs = new CodeSource(cs.getLocation(),
- getSignerCertificates(cs));
- } else {
- SubjectCodeSource scs = (SubjectCodeSource)cs;
- canonCs = new SubjectCodeSource(scs.getSubject(),
- scs.getPrincipals(),
- scs.getLocation(),
- getSignerCertificates(scs));
- }
- }
- }
- } else {
- if (extractSignerCerts) {
- if (!(cs instanceof SubjectCodeSource)) {
- canonCs = new CodeSource(cs.getLocation(),
- getSignerCertificates(cs));
- } else {
- SubjectCodeSource scs = (SubjectCodeSource)cs;
- canonCs = new SubjectCodeSource(scs.getSubject(),
- scs.getPrincipals(),
- scs.getLocation(),
- getSignerCertificates(scs));
- }
- }
- }
- return canonCs;
- }
-
- /**
- * Each entry in the policy configuration file is represented by a
- * PolicyEntry object. <p>
- *
- * A PolicyEntry is a (CodeSource,Permission) pair. The
- * CodeSource contains the (URL, PublicKey) that together identify
- * where the Java bytecodes come from and who (if anyone) signed
- * them. The URL could refer to localhost. The URL could also be
- * null, meaning that this policy entry is given to all comers, as
- * long as they match the signer field. The signer could be null,
- * meaning the code is not signed. <p>
- *
- * The Permission contains the (Type, Name, Action) triplet. <p>
- *
- * For now, the Policy object retrieves the public key from the
- * X.509 certificate on disk that corresponds to the signedBy
- * alias specified in the Policy config file. For reasons of
- * efficiency, the Policy object keeps a hashtable of certs already
- * read in. This could be replaced by a secure internal key
- * store.
- *
- * <p>
- * For example, the entry
- * <pre>
- * permission java.io.File "/tmp", "read,write",
- * signedBy "Duke";
- * </pre>
- * is represented internally
- * <pre>
- *
- * FilePermission f = new FilePermission("/tmp", "read,write");
- * PublicKey p = publickeys.get("Duke");
- * URL u = InetAddress.getLocalHost();
- * CodeBase c = new CodeBase( p, u );
- * pe = new PolicyEntry(f, c);
- * </pre>
- *
- * @author Marianne Mueller
- * @author Roland Schemers
- * @see java.security.CodeSource
- * @see java.security.Policy
- * @see java.security.Permissions
- * @see java.security.ProtectionDomain
- */
-
- private static class PolicyEntry {
-
- CodeSource codesource;
- Vector<Permission> permissions;
-
- /**
- * Given a Permission and a CodeSource, create a policy entry.
- *
- * XXX Decide if/how to add validity fields and "purpose" fields to
- * XXX policy entries
- *
- * @param cs the CodeSource, which encapsulates the URL and the public
- * key
- * attributes from the policy config file. Validity checks are
- * performed on the public key before PolicyEntry is called.
- *
- */
- PolicyEntry(CodeSource cs)
- {
- this.codesource = cs;
- this.permissions = new Vector<Permission>();
- }
-
- /**
- * add a Permission object to this entry.
- */
- void add(Permission p) {
- permissions.addElement(p);
- }
-
- /**
- * Return the CodeSource for this policy entry
- */
- CodeSource getCodeSource() {
- return this.codesource;
- }
-
- public String toString(){
- StringBuffer sb = new StringBuffer();
- sb.append(rb.getString("LPARAM"));
- sb.append(getCodeSource());
- sb.append("\n");
- for (int j = 0; j < permissions.size(); j++) {
- Permission p = permissions.elementAt(j);
- sb.append(rb.getString("SPACE"));
- sb.append(rb.getString("SPACE"));
- sb.append(p);
- sb.append(rb.getString("NEWLINE"));
- }
- sb.append(rb.getString("RPARAM"));
- sb.append(rb.getString("NEWLINE"));
- return sb.toString();
- }
-
+ final CodeSource codesource) {
+ return apf.getPermissions(subject, codesource);
}
}
-
-@SuppressWarnings("deprecation")
-class PolicyPermissions extends PermissionCollection {
-
- private static final long serialVersionUID = -1954188373270545523L;
-
- private CodeSource codesource;
- private Permissions perms;
- private PolicyFile policy;
- private boolean notInit; // have we pulled in the policy permissions yet?
- private Vector<Permission> additionalPerms;
-
- PolicyPermissions(PolicyFile policy,
- CodeSource codesource)
- {
- this.codesource = codesource;
- this.policy = policy;
- this.perms = null;
- this.notInit = true;
- this.additionalPerms = null;
- }
-
- public void add(Permission permission) {
- if (isReadOnly())
- throw new SecurityException
- (PolicyFile.rb.getString
- ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection"));
-
- if (perms == null) {
- if (additionalPerms == null)
- additionalPerms = new Vector<Permission>();
- additionalPerms.add(permission);
- } else {
- perms.add(permission);
- }
- }
-
- private synchronized void init() {
- if (notInit) {
- if (perms == null)
- perms = new Permissions();
-
- if (additionalPerms != null) {
- Enumeration<Permission> e = additionalPerms.elements();
- while (e.hasMoreElements()) {
- perms.add(e.nextElement());
- }
- additionalPerms = null;
- }
- policy.getPermissions(perms,codesource);
- notInit=false;
- }
- }
-
- public boolean implies(Permission permission) {
- if (notInit)
- init();
- return perms.implies(permission);
- }
-
- public Enumeration<Permission> elements() {
- if (notInit)
- init();
- return perms.elements();
- }
-
- public String toString() {
- if (notInit)
- init();
- return perms.toString();
- }
-}
--- a/jdk/src/share/classes/com/sun/security/auth/PolicyParser.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,964 +0,0 @@
-/*
- * Copyright (c) 1998, 2011, 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.security.auth;
-
-import java.io.*;
-import java.lang.RuntimePermission;
-import java.net.MalformedURLException;
-import java.net.SocketPermission;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.text.MessageFormat;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Vector;
-import java.util.StringTokenizer;
-import sun.security.util.PropertyExpander;
-
-/**
- * The policy for a Java runtime (specifying
- * which permissions are available for code from various principals)
- * is represented as a separate
- * persistent configuration. The configuration may be stored as a
- * flat ASCII file, as a serialized binary file of
- * the Policy class, or as a database. <p>
- *
- * <p>The Java runtime creates one global Policy object, which is used to
- * represent the static policy configuration file. It is consulted by
- * a ProtectionDomain when the protection domain initializes its set of
- * permissions. <p>
- *
- * <p>The Policy <code>init</code> method parses the policy
- * configuration file, and then
- * populates the Policy object. The Policy object is agnostic in that
- * it is not involved in making policy decisions. It is merely the
- * Java runtime representation of the persistent policy configuration
- * file. <p>
- *
- * <p>When a protection domain needs to initialize its set of
- * permissions, it executes code such as the following
- * to ask the global Policy object to populate a
- * Permissions object with the appropriate permissions:
- * <pre>
- * policy = Policy.getPolicy();
- * Permissions perms = policy.getPermissions(MyCodeSource)
- * </pre>
- *
- * <p>The protection domain passes in a CodeSource
- * object, which encapsulates its codebase (URL) and public key attributes.
- * The Policy object evaluates the global policy in light of who the
- * principal is and returns an appropriate Permissions object.
- *
- * @deprecated As of JDK 1.4, replaced by
- * {@link sun.security.provider.PolicyParser}.
- * This class is entirely deprecated.
- *
- * @author Roland Schemers
- *
- * @since 1.2
- */
-@Deprecated
-class PolicyParser {
-
- private static final java.util.ResourceBundle rb =
- java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
- public java.util.ResourceBundle run() {
- return (java.util.ResourceBundle.getBundle
- ("sun.security.util.AuthResources"));
- }
- });
-
- private Vector<GrantEntry> grantEntries;
-
- // Convenience variables for parsing
- private static final sun.security.util.Debug debug =
- sun.security.util.Debug.getInstance("parser", "\t[Auth Policy Parser]");
- private StreamTokenizer st;
- private int lookahead;
- private int linenum;
- private boolean expandProp = false;
- private String keyStoreUrlString = null; // unexpanded
- private String keyStoreType = null;
-
- private String expand(String value)
- throws PropertyExpander.ExpandException
- {
- if (expandProp)
- return PropertyExpander.expand(value);
- else
- return value;
- }
- /**
- * Creates a PolicyParser object.
- */
-
- public PolicyParser() {
- grantEntries = new Vector<GrantEntry>();
- }
-
-
- public PolicyParser(boolean expandProp) {
- this();
- this.expandProp = expandProp;
- }
-
- /**
- * Reads a policy configuration into the Policy object using a
- * Reader object. <p>
- *
- * @param policy the policy Reader object.
- *
- * @exception ParsingException if the policy configuration contains
- * a syntax error.
- *
- * @exception IOException if an error occurs while reading the policy
- * configuration.
- */
-
- public void read(Reader policy)
- throws ParsingException, IOException
- {
- if (!(policy instanceof BufferedReader)) {
- policy = new BufferedReader(policy);
- }
-
- /**
- * Configure the stream tokenizer:
- * Recognize strings between "..."
- * Don't convert words to lowercase
- * Recognize both C-style and C++-style comments
- * Treat end-of-line as white space, not as a token
- */
- st = new StreamTokenizer(policy);
-
- st.resetSyntax();
- st.wordChars('a', 'z');
- st.wordChars('A', 'Z');
- st.wordChars('.', '.');
- st.wordChars('0', '9');
- st.wordChars('_', '_');
- st.wordChars('$', '$');
- st.wordChars(128 + 32, 255);
- st.whitespaceChars(0, ' ');
- st.commentChar('/');
- st.quoteChar('\'');
- st.quoteChar('"');
- st.lowerCaseMode(false);
- st.ordinaryChar('/');
- st.slashSlashComments(true);
- st.slashStarComments(true);
-
- /**
- * The main parsing loop. The loop is executed once
- * for each entry in the config file. The entries
- * are delimited by semicolons. Once we've read in
- * the information for an entry, go ahead and try to
- * add it to the policy vector.
- *
- */
-
- lookahead = st.nextToken();
- while (lookahead != StreamTokenizer.TT_EOF) {
- if (peek("grant")) {
- GrantEntry ge = parseGrantEntry();
- // could be null if we couldn't expand a property
- if (ge != null)
- add(ge);
- } else if (peek("keystore") && keyStoreUrlString==null) {
- // only one keystore entry per policy file, others will be
- // ignored
- parseKeyStoreEntry();
- } else {
- // error?
- }
- match(";");
- }
- }
-
- public void add(GrantEntry ge)
- {
- grantEntries.addElement(ge);
- }
-
- public void replace(GrantEntry origGe, GrantEntry newGe)
- {
- grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe));
- }
-
- public boolean remove(GrantEntry ge)
- {
- return grantEntries.removeElement(ge);
- }
-
- /**
- * Returns the (possibly expanded) keystore location, or null if the
- * expansion fails.
- */
- public String getKeyStoreUrl() {
- try {
- if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) {
- return expand(keyStoreUrlString).replace(File.separatorChar,
- '/');
- }
- } catch (PropertyExpander.ExpandException peee) {
- return null;
- }
- return null;
- }
-
- public void setKeyStoreUrl(String url) {
- keyStoreUrlString = url;
- }
-
- public String getKeyStoreType() {
- return keyStoreType;
- }
-
- public void setKeyStoreType(String type) {
- keyStoreType = type;
- }
-
- /**
- * Enumerate all the entries in the global policy object.
- * This method is used by policy admin tools. The tools
- * should use the Enumeration methods on the returned object
- * to fetch the elements sequentially.
- */
- public Enumeration<GrantEntry> grantElements(){
- return grantEntries.elements();
- }
-
- /**
- * write out the policy
- */
-
- public void write(Writer policy)
- {
- PrintWriter out = new PrintWriter(new BufferedWriter(policy));
-
- Enumeration<GrantEntry> enum_ = grantElements();
-
- out.println("/* AUTOMATICALLY GENERATED ON "+
- (new java.util.Date()) + "*/");
- out.println("/* DO NOT EDIT */");
- out.println();
-
- // write the (unexpanded) keystore entry as the first entry of the
- // policy file
- if (keyStoreUrlString != null) {
- writeKeyStoreEntry(out);
- }
-
- // write "grant" entries
- while (enum_.hasMoreElements()) {
- GrantEntry ge = enum_.nextElement();
- ge.write(out);
- out.println();
- }
- out.flush();
- }
-
- /**
- * parses a keystore entry
- */
- private void parseKeyStoreEntry() throws ParsingException, IOException {
- match("keystore");
- keyStoreUrlString = match("quoted string");
-
- // parse keystore type
- if (!peek(",")) {
- return; // default type
- }
- match(",");
-
- if (peek("\"")) {
- keyStoreType = match("quoted string");
- } else {
- throw new ParsingException(st.lineno(),
- rb.getString("expected.keystore.type"));
- }
- }
-
- /**
- * writes the (unexpanded) keystore entry
- */
- private void writeKeyStoreEntry(PrintWriter out) {
- out.print("keystore \"");
- out.print(keyStoreUrlString);
- out.print('"');
- if (keyStoreType != null && keyStoreType.length() > 0)
- out.print(", \"" + keyStoreType + "\"");
- out.println(";");
- out.println();
- }
-
- /**
- * parse a Grant entry
- */
- private GrantEntry parseGrantEntry()
- throws ParsingException, IOException
- {
- GrantEntry e = new GrantEntry();
- LinkedList<PrincipalEntry> principals = null;
- boolean ignoreEntry = false;
-
- match("grant");
-
- while(!peek("{")) {
-
- if (peekAndMatch("Codebase")) {
- e.codeBase = match("quoted string");
- peekAndMatch(",");
- } else if (peekAndMatch("SignedBy")) {
- e.signedBy = match("quoted string");
- peekAndMatch(",");
- } else if (peekAndMatch("Principal")) {
- if (principals == null) {
- principals = new LinkedList<PrincipalEntry>();
- }
-
- // check for principalClass wildcard
- String principalClass;
- if (peek("*")) {
- match("*");
- principalClass = PrincipalEntry.WILDCARD_CLASS;
- } else {
- principalClass = match("principal type");
- }
-
- // check for principalName wildcard
- String principalName;
- if (peek("*")) {
- match("*");
- principalName = PrincipalEntry.WILDCARD_NAME;
- } else {
- principalName = match("quoted string");
- }
-
- // disallow WILDCARD_CLASS && actual name
- if (principalClass.equals(PrincipalEntry.WILDCARD_CLASS) &&
- !principalName.equals(PrincipalEntry.WILDCARD_NAME)) {
- if (debug != null)
- debug.println("disallowing principal that has " +
- "WILDCARD class but no WILDCARD name");
- throw new ParsingException
- (st.lineno(),
- rb.getString("can.not.specify.Principal.with.a." +
- "wildcard.class.without.a.wildcard.name"));
- }
-
- try {
- principalName = expand(principalName);
- principals.add
- (new PrincipalEntry(principalClass, principalName));
- } catch (PropertyExpander.ExpandException peee) {
- // ignore the entire policy entry
- // but continue parsing all the info
- // so we can get to the next entry
- if (debug != null)
- debug.println("principal name expansion failed: " +
- principalName);
- ignoreEntry = true;
- }
- peekAndMatch(",");
- } else {
- throw new
- ParsingException(st.lineno(),
- rb.getString("expected.codeBase.or.SignedBy"));
- }
- }
-
- // disallow non principal-based grant entries
- if (principals == null) {
- throw new ParsingException
- (st.lineno(),
- rb.getString("only.Principal.based.grant.entries.permitted"));
- }
-
- e.principals = principals;
- match("{");
-
- while(!peek("}")) {
- if (peek("Permission")) {
- try {
- PermissionEntry pe = parsePermissionEntry();
- e.add(pe);
- } catch (PropertyExpander.ExpandException peee) {
- // ignore. The add never happened
- skipEntry(); // BugId 4219343
- }
- match(";");
- } else {
- throw new
- ParsingException(st.lineno(),
- rb.getString("expected.permission.entry"));
- }
- }
- match("}");
-
- try {
- if (e.codeBase != null)
- e.codeBase = expand(e.codeBase).replace(File.separatorChar, '/');
- e.signedBy = expand(e.signedBy);
- } catch (PropertyExpander.ExpandException peee) {
- return null;
- }
-
- return (ignoreEntry == true) ? null : e;
- }
-
- /**
- * parse a Permission entry
- */
- private PermissionEntry parsePermissionEntry()
- throws ParsingException, IOException, PropertyExpander.ExpandException
- {
- PermissionEntry e = new PermissionEntry();
-
- // Permission
- match("Permission");
- e.permission = match("permission type");
-
- if (peek("\"")) {
- // Permission name
- e.name = expand(match("quoted string"));
- }
-
- if (!peek(",")) {
- return e;
- }
- match(",");
-
- if (peek("\"")) {
- e.action = expand(match("quoted string"));
- if (!peek(",")) {
- return e;
- }
- match(",");
- }
-
- if (peekAndMatch("SignedBy")) {
- e.signedBy = expand(match("quoted string"));
- }
- return e;
- }
-
- private boolean peekAndMatch(String expect)
- throws ParsingException, IOException
- {
- if (peek(expect)) {
- match(expect);
- return true;
- } else {
- return false;
- }
- }
-
- private boolean peek(String expect) {
- boolean found = false;
-
- switch (lookahead) {
-
- case StreamTokenizer.TT_WORD:
- if (expect.equalsIgnoreCase(st.sval))
- found = true;
- break;
- case ',':
- if (expect.equalsIgnoreCase(","))
- found = true;
- break;
- case '{':
- if (expect.equalsIgnoreCase("{"))
- found = true;
- break;
- case '}':
- if (expect.equalsIgnoreCase("}"))
- found = true;
- break;
- case '"':
- if (expect.equalsIgnoreCase("\""))
- found = true;
- break;
- case '*':
- if (expect.equalsIgnoreCase("*"))
- found = true;
- break;
- default:
-
- }
- return found;
- }
-
- private String match(String expect)
- throws ParsingException, IOException
- {
- String value = null;
-
- switch (lookahead) {
- case StreamTokenizer.TT_NUMBER:
- throw new ParsingException(st.lineno(), expect,
- rb.getString("number.") +
- String.valueOf(st.nval));
- case StreamTokenizer.TT_EOF:
- MessageFormat form = new MessageFormat(
- rb.getString("expected.expect.read.end.of.file."));
- Object[] source = {expect};
- throw new ParsingException(form.format(source));
- case StreamTokenizer.TT_WORD:
- if (expect.equalsIgnoreCase(st.sval)) {
- lookahead = st.nextToken();
- } else if (expect.equalsIgnoreCase("permission type")) {
- value = st.sval;
- lookahead = st.nextToken();
- } else if (expect.equalsIgnoreCase("principal type")) {
- value = st.sval;
- lookahead = st.nextToken();
- } else {
- throw new ParsingException(st.lineno(), expect, st.sval);
- }
- break;
- case '"':
- if (expect.equalsIgnoreCase("quoted string")) {
- value = st.sval;
- lookahead = st.nextToken();
- } else if (expect.equalsIgnoreCase("permission type")) {
- value = st.sval;
- lookahead = st.nextToken();
- } else if (expect.equalsIgnoreCase("principal type")) {
- value = st.sval;
- lookahead = st.nextToken();
- } else {
- throw new ParsingException(st.lineno(), expect, st.sval);
- }
- break;
- case ',':
- if (expect.equalsIgnoreCase(","))
- lookahead = st.nextToken();
- else
- throw new ParsingException(st.lineno(), expect, ",");
- break;
- case '{':
- if (expect.equalsIgnoreCase("{"))
- lookahead = st.nextToken();
- else
- throw new ParsingException(st.lineno(), expect, "{");
- break;
- case '}':
- if (expect.equalsIgnoreCase("}"))
- lookahead = st.nextToken();
- else
- throw new ParsingException(st.lineno(), expect, "}");
- break;
- case ';':
- if (expect.equalsIgnoreCase(";"))
- lookahead = st.nextToken();
- else
- throw new ParsingException(st.lineno(), expect, ";");
- break;
- case '*':
- if (expect.equalsIgnoreCase("*"))
- lookahead = st.nextToken();
- else
- throw new ParsingException(st.lineno(), expect, "*");
- break;
- default:
- throw new ParsingException(st.lineno(), expect,
- new String(new char[] {(char)lookahead}));
- }
- return value;
- }
-
- /**
- * skip all tokens for this entry leaving the delimiter ";"
- * in the stream.
- */
- private void skipEntry()
- throws ParsingException, IOException
- {
- while(lookahead != ';') {
- switch (lookahead) {
- case StreamTokenizer.TT_NUMBER:
- throw new ParsingException(st.lineno(), ";",
- rb.getString("number.") +
- String.valueOf(st.nval));
- case StreamTokenizer.TT_EOF:
- throw new ParsingException
- (rb.getString("expected.read.end.of.file"));
- default:
- lookahead = st.nextToken();
- }
- }
- }
-
- /**
- * Each grant entry in the policy configuration file is
- * represented by a
- * GrantEntry object. <p>
- *
- * <p>
- * For example, the entry
- * <pre>
- * grant signedBy "Duke" {
- * permission java.io.FilePermission "/tmp", "read,write";
- * };
- *
- * </pre>
- * is represented internally
- * <pre>
- *
- * pe = new PermissionEntry("java.io.FilePermission",
- * "/tmp", "read,write");
- *
- * ge = new GrantEntry("Duke", null);
- *
- * ge.add(pe);
- *
- * </pre>
- *
- * @author Roland Schemers
- *
- * version 1.19, 05/21/98
- */
-
- static class GrantEntry {
-
- public String signedBy;
- public String codeBase;
- public LinkedList<PrincipalEntry> principals;
- public Vector<PermissionEntry> permissionEntries;
-
- public GrantEntry() {
- permissionEntries = new Vector<PermissionEntry>();
- }
-
- public GrantEntry(String signedBy, String codeBase) {
- this.codeBase = codeBase;
- this.signedBy = signedBy;
- permissionEntries = new Vector<PermissionEntry>();
- }
-
- public void add(PermissionEntry pe)
- {
- permissionEntries.addElement(pe);
- }
-
- public boolean remove(PermissionEntry pe)
- {
- return permissionEntries.removeElement(pe);
- }
-
- public boolean contains(PermissionEntry pe)
- {
- return permissionEntries.contains(pe);
- }
-
- /**
- * Enumerate all the permission entries in this GrantEntry.
- */
- public Enumeration<PermissionEntry> permissionElements(){
- return permissionEntries.elements();
- }
-
-
- public void write(PrintWriter out) {
- out.print("grant");
- if (signedBy != null) {
- out.print(" signedBy \"");
- out.print(signedBy);
- out.print('"');
- if (codeBase != null)
- out.print(", ");
- }
- if (codeBase != null) {
- out.print(" codeBase \"");
- out.print(codeBase);
- out.print('"');
- if (principals != null && principals.size() > 0)
- out.print(",\n");
- }
- if (principals != null && principals.size() > 0) {
- ListIterator<PrincipalEntry> pli = principals.listIterator();
- while (pli.hasNext()) {
- out.print("\tPrincipal ");
- PrincipalEntry pe = pli.next();
- out.print(pe.principalClass +
- " \"" + pe.principalName + "\"");
- if (pli.hasNext())
- out.print(",\n");
- }
- }
- out.println(" {");
- Enumeration<PermissionEntry> enum_ = permissionEntries.elements();
- while (enum_.hasMoreElements()) {
- PermissionEntry pe = enum_.nextElement();
- out.write(" ");
- pe.write(out);
- }
- out.println("};");
- }
-
- }
-
- /**
- * Principal info (class and name) in a grant entry
- */
- static class PrincipalEntry {
-
- static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS";
- static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";
-
- String principalClass;
- String principalName;
-
- /**
- * A PrincipalEntry consists of the <code>Principal</code>
- * class and <code>Principal</code> name.
- *
- * <p>
- *
- * @param principalClass the <code>Principal</code> class. <p>
- *
- * @param principalName the <code>Principal</code> name. <p>
- */
- public PrincipalEntry(String principalClass, String principalName) {
- if (principalClass == null || principalName == null)
- throw new NullPointerException
- ("null principalClass or principalName");
- this.principalClass = principalClass;
- this.principalName = principalName;
- }
-
- /**
- * Test for equality between the specified object and this object.
- * Two PrincipalEntries are equal if their PrincipalClass and
- * PrincipalName values are equal.
- *
- * <p>
- *
- * @param obj the object to test for equality with this object.
- *
- * @return true if the objects are equal, false otherwise.
- */
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
-
- if (!(obj instanceof PrincipalEntry))
- return false;
-
- PrincipalEntry that = (PrincipalEntry)obj;
- if (this.principalClass.equals(that.principalClass) &&
- this.principalName.equals(that.principalName)) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Return a hashcode for this <code>PrincipalEntry</code>.
- *
- * <p>
- *
- * @return a hashcode for this <code>PrincipalEntry</code>.
- */
- public int hashCode() {
- return principalClass.hashCode();
- }
- }
-
- /**
- * Each permission entry in the policy configuration file is
- * represented by a
- * PermissionEntry object. <p>
- *
- * <p>
- * For example, the entry
- * <pre>
- * permission java.io.FilePermission "/tmp", "read,write";
- * </pre>
- * is represented internally
- * <pre>
- *
- * pe = new PermissionEntry("java.io.FilePermission",
- * "/tmp", "read,write");
- * </pre>
- *
- * @author Roland Schemers
- *
- * version 1.19, 05/21/98
- */
-
- static class PermissionEntry {
-
- public String permission;
- public String name;
- public String action;
- public String signedBy;
-
- public PermissionEntry() {
- }
-
- public PermissionEntry(String permission,
- String name,
- String action) {
- this.permission = permission;
- this.name = name;
- this.action = action;
- }
-
- /**
- * Calculates a hash code value for the object. Objects
- * which are equal will also have the same hashcode.
- */
- public int hashCode() {
- int retval = permission.hashCode();
- if (name != null) retval ^= name.hashCode();
- if (action != null) retval ^= action.hashCode();
- return retval;
- }
-
- public boolean equals(Object obj) {
- if (obj == this)
- return true;
-
- if (! (obj instanceof PermissionEntry))
- return false;
-
- PermissionEntry that = (PermissionEntry) obj;
-
- if (this.permission == null) {
- if (that.permission != null) return false;
- } else {
- if (!this.permission.equals(that.permission)) return false;
- }
-
- if (this.name == null) {
- if (that.name != null) return false;
- } else {
- if (!this.name.equals(that.name)) return false;
- }
-
- if (this.action == null) {
- if (that.action != null) return false;
- } else {
- if (!this.action.equals(that.action)) return false;
- }
-
- if (this.signedBy == null) {
- if (that.signedBy != null) return false;
- } else {
- if (!this.signedBy.equals(that.signedBy)) return false;
- }
-
- // everything matched -- the 2 objects are equal
- return true;
- }
-
- public void write(PrintWriter out) {
- out.print("permission ");
- out.print(permission);
- if (name != null) {
- out.print(" \"");
-
- // have to add escape chars for quotes
- if (name.indexOf("\"") != -1) {
- int numQuotes = 0;
- char[] chars = name.toCharArray();
-
- // count the number of quote chars
- for (int i = 0; i < chars.length; i++) {
- if (chars[i] == '"')
- numQuotes++;
- }
-
- // now, add an escape char before each quote
- char[] newChars = new char[chars.length + numQuotes];
- for (int i = 0, j = 0; i < chars.length; i++) {
- if (chars[i] != '"') {
- newChars[j++] = chars[i];
- } else {
- newChars[j++] = '\\';
- newChars[j++] = chars[i];
- }
- }
- name = new String(newChars);
- }
- out.print(name);
- out.print('"');
- }
- if (action != null) {
- out.print(", \"");
- out.print(action);
- out.print('"');
- }
- if (signedBy != null) {
- out.print(", signedBy \"");
- out.print(signedBy);
- out.print('"');
- }
- out.println(";");
- }
- }
-
- static class ParsingException extends GeneralSecurityException {
-
- private static final long serialVersionUID = 8240970523155877400L;
-
- /**
- * Constructs a ParsingException with the specified
- * detail message. A detail message is a String that describes
- * this particular exception, which may, for example, specify which
- * algorithm is not available.
- *
- * @param msg the detail message.
- */
- public ParsingException(String msg) {
- super(msg);
- }
-
- public ParsingException(int line, String msg) {
- super(rb.getString("line.") + line + rb.getString("COLON") + msg);
- }
-
- public ParsingException(int line, String expect, String actual) {
- super(rb.getString("line.") + line + rb.getString(".expected.") +
- expect + rb.getString(".found.") + actual +
- rb.getString("QUOTE"));
- }
- }
-
- public static void main(String arg[]) throws Exception {
- PolicyParser pp = new PolicyParser(true);
- pp.read(new FileReader(arg[0]));
- FileWriter fr = new FileWriter(arg[1]);
- pp.write(fr);
- fr.close();
- }
-}
--- a/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,398 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, 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.security.auth;
-
-import java.net.URL;
-import java.util.*;
-import java.security.CodeSource;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.lang.reflect.Constructor;
-
-import javax.security.auth.Subject;
-import sun.security.provider.PolicyParser.PrincipalEntry;
-
-/**
- * <p> This <code>SubjectCodeSource</code> class contains
- * a <code>URL</code>, signer certificates, and either a <code>Subject</code>
- * (that represents the <code>Subject</code> in the current
- * <code>AccessControlContext</code>),
- * or a linked list of Principals/PrincipalComparators
- * (that represent a "subject" in a <code>Policy</code>).
- *
- */
-class SubjectCodeSource extends CodeSource implements java.io.Serializable {
-
- private static final long serialVersionUID = 6039418085604715275L;
-
- private static final java.util.ResourceBundle rb =
- java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
- public java.util.ResourceBundle run() {
- return (java.util.ResourceBundle.getBundle
- ("sun.security.util.AuthResources"));
- }
- });
-
- private Subject subject;
- private LinkedList<PrincipalEntry> principals;
- private static final Class[] PARAMS = { String.class };
- private static final sun.security.util.Debug debug =
- sun.security.util.Debug.getInstance("auth", "\t[Auth Access]");
- private ClassLoader sysClassLoader;
-
- /**
- * Creates a new <code>SubjectCodeSource</code>
- * with the given <code>Subject</code>, principals, <code>URL</code>,
- * and signers (Certificates). The <code>Subject</code>
- * represents the <code>Subject</code> associated with the current
- * <code>AccessControlContext</code>.
- * The Principals are given as a <code>LinkedList</code>
- * of <code>PolicyParser.PrincipalEntry</code> objects.
- * Typically either a <code>Subject</code> will be provided,
- * or a list of <code>principals</code> will be provided
- * (not both).
- *
- * <p>
- *
- * @param subject the <code>Subject</code> associated with this
- * <code>SubjectCodeSource</code> <p>
- *
- * @param url the <code>URL</code> associated with this
- * <code>SubjectCodeSource</code> <p>
- *
- * @param certs the signers associated with this
- * <code>SubjectCodeSource</code> <p>
- */
- SubjectCodeSource(Subject subject,
- LinkedList<PrincipalEntry> principals,
- URL url, Certificate[] certs) {
-
- super(url, certs);
- this.subject = subject;
- this.principals = (principals == null ?
- new LinkedList<PrincipalEntry>() :
- new LinkedList<PrincipalEntry>(principals));
- sysClassLoader = java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return ClassLoader.getSystemClassLoader();
- }
- });
- }
-
- /**
- * Get the Principals associated with this <code>SubjectCodeSource</code>.
- * The Principals are retrieved as a <code>LinkedList</code>
- * of <code>PolicyParser.PrincipalEntry</code> objects.
- *
- * <p>
- *
- * @return the Principals associated with this
- * <code>SubjectCodeSource</code> as a <code>LinkedList</code>
- * of <code>PolicyParser.PrincipalEntry</code> objects.
- */
- LinkedList<PrincipalEntry> getPrincipals() {
- return principals;
- }
-
- /**
- * Get the <code>Subject</code> associated with this
- * <code>SubjectCodeSource</code>. The <code>Subject</code>
- * represents the <code>Subject</code> associated with the
- * current <code>AccessControlContext</code>.
- *
- * <p>
- *
- * @return the <code>Subject</code> associated with this
- * <code>SubjectCodeSource</code>.
- */
- Subject getSubject() {
- return subject;
- }
-
- /**
- * Returns true if this <code>SubjectCodeSource</code> object "implies"
- * the specified <code>CodeSource</code>.
- * More specifically, this method makes the following checks.
- * If any fail, it returns false. If they all succeed, it returns true.
- *
- * <p>
- * <ol>
- * <li> The provided codesource must not be <code>null</code>.
- * <li> codesource must be an instance of <code>SubjectCodeSource</code>.
- * <li> super.implies(codesource) must return true.
- * <li> for each principal in this codesource's principal list:
- * <ol>
- * <li> if the principal is an instanceof
- * <code>PrincipalComparator</code>, then the principal must
- * imply the provided codesource's <code>Subject</code>.
- * <li> if the principal is not an instanceof
- * <code>PrincipalComparator</code>, then the provided
- * codesource's <code>Subject</code> must have an
- * associated <code>Principal</code>, <i>P</i>, where
- * P.getClass().getName equals principal.principalClass,
- * and P.getName() equals principal.principalName.
- * </ol>
- * </ol>
- *
- * <p>
- *
- * @param codesource the <code>CodeSource</code> to compare against.
- *
- * @return true if this <code>SubjectCodeSource</code> implies the
- * the specified <code>CodeSource</code>.
- */
- public boolean implies(CodeSource codesource) {
-
- LinkedList<PrincipalEntry> subjectList = null;
-
- if (codesource == null ||
- !(codesource instanceof SubjectCodeSource) ||
- !(super.implies(codesource))) {
-
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: FAILURE 1");
- return false;
- }
-
- SubjectCodeSource that = (SubjectCodeSource)codesource;
-
- // if the principal list in the policy "implies"
- // the Subject associated with the current AccessControlContext,
- // then return true
-
- if (this.principals == null) {
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: PASS 1");
- return true;
- }
-
- if (that.getSubject() == null ||
- that.getSubject().getPrincipals().size() == 0) {
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: FAILURE 2");
- return false;
- }
-
- ListIterator<PrincipalEntry> li = this.principals.listIterator(0);
- while (li.hasNext()) {
- PrincipalEntry pppe = li.next();
- try {
-
- // handle PrincipalComparators
-
- Class<?> principalComparator = Class.forName(
- pppe.getPrincipalClass(), true, sysClassLoader);
- Constructor<?> c = principalComparator.getConstructor(PARAMS);
- PrincipalComparator pc =
- (PrincipalComparator)c.newInstance
- (new Object[] { pppe.getPrincipalName() });
-
- if (!pc.implies(that.getSubject())) {
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: FAILURE 3");
- return false;
- } else {
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: PASS 2");
- return true;
- }
- } catch (Exception e) {
-
- // no PrincipalComparator, simply compare Principals
-
- if (subjectList == null) {
-
- if (that.getSubject() == null) {
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: " +
- "FAILURE 4");
- return false;
- }
- Iterator<Principal> i =
- that.getSubject().getPrincipals().iterator();
-
- subjectList = new LinkedList<PrincipalEntry>();
- while (i.hasNext()) {
- Principal p = i.next();
- PrincipalEntry spppe = new PrincipalEntry
- (p.getClass().getName(), p.getName());
- subjectList.add(spppe);
- }
- }
-
- if (!subjectListImpliesPrincipalEntry(subjectList, pppe)) {
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: FAILURE 5");
- return false;
- }
- }
- }
-
- if (debug != null)
- debug.println("\tSubjectCodeSource.implies: PASS 3");
- return true;
- }
-
- /**
- * This method returns, true, if the provided <i>subjectList</i>
- * "contains" the <code>Principal</code> specified
- * in the provided <i>pppe</i> argument.
- *
- * Note that the provided <i>pppe</i> argument may have
- * wildcards (*) for the <code>Principal</code> class and name,
- * which need to be considered.
- *
- * <p>
- *
- * @param subjectList a list of PolicyParser.PrincipalEntry objects
- * that correspond to all the Principals in the Subject currently
- * on this thread's AccessControlContext. <p>
- *
- * @param pppe the Principals specified in a grant entry.
- *
- * @return true if the provided <i>subjectList</i> "contains"
- * the <code>Principal</code> specified in the provided
- * <i>pppe</i> argument.
- */
- private boolean subjectListImpliesPrincipalEntry(
- LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) {
-
- ListIterator<PrincipalEntry> li = subjectList.listIterator(0);
- while (li.hasNext()) {
- PrincipalEntry listPppe = li.next();
-
- if (pppe.getPrincipalClass().equals
- (PrincipalEntry.WILDCARD_CLASS) ||
- pppe.getPrincipalClass().equals(listPppe.getPrincipalClass()))
- {
- if (pppe.getPrincipalName().equals
- (PrincipalEntry.WILDCARD_NAME) ||
- pppe.getPrincipalName().equals(listPppe.getPrincipalName()))
- return true;
- }
- }
- return false;
- }
-
- /**
- * Tests for equality between the specified object and this
- * object. Two <code>SubjectCodeSource</code> objects are considered equal
- * if their locations are of identical value, if the two sets of
- * Certificates are of identical values, and if the
- * Subjects are equal, and if the PolicyParser.PrincipalEntry values
- * are of identical values. It is not required that
- * the Certificates or PolicyParser.PrincipalEntry values
- * be in the same order.
- *
- * <p>
- *
- * @param obj the object to test for equality with this object.
- *
- * @return true if the objects are considered equal, false otherwise.
- */
- public boolean equals(Object obj) {
-
- if (obj == this)
- return true;
-
- if (super.equals(obj) == false)
- return false;
-
- if (!(obj instanceof SubjectCodeSource))
- return false;
-
- SubjectCodeSource that = (SubjectCodeSource)obj;
-
- // the principal lists must match
- try {
- if (this.getSubject() != that.getSubject())
- return false;
- } catch (SecurityException se) {
- return false;
- }
-
- if ((this.principals == null && that.principals != null) ||
- (this.principals != null && that.principals == null))
- return false;
-
- if (this.principals != null && that.principals != null) {
- if (!this.principals.containsAll(that.principals) ||
- !that.principals.containsAll(this.principals))
-
- return false;
- }
-
- return true;
- }
-
- /**
- * Return a hashcode for this <code>SubjectCodeSource</code>.
- *
- * <p>
- *
- * @return a hashcode for this <code>SubjectCodeSource</code>.
- */
- public int hashCode() {
- return super.hashCode();
- }
-
- /**
- * Return a String representation of this <code>SubjectCodeSource</code>.
- *
- * <p>
- *
- * @return a String representation of this <code>SubjectCodeSource</code>.
- */
- public String toString() {
- String returnMe = super.toString();
- if (getSubject() != null) {
- if (debug != null) {
- final Subject finalSubject = getSubject();
- returnMe = returnMe + "\n" +
- java.security.AccessController.doPrivileged
- (new java.security.PrivilegedAction<String>() {
- public String run() {
- return finalSubject.toString();
- }
- });
- } else {
- returnMe = returnMe + "\n" + getSubject().toString();
- }
- }
- if (principals != null) {
- ListIterator<PrincipalEntry> li = principals.listIterator();
- while (li.hasNext()) {
- PrincipalEntry pppe = li.next();
- returnMe = returnMe + rb.getString("NEWLINE") +
- pppe.getPrincipalClass() + " " +
- pppe.getPrincipalName();
- }
- }
- return returnMe;
- }
-}
--- a/jdk/src/share/classes/com/sun/security/auth/login/ConfigFile.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/security/auth/login/ConfigFile.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, 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,9 +30,9 @@
import java.net.URI;
// NOTE: As of JDK 8, this class instantiates
-// sun.security.provider.ConfigSpiFile and forwards all methods to that
+// sun.security.provider.ConfigFile.Spi and forwards all methods to that
// implementation. All implementation fixes and enhancements should be made to
-// sun.security.provider.ConfigSpiFile and not this class.
+// sun.security.provider.ConfigFile.Spi and not this class.
// See JDK-8005117 for more information.
/**
@@ -85,7 +85,7 @@
*/
public class ConfigFile extends Configuration {
- private sun.security.provider.ConfigSpiFile configFile;
+ private final sun.security.provider.ConfigFile.Spi spi;
/**
* Create a new {@code Configuration} object.
@@ -94,7 +94,7 @@
* initialized
*/
public ConfigFile() {
- configFile = new sun.security.provider.ConfigSpiFile();
+ spi = new sun.security.provider.ConfigFile.Spi();
}
/**
@@ -106,7 +106,7 @@
* @throws NullPointerException if {@code uri} is null
*/
public ConfigFile(URI uri) {
- configFile = new sun.security.provider.ConfigSpiFile(uri);
+ spi = new sun.security.provider.ConfigFile.Spi(uri);
}
/**
@@ -123,7 +123,7 @@
public AppConfigurationEntry[] getAppConfigurationEntry
(String applicationName) {
- return configFile.engineGetAppConfigurationEntry(applicationName);
+ return spi.engineGetAppConfigurationEntry(applicationName);
}
/**
@@ -134,7 +134,7 @@
* to refresh the {@code Configuration}
*/
@Override
- public synchronized void refresh() {
- configFile.engineRefresh();
+ public void refresh() {
+ spi.engineRefresh();
}
}
--- a/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js Wed Jul 05 19:09:26 2017 +0200
@@ -1144,7 +1144,7 @@
} else {
for (var index in array) {
var it = array[index];
- if (func(it, index, array)) {
+ if (func(it, String(index), array)) {
return true;
}
}
@@ -1244,7 +1244,7 @@
var result = new Array();
for (var index in array) {
var it = array[index];
- if (func(it, index, array, result)) {
+ if (func(it, String(index), array, result)) {
result[result.length] = it;
}
}
@@ -1317,7 +1317,7 @@
var result = new Array();
for (var index in array) {
var it = array[index];
- result[result.length] = func(it, index, array, result);
+ result[result.length] = func(it, String(index), array, result);
}
return result;
}
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Wed Jul 05 19:09:26 2017 +0200
@@ -2426,7 +2426,8 @@
focusLog.finest("Request {0}", String.valueOf(hwFocusRequest));
}
if (hwFocusRequest == null &&
- heavyweight == nativeFocusOwner)
+ heavyweight == nativeFocusOwner &&
+ heavyweight.getContainingWindow() == nativeFocusedWindow)
{
if (descendant == currentFocusOwner) {
// Redundant request.
--- a/jdk/src/share/classes/java/awt/Window.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/awt/Window.java Wed Jul 05 19:09:26 2017 +0200
@@ -62,18 +62,18 @@
import sun.util.logging.PlatformLogger;
/**
- * A <code>Window</code> object is a top-level window with no borders and no
+ * A {@code Window} object is a top-level window with no borders and no
* menubar.
- * The default layout for a window is <code>BorderLayout</code>.
+ * The default layout for a window is {@code BorderLayout}.
* <p>
* A window must have either a frame, dialog, or another window defined as its
* owner when it's constructed.
* <p>
- * In a multi-screen environment, you can create a <code>Window</code>
- * on a different screen device by constructing the <code>Window</code>
+ * In a multi-screen environment, you can create a {@code Window}
+ * on a different screen device by constructing the {@code Window}
* with {@link #Window(Window, GraphicsConfiguration)}. The
- * <code>GraphicsConfiguration</code> object is one of the
- * <code>GraphicsConfiguration</code> objects of the target screen device.
+ * {@code GraphicsConfiguration} object is one of the
+ * {@code GraphicsConfiguration} objects of the target screen device.
* <p>
* In a virtual device multi-screen environment in which the desktop
* area could span multiple physical screen devices, the bounds of all
@@ -87,21 +87,21 @@
* alt="Diagram shows virtual device containing 4 physical screens. Primary physical screen shows coords (0,0), other screen shows (-80,-100)."
* ALIGN=center HSPACE=10 VSPACE=7>
* <p>
- * In such an environment, when calling <code>setLocation</code>,
+ * In such an environment, when calling {@code setLocation},
* you must pass a virtual coordinate to this method. Similarly,
- * calling <code>getLocationOnScreen</code> on a <code>Window</code> returns
- * virtual device coordinates. Call the <code>getBounds</code> method
- * of a <code>GraphicsConfiguration</code> to find its origin in the virtual
+ * calling {@code getLocationOnScreen} on a {@code Window} returns
+ * virtual device coordinates. Call the {@code getBounds} method
+ * of a {@code GraphicsConfiguration} to find its origin in the virtual
* coordinate system.
* <p>
- * The following code sets the location of a <code>Window</code>
+ * The following code sets the location of a {@code Window}
* at (10, 10) relative to the origin of the physical screen
- * of the corresponding <code>GraphicsConfiguration</code>. If the
- * bounds of the <code>GraphicsConfiguration</code> is not taken
- * into account, the <code>Window</code> location would be set
+ * of the corresponding {@code GraphicsConfiguration}. If the
+ * bounds of the {@code GraphicsConfiguration} is not taken
+ * into account, the {@code Window} location would be set
* at (10, 10) relative to the virtual-coordinate system and would appear
* on the primary physical screen, which might be different from the
- * physical screen of the specified <code>GraphicsConfiguration</code>.
+ * physical screen of the specified {@code GraphicsConfiguration}.
*
* <pre>
* Window w = new Window(Window owner, GraphicsConfiguration gc);
@@ -111,19 +111,19 @@
*
* <p>
* Note: the location and size of top-level windows (including
- * <code>Window</code>s, <code>Frame</code>s, and <code>Dialog</code>s)
+ * {@code Window}s, {@code Frame}s, and {@code Dialog}s)
* are under the control of the desktop's window management system.
- * Calls to <code>setLocation</code>, <code>setSize</code>, and
- * <code>setBounds</code> are requests (not directives) which are
+ * Calls to {@code setLocation}, {@code setSize}, and
+ * {@code setBounds} are requests (not directives) which are
* forwarded to the window management system. Every effort will be
* made to honor such requests. However, in some cases the window
* management system may ignore such requests, or modify the requested
- * geometry in order to place and size the <code>Window</code> in a way
+ * geometry in order to place and size the {@code Window} in a way
* that more closely matches the desktop settings.
* <p>
* Due to the asynchronous nature of native event handling, the results
- * returned by <code>getBounds</code>, <code>getLocation</code>,
- * <code>getLocationOnScreen</code>, and <code>getSize</code> might not
+ * returned by {@code getBounds}, {@code getLocation},
+ * {@code getLocationOnScreen}, and {@code getSize} might not
* reflect the actual geometry of the Window on screen until the last
* request has been processed. During the processing of subsequent
* requests these values might change accordingly while the window
@@ -340,7 +340,7 @@
*/
transient boolean isInShow = false;
- /*
+ /**
* The opacity level of the window
*
* @serial
@@ -350,7 +350,7 @@
*/
private float opacity = 1.0f;
- /*
+ /**
* The shape assigned to this window. This field is set to {@code null} if
* no shape is set (rectangular window).
*
@@ -415,21 +415,21 @@
/**
* Constructs a new, initially invisible window in default size with the
- * specified <code>GraphicsConfiguration</code>.
+ * specified {@code GraphicsConfiguration}.
* <p>
* If there is a security manager, this method first calls
- * the security manager's <code>checkTopLevelWindow</code>
- * method with <code>this</code>
+ * the security manager's {@code checkTopLevelWindow}
+ * method with {@code this}
* as its argument to determine whether or not the window
* must be displayed with a warning banner.
*
- * @param gc the <code>GraphicsConfiguration</code> of the target screen
- * device. If <code>gc</code> is <code>null</code>, the system default
- * <code>GraphicsConfiguration</code> is assumed
- * @exception IllegalArgumentException if <code>gc</code>
+ * @param gc the {@code GraphicsConfiguration} of the target screen
+ * device. If {@code gc} is {@code null}, the system default
+ * {@code GraphicsConfiguration} is assumed
+ * @exception IllegalArgumentException if {@code gc}
* is not from a screen device
* @exception HeadlessException when
- * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
+ * {@code GraphicsEnvironment.isHeadless()} returns {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
* @see java.lang.SecurityManager#checkTopLevelWindow
@@ -513,20 +513,20 @@
* Constructs a new, initially invisible window in the default size.
*
* <p>First, if there is a security manager, its
- * <code>checkTopLevelWindow</code>
- * method is called with <code>this</code>
+ * {@code checkTopLevelWindow}
+ * method is called with {@code this}
* as its argument
* to see if it's ok to display the window without a warning banner.
- * If the default implementation of <code>checkTopLevelWindow</code>
+ * If the default implementation of {@code checkTopLevelWindow}
* is used (that is, that method is not overriden), then this results in
- * a call to the security manager's <code>checkPermission</code> method
- * with an <code>AWTPermission("showWindowWithoutWarningBanner")</code>
+ * a call to the security manager's {@code checkPermission} method
+ * with an {@code AWTPermission("showWindowWithoutWarningBanner")}
* permission. It that method raises a SecurityException,
- * <code>checkTopLevelWindow</code> returns false, otherwise it
+ * {@code checkTopLevelWindow} returns false, otherwise it
* returns true. If it returns false, a warning banner is created.
*
* @exception HeadlessException when
- * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
+ * {@code GraphicsEnvironment.isHeadless()} returns {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
* @see java.lang.SecurityManager#checkTopLevelWindow
@@ -538,21 +538,21 @@
/**
* Constructs a new, initially invisible window with the specified
- * <code>Frame</code> as its owner. The window will not be focusable
+ * {@code Frame} as its owner. The window will not be focusable
* unless its owner is showing on the screen.
* <p>
* If there is a security manager, this method first calls
- * the security manager's <code>checkTopLevelWindow</code>
- * method with <code>this</code>
+ * the security manager's {@code checkTopLevelWindow}
+ * method with {@code this}
* as its argument to determine whether or not the window
* must be displayed with a warning banner.
*
- * @param owner the <code>Frame</code> to act as owner or <code>null</code>
+ * @param owner the {@code Frame} to act as owner or {@code null}
* if this window has no owner
- * @exception IllegalArgumentException if the <code>owner</code>'s
- * <code>GraphicsConfiguration</code> is not from a screen device
+ * @exception IllegalArgumentException if the {@code owner}'s
+ * {@code GraphicsConfiguration} is not from a screen device
* @exception HeadlessException when
- * <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>
+ * {@code GraphicsEnvironment.isHeadless} returns {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
* @see java.lang.SecurityManager#checkTopLevelWindow
@@ -566,23 +566,23 @@
/**
* Constructs a new, initially invisible window with the specified
- * <code>Window</code> as its owner. This window will not be focusable
- * unless its nearest owning <code>Frame</code> or <code>Dialog</code>
+ * {@code Window} as its owner. This window will not be focusable
+ * unless its nearest owning {@code Frame} or {@code Dialog}
* is showing on the screen.
* <p>
* If there is a security manager, this method first calls
- * the security manager's <code>checkTopLevelWindow</code>
- * method with <code>this</code>
+ * the security manager's {@code checkTopLevelWindow}
+ * method with {@code this}
* as its argument to determine whether or not the window
* must be displayed with a warning banner.
*
- * @param owner the <code>Window</code> to act as owner or
- * <code>null</code> if this window has no owner
- * @exception IllegalArgumentException if the <code>owner</code>'s
- * <code>GraphicsConfiguration</code> is not from a screen device
+ * @param owner the {@code Window} to act as owner or
+ * {@code null} if this window has no owner
+ * @exception IllegalArgumentException if the {@code owner}'s
+ * {@code GraphicsConfiguration} is not from a screen device
* @exception HeadlessException when
- * <code>GraphicsEnvironment.isHeadless()</code> returns
- * <code>true</code>
+ * {@code GraphicsEnvironment.isHeadless()} returns
+ * {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
* @see java.lang.SecurityManager#checkTopLevelWindow
@@ -598,27 +598,27 @@
/**
* Constructs a new, initially invisible window with the specified owner
- * <code>Window</code> and a <code>GraphicsConfiguration</code>
+ * {@code Window} and a {@code GraphicsConfiguration}
* of a screen device. The Window will not be focusable unless
- * its nearest owning <code>Frame</code> or <code>Dialog</code>
+ * its nearest owning {@code Frame} or {@code Dialog}
* is showing on the screen.
* <p>
* If there is a security manager, this method first calls
- * the security manager's <code>checkTopLevelWindow</code>
- * method with <code>this</code>
+ * the security manager's {@code checkTopLevelWindow}
+ * method with {@code this}
* as its argument to determine whether or not the window
* must be displayed with a warning banner.
*
- * @param owner the window to act as owner or <code>null</code>
+ * @param owner the window to act as owner or {@code null}
* if this window has no owner
- * @param gc the <code>GraphicsConfiguration</code> of the target
- * screen device; if <code>gc</code> is <code>null</code>,
- * the system default <code>GraphicsConfiguration</code> is assumed
- * @exception IllegalArgumentException if <code>gc</code>
+ * @param gc the {@code GraphicsConfiguration} of the target
+ * screen device; if {@code gc} is {@code null},
+ * the system default {@code GraphicsConfiguration} is assumed
+ * @exception IllegalArgumentException if {@code gc}
* is not from a screen device
* @exception HeadlessException when
- * <code>GraphicsEnvironment.isHeadless()</code> returns
- * <code>true</code>
+ * {@code GraphicsEnvironment.isHeadless()} returns
+ * {@code true}
*
* @see java.awt.GraphicsEnvironment#isHeadless
* @see java.lang.SecurityManager#checkTopLevelWindow
@@ -936,7 +936,7 @@
/**
* @deprecated As of JDK version 1.1,
- * replaced by <code>setBounds(int, int, int, int)</code>.
+ * replaced by {@code setBounds(int, int, int, int)}.
*/
@Deprecated
public void reshape(int x, int y, int width, int height) {
@@ -1122,16 +1122,16 @@
/**
* Releases all of the native screen resources used by this
- * <code>Window</code>, its subcomponents, and all of its owned
- * children. That is, the resources for these <code>Component</code>s
+ * {@code Window}, its subcomponents, and all of its owned
+ * children. That is, the resources for these {@code Component}s
* will be destroyed, any memory they consume will be returned to the
* OS, and they will be marked as undisplayable.
* <p>
- * The <code>Window</code> and its subcomponents can be made displayable
+ * The {@code Window} and its subcomponents can be made displayable
* again by rebuilding the native resources with a subsequent call to
- * <code>pack</code> or <code>show</code>. The states of the recreated
- * <code>Window</code> and its subcomponents will be identical to the
- * states of these objects at the point where the <code>Window</code>
+ * {@code pack} or {@code show}. The states of the recreated
+ * {@code Window} and its subcomponents will be identical to the
+ * states of these objects at the point where the {@code Window}
* was disposed (not accounting for additional modifications between
* those actions).
* <p>
@@ -1363,14 +1363,14 @@
* If this window is insecure, the warning string is displayed
* somewhere in the visible area of the window. A window is
* insecure if there is a security manager, and the security
- * manager's <code>checkTopLevelWindow</code> method returns
- * <code>false</code> when this window is passed to it as an
+ * manager's {@code checkTopLevelWindow} method returns
+ * {@code false} when this window is passed to it as an
* argument.
* <p>
- * If the window is secure, then <code>getWarningString</code>
- * returns <code>null</code>. If the window is insecure, this
+ * If the window is secure, then {@code getWarningString}
+ * returns {@code null}. If the window is insecure, this
* method checks for the system property
- * <code>awt.appletWarning</code>
+ * {@code awt.appletWarning}
* and returns the string value of that property.
* @return the warning string for this window.
* @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
@@ -1395,7 +1395,7 @@
}
/**
- * Gets the <code>Locale</code> object that is associated
+ * Gets the {@code Locale} object that is associated
* with this window, if the locale has been set.
* If no locale has been set, then the default locale
* is returned.
@@ -1432,7 +1432,7 @@
* implementation and/or the native system do not support
* changing the mouse cursor shape.
* @param cursor One of the constants defined
- * by the <code>Cursor</code> class. If this parameter is null
+ * by the {@code Cursor} class. If this parameter is null
* then the cursor for this window will be set to the type
* Cursor.DEFAULT_CURSOR.
* @see Component#getCursor
@@ -1579,7 +1579,7 @@
* <b>Warning:</b> this method may return system created windows, such
* as a print dialog. Applications should not assume the existence of
* these dialogs, nor should an application assume anything about these
- * dialogs such as component positions, <code>LayoutManager</code>s
+ * dialogs such as component positions, {@code LayoutManager}s
* or serialization.
*
* @see Frame#getFrames
@@ -1601,7 +1601,7 @@
* <b>Warning:</b> this method may return system created windows, such
* as a print dialog. Applications should not assume the existence of
* these dialogs, nor should an application assume anything about these
- * dialogs such as component positions, <code>LayoutManager</code>s
+ * dialogs such as component positions, {@code LayoutManager}s
* or serialization.
*
* @see Frame#getFrames
@@ -1646,17 +1646,17 @@
* java.awt.Dialog.ModalExclusionType Dialog.ModalExclusionType} for
* possible modal exclusion types.
* <p>
- * If the given type is not supported, <code>NO_EXCLUDE</code> is used.
+ * If the given type is not supported, {@code NO_EXCLUDE} is used.
* <p>
* Note: changing the modal exclusion type for a visible window may have no
* effect until it is hidden and then shown again.
*
- * @param exclusionType the modal exclusion type for this window; a <code>null</code>
+ * @param exclusionType the modal exclusion type for this window; a {@code null}
* value is equivivalent to {@link Dialog.ModalExclusionType#NO_EXCLUDE
* NO_EXCLUDE}
* @throws SecurityException if the calling thread does not have permission
* to set the modal exclusion property to the window with the given
- * <code>exclusionType</code>
+ * {@code exclusionType}
* @see java.awt.Dialog.ModalExclusionType
* @see java.awt.Window#getModalExclusionType
* @see java.awt.Toolkit#isModalExclusionTypeSupported
@@ -1762,7 +1762,7 @@
/**
* Adds the specified window state listener to receive window
- * events from this window. If <code>l</code> is <code>null</code>,
+ * events from this window. If {@code l} is {@code null},
* no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
@@ -1821,7 +1821,7 @@
/**
* Removes the specified window state listener so that it no
* longer receives window events from this window. If
- * <code>l</code> is <code>null</code>, no exception is thrown and
+ * {@code l} is {@code null}, no exception is thrown and
* no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
@@ -1861,7 +1861,7 @@
* Returns an array of all the window listeners
* registered on this window.
*
- * @return all of this window's <code>WindowListener</code>s
+ * @return all of this window's {@code WindowListener}s
* or an empty array if no window
* listeners are currently registered
*
@@ -1877,7 +1877,7 @@
* Returns an array of all the window focus listeners
* registered on this window.
*
- * @return all of this window's <code>WindowFocusListener</code>s
+ * @return all of this window's {@code WindowFocusListener}s
* or an empty array if no window focus
* listeners are currently registered
*
@@ -1893,7 +1893,7 @@
* Returns an array of all the window state listeners
* registered on this window.
*
- * @return all of this window's <code>WindowStateListener</code>s
+ * @return all of this window's {@code WindowStateListener}s
* or an empty array if no window state
* listeners are currently registered
*
@@ -1909,17 +1909,17 @@
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
- * upon this <code>Window</code>.
+ * upon this {@code Window}.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
*
- * You can specify the <code>listenerType</code> argument
+ * You can specify the {@code listenerType} argument
* with a class literal, such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
- * <code>Window</code> <code>w</code>
+ * {@code Window} {@code w}
* for its window listeners with the following code:
*
* <pre>WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class));</pre>
@@ -1928,14 +1928,14 @@
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
- * <code>java.util.EventListener</code>
+ * {@code java.util.EventListener}
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this window,
* or an empty array if no such
* listeners have been added
- * @exception ClassCastException if <code>listenerType</code>
+ * @exception ClassCastException if {@code listenerType}
* doesn't specify a class or interface that implements
- * <code>java.util.EventListener</code>
+ * {@code java.util.EventListener}
* @exception NullPointerException if {@code listenerType} is {@code null}
*
* @see #getWindowListeners
@@ -1991,10 +1991,10 @@
/**
* Processes events on this window. If the event is an
- * <code>WindowEvent</code>, it invokes the
- * <code>processWindowEvent</code> method, else it invokes its
- * superclass's <code>processEvent</code>.
- * <p>Note that if the event parameter is <code>null</code>
+ * {@code WindowEvent}, it invokes the
+ * {@code processWindowEvent} method, else it invokes its
+ * superclass's {@code processEvent}.
+ * <p>Note that if the event parameter is {@code null}
* the behavior is unspecified and may result in an
* exception.
*
@@ -2033,10 +2033,10 @@
* following occurs:
* <ul>
* <li>A WindowListener object is registered via
- * <code>addWindowListener</code>
- * <li>Window events are enabled via <code>enableEvents</code>
+ * {@code addWindowListener}
+ * <li>Window events are enabled via {@code enableEvents}
* </ul>
- * <p>Note that if the event parameter is <code>null</code>
+ * <p>Note that if the event parameter is {@code null}
* the behavior is unspecified and may result in an
* exception.
*
@@ -2082,10 +2082,10 @@
* following occurs:
* <ul>
* <li>a WindowFocusListener is registered via
- * <code>addWindowFocusListener</code>
- * <li>Window focus events are enabled via <code>enableEvents</code>
+ * {@code addWindowFocusListener}
+ * <li>Window focus events are enabled via {@code enableEvents}
* </ul>
- * <p>Note that if the event parameter is <code>null</code>
+ * <p>Note that if the event parameter is {@code null}
* the behavior is unspecified and may result in an
* exception.
*
@@ -2111,17 +2111,17 @@
/**
* Processes window state event occuring on this window by
- * dispatching them to any registered <code>WindowStateListener</code>
+ * dispatching them to any registered {@code WindowStateListener}
* objects.
* NOTE: this method will not be called unless window state events
* are enabled for this window. This happens when one of the
* following occurs:
* <ul>
- * <li>a <code>WindowStateListener</code> is registered via
- * <code>addWindowStateListener</code>
- * <li>window state events are enabled via <code>enableEvents</code>
+ * <li>a {@code WindowStateListener} is registered via
+ * {@code addWindowStateListener}
+ * <li>window state events are enabled via {@code enableEvents}
* </ul>
- * <p>Note that if the event parameter is <code>null</code>
+ * <p>Note that if the event parameter is {@code null}
* the behavior is unspecified and may result in an
* exception.
*
@@ -2145,7 +2145,7 @@
/**
* Implements a debugging hook -- checks to see if
* the user has typed <i>control-shift-F1</i>. If so,
- * the list of child windows is dumped to <code>System.out</code>.
+ * the list of child windows is dumped to {@code System.out}.
* @param e the keyboard event
*/
void preProcessKeyEvent(KeyEvent e) {
@@ -2176,21 +2176,21 @@
* automatically become always-on-top. If a window ceases to be
* always-on-top, the windows that it owns will no longer be
* always-on-top. When an always-on-top window is sent {@link #toBack
- * toBack}, its always-on-top state is set to <code>false</code>.
+ * toBack}, its always-on-top state is set to {@code false}.
*
* <p> When this method is called on a window with a value of
- * <code>true</code>, and the window is visible and the platform
+ * {@code true}, and the window is visible and the platform
* supports always-on-top for this window, the window is immediately
* brought forward, "sticking" it in the top-most position. If the
* window isn`t currently visible, this method sets the always-on-top
- * state to <code>true</code> but does not bring the window forward.
+ * state to {@code true} but does not bring the window forward.
* When the window is later shown, it will be always-on-top.
*
* <p> When this method is called on a window with a value of
- * <code>false</code> the always-on-top state is set to normal. The
+ * {@code false} the always-on-top state is set to normal. The
* window remains in the top-most position but it`s z-order can be
* changed as for any other window. Calling this method with a value
- * of <code>false</code> on a window that has a normal state has no
+ * of {@code false} on a window that has a normal state has no
* effect. Setting the always-on-top state to false has no effect on
* the relative z-order of the windows if there are no other
* always-on-top windows.
@@ -2250,9 +2250,9 @@
* window. Some platforms may not support always-on-top windows, some
* may support only some kinds of top-level windows; for example,
* a platform may not support always-on-top modal dialogs.
- * @return <code>true</code>, if the always-on-top mode is
+ * @return {@code true}, if the always-on-top mode is
* supported by the toolkit and for this window,
- * <code>false</code>, if always-on-top mode is not supported
+ * {@code false}, if always-on-top mode is not supported
* for this window or toolkit doesn't support always-on-top windows.
* @see #setAlwaysOnTop(boolean)
* @see Toolkit#isAlwaysOnTopSupported
@@ -2265,8 +2265,8 @@
/**
* Returns whether this window is an always-on-top window.
- * @return <code>true</code>, if the window is in always-on-top state,
- * <code>false</code> otherwise
+ * @return {@code true}, if the window is in always-on-top state,
+ * {@code false} otherwise
* @see #setAlwaysOnTop
* @since 1.5
*/
@@ -2294,7 +2294,7 @@
/**
* Returns the child Component of this Window that will receive the focus
* when this Window is focused. If this Window is currently focused, this
- * method returns the same Component as <code>getFocusOwner()</code>. If
+ * method returns the same Component as {@code getFocusOwner()}. If
* this Window is not focused, then the child Component that most recently
* requested focus will be returned. If no child Component has ever
* requested focus, and this is a focusable Window, then this Window's
@@ -2359,8 +2359,8 @@
}
/**
- * Gets a focus traversal key for this Window. (See <code>
- * setFocusTraversalKeys</code> for a full description of each key.)
+ * Gets a focus traversal key for this Window. (See {@code
+ * setFocusTraversalKeys} for a full description of each key.)
* <p>
* If the traversal key has not been explicitly set for this Window,
* then this Window's parent's traversal key is returned. If the
@@ -2419,10 +2419,10 @@
}
/**
- * Always returns <code>true</code> because all Windows must be roots of a
+ * Always returns {@code true} because all Windows must be roots of a
* focus traversal cycle.
*
- * @return <code>true</code>
+ * @return {@code true}
* @see #setFocusCycleRoot
* @see Container#setFocusTraversalPolicy
* @see Container#getFocusTraversalPolicy
@@ -2433,10 +2433,10 @@
}
/**
- * Always returns <code>null</code> because Windows have no ancestors; they
+ * Always returns {@code null} because Windows have no ancestors; they
* represent the top of the Component hierarchy.
*
- * @return <code>null</code>
+ * @return {@code null}
* @see Container#isFocusCycleRoot()
* @since 1.4
*/
@@ -2448,16 +2448,16 @@
* Returns whether this Window can become the focused Window, that is,
* whether this Window or any of its subcomponents can become the focus
* owner. For a Frame or Dialog to be focusable, its focusable Window state
- * must be set to <code>true</code>. For a Window which is not a Frame or
+ * must be set to {@code true}. For a Window which is not a Frame or
* Dialog to be focusable, its focusable Window state must be set to
- * <code>true</code>, its nearest owning Frame or Dialog must be
+ * {@code true}, its nearest owning Frame or Dialog must be
* showing on the screen, and it must contain at least one Component in
* its focus traversal cycle. If any of these conditions is not met, then
* neither this Window nor any of its subcomponents can become the focus
* owner.
*
- * @return <code>true</code> if this Window can be the focused Window;
- * <code>false</code> otherwise
+ * @return {@code true} if this Window can be the focused Window;
+ * {@code false} otherwise
* @see #getFocusableWindowState
* @see #setFocusableWindowState
* @see #isShowing
@@ -2497,16 +2497,16 @@
/**
* Returns whether this Window can become the focused Window if it meets
- * the other requirements outlined in <code>isFocusableWindow</code>. If
- * this method returns <code>false</code>, then
- * <code>isFocusableWindow</code> will return <code>false</code> as well.
- * If this method returns <code>true</code>, then
- * <code>isFocusableWindow</code> may return <code>true</code> or
- * <code>false</code> depending upon the other requirements which must be
+ * the other requirements outlined in {@code isFocusableWindow}. If
+ * this method returns {@code false}, then
+ * {@code isFocusableWindow} will return {@code false} as well.
+ * If this method returns {@code true}, then
+ * {@code isFocusableWindow} may return {@code true} or
+ * {@code false} depending upon the other requirements which must be
* met in order for a Window to be focusable.
* <p>
* By default, all Windows have a focusable Window state of
- * <code>true</code>.
+ * {@code true}.
*
* @return whether this Window can be the focused Window
* @see #isFocusableWindow
@@ -2521,25 +2521,25 @@
/**
* Sets whether this Window can become the focused Window if it meets
- * the other requirements outlined in <code>isFocusableWindow</code>. If
- * this Window's focusable Window state is set to <code>false</code>, then
- * <code>isFocusableWindow</code> will return <code>false</code>. If this
- * Window's focusable Window state is set to <code>true</code>, then
- * <code>isFocusableWindow</code> may return <code>true</code> or
- * <code>false</code> depending upon the other requirements which must be
+ * the other requirements outlined in {@code isFocusableWindow}. If
+ * this Window's focusable Window state is set to {@code false}, then
+ * {@code isFocusableWindow} will return {@code false}. If this
+ * Window's focusable Window state is set to {@code true}, then
+ * {@code isFocusableWindow} may return {@code true} or
+ * {@code false} depending upon the other requirements which must be
* met in order for a Window to be focusable.
* <p>
- * Setting a Window's focusability state to <code>false</code> is the
+ * Setting a Window's focusability state to {@code false} is the
* standard mechanism for an application to identify to the AWT a Window
* which will be used as a floating palette or toolbar, and thus should be
* a non-focusable Window.
*
- * Setting the focusability state on a visible <code>Window</code>
+ * Setting the focusability state on a visible {@code Window}
* can have a delayed effect on some platforms — the actual
- * change may happen only when the <code>Window</code> becomes
+ * change may happen only when the {@code Window} becomes
* hidden and then visible again. To ensure consistent behavior
- * across platforms, set the <code>Window</code>'s focusable state
- * when the <code>Window</code> is invisible and then show it.
+ * across platforms, set the {@code Window}'s focusable state
+ * when the {@code Window} is invisible and then show it.
*
* @param focusableWindowState whether this Window can be the focused
* Window
@@ -2726,7 +2726,7 @@
/**
* @deprecated As of JDK version 1.1
- * replaced by <code>dispatchEvent(AWTEvent)</code>.
+ * replaced by {@code dispatchEvent(AWTEvent)}.
*/
@Deprecated
public boolean postEvent(Event e) {
@@ -2876,22 +2876,22 @@
/**
* Writes default serializable fields to stream. Writes
- * a list of serializable <code>WindowListener</code>s and
- * <code>WindowFocusListener</code>s as optional data.
+ * a list of serializable {@code WindowListener}s and
+ * {@code WindowFocusListener}s as optional data.
* Writes a list of child windows as optional data.
* Writes a list of icon images as optional data
*
- * @param s the <code>ObjectOutputStream</code> to write
- * @serialData <code>null</code> terminated sequence of
- * 0 or more pairs; the pair consists of a <code>String</code>
- * and and <code>Object</code>; the <code>String</code>
+ * @param s the {@code ObjectOutputStream} to write
+ * @serialData {@code null} terminated sequence of
+ * 0 or more pairs; the pair consists of a {@code String}
+ * and {@code Object}; the {@code String}
* indicates the type of object and is one of the following:
- * <code>windowListenerK</code> indicating a
- * <code>WindowListener</code> object;
- * <code>windowFocusWindowK</code> indicating a
- * <code>WindowFocusListener</code> object;
- * <code>ownedWindowK</code> indicating a child
- * <code>Window</code> object
+ * {@code windowListenerK} indicating a
+ * {@code WindowListener} object;
+ * {@code windowFocusWindowK} indicating a
+ * {@code WindowFocusListener} object;
+ * {@code ownedWindowK} indicating a child
+ * {@code Window} object
*
* @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
* @see Component#windowListenerK
@@ -3029,16 +3029,16 @@
}
/**
- * Reads the <code>ObjectInputStream</code> and an optional
+ * Reads the {@code ObjectInputStream} and an optional
* list of listeners to receive various events fired by
* the component; also reads a list of
- * (possibly <code>null</code>) child windows.
+ * (possibly {@code null}) child windows.
* Unrecognized keys or values will be ignored.
*
- * @param s the <code>ObjectInputStream</code> to read
+ * @param s the {@code ObjectInputStream} to read
* @exception HeadlessException if
- * <code>GraphicsEnvironment.isHeadless</code> returns
- * <code>true</code>
+ * {@code GraphicsEnvironment.isHeadless} returns
+ * {@code true}
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #writeObject
*/
@@ -3100,7 +3100,7 @@
/**
* This class implements accessibility support for the
- * <code>Window</code> class. It provides an implementation of the
+ * {@code Window} class. It provides an implementation of the
* Java Accessibility API appropriate to window user-interface elements.
* @since 1.3
*/
@@ -3186,7 +3186,7 @@
* not changed.
* <p>
* <b>Note</b>: If the lower edge of the window is out of the screen,
- * then the window is placed to the side of the <code>Component</code>
+ * then the window is placed to the side of the {@code Component}
* that is closest to the center of the screen. So if the
* component is on the right part of the screen, the window
* is placed to its left, and vice versa.
@@ -3289,7 +3289,7 @@
* Creates a new strategy for multi-buffering on this component.
* Multi-buffering is useful for rendering performance. This method
* attempts to create the best strategy available with the number of
- * buffers supplied. It will always create a <code>BufferStrategy</code>
+ * buffers supplied. It will always create a {@code BufferStrategy}
* with that number of buffers.
* A page-flipping strategy is attempted first, then a blitting strategy
* using accelerated buffers. Finally, an unaccelerated blitting
@@ -3318,13 +3318,13 @@
* is called, the existing buffer strategy for this component is discarded.
* @param numBuffers number of buffers to create, including the front buffer
* @param caps the required capabilities for creating the buffer strategy;
- * cannot be <code>null</code>
+ * cannot be {@code null}
* @exception AWTException if the capabilities supplied could not be
* supported or met; this may happen, for example, if there is not enough
* accelerated memory currently available, or if page flipping is specified
* but not possible.
* @exception IllegalArgumentException if numBuffers is less than 1, or if
- * caps is <code>null</code>
+ * caps is {@code null}
* @see #getBufferStrategy
* @since 1.4
*/
@@ -3334,8 +3334,8 @@
}
/**
- * Returns the <code>BufferStrategy</code> used by this component. This
- * method will return null if a <code>BufferStrategy</code> has not yet
+ * Returns the {@code BufferStrategy} used by this component. This
+ * method will return null if a {@code BufferStrategy} has not yet
* been created or has been disposed.
*
* @return the buffer strategy used by this component
@@ -3376,7 +3376,7 @@
/**
* Sets whether this Window should appear at the default location for the
* native windowing system or at the current location (returned by
- * <code>getLocation</code>) the next time the Window is made visible.
+ * {@code getLocation}) the next time the Window is made visible.
* This behavior resembles a native window shown without programmatically
* setting its location. Most windowing systems cascade windows if their
* locations are not explicitly set. The actual location is determined once the
@@ -3386,8 +3386,8 @@
* "java.awt.Window.locationByPlatform" to "true", though calls to this method
* take precedence.
* <p>
- * Calls to <code>setVisible</code>, <code>setLocation</code> and
- * <code>setBounds</code> after calling <code>setLocationByPlatform</code> clear
+ * Calls to {@code setVisible}, {@code setLocation} and
+ * {@code setBounds} after calling {@code setLocationByPlatform} clear
* this property of the Window.
* <p>
* For example, after the following code is executed:
@@ -3397,7 +3397,7 @@
* boolean flag = isLocationByPlatform();
* </blockquote></pre>
* The window will be shown at platform's default location and
- * <code>flag</code> will be <code>false</code>.
+ * {@code flag} will be {@code false}.
* <p>
* In the following sample:
* <pre><blockquote>
@@ -3406,13 +3406,13 @@
* boolean flag = isLocationByPlatform();
* setVisible(true);
* </blockquote></pre>
- * The window will be shown at (10, 10) and <code>flag</code> will be
- * <code>false</code>.
+ * The window will be shown at (10, 10) and {@code flag} will be
+ * {@code false}.
*
- * @param locationByPlatform <code>true</code> if this Window should appear
- * at the default location, <code>false</code> if at the current location
- * @throws <code>IllegalComponentStateException</code> if the window
- * is showing on screen and locationByPlatform is <code>true</code>.
+ * @param locationByPlatform {@code true} if this Window should appear
+ * at the default location, {@code false} if at the current location
+ * @throws {@code IllegalComponentStateException} if the window
+ * is showing on screen and locationByPlatform is {@code true}.
* @see #setLocation
* @see #isShowing
* @see #setVisible
@@ -3430,9 +3430,9 @@
}
/**
- * Returns <code>true</code> if this Window will appear at the default location
+ * Returns {@code true} if this Window will appear at the default location
* for the native windowing system the next time this Window is made visible.
- * This method always returns <code>false</code> if the Window is showing on the
+ * This method always returns {@code false} if the Window is showing on the
* screen.
*
* @return whether this Window will appear at the default location
@@ -3509,8 +3509,8 @@
/**
* Determines whether this component will be displayed on the screen.
- * @return <code>true</code> if the component and all of its ancestors
- * until a toplevel window are visible, <code>false</code> otherwise
+ * @return {@code true} if the component and all of its ancestors
+ * until a toplevel window are visible, {@code false} otherwise
*/
boolean isRecursivelyVisible() {
// 5079694 fix: for a toplevel to be displayed, its parent doesn't have to be visible.
--- a/jdk/src/share/classes/java/io/RandomAccessFile.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/io/RandomAccessFile.java Wed Jul 05 19:09:26 2017 +0200
@@ -518,7 +518,15 @@
* @exception IOException if {@code pos} is less than
* {@code 0} or if an I/O error occurs.
*/
- public native void seek(long pos) throws IOException;
+ public void seek(long pos) throws IOException {
+ if (pos < 0) {
+ throw new IOException("Negative seek offset");
+ } else {
+ seek0(pos);
+ }
+ }
+
+ private native void seek0(long pos) throws IOException;
/**
* Returns the length of this file.
--- a/jdk/src/share/classes/java/lang/Math.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/lang/Math.java Wed Jul 05 19:09:26 2017 +0200
@@ -825,7 +825,7 @@
public static int multiplyExact(int x, int y) {
long r = (long)x * (long)y;
if ((int)r != r) {
- throw new ArithmeticException("long overflow");
+ throw new ArithmeticException("integer overflow");
}
return (int)r;
}
@@ -857,6 +857,108 @@
}
/**
+ * Returns the argument incremented by one, throwing an exception if the
+ * result overflows an {@code int}.
+ *
+ * @param a the value to increment
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int incrementExact(int a) {
+ if (a == Integer.MAX_VALUE) {
+ throw new ArithmeticException("integer overflow");
+ }
+
+ return a + 1;
+ }
+
+ /**
+ * Returns the argument incremented by one, throwing an exception if the
+ * result overflows a {@code long}.
+ *
+ * @param a the value to increment
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long incrementExact(long a) {
+ if (a == Long.MAX_VALUE) {
+ throw new ArithmeticException("long overflow");
+ }
+
+ return a + 1L;
+ }
+
+ /**
+ * Returns the argument decremented by one, throwing an exception if the
+ * result overflows an {@code int}.
+ *
+ * @param a the value to decrement
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int decrementExact(int a) {
+ if (a == Integer.MIN_VALUE) {
+ throw new ArithmeticException("integer overflow");
+ }
+
+ return a - 1;
+ }
+
+ /**
+ * Returns the argument decremented by one, throwing an exception if the
+ * result overflows a {@code long}.
+ *
+ * @param a the value to decrement
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long decrementExact(long a) {
+ if (a == Long.MIN_VALUE) {
+ throw new ArithmeticException("long overflow");
+ }
+
+ return a - 1L;
+ }
+
+ /**
+ * Returns the negation of the argument, throwing an exception if the
+ * result overflows an {@code int}.
+ *
+ * @param a the value to negate
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int negateExact(int a) {
+ if (a == Integer.MIN_VALUE) {
+ throw new ArithmeticException("integer overflow");
+ }
+
+ return -a;
+ }
+
+ /**
+ * Returns the negation of the argument, throwing an exception if the
+ * result overflows a {@code long}.
+ *
+ * @param a the value to negate
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long negateExact(long a) {
+ if (a == Long.MIN_VALUE) {
+ throw new ArithmeticException("long overflow");
+ }
+
+ return -a;
+ }
+
+ /**
* Returns the value of the {@code long} argument;
* throwing an exception if the value overflows an {@code int}.
*
--- a/jdk/src/share/classes/java/math/MutableBigInteger.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/math/MutableBigInteger.java Wed Jul 05 19:09:26 2017 +0200
@@ -1242,6 +1242,9 @@
int r = intLen;
int s = b.intLen;
+ // Clear the quotient
+ quotient.offset = quotient.intLen = 0;
+
if (r < s) {
return this;
} else {
@@ -1276,7 +1279,6 @@
// do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers
MutableBigInteger qi = new MutableBigInteger();
MutableBigInteger ri;
- quotient.offset = quotient.intLen = 0;
for (int i=t-2; i > 0; i--) {
// step 8a: compute (qi,ri) such that z=b*qi+ri
ri = z.divide2n1n(bShifted, qi);
--- a/jdk/src/share/classes/java/net/DatagramPacket.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/net/DatagramPacket.java Wed Jul 05 19:09:26 2017 +0200
@@ -139,8 +139,7 @@
*
* @since 1.4
*/
- public DatagramPacket(byte buf[], int offset, int length,
- SocketAddress address) throws SocketException {
+ public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {
setData(buf, offset, length);
setSocketAddress(address);
}
@@ -175,8 +174,7 @@
* @since 1.4
* @see java.net.InetAddress
*/
- public DatagramPacket(byte buf[], int length,
- SocketAddress address) throws SocketException {
+ public DatagramPacket(byte buf[], int length, SocketAddress address) {
this(buf, 0, length, address);
}
--- a/jdk/src/share/classes/java/net/IDN.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/net/IDN.java Wed Jul 05 19:09:26 2017 +0200
@@ -113,11 +113,18 @@
int p = 0, q = 0;
StringBuffer out = new StringBuffer();
+ if (isRootLabel(input)) {
+ return ".";
+ }
+
while (p < input.length()) {
q = searchDots(input, p);
out.append(toASCIIInternal(input.substring(p, q), flag));
+ if (q != (input.length())) {
+ // has more labels, or keep the trailing dot as at present
+ out.append('.');
+ }
p = q + 1;
- if (p < input.length()) out.append('.');
}
return out.toString();
@@ -167,11 +174,18 @@
int p = 0, q = 0;
StringBuffer out = new StringBuffer();
+ if (isRootLabel(input)) {
+ return ".";
+ }
+
while (p < input.length()) {
q = searchDots(input, p);
out.append(toUnicodeInternal(input.substring(p, q), flag));
+ if (q != (input.length())) {
+ // has more labels, or keep the trailing dot as at present
+ out.append('.');
+ }
p = q + 1;
- if (p < input.length()) out.append('.');
}
return out.toString();
@@ -263,6 +277,13 @@
dest = new StringBuffer(label);
}
+ // step 8, move forward to check the smallest number of the code points
+ // the length must be inside 1..63
+ if (dest.length() == 0) {
+ throw new IllegalArgumentException(
+ "Empty label is not a legal name");
+ }
+
// step 3
// Verify the absence of non-LDH ASCII code points
// 0..0x2c, 0x2e..0x2f, 0x3a..0x40, 0x5b..0x60, 0x7b..0x7f
@@ -311,7 +332,7 @@
// step 8
// the length must be inside 1..63
- if(dest.length() > MAX_LABEL_LENGTH){
+ if (dest.length() > MAX_LABEL_LENGTH) {
throw new IllegalArgumentException("The label in the input is too long");
}
@@ -409,8 +430,7 @@
private static int searchDots(String s, int start) {
int i;
for (i = start; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61') {
+ if (isLabelSeparator(s.charAt(i))) {
break;
}
}
@@ -418,6 +438,19 @@
return i;
}
+ //
+ // to check if a string is a root label, ".".
+ //
+ private static boolean isRootLabel(String s) {
+ return (s.length() == 1 && isLabelSeparator(s.charAt(0)));
+ }
+
+ //
+ // to check if a character is a label separator, i.e. a dot character.
+ //
+ private static boolean isLabelSeparator(char c) {
+ return (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61');
+ }
//
// to check if a string only contains US-ASCII code point
--- a/jdk/src/share/classes/java/net/InetAddress.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/net/InetAddress.java Wed Jul 05 19:09:26 2017 +0200
@@ -1601,7 +1601,6 @@
pf.put("address", holder().getAddress());
pf.put("family", holder().getFamily());
s.writeFields();
- s.flush();
}
}
--- a/jdk/src/share/classes/java/net/URLClassLoader.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/net/URLClassLoader.java Wed Jul 05 19:09:26 2017 +0200
@@ -57,12 +57,6 @@
* <p>
* The classes that are loaded are by default granted permission only to
* access the URLs specified when the URLClassLoader was created.
- * <p>
- * Where a JAR file contains the {@link Name#PROFILE Profile} attribute
- * then its value is the name of the Java SE profile that the library
- * minimally requires. If this runtime does not support the profile then
- * it causes {@link java.util.jar.UnsupportedProfileException} to be
- * thrown at some unspecified time.
*
* @author David Connelly
* @since 1.2
--- a/jdk/src/share/classes/java/sql/SQLXML.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/sql/SQLXML.java Wed Jul 05 19:09:26 2017 +0200
@@ -98,7 +98,7 @@
* or, to set the result value from SAX events:
* <pre>
* SAXResult saxResult = sqlxml.setResult(SAXResult.class);
- * ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
+ * ContentHandler contentHandler = saxResult.getHandler();
* contentHandler.startDocument();
* // set the XML elements and attributes into the result
* contentHandler.endDocument();
--- a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java Wed Jul 05 19:09:26 2017 +0200
@@ -107,7 +107,7 @@
* The singleton instance for the 'Meiji' era (1868-09-08 - 1912-07-29)
* which has the value -1.
*/
- public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 9, 8));
+ public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 1, 1));
/**
* The singleton instance for the 'Taisho' era (1912-07-30 - 1926-12-24)
* which has the value 0.
--- a/jdk/src/share/classes/java/util/ArrayDeque.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/ArrayDeque.java Wed Jul 05 19:09:26 2017 +0200
@@ -888,6 +888,19 @@
elements[i] = s.readObject();
}
+ /**
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@link Spliterator} over the elements in this
+ * deque.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
+ * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
+ * {@link Spliterator#NONNULL}. Overriding implementations should document
+ * the reporting of additional characteristic values.
+ *
+ * @return a {@code Spliterator} over the elements in this deque
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return new DeqSpliterator<E>(this, -1, -1);
}
--- a/jdk/src/share/classes/java/util/ArrayList.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java Wed Jul 05 19:09:26 2017 +0200
@@ -1238,6 +1238,20 @@
}
}
+ /**
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@link Spliterator} over the elements in this
+ * list.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
+ * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
+ * Overriding implementations should document the reporting of additional
+ * characteristic values.
+ *
+ * @return a {@code Spliterator} over the elements in this list
+ * @since 1.8
+ */
+ @Override
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
--- a/jdk/src/share/classes/java/util/Collection.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/Collection.java Wed Jul 05 19:09:26 2017 +0200
@@ -504,7 +504,10 @@
*
* <p>The returned {@code Spliterator} must report the characteristic
* {@link Spliterator#SIZED}; implementations should document any additional
- * characteristic values reported by the returned Spliterator.
+ * characteristic values reported by the returned spliterator. If
+ * this collection contains no elements then the returned spliterator is
+ * only required to report {@link Spliterator#SIZED} and is not required to
+ * report additional characteristic values (if any).
*
* <p>The default implementation should be overridden by subclasses that
* can return a more efficient spliterator. In order to
@@ -535,6 +538,14 @@
* The returned {@code Spliterator} additionally reports
* {@link Spliterator#SUBSIZED}.
*
+ * <p>If a spliterator covers no elements then the reporting of additional
+ * characteristic values, beyond that of {@code SIZED} and {@code SUBSIZED},
+ * does not aid clients to control, specialize or simplify computation.
+ * However, this does enable shared use of an immutable and empty
+ * spliterator instance (see {@link Spliterators#emptySpliterator()}) for
+ * empty collections, and enables clients to determine if such a spliterator
+ * covers no elements.
+ *
* @return a {@code Spliterator} over the elements in this collection
* @since 1.8
*/
--- a/jdk/src/share/classes/java/util/Collections.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/Collections.java Wed Jul 05 19:09:26 2017 +0200
@@ -4508,7 +4508,6 @@
}
@Override
public void sort(Comparator<? super E> c) {
- Objects.requireNonNull(c);
}
// Override default methods in Collection
--- a/jdk/src/share/classes/java/util/CurrencyData.properties Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/CurrencyData.properties Wed Jul 05 19:09:26 2017 +0200
@@ -28,7 +28,7 @@
# Version of the currency code information in this class.
# It is a serial number that accompanies with each amendment.
-dataVersion=155
+dataVersion=156
# List of all valid ISO 4217 currency codes.
# To ensure compatibility, do not remove codes.
@@ -320,7 +320,7 @@
# LAO PEOPLE'S DEMOCRATIC REPUBLIC
LA=LAK
# LATVIA
-LV=LVL
+LV=LVL;2013-12-31-22-00-00;EUR
# LEBANON
LB=LBP
# LESOTHO
--- a/jdk/src/share/classes/java/util/Formatter.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/Formatter.java Wed Jul 05 19:09:26 2017 +0200
@@ -4196,7 +4196,7 @@
case DateTime.CENTURY: // 'C' (00 - 99)
case DateTime.YEAR_2: // 'y' (00 - 99)
case DateTime.YEAR_4: { // 'Y' (0000 - 9999)
- int i = t.get(ChronoField.YEAR);
+ int i = t.get(ChronoField.YEAR_OF_ERA);
int size = 2;
switch (c) {
case DateTime.CENTURY:
--- a/jdk/src/share/classes/java/util/HashSet.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/HashSet.java Wed Jul 05 19:09:26 2017 +0200
@@ -312,6 +312,18 @@
}
}
+ /**
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@link Spliterator} over the elements in this
+ * set.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
+ * {@link Spliterator#DISTINCT}. Overriding implementations should document
+ * the reporting of additional characteristic values.
+ *
+ * @return a {@code Spliterator} over the elements in this set
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return new HashMap.KeySpliterator<E,Object>(map, 0, -1, 0, 0);
}
--- a/jdk/src/share/classes/java/util/LinkedHashMap.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/LinkedHashMap.java Wed Jul 05 19:09:26 2017 +0200
@@ -129,10 +129,20 @@
* exception for its correctness: <i>the fail-fast behavior of iterators
* should be used only to detect bugs.</i>
*
+ * <p>The spliterators returned by the spliterator method of the collections
+ * returned by all of this class's collection view methods are
+ * <em><a href="Spliterator.html#binding">late-binding</a></em>,
+ * <em>fail-fast</em>, and additionally report {@link Spliterator#ORDERED}.
+ *
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
+ * @implNote
+ * The spliterators returned by the spliterator method of the collections
+ * returned by all of this class's collection view methods are created from
+ * the iterators of the corresponding collections.
+ *
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*
--- a/jdk/src/share/classes/java/util/LinkedHashSet.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/LinkedHashSet.java Wed Jul 05 19:09:26 2017 +0200
@@ -170,13 +170,23 @@
}
/**
- * Creates a {@code Spliterator}, over the elements in this set, that
- * reports {@code SIZED}, {@code DISTINCT} and {@code ORDERED}.
- * Overriding implementations are expected to document if the
- * {@code Spliterator} reports any additional and relevant characteristic
- * values.
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@code Spliterator} over the elements in this set.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
+ * {@link Spliterator#DISTINCT}, and {@code ORDERED}. Implementations
+ * should document the reporting of additional characteristic values.
+ *
+ * @implNote
+ * The implementation creates a
+ * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
+ * from the set's {@code Iterator}. The spliterator inherits the
+ * <em>fail-fast</em> properties of the set's iterator.
+ * The created {@code Spliterator} additionally reports
+ * {@link Spliterator#SUBSIZED}.
*
* @return a {@code Spliterator} over the elements in this set
+ * @since 1.8
*/
@Override
public Spliterator<E> spliterator() {
--- a/jdk/src/share/classes/java/util/LinkedList.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/LinkedList.java Wed Jul 05 19:09:26 2017 +0200
@@ -1149,6 +1149,23 @@
linkLast((E)s.readObject());
}
+ /**
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@link Spliterator} over the elements in this
+ * list.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
+ * {@link Spliterator#ORDERED}. Overriding implementations should document
+ * the reporting of additional characteristic values.
+ *
+ * @implNote
+ * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}
+ * and implements {@code trySplit} to permit limited parallelism..
+ *
+ * @return a {@code Spliterator} over the elements in this list
+ * @since 1.8
+ */
+ @Override
public Spliterator<E> spliterator() {
return new LLSpliterator<E>(this, -1, 0);
}
--- a/jdk/src/share/classes/java/util/List.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/List.java Wed Jul 05 19:09:26 2017 +0200
@@ -671,7 +671,7 @@
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the list's {@code Iterator}. The spliterator inherits the
- * <em>fail-fast</em> properties of the collection's iterator.
+ * <em>fail-fast</em> properties of the list's iterator.
*
* @implNote
* The created {@code Spliterator} additionally reports
--- a/jdk/src/share/classes/java/util/PriorityQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/PriorityQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -795,6 +795,19 @@
heapify();
}
+ /**
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@link Spliterator} over the elements in this
+ * queue.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
+ * {@link Spliterator#SUBSIZED}, and {@link Spliterator#NONNULL}.
+ * Overriding implementations should document the reporting of additional
+ * characteristic values.
+ *
+ * @return a {@code Spliterator} over the elements in this queue
+ * @since 1.8
+ */
public final Spliterator<E> spliterator() {
return new PriorityQueueSpliterator<E>(this, 0, -1, 0);
}
--- a/jdk/src/share/classes/java/util/Set.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/Set.java Wed Jul 05 19:09:26 2017 +0200
@@ -394,7 +394,7 @@
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the set's {@code Iterator}. The spliterator inherits the
- * <em>fail-fast</em> properties of the collection's iterator.
+ * <em>fail-fast</em> properties of the set's iterator.
*
* @implNote
* The created {@code Spliterator} additionally reports
--- a/jdk/src/share/classes/java/util/SortedSet.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/SortedSet.java Wed Jul 05 19:09:26 2017 +0200
@@ -238,7 +238,7 @@
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the sorted set's {@code Iterator}. The spliterator inherits the
- * <em>fail-fast</em> properties of the collection's iterator. The
+ * <em>fail-fast</em> properties of the set's iterator. The
* spliterator's comparator is the same as the sorted set's comparator.
*
* @implNote
--- a/jdk/src/share/classes/java/util/Spliterator.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/Spliterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -74,7 +74,11 @@
* source prior to binding are reflected when the Spliterator is traversed.
* After binding a Spliterator should, on a best-effort basis, throw
* {@link ConcurrentModificationException} if structural interference is
- * detected. Spliterators that do this are called <em>fail-fast</em>.
+ * detected. Spliterators that do this are called <em>fail-fast</em>. The
+ * bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a
+ * Spliterator may optimize traversal and check for structural interference
+ * after all elements have been traversed, rather than checking per-element and
+ * failing immediately.
*
* <p>Spliterators can provide an estimate of the number of remaining elements
* via the {@link #estimateSize} method. Ideally, as reflected in characteristic
--- a/jdk/src/share/classes/java/util/TreeMap.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/TreeMap.java Wed Jul 05 19:09:26 2017 +0200
@@ -790,8 +790,19 @@
/**
* Returns a {@link Set} view of the keys contained in this map.
- * The set's iterator returns the keys in ascending order.
- * The set is backed by the map, so changes to the map are
+ *
+ * <p>The set's iterator returns the keys in ascending order.
+ * The set's spliterator is
+ * <em><a href="Spliterator.html#binding">late-binding</a></em>,
+ * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED}
+ * and {@link Spliterator#ORDERED} with an encounter order that is ascending
+ * key order. The spliterator's comparator (see
+ * {@link java.util.Spliterator#getComparator()}) is {@code null} if
+ * the tree map's comparator (see {@link #comparator()}) is {@code null}.
+ * Otherwise, the spliterator's comparator is the same as or imposes the
+ * same total ordering as the tree map's comparator.
+ *
+ * <p>The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. If the map is modified
* while an iteration over the set is in progress (except through
* the iterator's own {@code remove} operation), the results of
@@ -823,9 +834,15 @@
/**
* Returns a {@link Collection} view of the values contained in this map.
- * The collection's iterator returns the values in ascending order
- * of the corresponding keys.
- * The collection is backed by the map, so changes to the map are
+ *
+ * <p>The collection's iterator returns the values in ascending order
+ * of the corresponding keys. The collection's spliterator is
+ * <em><a href="Spliterator.html#binding">late-binding</a></em>,
+ * <em>fail-fast</em>, and additionally reports {@link Spliterator#ORDERED}
+ * with an encounter order that is ascending order of the corresponding
+ * keys.
+ *
+ * <p>The collection is backed by the map, so changes to the map are
* reflected in the collection, and vice-versa. If the map is
* modified while an iteration over the collection is in progress
* (except through the iterator's own {@code remove} operation),
@@ -843,8 +860,15 @@
/**
* Returns a {@link Set} view of the mappings contained in this map.
- * The set's iterator returns the entries in ascending key order.
- * The set is backed by the map, so changes to the map are
+ *
+ * <p>The set's iterator returns the entries in ascending key order. The
+ * sets's spliterator is
+ * <em><a href="Spliterator.html#binding">late-binding</a></em>,
+ * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} and
+ * {@link Spliterator#ORDERED} with an encounter order that is ascending key
+ * order.
+ *
+ * <p>The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. If the map is modified
* while an iteration over the set is in progress (except through
* the iterator's own {@code remove} operation, or through the
@@ -2944,16 +2968,11 @@
@Override
public Comparator<Map.Entry<K, V>> getComparator() {
- // Since SORTED is reported and Map.Entry elements are not comparable
- // then a non-null comparator needs to be returned
+ // Adapt or create a key-based comparator
if (tree.comparator != null) {
- // Adapt the existing non-null comparator to compare entries
- // by key
return Map.Entry.comparingByKey(tree.comparator);
}
else {
- // Return a comparator of entries by key, with K assumed to be
- // of Comparable
return (Comparator<Map.Entry<K, V>> & Serializable) (e1, e2) -> {
@SuppressWarnings("unchecked")
Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey();
--- a/jdk/src/share/classes/java/util/TreeSet.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/TreeSet.java Wed Jul 05 19:09:26 2017 +0200
@@ -533,6 +533,25 @@
tm.readTreeSet(size, s, PRESENT);
}
+ /**
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@link Spliterator} over the elements in this
+ * set.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
+ * {@link Spliterator#DISTINCT}, {@link Spliterator#SORTED}, and
+ * {@link Spliterator#ORDERED}. Overriding implementations should document
+ * the reporting of additional characteristic values.
+ *
+ * <p>The spliterator's comparator (see
+ * {@link java.util.Spliterator#getComparator()}) is {@code null} if
+ * the tree set's comparator (see {@link #comparator()}) is {@code null}.
+ * Otherwise, the spliterator's comparator is the same as or imposes the
+ * same total ordering as the tree set's comparator.
+ *
+ * @return a {@code Spliterator} over the elements in this set
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return TreeMap.keySpliteratorFor(m);
}
--- a/jdk/src/share/classes/java/util/Vector.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/Vector.java Wed Jul 05 19:09:26 2017 +0200
@@ -1323,6 +1323,19 @@
modCount++;
}
+ /**
+ * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
+ * and <em>fail-fast</em> {@link Spliterator} over the elements in this
+ * list.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
+ * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
+ * Overriding implementations should document the reporting of additional
+ * characteristic values.
+ *
+ * @return a {@code Spliterator} over the elements in this list
+ * @since 1.8
+ */
@Override
public Spliterator<E> spliterator() {
return new VectorSpliterator<>(this, null, 0, -1, 0);
--- a/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -757,12 +757,8 @@
* Returns an iterator over the elements in this queue in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this queue in proper sequence
*/
@@ -1396,9 +1392,26 @@
// }
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this queue.
+ *
+ * <p>The returned spliterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+ *
+ * @implNote
+ * The {@code Spliterator} implements {@code trySplit} to permit limited
+ * parallelism.
+ *
+ * @return a {@code Spliterator} over the elements in this queue
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return Spliterators.spliterator
(this, Spliterator.ORDERED | Spliterator.NONNULL |
Spliterator.CONCURRENT);
}
+
}
--- a/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java Wed Jul 05 19:09:26 2017 +0200
@@ -420,6 +420,7 @@
}
/** Base class can act as either FJ or plain Runnable */
+ @SuppressWarnings("serial")
abstract static class Async extends ForkJoinTask<Void>
implements Runnable, AsynchronousCompletionTask {
public final Void getRawResult() { return null; }
@@ -671,6 +672,7 @@
}
// Opportunistically subclass AtomicInteger to use compareAndSet to claim.
+ @SuppressWarnings("serial")
abstract static class Completion extends AtomicInteger implements Runnable {
}
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Jul 05 19:09:26 2017 +0200
@@ -43,7 +43,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
-import java.util.ConcurrentModificationException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
@@ -94,14 +93,14 @@
* that key reporting the updated value.) For aggregate operations
* such as {@code putAll} and {@code clear}, concurrent retrievals may
* reflect insertion or removal of only some entries. Similarly,
- * Iterators and Enumerations return elements reflecting the state of
- * the hash table at some point at or since the creation of the
+ * Iterators, Spliterators and Enumerations return elements reflecting the
+ * state of the hash table at some point at or since the creation of the
* iterator/enumeration. They do <em>not</em> throw {@link
- * ConcurrentModificationException}. However, iterators are designed
- * to be used by only one thread at a time. Bear in mind that the
- * results of aggregate status methods including {@code size}, {@code
- * isEmpty}, and {@code containsValue} are typically useful only when
- * a map is not undergoing concurrent updates in other threads.
+ * java.util.ConcurrentModificationException ConcurrentModificationException}.
+ * However, iterators are designed to be used by only one thread at a time.
+ * Bear in mind that the results of aggregate status methods including
+ * {@code size}, {@code isEmpty}, and {@code containsValue} are typically
+ * useful only when a map is not undergoing concurrent updates in other threads.
* Otherwise the results of these methods reflect transient states
* that may be adequate for monitoring or estimation purposes, but not
* for program control.
@@ -1200,11 +1199,11 @@
* operations. It does not support the {@code add} or
* {@code addAll} operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}.
*
* @return the set view
*/
@@ -1223,11 +1222,11 @@
* {@code retainAll}, and {@code clear} operations. It does not
* support the {@code add} or {@code addAll} operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}
+ * and {@link Spliterator#NONNULL}.
*
* @return the collection view
*/
@@ -1245,11 +1244,11 @@
* {@code removeAll}, {@code retainAll}, and {@code clear}
* operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}.
*
* @return the set view
*/
@@ -2785,7 +2784,7 @@
return;
}
}
- else if ((s | WAITER) == 0) {
+ else if ((s & WAITER) == 0) {
if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
waiting = true;
waiter = Thread.currentThread();
@@ -4308,12 +4307,12 @@
// implementations below rely on concrete classes supplying these
// abstract methods
/**
- * Returns a "weakly consistent" iterator that will never
- * throw {@link ConcurrentModificationException}, and
- * guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not
- * guaranteed to) reflect any modifications subsequent to
- * construction.
+ * Returns an iterator over the elements in this collection.
+ *
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * @return an iterator over the elements in this collection
*/
public abstract Iterator<E> iterator();
public abstract boolean contains(Object o);
@@ -4716,6 +4715,7 @@
* Base class for bulk tasks. Repeats some fields and code from
* class Traverser, because we need to subclass CountedCompleter.
*/
+ @SuppressWarnings("serial")
abstract static class BulkTask<K,V,R> extends CountedCompleter<R> {
Node<K,V>[] tab; // same as Traverser
Node<K,V> next;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Wed Jul 05 19:09:26 2017 +0200
@@ -55,12 +55,8 @@
* Like most other concurrent collection implementations, this class
* does not permit the use of {@code null} elements.
*
- * <p>Iterators are <i>weakly consistent</i>, returning elements
- * reflecting the state of the deque at some point at or since the
- * creation of the iterator. They do <em>not</em> throw {@link
- * java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and may proceed concurrently with
- * other operations.
+ * <p>Iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* <p>Beware that, unlike in most collections, the {@code size} method
* is <em>NOT</em> a constant-time operation. Because of the
@@ -1290,12 +1286,8 @@
* Returns an iterator over the elements in this deque in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this deque in proper sequence
*/
@@ -1308,12 +1300,8 @@
* sequential order. The elements will be returned in order from
* last (tail) to first (head).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this deque in reverse order
*/
@@ -1493,6 +1481,22 @@
}
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this deque.
+ *
+ * <p>The returned spliterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+ *
+ * @implNote
+ * The {@code Spliterator} implements {@code trySplit} to permit limited
+ * parallelism.
+ *
+ * @return a {@code Spliterator} over the elements in this deque
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return new CLDSpliterator<E>(this);
}
@@ -1500,6 +1504,8 @@
/**
* Saves this deque to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData All of the elements (each an {@code E}) in
* the proper order, followed by a null
*/
@@ -1522,6 +1528,10 @@
/**
* Reconstitutes this deque from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -654,12 +654,8 @@
* Returns an iterator over the elements in this queue in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this queue in proper sequence
*/
@@ -749,6 +745,8 @@
/**
* Saves this queue to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData All of the elements (each an {@code E}) in
* the proper order, followed by a null
*/
@@ -771,6 +769,10 @@
/**
* Reconstitutes this queue from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
@@ -881,6 +883,23 @@
}
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this queue.
+ *
+ * <p>The returned spliterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+ *
+ * @implNote
+ * The {@code Spliterator} implements {@code trySplit} to permit limited
+ * parallelism.
+ *
+ * @return a {@code Spliterator} over the elements in this queue
+ * @since 1.8
+ */
+ @Override
public Spliterator<E> spliterator() {
return new CLQSpliterator<E>(this);
}
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java Wed Jul 05 19:09:26 2017 +0200
@@ -120,11 +120,8 @@
* operations. It does not support the {@code add} or {@code addAll}
* operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return a navigable set view of the keys in this map
*/
@@ -141,11 +138,8 @@
* operations. It does not support the {@code add} or {@code addAll}
* operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* <p>This method is equivalent to method {@code navigableKeySet}.
*
@@ -164,11 +158,8 @@
* operations. It does not support the {@code add} or {@code addAll}
* operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator
- * that will never throw {@link ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return a reverse order navigable set view of the keys in this map
*/
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Wed Jul 05 19:09:26 2017 +0200
@@ -34,6 +34,7 @@
*/
package java.util.concurrent;
+import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
@@ -44,11 +45,15 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
+import java.util.SortedSet;
import java.util.Spliterator;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentNavigableMap;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.BiConsumer;
@@ -66,12 +71,13 @@
* {@code containsKey}, {@code get}, {@code put} and
* {@code remove} operations and their variants. Insertion, removal,
* update, and access operations safely execute concurrently by
- * multiple threads. Iterators are <i>weakly consistent</i>, returning
- * elements reflecting the state of the map at some point at or since
- * the creation of the iterator. They do <em>not</em> throw {@link
- * java.util.ConcurrentModificationException ConcurrentModificationException},
- * and may proceed concurrently with other operations. Ascending key ordered
- * views and their iterators are faster than descending ones.
+ * multiple threads.
+ *
+ * <p>Iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>Ascending key ordered views and their iterators are faster than
+ * descending ones.
*
* <p>All {@code Map.Entry} pairs returned by methods in this class
* and its views represent snapshots of mappings at the time they were
@@ -108,9 +114,7 @@
* @since 1.6
*/
public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
- implements ConcurrentNavigableMap<K,V>,
- Cloneable,
- java.io.Serializable {
+ implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable {
/*
* This class implements a tree-like two-dimensionally linked skip
* list in which the index levels are represented in separate
@@ -1412,6 +1416,8 @@
/**
* Saves this map to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData The key (Object) and value (Object) for each
* key-value mapping represented by the map, followed by
* {@code null}. The key-value mappings are emitted in key-order
@@ -1436,6 +1442,10 @@
/**
* Reconstitutes this map from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
@SuppressWarnings("unchecked")
private void readObject(final java.io.ObjectInputStream s)
@@ -1795,8 +1805,18 @@
/**
* Returns a {@link NavigableSet} view of the keys contained in this map.
- * The set's iterator returns the keys in ascending order.
- * The set is backed by the map, so changes to the map are
+ *
+ * <p>The set's iterator returns the keys in ascending order.
+ * The set's spliterator additionally reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
+ * {@link Spliterator#ORDERED}, with an encounter order that is ascending
+ * key order. The spliterator's comparator (see
+ * {@link java.util.Spliterator#getComparator()}) is {@code null} if
+ * the map's comparator (see {@link #comparator()}) is {@code null}.
+ * Otherwise, the spliterator's comparator is the same as or imposes the
+ * same total ordering as the map's comparator.
+ *
+ * <p>The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. The set supports element
* removal, which removes the corresponding mapping from the map,
* via the {@code Iterator.remove}, {@code Set.remove},
@@ -1804,11 +1824,8 @@
* operations. It does not support the {@code add} or {@code addAll}
* operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse elements
- * as they existed upon construction of the iterator, and may (but is not
- * guaranteed to) reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* <p>This method is equivalent to method {@code navigableKeySet}.
*
@@ -1826,9 +1843,13 @@
/**
* Returns a {@link Collection} view of the values contained in this map.
- * The collection's iterator returns the values in ascending order
- * of the corresponding keys.
- * The collection is backed by the map, so changes to the map are
+ * <p>The collection's iterator returns the values in ascending order
+ * of the corresponding keys. The collections's spliterator additionally
+ * reports {@link Spliterator#CONCURRENT}, {@link Spliterator#NONNULL} and
+ * {@link Spliterator#ORDERED}, with an encounter order that is ascending
+ * order of the corresponding keys.
+ *
+ * <p>The collection is backed by the map, so changes to the map are
* reflected in the collection, and vice-versa. The collection
* supports element removal, which removes the corresponding
* mapping from the map, via the {@code Iterator.remove},
@@ -1836,11 +1857,8 @@
* {@code retainAll} and {@code clear} operations. It does not
* support the {@code add} or {@code addAll} operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse elements
- * as they existed upon construction of the iterator, and may (but is not
- * guaranteed to) reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*/
public Collection<V> values() {
Values<V> vs = values;
@@ -1849,8 +1867,14 @@
/**
* Returns a {@link Set} view of the mappings contained in this map.
- * The set's iterator returns the entries in ascending key order.
- * The set is backed by the map, so changes to the map are
+ *
+ * <p>The set's iterator returns the entries in ascending key order. The
+ * set's spliterator additionally reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
+ * {@link Spliterator#ORDERED}, with an encounter order that is ascending
+ * key order.
+ *
+ * <p>The set is backed by the map, so changes to the map are
* reflected in the set, and vice-versa. The set supports element
* removal, which removes the corresponding mapping from the map,
* via the {@code Iterator.remove}, {@code Set.remove},
@@ -1858,15 +1882,12 @@
* operations. It does not support the {@code add} or
* {@code addAll} operations.
*
- * <p>The view's {@code iterator} is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse elements
- * as they existed upon construction of the iterator, and may (but is not
- * guaranteed to) reflect any modifications subsequent to construction.
+ * <p>The view's iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
- * <p>The {@code Map.Entry} elements returned by
- * {@code iterator.next()} do <em>not</em> support the
- * {@code setValue} operation.
+ * <p>The {@code Map.Entry} elements traversed by the {@code iterator}
+ * or {@code spliterator} do <em>not</em> support the {@code setValue}
+ * operation.
*
* @return a set view of the mappings contained in this map,
* sorted in ascending key order
@@ -2548,8 +2569,7 @@
* @serial include
*/
static final class SubMap<K,V> extends AbstractMap<K,V>
- implements ConcurrentNavigableMap<K,V>, Cloneable,
- java.io.Serializable {
+ implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable {
private static final long serialVersionUID = -7647078645895051609L;
/** Underlying map */
@@ -3180,6 +3200,7 @@
public long estimateSize() {
return Long.MAX_VALUE;
}
+
}
final class SubMapValueIterator extends SubMapIter<V> {
@@ -3434,7 +3455,8 @@
}
public int characteristics() {
- return Spliterator.CONCURRENT | Spliterator.NONNULL;
+ return Spliterator.CONCURRENT | Spliterator.ORDERED |
+ Spliterator.NONNULL;
}
}
@@ -3528,8 +3550,17 @@
}
public final Comparator<Map.Entry<K,V>> getComparator() {
- return comparator == null ? null :
- Map.Entry.comparingByKey(comparator);
+ // Adapt or create a key-based comparator
+ if (comparator != null) {
+ return Map.Entry.comparingByKey(comparator);
+ }
+ else {
+ return (Comparator<Map.Entry<K,V>> & Serializable) (e1, e2) -> {
+ @SuppressWarnings("unchecked")
+ Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey();
+ return k1.compareTo(e2.getKey());
+ };
+ }
}
}
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Wed Jul 05 19:09:26 2017 +0200
@@ -57,12 +57,12 @@
* cost for the {@code contains}, {@code add}, and {@code remove}
* operations and their variants. Insertion, removal, and access
* operations safely execute concurrently by multiple threads.
- * Iterators are <i>weakly consistent</i>, returning elements
- * reflecting the state of the set at some point at or since the
- * creation of the iterator. They do <em>not</em> throw {@link
- * java.util.ConcurrentModificationException}, and may proceed
- * concurrently with other operations. Ascending ordered views and
- * their iterators are faster than descending ones.
+ *
+ * <p>Iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>Ascending ordered views and their iterators are faster than
+ * descending ones.
*
* <p>Beware that, unlike in most collections, the {@code size}
* method is <em>not</em> a constant-time operation. Because of the
@@ -480,6 +480,24 @@
return new ConcurrentSkipListSet<E>(m.descendingMap());
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this set.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#NONNULL}, {@link Spliterator#DISTINCT},
+ * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}, with an
+ * encounter order that is ascending order. Overriding implementations
+ * should document the reporting of additional characteristic values.
+ *
+ * <p>The spliterator's comparator (see
+ * {@link java.util.Spliterator#getComparator()}) is {@code null} if
+ * the set's comparator (see {@link #comparator()}) is {@code null}.
+ * Otherwise, the spliterator's comparator is the same as or imposes the
+ * same total ordering as the set's comparator.
+ *
+ * @return a {@code Spliterator} over the elements in this set
+ * @since 1.8
+ */
@SuppressWarnings("unchecked")
public Spliterator<E> spliterator() {
if (m instanceof ConcurrentSkipListMap)
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Wed Jul 05 19:09:26 2017 +0200
@@ -952,6 +952,8 @@
/**
* Saves this list to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData The length of the array backing the list is emitted
* (int), followed by all of its elements (each an Object)
* in the proper order.
@@ -972,6 +974,10 @@
/**
* Reconstitutes this list from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
@@ -1092,15 +1098,29 @@
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
- public ListIterator<E> listIterator(final int index) {
+ public ListIterator<E> listIterator(int index) {
Object[] elements = getArray();
int len = elements.length;
- if (index<0 || index>len)
+ if (index < 0 || index > len)
throw new IndexOutOfBoundsException("Index: "+index);
return new COWIterator<E>(elements, index);
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this list.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE},
+ * {@link Spliterator#ORDERED}, {@link Spliterator#SIZED}, and
+ * {@link Spliterator#SUBSIZED}.
+ *
+ * <p>The spliterator provides a snapshot of the state of the list
+ * when the spliterator was constructed. No synchronization is needed while
+ * operating on the spliterator.
+ *
+ * @return a {@code Spliterator} over the elements in this list
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return Spliterators.spliterator
(getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
@@ -1257,7 +1277,7 @@
// only call this holding l's lock
private void rangeCheck(int index) {
- if (index<0 || index>=size)
+ if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
",Size: "+size);
}
@@ -1304,7 +1324,7 @@
lock.lock();
try {
checkForComodification();
- if (index<0 || index>size)
+ if (index < 0 || index > size)
throw new IndexOutOfBoundsException();
l.add(index+offset, element);
expectedArray = l.getArray();
@@ -1361,12 +1381,12 @@
}
}
- public ListIterator<E> listIterator(final int index) {
+ public ListIterator<E> listIterator(int index) {
final ReentrantLock lock = l.lock;
lock.lock();
try {
checkForComodification();
- if (index<0 || index>size)
+ if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
return new COWSubListIterator<E>(l, index, offset, size);
@@ -1380,7 +1400,7 @@
lock.lock();
try {
checkForComodification();
- if (fromIndex<0 || toIndex>size)
+ if (fromIndex < 0 || toIndex > size)
throw new IndexOutOfBoundsException();
return new COWSubList<E>(l, fromIndex + offset,
toIndex + offset);
@@ -1580,6 +1600,7 @@
return Spliterators.spliterator
(a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED);
}
+
}
private static class COWSubListIterator<E> implements ListIterator<E> {
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Wed Jul 05 19:09:26 2017 +0200
@@ -404,6 +404,21 @@
al.forEach(action);
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this set in the order
+ * in which these elements were added.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE},
+ * {@link Spliterator#DISTINCT}, {@link Spliterator#SIZED}, and
+ * {@link Spliterator#SUBSIZED}.
+ *
+ * <p>The spliterator provides a snapshot of the state of the set
+ * when the spliterator was constructed. No synchronization is needed while
+ * operating on the spliterator.
+ *
+ * @return a {@code Spliterator} over the elements in this set
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return Spliterators.spliterator
(al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT);
--- a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -512,12 +512,8 @@
* unexpired) in this queue. The iterator does not return the
* elements in any particular order.
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this queue
*/
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Wed Jul 05 19:09:26 2017 +0200
@@ -144,7 +144,8 @@
* Upon any error in establishing these settings, default parameters
* are used. It is possible to disable or limit the use of threads in
* the common pool by setting the parallelism property to zero, and/or
- * using a factory that may return {@code null}.
+ * using a factory that may return {@code null}. However doing so may
+ * cause unjoined tasks to never be executed.
*
* <p><b>Implementation notes</b>: This implementation restricts the
* maximum number of running threads to 32767. Attempts to create
@@ -3303,8 +3304,8 @@
}
if (parallelism < 0 && // default 1 less than #cores
- (parallelism = Runtime.getRuntime().availableProcessors() - 1) < 0)
- parallelism = 0;
+ (parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0)
+ parallelism = 1;
if (parallelism > MAX_CAP)
parallelism = MAX_CAP;
return new ForkJoinPool(parallelism, factory, handler, LIFO_QUEUE,
--- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Wed Jul 05 19:09:26 2017 +0200
@@ -1008,12 +1008,8 @@
* Returns an iterator over the elements in this deque in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this deque in proper sequence
*/
@@ -1026,12 +1022,8 @@
* sequential order. The elements will be returned in order from
* last (tail) to first (head).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this deque in reverse order
*/
@@ -1270,6 +1262,22 @@
}
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this deque.
+ *
+ * <p>The returned spliterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+ *
+ * @implNote
+ * The {@code Spliterator} implements {@code trySplit} to permit limited
+ * parallelism.
+ *
+ * @return a {@code Spliterator} over the elements in this deque
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return new LBDSpliterator<E>(this);
}
@@ -1277,6 +1285,8 @@
/**
* Saves this deque to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData The capacity (int), followed by elements (each an
* {@code Object}) in the proper order, followed by a null
*/
@@ -1299,6 +1309,10 @@
/**
* Reconstitutes this deque from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
--- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -766,12 +766,8 @@
* Returns an iterator over the elements in this queue in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this queue in proper sequence
*/
@@ -973,6 +969,22 @@
}
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this queue.
+ *
+ * <p>The returned spliterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+ *
+ * @implNote
+ * The {@code Spliterator} implements {@code trySplit} to permit limited
+ * parallelism.
+ *
+ * @return a {@code Spliterator} over the elements in this queue
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return new LBQSpliterator<E>(this);
}
@@ -980,6 +992,8 @@
/**
* Saves this queue to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData The capacity is emitted (int), followed by all of
* its elements (each an {@code Object}) in the proper order,
* followed by a null
@@ -1005,6 +1019,10 @@
/**
* Reconstitutes this queue from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
--- a/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -40,6 +40,7 @@
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Queue;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import java.util.Spliterator;
import java.util.Spliterators;
@@ -1018,6 +1019,22 @@
}
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this queue.
+ *
+ * <p>The returned spliterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+ * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+ *
+ * @implNote
+ * The {@code Spliterator} implements {@code trySplit} to permit limited
+ * parallelism.
+ *
+ * @return a {@code Spliterator} over the elements in this queue
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return new LTQSpliterator<E>(this);
}
@@ -1301,12 +1318,8 @@
* Returns an iterator over the elements in this queue in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this queue in proper sequence
*/
@@ -1407,6 +1420,8 @@
/**
* Saves this queue to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData All of the elements (each an {@code E}) in
* the proper order, followed by a null
*/
@@ -1421,6 +1436,10 @@
/**
* Reconstitutes this queue from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
--- a/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -229,7 +229,7 @@
/**
* Creates a {@code PriorityBlockingQueue} containing the elements
* in the specified collection. If the specified collection is a
- * {@link SortedSet} or a {@link PriorityQueue}, this
+ * {@link SortedSet} or a {@link PriorityQueue}, this
* priority queue will be ordered according to the same ordering.
* Otherwise, this priority queue will be ordered according to the
* {@linkplain Comparable natural ordering} of its elements.
@@ -864,12 +864,8 @@
* Returns an iterator over the elements in this queue. The
* iterator does not return the elements in any particular order.
*
- * <p>The returned iterator is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and guarantees to traverse
- * elements as they existed upon construction of the iterator, and
- * may (but is not guaranteed to) reflect any modifications
- * subsequent to construction.
+ * <p>The returned iterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
*
* @return an iterator over the elements in this queue
*/
@@ -915,6 +911,9 @@
* For compatibility with previous version of this class, elements
* are first copied to a java.util.PriorityQueue, which is then
* serialized.
+ *
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
@@ -932,6 +931,10 @@
/**
* Reconstitutes this queue from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
@@ -1005,6 +1008,21 @@
}
}
+ /**
+ * Returns a {@link Spliterator} over the elements in this queue.
+ *
+ * <p>The returned spliterator is
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
+ * {@link Spliterator#NONNULL}.
+ *
+ * @implNote
+ * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}.
+ *
+ * @return a {@code Spliterator} over the elements in this queue
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return new PBQSpliterator<E>(this, null, 0, -1);
}
--- a/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java Wed Jul 05 19:09:26 2017 +0200
@@ -38,6 +38,8 @@
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
import java.util.*;
+import java.util.Spliterator;
+import java.util.Spliterators;
/**
* A {@linkplain BlockingQueue blocking queue} in which each insert
@@ -1062,21 +1064,17 @@
*
* @return an empty iterator
*/
- @SuppressWarnings("unchecked")
public Iterator<E> iterator() {
- return (Iterator<E>) EmptyIterator.EMPTY_ITERATOR;
+ return Collections.emptyIterator();
}
- // Replicated from a previous version of Collections
- private static class EmptyIterator<E> implements Iterator<E> {
- static final EmptyIterator<Object> EMPTY_ITERATOR
- = new EmptyIterator<Object>();
-
- public boolean hasNext() { return false; }
- public E next() { throw new NoSuchElementException(); }
- public void remove() { throw new IllegalStateException(); }
- }
-
+ /**
+ * Returns an empty spliterator in which calls to
+ * {@link java.util.Spliterator#trySplit()} always return {@code null}.
+ *
+ * @return an empty spliterator
+ * @since 1.8
+ */
public Spliterator<E> spliterator() {
return Spliterators.emptySpliterator();
}
@@ -1163,6 +1161,8 @@
/**
* Saves this queue to a stream (that is, serializes it).
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
@@ -1182,8 +1182,12 @@
/**
* Reconstitutes this queue from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
- private void readObject(final java.io.ObjectInputStream s)
+ private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
if (waitingProducers instanceof FifoWaitQueue)
--- a/jdk/src/share/classes/java/util/concurrent/atomic/Striped64.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/Striped64.java Wed Jul 05 19:09:26 2017 +0200
@@ -43,6 +43,7 @@
* for classes supporting dynamic striping on 64bit values. The class
* extends Number so that concrete subclasses must publicly do so.
*/
+@SuppressWarnings("serial")
abstract class Striped64 extends Number {
/*
* This class maintains a lazily-initialized table of atomically
--- a/jdk/src/share/classes/java/util/concurrent/package-info.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/package-info.java Wed Jul 05 19:09:26 2017 +0200
@@ -210,13 +210,19 @@
* collections are unshared, or are accessible only when
* holding other locks.
*
- * <p>Most concurrent Collection implementations (including most
- * Queues) also differ from the usual java.util conventions in that
- * their Iterators provide <em>weakly consistent</em> rather than
- * fast-fail traversal. A weakly consistent iterator is thread-safe,
- * but does not necessarily freeze the collection while iterating, so
- * it may (or may not) reflect any updates since the iterator was
- * created.
+ * <p id="Weakly">Most concurrent Collection implementations
+ * (including most Queues) also differ from the usual {@code java.util}
+ * conventions in that their {@linkplain java.util.Iterator Iterators}
+ * and {@linkplain java.util.Spliterator Spliterators} provide
+ * <em>weakly consistent</em> rather than fast-fail traversal:
+ * <ul>
+ * <li>they may proceed concurrently with other operations
+ * <li>they will never throw {@link java.util.ConcurrentModificationException
+ * ConcurrentModificationException}
+ * <li>they are guaranteed to traverse elements as they existed upon
+ * construction exactly once, and may (but are not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ * </ul>
*
* <h2 id="MemoryVisibility">Memory Consistency Properties</h2>
*
--- a/jdk/src/share/classes/java/util/jar/Attributes.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/jar/Attributes.java Wed Jul 05 19:09:26 2017 +0200
@@ -565,15 +565,6 @@
public static final Name MAIN_CLASS = new Name("Main-Class");
/**
- * {@code Name} object for {@code Profile} manifest attribute used by
- * applications or libraries packaged as JAR files to indicate the
- * minimum profile required to execute the application.
- * @since 1.8
- * @see UnsupportedProfileException
- */
- public static final Name PROFILE = new Name("Profile");
-
- /**
* <code>Name</code> object for <code>Sealed</code> manifest attribute
* used for sealing.
* @see <a href="../../../../technotes/guides/extensions/spec.html#sealing">
--- a/jdk/src/share/classes/java/util/jar/JarFile.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java Wed Jul 05 19:09:26 2017 +0200
@@ -69,8 +69,6 @@
// indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true)
private boolean hasClassPathAttribute;
- // indicates if Profile attribute present (only valid if hasCheckedSpecialAttributes true)
- private boolean hasProfileAttribute;
// true if manifest checked for special attributes
private volatile boolean hasCheckedSpecialAttributes;
@@ -459,15 +457,10 @@
// Statics for hand-coded Boyer-Moore search
private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'};
- private static final char[] PROFILE_CHARS = { 'p', 'r', 'o', 'f', 'i', 'l', 'e' };
// The bad character shift for "class-path"
private static final int[] CLASSPATH_LASTOCC;
// The good suffix shift for "class-path"
private static final int[] CLASSPATH_OPTOSFT;
- // The bad character shift for "profile"
- private static final int[] PROFILE_LASTOCC;
- // The good suffix shift for "profile"
- private static final int[] PROFILE_OPTOSFT;
static {
CLASSPATH_LASTOCC = new int[128];
@@ -483,19 +476,6 @@
for (int i=0; i<9; i++)
CLASSPATH_OPTOSFT[i] = 10;
CLASSPATH_OPTOSFT[9]=1;
-
- PROFILE_LASTOCC = new int[128];
- PROFILE_OPTOSFT = new int[7];
- PROFILE_LASTOCC[(int)'p'] = 1;
- PROFILE_LASTOCC[(int)'r'] = 2;
- PROFILE_LASTOCC[(int)'o'] = 3;
- PROFILE_LASTOCC[(int)'f'] = 4;
- PROFILE_LASTOCC[(int)'i'] = 5;
- PROFILE_LASTOCC[(int)'l'] = 6;
- PROFILE_LASTOCC[(int)'e'] = 7;
- for (int i=0; i<6; i++)
- PROFILE_OPTOSFT[i] = 7;
- PROFILE_OPTOSFT[6] = 1;
}
private JarEntry getManEntry() {
@@ -530,15 +510,6 @@
}
/**
- * Returns {@code true} iff this JAR file has a manifest with the
- * Profile attribute
- */
- boolean hasProfileAttribute() throws IOException {
- checkForSpecialAttributes();
- return hasProfileAttribute;
- }
-
- /**
* Returns true if the pattern {@code src} is found in {@code b}.
* The {@code lastOcc} and {@code optoSft} arrays are the precomputed
* bad character and good suffix shifts.
@@ -564,7 +535,7 @@
/**
* On first invocation, check if the JAR file has the Class-Path
- * and/or Profile attributes. A no-op on subsequent calls.
+ * attribute. A no-op on subsequent calls.
*/
private void checkForSpecialAttributes() throws IOException {
if (hasCheckedSpecialAttributes) return;
@@ -574,8 +545,6 @@
byte[] b = getBytes(manEntry);
if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
hasClassPathAttribute = true;
- if (match(PROFILE_CHARS, b, PROFILE_LASTOCC, PROFILE_OPTOSFT))
- hasProfileAttribute = true;
}
}
hasCheckedSpecialAttributes = true;
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Wed Jul 05 19:09:26 2017 +0200
@@ -139,13 +139,21 @@
return;
}
+ if (uname.equals(JarFile.MANIFEST_NAME)) {
+ return;
+ }
+
if (SignatureFileVerifier.isBlockOrSF(uname)) {
/* We parse only DSA, RSA or EC PKCS7 blocks. */
parsingBlockOrSF = true;
baos.reset();
mev.setEntry(null, je);
+ return;
}
- return;
+
+ // If a META-INF entry is not MF or block or SF, they should
+ // be normal entries. According to 2 above, no more block or
+ // SF will appear. Let's doneWithMeta.
}
}
--- a/jdk/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Wed Jul 05 19:09:26 2017 +0200
@@ -37,10 +37,6 @@
return jar.hasClassPathAttribute();
}
- public boolean jarFileHasProfileAttribute(JarFile jar) throws IOException {
- return jar.hasProfileAttribute();
- }
-
public CodeSource[] getCodeSources(JarFile jar, URL url) {
return jar.getCodeSources(url);
}
--- a/jdk/src/share/classes/java/util/jar/UnsupportedProfileException.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2012, 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 java.util.jar;
-
-/**
- * Thrown to indicate an attempt to access a JAR file with a {@link
- * Attributes.Name#PROFILE Profile} attribute that names a profile that
- * is not supported by this runtime.
- *
- * @since 1.8
- */
-public class UnsupportedProfileException extends RuntimeException {
- private static final long serialVersionUID = -1834773870678792406L;
-
- /**
- * Constructs an {@code UnsupportedProfileException} with no detail
- * message.
- */
- public UnsupportedProfileException() {
- }
-
- /**
- * Constructs an {@code UnsupportedProfileException} with the
- * specified detail message.
- *
- * @param message the detail message
- */
- public UnsupportedProfileException(String message) {
- super(message);
- }
-}
--- a/jdk/src/share/classes/java/util/stream/Collectors.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Collectors.java Wed Jul 05 19:09:26 2017 +0200
@@ -354,6 +354,43 @@
}
/**
+ * Adapts a {@code Collector} to perform an additional finishing
+ * transformation. For example, one could adapt the {@link #toList()}
+ * collector to always produce an immutable list with:
+ * <pre>{@code
+ * List<String> people
+ * = people.stream().collect(collectingAndThen(toList(), Collections::unmodifiableList));
+ * }</pre>
+ *
+ * @param <T> the type of the input elements
+ * @param <A> intermediate accumulation type of the downstream collector
+ * @param <R> result type of the downstream collector
+ * @param <RR> result type of the resulting collector
+ * @param downstream a collector
+ * @param finisher a function to be applied to the final result of the downstream collector
+ * @return a collector which performs the action of the downstream collector,
+ * followed by an additional finishing step
+ */
+ public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
+ Function<R,RR> finisher) {
+ Set<Collector.Characteristics> characteristics = downstream.characteristics();
+ if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
+ if (characteristics.size() == 1)
+ characteristics = Collectors.CH_NOID;
+ else {
+ characteristics = EnumSet.copyOf(characteristics);
+ characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
+ characteristics = Collections.unmodifiableSet(characteristics);
+ }
+ }
+ return new CollectorImpl<>(downstream.supplier(),
+ downstream.accumulator(),
+ downstream.combiner(),
+ downstream.finisher().andThen(finisher),
+ characteristics);
+ }
+
+ /**
* Returns a {@code Collector} accepting elements of type {@code T} that
* counts the number of input elements. If no elements are present, the
* result is 0.
--- a/jdk/src/share/classes/java/util/zip/Adler32.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/Adler32.java Wed Jul 05 19:09:26 2017 +0200
@@ -62,6 +62,11 @@
/**
* Updates the checksum with the specified array of bytes.
+ *
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code off} is negative, or {@code len} is negative,
+ * or {@code off+len} is greater than the length of the
+ * array {@code b}
*/
public void update(byte[] b, int off, int len) {
if (b == null) {
--- a/jdk/src/share/classes/java/util/zip/CRC32.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/CRC32.java Wed Jul 05 19:09:26 2017 +0200
@@ -60,6 +60,11 @@
/**
* Updates the CRC-32 checksum with the specified array of bytes.
+ *
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code off} is negative, or {@code len} is negative,
+ * or {@code off+len} is greater than the length of the
+ * array {@code b}
*/
public void update(byte[] b, int off, int len) {
if (b == null) {
--- a/jdk/src/share/classes/java/util/zip/ZipConstants.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipConstants.java Wed Jul 05 19:09:26 2017 +0200
@@ -71,10 +71,17 @@
/*
* Extra field header ID
*/
- static final int EXTID_ZIP64 = 0x0001; // Zip64
- static final int EXTID_NTFS = 0x000a; // NTFS
- static final int EXTID_UNIX = 0x000d; // UNIX
- static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp
+ static final int EXTID_ZIP64 = 0x0001; // Zip64
+ static final int EXTID_NTFS = 0x000a; // NTFS
+ static final int EXTID_UNIX = 0x000d; // UNIX
+ static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp
+
+ /*
+ * EXTT timestamp flags
+ */
+ static final int EXTT_FLAG_LMT = 0x1; // LastModifiedTime
+ static final int EXTT_FLAG_LAT = 0x2; // LastAccessTime
+ static final int EXTT_FLAT_CT = 0x4; // CreationTime
/*
* Central directory (CEN) header field offsets
--- a/jdk/src/share/classes/java/util/zip/ZipEntry.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipEntry.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2013, 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
@@ -25,6 +25,11 @@
package java.util.zip;
+import static java.util.zip.ZipUtils.*;
+import java.nio.file.attribute.FileTime;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
/**
* This class is used to represent a ZIP file entry.
*
@@ -32,8 +37,12 @@
*/
public
class ZipEntry implements ZipConstants, Cloneable {
+
String name; // entry name
- long mtime = -1; // last modification time
+ long time = -1; // last modification time
+ FileTime mtime; // last modification time, from extra field data
+ FileTime atime; // last access time, from extra field data
+ FileTime ctime; // creation time, from extra field data
long crc = -1; // crc-32 of entry data
long size = -1; // uncompressed size of entry data
long csize = -1; // compressed size of entry data
@@ -55,15 +64,15 @@
/**
* Creates a new zip entry with the specified name.
*
- * @param name the entry name
- * @exception NullPointerException if the entry name is null
- * @exception IllegalArgumentException if the entry name is longer than
- * 0xFFFF bytes
+ * @param name
+ * The entry name
+ *
+ * @throws NullPointerException if the entry name is null
+ * @throws IllegalArgumentException if the entry name is longer than
+ * 0xFFFF bytes
*/
public ZipEntry(String name) {
- if (name == null) {
- throw new NullPointerException();
- }
+ Objects.requireNonNull(name, "name");
if (name.length() > 0xFFFF) {
throw new IllegalArgumentException("entry name too long");
}
@@ -73,11 +82,19 @@
/**
* Creates a new zip entry with fields taken from the specified
* zip entry.
- * @param e a zip Entry object
+ *
+ * @param e
+ * A zip Entry object
+ *
+ * @throws NullPointerException if the entry object is null
*/
public ZipEntry(ZipEntry e) {
+ Objects.requireNonNull(e, "entry");
name = e.name;
+ time = e.time;
mtime = e.mtime;
+ atime = e.atime;
+ ctime = e.ctime;
crc = e.crc;
size = e.size;
csize = e.csize;
@@ -103,33 +120,178 @@
/**
* Sets the last modification time of the entry.
*
- * @param time the last modification time of the entry in milliseconds since the epoch
+ * <p> If the entry is output to a ZIP file or ZIP file formatted
+ * output stream the last modification time set by this method will
+ * be stored into the {@code date and time fields} of the zip file
+ * entry and encoded in standard {@code MS-DOS date and time format}.
+ * The {@link java.util.TimeZone#getDefault() default TimeZone} is
+ * used to convert the epoch time to the MS-DOS data and time.
+ *
+ * @param time
+ * The last modification time of the entry in milliseconds
+ * since the epoch
+ *
* @see #getTime()
+ * @see #getLastModifiedTime()
*/
public void setTime(long time) {
+ this.time = time;
+ this.mtime = null;
+ }
+
+ /**
+ * Returns the last modification time of the entry.
+ *
+ * <p> If the entry is read from a ZIP file or ZIP file formatted
+ * input stream, this is the last modification time from the {@code
+ * date and time fields} of the zip file entry. The
+ * {@link java.util.TimeZone#getDefault() default TimeZone} is used
+ * to convert the standard MS-DOS formatted date and time to the
+ * epoch time.
+ *
+ * @return The last modification time of the entry in milliseconds
+ * since the epoch, or -1 if not specified
+ *
+ * @see #setTime(long)
+ * @see #setLastModifiedTime(FileTime)
+ */
+ public long getTime() {
+ return time;
+ }
+
+ /**
+ * Sets the last modification time of the entry.
+ *
+ * <p> When output to a ZIP file or ZIP file formatted output stream
+ * the last modification time set by this method will be stored into
+ * zip file entry's {@code date and time fields} in {@code standard
+ * MS-DOS date and time format}), and the extended timestamp fields
+ * in {@code optional extra data} in UTC time.
+ *
+ * @param time
+ * The last modification time of the entry
+ * @return This zip entry
+ *
+ * @throws NullPointerException if the {@code time} is null
+ *
+ * @see #getLastModifiedTime()
+ * @since 1.8
+ */
+ public ZipEntry setLastModifiedTime(FileTime time) {
+ Objects.requireNonNull(name, "time");
this.mtime = time;
+ this.time = time.to(TimeUnit.MILLISECONDS);
+ return this;
}
/**
* Returns the last modification time of the entry.
- * <p> The last modificatin time may come from zip entry's extensible
- * data field {@code NTFS} or {@code Info-ZIP Extended Timestamp}, if
- * the entry is read from {@link ZipInputStream} or {@link ZipFile}.
+ *
+ * <p> If the entry is read from a ZIP file or ZIP file formatted
+ * input stream, this is the last modification time from the zip
+ * file entry's {@code optional extra data} if the extended timestamp
+ * fields are present. Otherwise the last modification time is read
+ * from the entry's {@code date and time fields}, the {@link
+ * java.util.TimeZone#getDefault() default TimeZone} is used to convert
+ * the standard MS-DOS formatted date and time to the epoch time.
+ *
+ * @return The last modification time of the entry, null if not specified
+ *
+ * @see #setLastModifiedTime(FileTime)
+ * @since 1.8
+ */
+ public FileTime getLastModifiedTime() {
+ if (mtime != null)
+ return mtime;
+ if (time == -1)
+ return null;
+ return FileTime.from(time, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Sets the last access time of the entry.
+ *
+ * <p> If set, the last access time will be stored into the extended
+ * timestamp fields of entry's {@code optional extra data}, when output
+ * to a ZIP file or ZIP file formatted stream.
+ *
+ * @param time
+ * The last access time of the entry
+ * @return This zip entry
+ *
+ * @throws NullPointerException if the {@code time} is null
+ *
+ * @see #getLastAccessTime()
+ * @since 1.8
+ */
+ public ZipEntry setLastAccessTime(FileTime time) {
+ Objects.requireNonNull(name, "time");
+ this.atime = time;
+ return this;
+ }
+
+ /**
+ * Returns the last access time of the entry.
*
- * @return the last modification time of the entry, or -1 if not specified
- * @see #setTime(long)
+ * <p> The last access time is from the extended timestamp fields
+ * of entry's {@code optional extra data} when read from a ZIP file
+ * or ZIP file formatted stream.
+ *
+ * @return The last access time of the entry, null if not specified
+
+ * @see #setLastAccessTime(FileTime)
+ * @since 1.8
*/
- public long getTime() {
- return mtime;
+ public FileTime getLastAccessTime() {
+ return atime;
+ }
+
+ /**
+ * Sets the creation time of the entry.
+ *
+ * <p> If set, the creation time will be stored into the extended
+ * timestamp fields of entry's {@code optional extra data}, when
+ * output to a ZIP file or ZIP file formatted stream.
+ *
+ * @param time
+ * The creation time of the entry
+ * @return This zip entry
+ *
+ * @throws NullPointerException if the {@code time} is null
+ *
+ * @see #getCreationTime()
+ * @since 1.8
+ */
+ public ZipEntry setCreationTime(FileTime time) {
+ Objects.requireNonNull(name, "time");
+ this.ctime = time;
+ return this;
+ }
+
+ /**
+ * Returns the creation time of the entry.
+ *
+ * <p> The creation time is from the extended timestamp fields of
+ * entry's {@code optional extra data} when read from a ZIP file
+ * or ZIP file formatted stream.
+ *
+ * @return the creation time of the entry, null if not specified
+ * @see #setCreationTime(FileTime)
+ * @since 1.8
+ */
+ public FileTime getCreationTime() {
+ return ctime;
}
/**
* Sets the uncompressed size of the entry data.
+ *
* @param size the uncompressed size in bytes
- * @exception IllegalArgumentException if the specified size is less
- * than 0, is greater than 0xFFFFFFFF when
- * <a href="package-summary.html#zip64">ZIP64 format</a> is not supported,
- * or is less than 0 when ZIP64 is supported
+ *
+ * @throws IllegalArgumentException if the specified size is less
+ * than 0, is greater than 0xFFFFFFFF when
+ * <a href="package-summary.html#zip64">ZIP64 format</a> is not supported,
+ * or is less than 0 when ZIP64 is supported
* @see #getSize()
*/
public void setSize(long size) {
@@ -140,7 +302,8 @@
}
/**
- * Returns the uncompressed size of the entry data, or -1 if not known.
+ * Returns the uncompressed size of the entry data.
+ *
* @return the uncompressed size of the entry data, or -1 if not known
* @see #setSize(long)
*/
@@ -149,9 +312,11 @@
}
/**
- * Returns the size of the compressed entry data, or -1 if not known.
- * In the case of a stored entry, the compressed size will be the same
+ * Returns the size of the compressed entry data.
+ *
+ * <p> In the case of a stored entry, the compressed size will be the same
* as the uncompressed size of the entry.
+ *
* @return the size of the compressed entry data, or -1 if not known
* @see #setCompressedSize(long)
*/
@@ -161,7 +326,9 @@
/**
* Sets the size of the compressed entry data.
+ *
* @param csize the compressed size to set to
+ *
* @see #getCompressedSize()
*/
public void setCompressedSize(long csize) {
@@ -170,9 +337,11 @@
/**
* Sets the CRC-32 checksum of the uncompressed entry data.
+ *
* @param crc the CRC-32 value
- * @exception IllegalArgumentException if the specified CRC-32 value is
- * less than 0 or greater than 0xFFFFFFFF
+ *
+ * @throws IllegalArgumentException if the specified CRC-32 value is
+ * less than 0 or greater than 0xFFFFFFFF
* @see #getCrc()
*/
public void setCrc(long crc) {
@@ -183,10 +352,11 @@
}
/**
- * Returns the CRC-32 checksum of the uncompressed entry data, or -1 if
- * not known.
+ * Returns the CRC-32 checksum of the uncompressed entry data.
+ *
* @return the CRC-32 checksum of the uncompressed entry data, or -1 if
* not known
+ *
* @see #setCrc(long)
*/
public long getCrc() {
@@ -195,9 +365,11 @@
/**
* Sets the compression method for the entry.
+ *
* @param method the compression method, either STORED or DEFLATED
- * @exception IllegalArgumentException if the specified compression
- * method is invalid
+ *
+ * @throws IllegalArgumentException if the specified compression
+ * method is invalid
* @see #getMethod()
*/
public void setMethod(int method) {
@@ -208,7 +380,8 @@
}
/**
- * Returns the compression method of the entry, or -1 if not specified.
+ * Returns the compression method of the entry.
+ *
* @return the compression method of the entry, or -1 if not specified
* @see #setMethod(int)
*/
@@ -218,21 +391,104 @@
/**
* Sets the optional extra field data for the entry.
- * @param extra the extra field data bytes
- * @exception IllegalArgumentException if the length of the specified
- * extra field data is greater than 0xFFFF bytes
+ *
+ * <p> Invoking this method may change this entry's last modification
+ * time, last access time and creation time, if the {@code extra} field
+ * data includes the extensible timestamp fields, such as {@code NTFS tag
+ * 0x0001} or {@code Info-ZIP Extended Timestamp}, as specified in
+ * <a href="http://www.info-zip.org/doc/appnote-19970311-iz.zip">Info-ZIP
+ * Application Note 970311</a>.
+ *
+ * @param extra
+ * The extra field data bytes
+ *
+ * @throws IllegalArgumentException if the length of the specified
+ * extra field data is greater than 0xFFFF bytes
+ *
* @see #getExtra()
*/
public void setExtra(byte[] extra) {
- if (extra != null && extra.length > 0xFFFF) {
- throw new IllegalArgumentException("invalid extra field length");
+ setExtra0(extra, false);
+ }
+
+ /**
+ * Sets the optional extra field data for the entry.
+ *
+ * @param extra
+ * the extra field data bytes
+ * @param doZIP64
+ * if true, set size and csize from ZIP64 fields if present
+ */
+ void setExtra0(byte[] extra, boolean doZIP64) {
+ if (extra != null) {
+ if (extra.length > 0xFFFF) {
+ throw new IllegalArgumentException("invalid extra field length");
+ }
+ // extra fields are in "HeaderID(2)DataSize(2)Data... format
+ int off = 0;
+ int len = extra.length;
+ while (off + 4 < len) {
+ int tag = get16(extra, off);
+ int sz = get16(extra, off + 2);
+ off += 4;
+ if (off + sz > len) // invalid data
+ break;
+ switch (tag) {
+ case EXTID_ZIP64:
+ if (doZIP64) {
+ // LOC extra zip64 entry MUST include BOTH original
+ // and compressed file size fields.
+ // If invalid zip64 extra fields, simply skip. Even
+ // it's rare, it's possible the entry size happens to
+ // be the magic value and it "accidently" has some
+ // bytes in extra match the id.
+ if (sz >= 16) {
+ size = get64(extra, off);
+ csize = get64(extra, off + 8);
+ }
+ }
+ break;
+ case EXTID_NTFS:
+ int pos = off + 4; // reserved 4 bytes
+ if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
+ break;
+ mtime = winTimeToFileTime(get64(extra, pos + 4));
+ atime = winTimeToFileTime(get64(extra, pos + 12));
+ ctime = winTimeToFileTime(get64(extra, pos + 20));
+ break;
+ case EXTID_EXTT:
+ int flag = Byte.toUnsignedInt(extra[off]);
+ int sz0 = 1;
+ // The CEN-header extra field contains the modification
+ // time only, or no timestamp at all. 'sz' is used to
+ // flag its presence or absence. But if mtime is present
+ // in LOC it must be present in CEN as well.
+ if ((flag & 0x1) != 0 && (sz0 + 4) <= sz) {
+ mtime = unixTimeToFileTime(get32(extra, off + sz0));
+ sz0 += 4;
+ }
+ if ((flag & 0x2) != 0 && (sz0 + 4) <= sz) {
+ atime = unixTimeToFileTime(get32(extra, off + sz0));
+ sz0 += 4;
+ }
+ if ((flag & 0x4) != 0 && (sz0 + 4) <= sz) {
+ ctime = unixTimeToFileTime(get32(extra, off + sz0));
+ sz0 += 4;
+ }
+ break;
+ default:
+ }
+ off += sz;
+ }
}
this.extra = extra;
}
/**
- * Returns the extra field data for the entry, or null if none.
+ * Returns the extra field data for the entry.
+ *
* @return the extra field data for the entry, or null if none
+ *
* @see #setExtra(byte[])
*/
public byte[] getExtra() {
@@ -255,8 +511,10 @@
}
/**
- * Returns the comment string for the entry, or null if none.
+ * Returns the comment string for the entry.
+ *
* @return the comment string for the entry, or null if none
+ *
* @see #setComment(String)
*/
public String getComment() {
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2013, 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
@@ -567,44 +567,12 @@
e.name = zc.toString(bname, bname.length);
}
}
+ e.time = dosToJavaTime(getEntryTime(jzentry));
e.crc = getEntryCrc(jzentry);
e.size = getEntrySize(jzentry);
- e. csize = getEntryCSize(jzentry);
+ e.csize = getEntryCSize(jzentry);
e.method = getEntryMethod(jzentry);
- e.extra = getEntryBytes(jzentry, JZENTRY_EXTRA);
- if (e.extra != null) {
- byte[] extra = e.extra;
- int len = e.extra.length;
- int off = 0;
- while (off + 4 < len) {
- int pos = off;
- int tag = get16(extra, pos);
- int sz = get16(extra, pos + 2);
- pos += 4;
- if (pos + sz > len) // invalid data
- break;
- switch (tag) {
- case EXTID_NTFS:
- pos += 4; // reserved 4 bytes
- if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
- break;
- e.mtime = winToJavaTime(get64(extra, pos + 4));
- break;
- case EXTID_EXTT:
- int flag = Byte.toUnsignedInt(extra[pos++]);
- if ((flag & 0x1) != 0) {
- e.mtime = unixToJavaTime(get32(extra, pos));
- pos += 4;
- }
- break;
- default: // unknown tag
- }
- off += (sz + 4);
- }
- }
- if (e.mtime == -1) {
- e.mtime = dosToJavaTime(getEntryTime(jzentry));
- }
+ e.setExtra0(getEntryBytes(jzentry, JZENTRY_EXTRA), false);
byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT);
if (bcomm == null) {
e.comment = null;
--- a/jdk/src/share/classes/java/util/zip/ZipInputStream.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipInputStream.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -288,9 +288,9 @@
int len = get16(tmpbuf, LOCNAM);
int blen = b.length;
if (len > blen) {
- do
+ do {
blen = blen * 2;
- while (len > blen);
+ } while (len > blen);
b = new byte[blen];
}
readFully(b, 0, len);
@@ -303,7 +303,7 @@
throw new ZipException("encrypted ZIP entry not supported");
}
e.method = get16(tmpbuf, LOCHOW);
- e.mtime = dosToJavaTime(get32(tmpbuf, LOCTIM));
+ e.time = dosToJavaTime(get32(tmpbuf, LOCTIM));
if ((flag & 8) == 8) {
/* "Data Descriptor" present */
if (e.method != DEFLATED) {
@@ -319,49 +319,7 @@
if (len > 0) {
byte[] extra = new byte[len];
readFully(extra, 0, len);
- e.setExtra(extra);
- // extra fields are in "HeaderID(2)DataSize(2)Data... format
- int off = 0;
- while (off + 4 < len) {
- int pos = off;
- int tag = get16(extra, pos);
- int sz = get16(extra, pos + 2);
- pos += 4;
- if (pos + sz > len) // invalid data
- break;
- switch (tag) {
- case EXTID_ZIP64 :
- // LOC extra zip64 entry MUST include BOTH original and
- // compressed file size fields.
- //
- // If invalid zip64 extra fields, simply skip. Even it's
- // rare, it's possible the entry size happens to be
- // the magic value and it "accidently" has some bytes
- // in extra match the id.
- if (sz >= 16 && (pos + sz) <= len ) {
- e.size = get64(extra, pos);
- e.csize = get64(extra, pos + 8);
- }
- break;
- case EXTID_NTFS:
- pos += 4; // reserved 4 bytes
- if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
- break;
- // override the loc field, NTFS time has 'microsecond' granularity
- e.mtime = winToJavaTime(get64(extra, pos + 4));
- break;
- case EXTID_EXTT:
- int flag = Byte.toUnsignedInt(extra[pos++]);
- if ((flag & 0x1) != 0) {
- e.mtime = unixToJavaTime(get32(extra, pos));
- pos += 4;
- }
- break;
- default: // unknown tag
- }
- off += (sz + 4);
- }
-
+ e.setExtra0(extra, true);
}
return e;
}
--- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java Wed Jul 05 19:09:26 2017 +0200
@@ -59,8 +59,9 @@
"jdk.util.zip.inhibitZip64", "false")));
private static class XEntry {
- public final ZipEntry entry;
- public final long offset;
+ final ZipEntry entry;
+ final long offset;
+ long dostime; // last modification time in msdos format
public XEntry(ZipEntry entry, long offset) {
this.entry = entry;
this.offset = offset;
@@ -191,7 +192,9 @@
if (current != null) {
closeEntry(); // close previous entry
}
- if (e.mtime == -1) {
+ if (e.time == -1) {
+ // by default, do NOT use extended timestamps in extra
+ // data, for now.
e.setTime(System.currentTimeMillis());
}
if (e.method == -1) {
@@ -384,25 +387,20 @@
ZipEntry e = xentry.entry;
int flag = e.flag;
boolean hasZip64 = false;
- int elen = (e.extra != null) ? e.extra.length : 0;
- int eoff = 0;
- boolean foundEXTT = false; // if EXTT already present
- // do nothing.
- while (eoff + 4 < elen) {
- int tag = get16(e.extra, eoff);
- int sz = get16(e.extra, eoff + 2);
- if (tag == EXTID_EXTT) {
- foundEXTT = true;
- }
- eoff += (4 + sz);
- }
+ int elen = getExtraLen(e.extra);
+
+ // keep a copy of dostime for writeCEN(), otherwise the tz
+ // sensitive local time entries in loc and cen might be
+ // different if the default tz get changed during writeLOC()
+ // and writeCEN()
+ xentry.dostime = javaToDosTime(e.time);
+
writeInt(LOCSIG); // LOC header signature
if ((flag & 8) == 8) {
writeShort(version(e)); // version needed to extract
writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method
- writeInt(javaToDosTime(e.mtime)); // last modification time
-
+ writeInt(xentry.dostime); // last modification time
// store size, uncompressed size, and crc-32 in data descriptor
// immediately following compressed entry data
writeInt(0);
@@ -417,7 +415,7 @@
}
writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method
- writeInt(javaToDosTime(e.mtime)); // last modification time
+ writeInt(xentry.dostime); // last modification time
writeInt(e.crc); // crc-32
if (hasZip64) {
writeInt(ZIP64_MAGICVAL);
@@ -430,8 +428,23 @@
}
byte[] nameBytes = zc.getBytes(e.name);
writeShort(nameBytes.length);
- if (!foundEXTT)
- elen += 9; // use Info-ZIP's ext time in extra
+
+ int elenEXTT = 0; // info-zip extended timestamp
+ int flagEXTT = 0;
+ if (e.mtime != null) {
+ elenEXTT += 4;
+ flagEXTT |= EXTT_FLAG_LMT;
+ }
+ if (e.atime != null) {
+ elenEXTT += 4;
+ flagEXTT |= EXTT_FLAG_LAT;
+ }
+ if (e.ctime != null) {
+ elenEXTT += 4;
+ flagEXTT |= EXTT_FLAT_CT;
+ }
+ if (flagEXTT != 0)
+ elen += (elenEXTT + 5); // headid(2) + size(2) + flag(1) + data
writeShort(elen);
writeBytes(nameBytes, 0, nameBytes.length);
if (hasZip64) {
@@ -440,15 +453,18 @@
writeLong(e.size);
writeLong(e.csize);
}
- if (!foundEXTT) {
+ if (flagEXTT != 0) {
writeShort(EXTID_EXTT);
- writeShort(5); // size for the folowing data block
- writeByte(0x1); // flags byte, mtime only
- writeInt(javaToUnixTime(e.mtime));
+ writeShort(elenEXTT + 1); // flag + data
+ writeByte(flagEXTT);
+ if (e.mtime != null)
+ writeInt(fileTimeToUnixTime(e.mtime));
+ if (e.atime != null)
+ writeInt(fileTimeToUnixTime(e.atime));
+ if (e.ctime != null)
+ writeInt(fileTimeToUnixTime(e.ctime));
}
- if (e.extra != null) {
- writeBytes(e.extra, 0, e.extra.length);
- }
+ writeExtra(e.extra);
locoff = written;
}
@@ -506,31 +522,35 @@
}
writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method
- writeInt(javaToDosTime(e.mtime)); // last modification time
+ // use the copy in xentry, which has been converted
+ // from e.time in writeLOC()
+ writeInt(xentry.dostime); // last modification time
writeInt(e.crc); // crc-32
writeInt(csize); // compressed size
writeInt(size); // uncompressed size
byte[] nameBytes = zc.getBytes(e.name);
writeShort(nameBytes.length);
- int elen = (e.extra != null) ? e.extra.length : 0;
- int eoff = 0;
- boolean foundEXTT = false; // if EXTT already present
- // do nothing.
- while (eoff + 4 < elen) {
- int tag = get16(e.extra, eoff);
- int sz = get16(e.extra, eoff + 2);
- if (tag == EXTID_EXTT) {
- foundEXTT = true;
- }
- eoff += (4 + sz);
+ int elen = getExtraLen(e.extra);
+ if (hasZip64) {
+ elen += (elenZIP64 + 4);// + headid(2) + datasize(2)
}
- if (hasZip64) {
- // + headid(2) + datasize(2)
- elen += (elenZIP64 + 4);
+ // cen info-zip extended timestamp only outputs mtime
+ // but set the flag for a/ctime, if present in loc
+ int flagEXTT = 0;
+ if (e.mtime != null) {
+ elen += 4; // + mtime(4)
+ flagEXTT |= EXTT_FLAG_LMT;
}
- if (!foundEXTT)
- elen += 9; // Info-ZIP's Extended Timestamp
+ if (e.atime != null) {
+ flagEXTT |= EXTT_FLAG_LAT;
+ }
+ if (e.ctime != null) {
+ flagEXTT |= EXTT_FLAT_CT;
+ }
+ if (flagEXTT != 0) {
+ elen += 5; // headid + sz + flag
+ }
writeShort(elen);
byte[] commentBytes;
if (e.comment != null) {
@@ -545,6 +565,8 @@
writeInt(0); // external file attributes (unused)
writeInt(offset); // relative offset of local header
writeBytes(nameBytes, 0, nameBytes.length);
+
+ // take care of EXTID_ZIP64 and EXTID_EXTT
if (hasZip64) {
writeShort(ZIP64_EXTID);// Zip64 extra
writeShort(elenZIP64);
@@ -555,15 +577,18 @@
if (offset == ZIP64_MAGICVAL)
writeLong(xentry.offset);
}
- if (!foundEXTT) {
+ if (flagEXTT != 0) {
writeShort(EXTID_EXTT);
- writeShort(5);
- writeByte(0x1); // flags byte
- writeInt(javaToUnixTime(e.mtime));
+ if (e.mtime != null) {
+ writeShort(5); // flag + mtime
+ writeByte(flagEXTT);
+ writeInt(fileTimeToUnixTime(e.mtime));
+ } else {
+ writeShort(1); // flag only
+ writeByte(flagEXTT);
+ }
}
- if (e.extra != null) {
- writeBytes(e.extra, 0, e.extra.length);
- }
+ writeExtra(e.extra);
if (commentBytes != null) {
writeBytes(commentBytes, 0, Math.min(commentBytes.length, 0xffff));
}
@@ -627,6 +652,47 @@
}
/*
+ * Returns the length of extra data without EXTT and ZIP64.
+ */
+ private int getExtraLen(byte[] extra) {
+ if (extra == null)
+ return 0;
+ int skipped = 0;
+ int len = extra.length;
+ int off = 0;
+ while (off + 4 <= len) {
+ int tag = get16(extra, off);
+ int sz = get16(extra, off + 2);
+ if (tag == EXTID_EXTT || tag == EXTID_ZIP64) {
+ skipped += (sz + 4);
+ }
+ off += (sz + 4);
+ }
+ return len - skipped;
+ }
+
+ /*
+ * Writes extra data without EXTT and ZIP64.
+ *
+ * Extra timestamp and ZIP64 data is handled/output separately
+ * in writeLOC and writeCEN.
+ */
+ private void writeExtra(byte[] extra) throws IOException {
+ if (extra != null) {
+ int len = extra.length;
+ int off = 0;
+ while (off + 4 <= len) {
+ int tag = get16(extra, off);
+ int sz = get16(extra, off + 2);
+ if (tag != EXTID_EXTT && tag != EXTID_ZIP64) {
+ writeBytes(extra, off, sz + 4);
+ }
+ off += (sz + 4);
+ }
+ }
+ }
+
+ /*
* Writes a 8-bit byte to the output stream.
*/
private void writeByte(int v) throws IOException {
--- a/jdk/src/share/classes/java/util/zip/ZipUtils.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipUtils.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,42 +25,45 @@
package java.util.zip;
+import java.nio.file.attribute.FileTime;
import java.util.Date;
import java.util.concurrent.TimeUnit;
+import static java.util.zip.ZipConstants.*;
+import static java.util.zip.ZipConstants64.*;
+
class ZipUtils {
// used to adjust values between Windows and java epoch
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
/**
- * Converts Windows time (in microseconds, UTC/GMT) time to Java time.
+ * Converts Windows time (in microseconds, UTC/GMT) time to FileTime.
*/
- public static final long winToJavaTime(long wtime) {
- return TimeUnit.MILLISECONDS.convert(
- wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
+ public static final FileTime winTimeToFileTime(long wtime) {
+ return FileTime.from(wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS,
+ TimeUnit.MICROSECONDS);
}
/**
- * Converts Java time to Windows time.
+ * Converts FileTime to Windows time.
*/
- public static final long javaToWinTime(long time) {
- return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS)
- - WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
+ public static final long fileTimeToWinTime(FileTime ftime) {
+ return (ftime.to(TimeUnit.MICROSECONDS) - WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
}
/**
- * Converts "standard Unix time"(in seconds, UTC/GMT) to Java time
+ * Converts "standard Unix time"(in seconds, UTC/GMT) to FileTime
*/
- public static final long unixToJavaTime(long utime) {
- return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS);
+ public static final FileTime unixTimeToFileTime(long utime) {
+ return FileTime.from(utime, TimeUnit.SECONDS);
}
/**
- * Converts Java time to "standard Unix time".
+ * Converts FileTime to "standard Unix time".
*/
- public static final long javaToUnixTime(long time) {
- return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS);
+ public static final long fileTimeToUnixTime(FileTime ftime) {
+ return ftime.to(TimeUnit.SECONDS);
}
/**
@@ -92,7 +95,6 @@
d.getSeconds() >> 1;
}
-
/**
* Fetches unsigned 16-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
@@ -116,5 +118,4 @@
public static final long get64(byte b[], int off) {
return get32(b, off) | (get32(b, off+4) << 32);
}
-
}
--- a/jdk/src/share/classes/javax/crypto/spec/PBEParameterSpec.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/javax/crypto/spec/PBEParameterSpec.java Wed Jul 05 19:09:26 2017 +0200
@@ -64,7 +64,8 @@
* @param salt the salt. The contents of <code>salt</code> are copied
* to protect against subsequent modification.
* @param iterationCount the iteration count.
- * @param paramSpec the cipher algorithm parameter specification.
+ * @param paramSpec the cipher algorithm parameter specification, which
+ * may be null.
* @exception NullPointerException if <code>salt</code> is null.
*
* @since 1.8
--- a/jdk/src/share/classes/javax/security/auth/Policy.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/javax/security/auth/Policy.java Wed Jul 05 19:09:26 2017 +0200
@@ -156,9 +156,10 @@
private static Policy policy;
private static ClassLoader contextClassLoader;
+ private final static String AUTH_POLICY =
+ "sun.security.provider.AuthPolicyFile";
- // true if a custom (not com.sun.security.auth.PolicyFile) system-wide
- // policy object is set
+ // true if a custom (not AUTH_POLICY) system-wide policy object is set
private static boolean isCustomPolicy;
static {
@@ -220,7 +221,7 @@
}
});
if (policy_class == null) {
- policy_class = "com.sun.security.auth.PolicyFile";
+ policy_class = AUTH_POLICY;
}
try {
@@ -236,8 +237,7 @@
contextClassLoader).newInstance();
}
});
- isCustomPolicy =
- !finalClass.equals("com.sun.security.auth.PolicyFile");
+ isCustomPolicy = !finalClass.equals(AUTH_POLICY);
} catch (Exception e) {
throw new SecurityException
(sun.security.util.ResourcesMgr.getString
@@ -274,14 +274,14 @@
}
/**
- * Returns true if a custom (not com.sun.security.auth.PolicyFile)
- * system-wide policy object has been set or installed. This method is
- * called by SubjectDomainCombiner to provide backwards compatibility for
+ * Returns true if a custom (not AUTH_POLICY) system-wide policy object
+ * has been set or installed. This method is called by
+ * SubjectDomainCombiner to provide backwards compatibility for
* developers that provide their own javax.security.auth.Policy
* implementations.
*
- * @return true if a custom (not com.sun.security.auth.PolicyFile)
- * system-wide policy object has been set; false otherwise
+ * @return true if a custom (not AUTH_POLICY) system-wide policy object
+ * has been set; false otherwise
*/
static boolean isCustomPolicySet(Debug debug) {
if (policy != null) {
@@ -299,8 +299,7 @@
return Security.getProperty("auth.policy.provider");
}
});
- if (policyClass != null
- && !policyClass.equals("com.sun.security.auth.PolicyFile")) {
+ if (policyClass != null && !policyClass.equals(AUTH_POLICY)) {
if (debug != null) {
debug.println("Providing backwards compatibility for " +
"javax.security.auth.policy implementation: " +
--- a/jdk/src/share/classes/javax/security/auth/login/Configuration.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/javax/security/auth/login/Configuration.java Wed Jul 05 19:09:26 2017 +0200
@@ -75,7 +75,7 @@
* LoginModules configured for that application. Each {@code LoginModule}
* is specified via its fully qualified class name.
* Authentication proceeds down the module list in the exact order specified.
- * If an application does not have specific entry,
+ * If an application does not have a specific entry,
* it defaults to the specific entry for "<i>other</i>".
*
* <p> The <i>Flag</i> value controls the overall behavior as authentication
@@ -248,7 +248,7 @@
}
});
if (config_class == null) {
- config_class = "com.sun.security.auth.login.ConfigFile";
+ config_class = "sun.security.provider.ConfigFile";
}
try {
--- a/jdk/src/share/classes/javax/sound/sampled/DataLine.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/javax/sound/sampled/DataLine.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,6 +25,8 @@
package javax.sound.sampled;
+import java.util.Arrays;
+
/**
* <code>DataLine</code> adds media-related functionality to its
* superinterface, <code>{@link Line}</code>. This functionality includes
@@ -282,9 +284,9 @@
*/
public static class Info extends Line.Info {
- private AudioFormat[] formats;
- private int minBufferSize;
- private int maxBufferSize;
+ private final AudioFormat[] formats;
+ private final int minBufferSize;
+ private final int maxBufferSize;
/**
* Constructs a data line's info object from the specified information,
@@ -304,7 +306,7 @@
if (formats == null) {
this.formats = new AudioFormat[0];
} else {
- this.formats = formats;
+ this.formats = Arrays.copyOf(formats, formats.length);
}
this.minBufferSize = minBufferSize;
@@ -329,8 +331,7 @@
if (format == null) {
this.formats = new AudioFormat[0];
} else {
- AudioFormat[] formats = { format };
- this.formats = formats;
+ this.formats = new AudioFormat[]{format};
}
this.minBufferSize = bufferSize;
@@ -373,10 +374,7 @@
* @see #isFormatSupported(AudioFormat)
*/
public AudioFormat[] getFormats() {
-
- AudioFormat[] returnedArray = new AudioFormat[formats.length];
- System.arraycopy(formats, 0, returnedArray, 0, formats.length);
- return returnedArray;
+ return Arrays.copyOf(formats, formats.length);
}
/**
--- a/jdk/src/share/classes/javax/swing/JLabel.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/javax/swing/JLabel.java Wed Jul 05 19:09:26 2017 +0200
@@ -1185,14 +1185,13 @@
}
/**
- * Determine the bounding box of the character at the given
- * index into the string. The bounds are returned in local
- * coordinates. If the index is invalid an empty rectangle is
- * returned.
+ * Returns the bounding box of the character at the given
+ * index in the string. The bounds are returned in local
+ * coordinates. If the index is invalid, <code>null</code> is returned.
*
* @param i the index into the String
- * @return the screen coordinates of the character's the bounding box,
- * if index is invalid returns an empty rectangle.
+ * @return the screen coordinates of the character's bounding box.
+ * If the index is invalid, <code>null</code> is returned.
* @since 1.3
*/
public Rectangle getCharacterBounds(int i) {
--- a/jdk/src/share/classes/sun/audio/AudioData.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/audio/AudioData.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,6 +26,8 @@
package sun.audio;
import java.io.*;
+import java.util.Arrays;
+
import javax.sound.sampled.*;
@@ -65,12 +67,11 @@
/**
* Constructor
*/
- public AudioData(byte buffer[]) {
-
- this.buffer = buffer;
- // if we cannot extract valid format information, we resort to assuming the data will be 8k mono u-law
- // in order to provide maximal backwards compatibility....
- this.format = DEFAULT_FORMAT;
+ public AudioData(final byte[] buffer) {
+ // if we cannot extract valid format information, we resort to assuming
+ // the data will be 8k mono u-law in order to provide maximal backwards
+ // compatibility....
+ this(DEFAULT_FORMAT, buffer);
// okay, we need to extract the format and the byte buffer of data
try {
@@ -90,9 +91,10 @@
* Non-public constructor; this is the one we use in ADS and CADS
* constructors.
*/
- AudioData(AudioFormat format, byte[] buffer) {
-
+ AudioData(final AudioFormat format, final byte[] buffer) {
this.format = format;
- this.buffer = buffer;
+ if (buffer != null) {
+ this.buffer = Arrays.copyOf(buffer, buffer.length);
+ }
}
}
--- a/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java Wed Jul 05 19:09:26 2017 +0200
@@ -98,8 +98,7 @@
}
flavors = DataTransferer.getInstance().
- setToSortedDataFlavorArray(flavorsToData.keySet(),
- flavorsForFormats);
+ setToSortedDataFlavorArray(flavorsToData.keySet());
}
} finally {
clipboard.closeClipboard();
--- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Jul 05 19:09:26 2017 +0200
@@ -2406,15 +2406,6 @@
}
/**
- * Helper function to reduce a Map with DataFlavor keys to a DataFlavor
- * array. The array will be sorted according to
- * <code>DataFlavorComparator</code>.
- */
- public static DataFlavor[] keysToDataFlavorArray(Map map) {
- return setToSortedDataFlavorArray(map.keySet(), map);
- }
-
- /**
* Helper function to convert a Set of DataFlavors to a sorted array.
* The array will be sorted according to <code>DataFlavorComparator</code>.
*/
@@ -2428,24 +2419,6 @@
}
/**
- * Helper function to convert a Set of DataFlavors to a sorted array.
- * The array will be sorted according to a
- * <code>DataFlavorComparator</code> created with the specified
- * flavor-to-native map as an argument.
- */
- public static DataFlavor[] setToSortedDataFlavorArray
- (Set flavorsSet, Map flavorToNativeMap)
- {
- DataFlavor[] flavors = new DataFlavor[flavorsSet.size()];
- flavorsSet.toArray(flavors);
- Comparator comparator =
- new DataFlavorComparator(flavorToNativeMap,
- IndexedComparator.SELECT_WORST);
- Arrays.sort(flavors, comparator);
- return flavors;
- }
-
- /**
* Helper function to convert an InputStream to a byte[] array.
*/
protected static byte[] inputStreamToByteArray(InputStream str)
@@ -2724,11 +2697,9 @@
* application/x-java-* MIME types. Unknown application types are preferred
* because if the user provides his own data flavor, it will likely be the
* most descriptive one. For flavors which are otherwise equal, the
- * flavors' native formats are compared, with greater long values
- * taking precedence.
+ * flavors' string representation are compared in the alphabetical order.
*/
public static class DataFlavorComparator extends IndexedComparator {
- protected final Map flavorToFormatMap;
private final CharsetComparator charsetComparator;
@@ -2864,20 +2835,6 @@
super(order);
charsetComparator = new CharsetComparator(order);
- flavorToFormatMap = Collections.EMPTY_MAP;
- }
-
- public DataFlavorComparator(Map map) {
- this(map, SELECT_BEST);
- }
-
- public DataFlavorComparator(Map map, boolean order) {
- super(order);
-
- charsetComparator = new CharsetComparator(order);
- HashMap hashMap = new HashMap(map.size());
- hashMap.putAll(map);
- flavorToFormatMap = Collections.unmodifiableMap(hashMap);
}
public int compare(Object obj1, Object obj2) {
@@ -2973,10 +2930,9 @@
}
}
- // As a last resort, take the DataFlavor with the greater integer
- // format.
- return compareLongs(flavorToFormatMap, flavor1, flavor2,
- UNKNOWN_OBJECT_LOSES_L);
+ // The flavours are not equal but still not distinguishable.
+ // Compare String representations in alphabetical order
+ return flavor1.getMimeType().compareTo(flavor2.getMimeType());
}
}
--- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java Wed Jul 05 19:09:26 2017 +0200
@@ -65,13 +65,10 @@
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
-import sun.misc.Version;
-import sun.misc.URLClassPath;
public enum LauncherHelper {
INSTANCE;
private static final String MAIN_CLASS = "Main-Class";
- private static final String PROFILE = "Profile";
private static StringBuilder outBuf = new StringBuilder();
@@ -415,27 +412,6 @@
}
/*
- * If this is not a full JRE then the Profile attribute must be
- * present with the Main-Class attribute so as to indicate the minimum
- * profile required. Note that we need to suppress checking of the Profile
- * attribute after we detect an error. This is because the abort may
- * need to lookup resources and this may involve opening additional JAR
- * files that would result in errors that suppress the main error.
- */
- String profile = mainAttrs.getValue(PROFILE);
- if (profile == null) {
- if (!Version.isFullJre()) {
- URLClassPath.suppressProfileCheckForLauncher();
- abort(null, "java.launcher.jar.error4", jarname);
- }
- } else {
- if (!Version.supportsProfile(profile)) {
- URLClassPath.suppressProfileCheckForLauncher();
- abort(null, "java.launcher.jar.error5", profile, jarname);
- }
- }
-
- /*
* Hand off to FXHelper if it detects a JavaFX application
* This must be done after ensuring a Main-Class entry
* exists to enforce compliance with the jar specification
--- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties Wed Jul 05 19:09:26 2017 +0200
@@ -139,8 +139,6 @@
Error: An unexpected error occurred while trying to open file {0}
java.launcher.jar.error2=manifest not found in {0}
java.launcher.jar.error3=no main manifest attribute, in {0}
-java.launcher.jar.error4=no Profile manifest attribute in {0}
-java.launcher.jar.error5=Profile {0} required by {1} not supported by this runtime
java.launcher.init.error=initialization error
java.launcher.javafx.error1=\
Error: The JavaFX launchApplication method has the wrong signature, it\n\
--- a/jdk/src/share/classes/sun/misc/JavaUtilJarAccess.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/misc/JavaUtilJarAccess.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,7 +35,6 @@
public interface JavaUtilJarAccess {
public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException;
- public boolean jarFileHasProfileAttribute(JarFile jar) throws IOException;
public CodeSource[] getCodeSources(JarFile jar, URL url);
public CodeSource getCodeSource(JarFile jar, URL url, String name);
public Enumeration<String> entryNames(JarFile jar, CodeSource[] cs);
--- a/jdk/src/share/classes/sun/misc/URLClassPath.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/misc/URLClassPath.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,7 +35,6 @@
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
-import java.util.jar.UnsupportedProfileException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
@@ -66,12 +65,6 @@
private static final boolean DEBUG;
private static final boolean DISABLE_JAR_CHECKING;
- /**
- * Used by launcher to indicate that checking of the JAR file "Profile"
- * attribute has been suppressed.
- */
- private static boolean profileCheckSuppressedByLauncher;
-
static {
JAVA_VERSION = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("java.version"));
@@ -593,15 +586,6 @@
}
}
- /**
- * Used by the launcher to suppress further checking of the JAR file Profile
- * attribute (necessary when the launcher is aborting as the abort involves
- * a resource lookup that may involve opening additional JAR files)
- */
- public static void suppressProfileCheckForLauncher() {
- profileCheckSuppressedByLauncher = true;
- }
-
/*
* Inner class used to represent a Loader of resources from a JAR URL.
*/
@@ -828,25 +812,6 @@
return false;
}
- /**
- * If the Profile attribute is present then this method checks that the runtime
- * supports that profile.
- */
- void checkProfileAttribute() throws IOException {
- Manifest man = jar.getManifest();
- if (man != null) {
- Attributes attr = man.getMainAttributes();
- if (attr != null) {
- String value = attr.getValue(Name.PROFILE);
- if (value != null && !Version.supportsProfile(value)) {
- String prefix = Version.profileName().length() > 0 ?
- "This runtime implements " + Version.profileName() + ", " : "";
- throw new UnsupportedProfileException(prefix + csu + " requires " + value);
- }
- }
- }
- }
-
/*
* Returns the URL for a resource with the specified name
*/
@@ -1017,12 +982,6 @@
ensureOpen();
parseExtensionsDependencies();
- // check Profile attribute if present
- if (!profileCheckSuppressedByLauncher &&
- SharedSecrets.javaUtilJarAccess().jarFileHasProfileAttribute(jar)) {
- checkProfileAttribute();
- }
-
if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary
Manifest man = jar.getManifest();
if (man != null) {
--- a/jdk/src/share/classes/sun/misc/Version.java.template Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/misc/Version.java.template Wed Jul 05 19:09:26 2017 +0200
@@ -339,68 +339,6 @@
// Return false if not available which implies an old VM (Tiger or before).
private static native boolean getJvmVersionInfo();
private static native void getJdkVersionInfo();
-
- // Possible runtime profiles, ordered from small to large
- private final static String[] PROFILES = { "compact1", "compact2", "compact3" };
-
- /**
- * Returns the name of the profile that this runtime implements. The empty
- * string is returned for the full Java Runtime.
- */
- public static String profileName() {
- return java_profile_name;
- }
-
- /**
- * Indicates if this runtime implements the full Java Runtime.
- */
- public static boolean isFullJre() {
- return java_profile_name.length() == 0;
- }
-
- // cached index of this profile's name in PROFILES (1-based)
- private static int thisRuntimeIndex;
-
- /**
- * Indicates if this runtime supports the given profile. Profile names are
- * case sensitive.
- *
- * @return {@code true} if the given profile is supported
- */
- public static boolean supportsProfile(String requiredProfile) {
- int x = thisRuntimeIndex - 1;
- if (x < 0) {
- String profile = profileName();
- if (profile.length() > 0) {
- x = 0;
- while (x < PROFILES.length) {
- if (PROFILES[x].equals(profile))
- break;
- x++;
- }
- if (x >= PROFILES.length)
- throw new InternalError(profile + " not known to sun.misc.Version");
-
- // okay if another thread has already set it
- thisRuntimeIndex = x + 1;
- }
- // else we are a full JRE
- }
-
- int y = 0;
- while (y < PROFILES.length) {
- if (PROFILES[y].equals(requiredProfile))
- break;
- y++;
- }
- if (y >= PROFILES.length) {
- // profile not found so caller has requested something that is not defined
- return false;
- }
-
- return x < 0 || x >= y;
- }
-
}
// Help Emacs a little because this file doesn't end in .java.
--- a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Wed Jul 05 19:09:26 2017 +0200
@@ -1031,6 +1031,24 @@
"ebcdic-s-871+euro"
});
+ charset("IBM290", "IBM290",
+ new String[] {
+ "cp290",
+ "ibm290",
+ "ibm-290",
+ "csIBM290",
+ "EBCDIC-JP-kana",
+ "290"
+ });
+
+ charset("x-IBM300", "IBM300",
+ new String[] {
+ "cp300",
+ "ibm300",
+ "ibm-300",
+ "300"
+ });
+
// Macintosh MacOS/Apple char encodingd
--- a/jdk/src/share/classes/sun/print/PSPrinterJob.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/print/PSPrinterJob.java Wed Jul 05 19:09:26 2017 +0200
@@ -339,6 +339,8 @@
*/
private static Properties mFontProps = null;
+ private static boolean isMac;
+
/* Class static initialiser block */
static {
//enable priviledges so initProps can access system properties,
@@ -347,6 +349,8 @@
new java.security.PrivilegedAction() {
public Object run() {
mFontProps = initProps();
+ String osName = System.getProperty("os.name");
+ isMac = osName.startsWith("Mac");
return null;
}
});
@@ -473,6 +477,12 @@
PrintService pServ = getPrintService();
if (pServ != null) {
mDestination = pServ.getName();
+ if (isMac) {
+ PrintServiceAttributeSet psaSet = pServ.getAttributes() ;
+ if (psaSet != null) {
+ mDestination = psaSet.get(PrinterName.class).toString();
+ }
+ }
}
}
}
@@ -771,6 +781,12 @@
PrintService pServ = getPrintService();
if (pServ != null) {
mDestination = pServ.getName();
+ if (isMac) {
+ PrintServiceAttributeSet psaSet = pServ.getAttributes();
+ if (psaSet != null) {
+ mDestination = psaSet.get(PrinterName.class).toString() ;
+ }
+ }
}
PrinterSpooler spooler = new PrinterSpooler();
java.security.AccessController.doPrivileged(spooler);
--- a/jdk/src/share/classes/sun/security/krb5/Credentials.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java Wed Jul 05 19:09:26 2017 +0200
@@ -62,7 +62,9 @@
private static CredentialsCache cache;
static boolean alreadyLoaded = false;
private static boolean alreadyTried = false;
- private static native Credentials acquireDefaultNativeCreds();
+
+ // Read native ticket with session key type in the given list
+ private static native Credentials acquireDefaultNativeCreds(int[] eTypes);
public Credentials(Ticket new_ticket,
PrincipalName new_client,
@@ -373,6 +375,8 @@
// It assumes that the GSS call has
// the privilege to access the default cache file.
+ // This method is only called on Windows and Mac OS X, the native
+ // acquireDefaultNativeCreds is also available on these platforms.
public static synchronized Credentials acquireDefaultCreds() {
Credentials result = null;
@@ -416,10 +420,15 @@
}
if (alreadyLoaded) {
// There is some native code
- if (DEBUG)
- System.out.println(">> Acquire default native Credentials");
- result = acquireDefaultNativeCreds();
- // only TGT with DES key will be returned by native method
+ if (DEBUG) {
+ System.out.println(">> Acquire default native Credentials");
+ }
+ try {
+ result = acquireDefaultNativeCreds(
+ EType.getDefaults("default_tkt_enctypes"));
+ } catch (KrbException ke) {
+ // when there is no default_tkt_enctypes.
+ }
}
}
return result;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/AuthPolicyFile.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,1195 @@
+/*
+ * Copyright (c) 1999, 2013, 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 sun.security.provider;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.URL;
+import java.util.*;
+
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.PermissionCollection;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.UnresolvedPermission;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.Subject;
+import javax.security.auth.PrivateCredentialPermission;
+
+import sun.security.provider.PolicyParser.GrantEntry;
+import sun.security.provider.PolicyParser.PermissionEntry;
+import sun.security.provider.PolicyParser.PrincipalEntry;
+import sun.security.util.Debug;
+import sun.security.util.PolicyUtil;
+import sun.security.util.PropertyExpander;
+
+/**
+ * See {@code com.sun.security.auth.PolicyFile} for the class description.
+ * This class is necessary in order to support a default
+ * {@code javax.security.auth.Policy} implementation on the compact1 and
+ * compact2 profiles.
+ *
+ * @deprecated As of JDK 1.4, replaced by
+ * {@code sun.security.provider.PolicyFile}.
+ * This class is entirely deprecated.
+ */
+@Deprecated
+public class AuthPolicyFile extends javax.security.auth.Policy {
+
+ static final ResourceBundle rb =
+ AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
+ @Override public ResourceBundle run() {
+ return (ResourceBundle.getBundle
+ ("sun.security.util.AuthResources"));
+ }
+ });
+
+ private static final Debug debug = Debug.getInstance("policy",
+ "\t[Auth Policy]");
+
+ private static final String AUTH_POLICY = "java.security.auth.policy";
+ private static final String SECURITY_MANAGER = "java.security.manager";
+ private static final String AUTH_POLICY_URL = "auth.policy.url.";
+
+ private Vector<PolicyEntry> policyEntries;
+ private Hashtable<Object, Object> aliasMapping;
+
+ private boolean initialized = false;
+
+ private boolean expandProperties = true;
+ private boolean ignoreIdentityScope = true;
+
+ // for use with the reflection API
+ private static final Class[] PARAMS = { String.class, String.class};
+
+ /**
+ * Initializes the Policy object and reads the default policy
+ * configuration file(s) into the Policy object.
+ */
+ public AuthPolicyFile() {
+ // initialize Policy if either the AUTH_POLICY or
+ // SECURITY_MANAGER properties are set
+ String prop = System.getProperty(AUTH_POLICY);
+
+ if (prop == null) {
+ prop = System.getProperty(SECURITY_MANAGER);
+ }
+ if (prop != null) {
+ init();
+ }
+ }
+
+ private synchronized void init() {
+ if (initialized) {
+ return;
+ }
+
+ policyEntries = new Vector<PolicyEntry>();
+ aliasMapping = new Hashtable<Object, Object>(11);
+
+ initPolicyFile();
+ initialized = true;
+ }
+
+ @Override
+ public synchronized void refresh() {
+
+ java.lang.SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new javax.security.auth.AuthPermission
+ ("refreshPolicy"));
+ }
+
+ // XXX
+ //
+ // 1) if code instantiates PolicyFile directly, then it will need
+ // all the permissions required for the PolicyFile initialization
+ // 2) if code calls Policy.getPolicy, then it simply needs
+ // AuthPermission(getPolicy), and the javax.security.auth.Policy
+ // implementation instantiates PolicyFile in a doPrivileged block
+ // 3) if after instantiating a Policy (either via #1 or #2),
+ // code calls refresh, it simply needs
+ // AuthPermission(refreshPolicy). then PolicyFile wraps
+ // the refresh in a doPrivileged block.
+ initialized = false;
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override public Void run() {
+ init();
+ return null;
+ }
+ });
+ }
+
+ private KeyStore initKeyStore(URL policyUrl, String keyStoreName,
+ String keyStoreType) {
+ if (keyStoreName != null) {
+ try {
+ /*
+ * location of keystore is specified as absolute URL in policy
+ * file, or is relative to URL of policy file
+ */
+ URL keyStoreUrl = null;
+ try {
+ keyStoreUrl = new URL(keyStoreName);
+ // absolute URL
+ } catch (java.net.MalformedURLException e) {
+ // relative URL
+ keyStoreUrl = new URL(policyUrl, keyStoreName);
+ }
+
+ if (debug != null) {
+ debug.println("reading keystore"+keyStoreUrl);
+ }
+
+ InputStream inStream = new BufferedInputStream(
+ PolicyUtil.getInputStream(keyStoreUrl));
+
+ KeyStore ks;
+ if (keyStoreType != null)
+ ks = KeyStore.getInstance(keyStoreType);
+ else
+ ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ ks.load(inStream, null);
+ inStream.close();
+ return ks;
+ } catch (Exception e) {
+ // ignore, treat it like we have no keystore
+ if (debug != null) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+ return null;
+ }
+
+ private void initPolicyFile() {
+
+ String prop = Security.getProperty("policy.expandProperties");
+ if (prop != null) {
+ expandProperties = prop.equalsIgnoreCase("true");
+ }
+
+ String iscp = Security.getProperty("policy.ignoreIdentityScope");
+ if (iscp != null) {
+ ignoreIdentityScope = iscp.equalsIgnoreCase("true");
+ }
+
+ String allowSys = Security.getProperty("policy.allowSystemProperty");
+ if (allowSys != null && allowSys.equalsIgnoreCase("true")) {
+ String extra_policy = System.getProperty(AUTH_POLICY);
+ if (extra_policy != null) {
+ boolean overrideAll = false;
+ if (extra_policy.startsWith("=")) {
+ overrideAll = true;
+ extra_policy = extra_policy.substring(1);
+ }
+ try {
+ extra_policy = PropertyExpander.expand(extra_policy);
+ URL policyURL;
+ File policyFile = new File(extra_policy);
+ if (policyFile.exists()) {
+ policyURL =
+ new URL("file:" + policyFile.getCanonicalPath());
+ } else {
+ policyURL = new URL(extra_policy);
+ }
+ if (debug != null) {
+ debug.println("reading " + policyURL);
+ }
+ init(policyURL);
+ } catch (Exception e) {
+ // ignore.
+ if (debug != null) {
+ debug.println("caught exception: " + e);
+ }
+
+ }
+ if (overrideAll) {
+ if (debug != null) {
+ debug.println("overriding other policies!");
+ }
+ return;
+ }
+ }
+ }
+
+ int n = 1;
+ boolean loaded_one = false;
+ String policy_url;
+
+ while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) {
+ try {
+ policy_url = PropertyExpander.expand(policy_url).replace
+ (File.separatorChar, '/');
+ if (debug != null) {
+ debug.println("reading " + policy_url);
+ }
+ init(new URL(policy_url));
+ loaded_one = true;
+ } catch (Exception e) {
+ if (debug != null) {
+ debug.println("error reading policy " + e);
+ e.printStackTrace();
+ }
+ // ignore that policy
+ }
+ n++;
+ }
+
+ if (loaded_one == false) {
+ // do not load a static policy
+ }
+ }
+
+ /**
+ * Checks public key. If it is marked as trusted in
+ * the identity database, add it to the policy
+ * with the AllPermission.
+ */
+ private boolean checkForTrustedIdentity(final Certificate cert) {
+ return false;
+ }
+
+ /**
+ * Reads a policy configuration into the Policy object using a
+ * Reader object.
+ *
+ * @param policyFile the policy Reader object.
+ */
+ private void init(URL policy) {
+ PolicyParser pp = new PolicyParser(expandProperties);
+ try (InputStreamReader isr
+ = new InputStreamReader(PolicyUtil.getInputStream(policy))) {
+ pp.read(isr);
+ KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
+ pp.getKeyStoreType());
+ Enumeration<GrantEntry> enum_ = pp.grantElements();
+ while (enum_.hasMoreElements()) {
+ GrantEntry ge = enum_.nextElement();
+ addGrantEntry(ge, keyStore);
+ }
+ } catch (PolicyParser.ParsingException pe) {
+ System.err.println(AUTH_POLICY +
+ rb.getString(".error.parsing.") + policy);
+ System.err.println(AUTH_POLICY + rb.getString("COLON") +
+ pe.getMessage());
+ if (debug != null) {
+ pe.printStackTrace();
+ }
+ } catch (Exception e) {
+ if (debug != null) {
+ debug.println("error parsing " + policy);
+ debug.println(e.toString());
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Given a PermissionEntry, create a codeSource.
+ *
+ * @return null if signedBy alias is not recognized
+ */
+ CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore)
+ throws java.net.MalformedURLException
+ {
+ Certificate[] certs = null;
+ if (ge.signedBy != null) {
+ certs = getCertificates(keyStore, ge.signedBy);
+ if (certs == null) {
+ // we don't have a key for this alias,
+ // just return
+ if (debug != null) {
+ debug.println(" no certs for alias " +
+ ge.signedBy + ", ignoring.");
+ }
+ return null;
+ }
+ }
+
+ URL location;
+ if (ge.codeBase != null) {
+ location = new URL(ge.codeBase);
+ } else {
+ location = null;
+ }
+
+ if (ge.principals == null || ge.principals.size() == 0) {
+ return (canonicalizeCodebase
+ (new CodeSource(location, certs),
+ false));
+ } else {
+ return (canonicalizeCodebase
+ (new SubjectCodeSource(null, ge.principals, location, certs),
+ false));
+ }
+ }
+
+ /**
+ * Add one policy entry to the vector.
+ */
+ private void addGrantEntry(GrantEntry ge, KeyStore keyStore) {
+
+ if (debug != null) {
+ debug.println("Adding policy entry: ");
+ debug.println(" signedBy " + ge.signedBy);
+ debug.println(" codeBase " + ge.codeBase);
+ if (ge.principals != null) {
+ for (PrincipalEntry pppe : ge.principals) {
+ debug.println(" " + pppe.getPrincipalClass() +
+ " " + pppe.getPrincipalName());
+ }
+ }
+ debug.println();
+ }
+
+ try {
+ CodeSource codesource = getCodeSource(ge, keyStore);
+ // skip if signedBy alias was unknown...
+ if (codesource == null) return;
+
+ PolicyEntry entry = new PolicyEntry(codesource);
+ Enumeration<PermissionEntry> enum_ = ge.permissionElements();
+ while (enum_.hasMoreElements()) {
+ PermissionEntry pe = enum_.nextElement();
+ try {
+ // XXX special case PrivateCredentialPermission-SELF
+ Permission perm;
+ if (pe.permission.equals
+ ("javax.security.auth.PrivateCredentialPermission") &&
+ pe.name.endsWith(" self")) {
+ perm = getInstance(pe.permission,
+ pe.name + " \"self\"",
+ pe.action);
+ } else {
+ perm = getInstance(pe.permission,
+ pe.name,
+ pe.action);
+ }
+ entry.add(perm);
+ if (debug != null) {
+ debug.println(" "+perm);
+ }
+ } catch (ClassNotFoundException cnfe) {
+ Certificate certs[];
+ if (pe.signedBy != null) {
+ certs = getCertificates(keyStore, pe.signedBy);
+ } else {
+ certs = null;
+ }
+
+ // only add if we had no signer or we had a
+ // a signer and found the keys for it.
+ if (certs != null || pe.signedBy == null) {
+ Permission perm = new UnresolvedPermission(
+ pe.permission,
+ pe.name,
+ pe.action,
+ certs);
+ entry.add(perm);
+ if (debug != null) {
+ debug.println(" "+perm);
+ }
+ }
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ System.err.println
+ (AUTH_POLICY +
+ rb.getString(".error.adding.Permission.") +
+ pe.permission +
+ rb.getString("SPACE") +
+ ite.getTargetException());
+ } catch (Exception e) {
+ System.err.println
+ (AUTH_POLICY +
+ rb.getString(".error.adding.Permission.") +
+ pe.permission +
+ rb.getString("SPACE") +
+ e);
+ }
+ }
+ policyEntries.addElement(entry);
+ } catch (Exception e) {
+ System.err.println
+ (AUTH_POLICY +
+ rb.getString(".error.adding.Entry.") +
+ ge +
+ rb.getString("SPACE") +
+ e);
+ }
+
+ if (debug != null) {
+ debug.println();
+ }
+ }
+
+ /**
+ * Returns a new Permission object of the given Type. The Permission is
+ * created by getting the
+ * Class object using the <code>Class.forName</code> method, and using
+ * the reflection API to invoke the (String name, String actions)
+ * constructor on the
+ * object.
+ *
+ * @param type the type of Permission being created.
+ * @param name the name of the Permission being created.
+ * @param actions the actions of the Permission being created.
+ *
+ * @exception ClassNotFoundException if the particular Permission
+ * class could not be found.
+ *
+ * @exception IllegalAccessException if the class or initializer is
+ * not accessible.
+ *
+ * @exception InstantiationException if getInstance tries to
+ * instantiate an abstract class or an interface, or if the
+ * instantiation fails for some other reason.
+ *
+ * @exception NoSuchMethodException if the (String, String) constructor
+ * is not found.
+ *
+ * @exception InvocationTargetException if the underlying Permission
+ * constructor throws an exception.
+ *
+ */
+ private static final Permission getInstance(String type,
+ String name,
+ String actions)
+ throws ClassNotFoundException,
+ InstantiationException,
+ IllegalAccessException,
+ NoSuchMethodException,
+ InvocationTargetException
+ {
+ //XXX we might want to keep a hash of created factories...
+ Class<?> pc = Class.forName(type);
+ Constructor<?> c = pc.getConstructor(PARAMS);
+ return (Permission) c.newInstance(new Object[] { name, actions });
+ }
+
+ /**
+ * Fetch all certs associated with this alias.
+ */
+ Certificate[] getCertificates(KeyStore keyStore, String aliases) {
+
+ Vector<Certificate> vcerts = null;
+
+ StringTokenizer st = new StringTokenizer(aliases, ",");
+ int n = 0;
+
+ while (st.hasMoreTokens()) {
+ String alias = st.nextToken().trim();
+ n++;
+ Certificate cert = null;
+ // See if this alias's cert has already been cached
+ cert = (Certificate) aliasMapping.get(alias);
+ if (cert == null && keyStore != null) {
+
+ try {
+ cert = keyStore.getCertificate(alias);
+ } catch (KeyStoreException kse) {
+ // never happens, because keystore has already been loaded
+ // when we call this
+ }
+ if (cert != null) {
+ aliasMapping.put(alias, cert);
+ aliasMapping.put(cert, alias);
+ }
+ }
+
+ if (cert != null) {
+ if (vcerts == null) {
+ vcerts = new Vector<Certificate>();
+ }
+ vcerts.addElement(cert);
+ }
+ }
+
+ // make sure n == vcerts.size, since we are doing a logical *and*
+ if (vcerts != null && n == vcerts.size()) {
+ Certificate[] certs = new Certificate[vcerts.size()];
+ vcerts.copyInto(certs);
+ return certs;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Enumerate all the entries in the global policy object.
+ * This method is used by policy admin tools. The tools
+ * should use the Enumeration methods on the returned object
+ * to fetch the elements sequentially.
+ */
+ private final synchronized Enumeration<PolicyEntry> elements() {
+ return policyEntries.elements();
+ }
+
+ @Override
+ public PermissionCollection getPermissions(final Subject subject,
+ final CodeSource codesource) {
+
+ // 1) if code instantiates PolicyFile directly, then it will need
+ // all the permissions required for the PolicyFile initialization
+ // 2) if code calls Policy.getPolicy, then it simply needs
+ // AuthPermission(getPolicy), and the javax.security.auth.Policy
+ // implementation instantiates PolicyFile in a doPrivileged block
+ // 3) if after instantiating a Policy (either via #1 or #2),
+ // code calls getPermissions, PolicyFile wraps the call
+ // in a doPrivileged block.
+ return AccessController.doPrivileged
+ (new PrivilegedAction<PermissionCollection>() {
+ @Override public PermissionCollection run() {
+ SubjectCodeSource scs = new SubjectCodeSource(
+ subject, null,
+ codesource == null ? null : codesource.getLocation(),
+ codesource == null ? null : codesource.getCertificates());
+ if (initialized) {
+ return getPermissions(new Permissions(), scs);
+ } else {
+ return new PolicyPermissions(AuthPolicyFile.this, scs);
+ }
+ }
+ });
+ }
+
+ /**
+ * Examines the global policy for the specified CodeSource, and
+ * creates a PermissionCollection object with
+ * the set of permissions for that principal's protection domain.
+ *
+ * @param CodeSource the codesource associated with the caller.
+ * This encapsulates the original location of the code (where the code
+ * came from) and the public key(s) of its signer.
+ *
+ * @return the set of permissions according to the policy.
+ */
+ PermissionCollection getPermissions(CodeSource codesource) {
+
+ if (initialized) {
+ return getPermissions(new Permissions(), codesource);
+ } else {
+ return new PolicyPermissions(this, codesource);
+ }
+ }
+
+ /**
+ * Examines the global policy for the specified CodeSource, and
+ * creates a PermissionCollection object with
+ * the set of permissions for that principal's protection domain.
+ *
+ * @param permissions the permissions to populate
+ * @param codesource the codesource associated with the caller.
+ * This encapsulates the original location of the code (where the code
+ * came from) and the public key(s) of its signer.
+ *
+ * @return the set of permissions according to the policy.
+ */
+ Permissions getPermissions(final Permissions perms,
+ final CodeSource cs)
+ {
+ if (!initialized) {
+ init();
+ }
+
+ final CodeSource codesource[] = {null};
+
+ codesource[0] = canonicalizeCodebase(cs, true);
+
+ if (debug != null) {
+ debug.println("evaluate(" + codesource[0] + ")\n");
+ }
+
+ // needs to be in a begin/endPrivileged block because
+ // codesource.implies calls URL.equals which does an
+ // InetAddress lookup
+
+ for (int i = 0; i < policyEntries.size(); i++) {
+
+ PolicyEntry entry = policyEntries.elementAt(i);
+
+ if (debug != null) {
+ debug.println("PolicyFile CodeSource implies: " +
+ entry.codesource.toString() + "\n\n" +
+ "\t" + codesource[0].toString() + "\n\n");
+ }
+
+ if (entry.codesource.implies(codesource[0])) {
+ for (int j = 0; j < entry.permissions.size(); j++) {
+ Permission p = entry.permissions.elementAt(j);
+ if (debug != null) {
+ debug.println(" granting " + p);
+ }
+ if (!addSelfPermissions(p, entry.codesource,
+ codesource[0], perms)) {
+ // we could check for duplicates
+ // before adding new permissions,
+ // but the SubjectDomainCombiner
+ // already checks for duplicates later
+ perms.add(p);
+ }
+ }
+ }
+ }
+
+ // now see if any of the keys are trusted ids.
+
+ if (!ignoreIdentityScope) {
+ Certificate certs[] = codesource[0].getCertificates();
+ if (certs != null) {
+ for (int k=0; k < certs.length; k++) {
+ if (aliasMapping.get(certs[k]) == null &&
+ checkForTrustedIdentity(certs[k])) {
+ // checkForTrustedIdentity added it
+ // to the policy for us. next time
+ // around we'll find it. This time
+ // around we need to add it.
+ perms.add(new java.security.AllPermission());
+ }
+ }
+ }
+ }
+ return perms;
+ }
+
+ /**
+ * Returns true if 'Self' permissions were added to the provided
+ * 'perms', and false otherwise.
+ *
+ * <p>
+ *
+ * @param p check to see if this Permission is a "SELF"
+ * PrivateCredentialPermission. <p>
+ *
+ * @param entryCs the codesource for the Policy entry.
+ *
+ * @param accCs the codesource for from the current AccessControlContext.
+ *
+ * @param perms the PermissionCollection where the individual
+ * PrivateCredentialPermissions will be added.
+ */
+ private boolean addSelfPermissions(final Permission p,
+ CodeSource entryCs,
+ CodeSource accCs,
+ Permissions perms) {
+
+ if (!(p instanceof PrivateCredentialPermission)) {
+ return false;
+ }
+
+ if (!(entryCs instanceof SubjectCodeSource)) {
+ return false;
+ }
+
+ PrivateCredentialPermission pcp = (PrivateCredentialPermission)p;
+ SubjectCodeSource scs = (SubjectCodeSource)entryCs;
+
+ // see if it is a SELF permission
+ String[][] pPrincipals = pcp.getPrincipals();
+ if (pPrincipals.length <= 0 ||
+ !pPrincipals[0][0].equalsIgnoreCase("self") ||
+ !pPrincipals[0][1].equalsIgnoreCase("self")) {
+
+ // regular PrivateCredentialPermission
+ return false;
+ } else {
+
+ // granted a SELF permission - create a
+ // PrivateCredentialPermission for each
+ // of the Policy entry's CodeSource Principals
+
+ if (scs.getPrincipals() == null) {
+ // XXX SubjectCodeSource has no Subject???
+ return true;
+ }
+
+ for (PrincipalEntry principal : scs.getPrincipals()) {
+
+ // if the Policy entry's Principal does not contain a
+ // WILDCARD for the Principal name, then a
+ // new PrivateCredentialPermission is created
+ // for the Principal listed in the Policy entry.
+ // if the Policy entry's Principal contains a WILDCARD
+ // for the Principal name, then a new
+ // PrivateCredentialPermission is created
+ // for each Principal associated with the Subject
+ // in the current ACC.
+
+ String[][] principalInfo = getPrincipalInfo(principal, accCs);
+
+ for (int i = 0; i < principalInfo.length; i++) {
+
+ // here's the new PrivateCredentialPermission
+
+ PrivateCredentialPermission newPcp =
+ new PrivateCredentialPermission
+ (pcp.getCredentialClass() +
+ " " +
+ principalInfo[i][0] +
+ " " +
+ "\"" + principalInfo[i][1] + "\"",
+ "read");
+
+ if (debug != null) {
+ debug.println("adding SELF permission: " +
+ newPcp.toString());
+ }
+
+ perms.add(newPcp);
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * return the principal class/name pair in the 2D array.
+ * array[x][y]: x corresponds to the array length.
+ * if (y == 0), it's the principal class.
+ * if (y == 1), it's the principal name.
+ */
+ private String[][] getPrincipalInfo(PrincipalEntry principal,
+ final CodeSource accCs) {
+
+ // there are 3 possibilities:
+ // 1) the entry's Principal class and name are not wildcarded
+ // 2) the entry's Principal name is wildcarded only
+ // 3) the entry's Principal class and name are wildcarded
+
+ if (!principal.getPrincipalClass().equals
+ (PrincipalEntry.WILDCARD_CLASS) &&
+ !principal.getPrincipalName().equals
+ (PrincipalEntry.WILDCARD_NAME)) {
+
+ // build a PrivateCredentialPermission for the principal
+ // from the Policy entry
+ String[][] info = new String[1][2];
+ info[0][0] = principal.getPrincipalClass();
+ info[0][1] = principal.getPrincipalName();
+ return info;
+
+ } else if (!principal.getPrincipalClass().equals
+ (PrincipalEntry.WILDCARD_CLASS) &&
+ principal.getPrincipalName().equals
+ (PrincipalEntry.WILDCARD_NAME)) {
+
+ // build a PrivateCredentialPermission for all
+ // the Subject's principals that are instances of principalClass
+
+ // the accCs is guaranteed to be a SubjectCodeSource
+ // because the earlier CodeSource.implies succeeded
+ SubjectCodeSource scs = (SubjectCodeSource)accCs;
+
+ Set<? extends Principal> principalSet = null;
+ try {
+ // principal.principalClass should extend Principal
+ // If it doesn't, we should stop here with a ClassCastException.
+ @SuppressWarnings("unchecked")
+ Class<? extends Principal> pClass = (Class<? extends Principal>)
+ Class.forName(principal.getPrincipalClass(), false,
+ ClassLoader.getSystemClassLoader());
+ principalSet = scs.getSubject().getPrincipals(pClass);
+ } catch (Exception e) {
+ if (debug != null) {
+ debug.println("problem finding Principal Class " +
+ "when expanding SELF permission: " +
+ e.toString());
+ }
+ }
+
+ if (principalSet == null) {
+ // error
+ return new String[0][0];
+ }
+
+ String[][] info = new String[principalSet.size()][2];
+
+ int i = 0;
+ for (Principal p : principalSet) {
+ info[i][0] = p.getClass().getName();
+ info[i][1] = p.getName();
+ i++;
+ }
+ return info;
+
+ } else {
+
+ // build a PrivateCredentialPermission for every
+ // one of the current Subject's principals
+
+ // the accCs is guaranteed to be a SubjectCodeSource
+ // because the earlier CodeSource.implies succeeded
+ SubjectCodeSource scs = (SubjectCodeSource)accCs;
+ Set<Principal> principalSet = scs.getSubject().getPrincipals();
+
+ String[][] info = new String[principalSet.size()][2];
+
+ int i = 0;
+ for (Principal p : principalSet) {
+ info[i][0] = p.getClass().getName();
+ info[i][1] = p.getName();
+ i++;
+ }
+ return info;
+ }
+ }
+
+ /*
+ * Returns the signer certificates from the list of certificates associated
+ * with the given code source.
+ *
+ * The signer certificates are those certificates that were used to verify
+ * signed code originating from the codesource location.
+ *
+ * This method assumes that in the given code source, each signer
+ * certificate is followed by its supporting certificate chain
+ * (which may be empty), and that the signer certificate and its
+ * supporting certificate chain are ordered bottom-to-top (i.e., with the
+ * signer certificate first and the (root) certificate authority last).
+ */
+ Certificate[] getSignerCertificates(CodeSource cs) {
+ Certificate[] certs = null;
+ if ((certs = cs.getCertificates()) == null) {
+ return null;
+ }
+ for (int i = 0; i < certs.length; i++) {
+ if (!(certs[i] instanceof X509Certificate))
+ return cs.getCertificates();
+ }
+
+ // Do we have to do anything?
+ int i = 0;
+ int count = 0;
+ while (i < certs.length) {
+ count++;
+ while (((i+1) < certs.length)
+ && ((X509Certificate)certs[i]).getIssuerDN().equals(
+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
+ i++;
+ }
+ i++;
+ }
+ if (count == certs.length) {
+ // Done
+ return certs;
+ }
+
+ ArrayList<Certificate> userCertList = new ArrayList<>();
+ i = 0;
+ while (i < certs.length) {
+ userCertList.add(certs[i]);
+ while (((i+1) < certs.length)
+ && ((X509Certificate)certs[i]).getIssuerDN().equals(
+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
+ i++;
+ }
+ i++;
+ }
+ Certificate[] userCerts = new Certificate[userCertList.size()];
+ userCertList.toArray(userCerts);
+ return userCerts;
+ }
+
+ private CodeSource canonicalizeCodebase(CodeSource cs,
+ boolean extractSignerCerts) {
+ CodeSource canonCs = cs;
+ if (cs.getLocation() != null &&
+ cs.getLocation().getProtocol().equalsIgnoreCase("file")) {
+ try {
+ String path = cs.getLocation().getFile().replace
+ ('/',
+ File.separatorChar);
+ URL csUrl = null;
+ if (path.endsWith("*")) {
+ // remove trailing '*' because it causes canonicalization
+ // to fail on win32
+ path = path.substring(0, path.length()-1);
+ boolean appendFileSep = false;
+ if (path.endsWith(File.separator)) {
+ appendFileSep = true;
+ }
+ if (path.equals("")) {
+ path = System.getProperty("user.dir");
+ }
+ File f = new File(path);
+ path = f.getCanonicalPath();
+ StringBuffer sb = new StringBuffer(path);
+ // reappend '*' to canonicalized filename (note that
+ // canonicalization may have removed trailing file
+ // separator, so we have to check for that, too)
+ if (!path.endsWith(File.separator) &&
+ (appendFileSep || f.isDirectory())) {
+ sb.append(File.separatorChar);
+ }
+ sb.append('*');
+ path = sb.toString();
+ } else {
+ path = new File(path).getCanonicalPath();
+ }
+ csUrl = new File(path).toURL();
+
+ if (cs instanceof SubjectCodeSource) {
+ SubjectCodeSource scs = (SubjectCodeSource)cs;
+ if (extractSignerCerts) {
+ canonCs = new SubjectCodeSource(scs.getSubject(),
+ scs.getPrincipals(),
+ csUrl,
+ getSignerCertificates(scs));
+ } else {
+ canonCs = new SubjectCodeSource(scs.getSubject(),
+ scs.getPrincipals(),
+ csUrl,
+ scs.getCertificates());
+ }
+ } else {
+ if (extractSignerCerts) {
+ canonCs = new CodeSource(csUrl,
+ getSignerCertificates(cs));
+ } else {
+ canonCs = new CodeSource(csUrl,
+ cs.getCertificates());
+ }
+ }
+ } catch (IOException ioe) {
+ // leave codesource as it is, unless we have to extract its
+ // signer certificates
+ if (extractSignerCerts) {
+ if (!(cs instanceof SubjectCodeSource)) {
+ canonCs = new CodeSource(cs.getLocation(),
+ getSignerCertificates(cs));
+ } else {
+ SubjectCodeSource scs = (SubjectCodeSource)cs;
+ canonCs = new SubjectCodeSource(scs.getSubject(),
+ scs.getPrincipals(),
+ scs.getLocation(),
+ getSignerCertificates(scs));
+ }
+ }
+ }
+ } else {
+ if (extractSignerCerts) {
+ if (!(cs instanceof SubjectCodeSource)) {
+ canonCs = new CodeSource(cs.getLocation(),
+ getSignerCertificates(cs));
+ } else {
+ SubjectCodeSource scs = (SubjectCodeSource)cs;
+ canonCs = new SubjectCodeSource(scs.getSubject(),
+ scs.getPrincipals(),
+ scs.getLocation(),
+ getSignerCertificates(scs));
+ }
+ }
+ }
+ return canonCs;
+ }
+
+ /**
+ * Each entry in the policy configuration file is represented by a
+ * PolicyEntry object. <p>
+ *
+ * A PolicyEntry is a (CodeSource,Permission) pair. The
+ * CodeSource contains the (URL, PublicKey) that together identify
+ * where the Java bytecodes come from and who (if anyone) signed
+ * them. The URL could refer to localhost. The URL could also be
+ * null, meaning that this policy entry is given to all comers, as
+ * long as they match the signer field. The signer could be null,
+ * meaning the code is not signed. <p>
+ *
+ * The Permission contains the (Type, Name, Action) triplet. <p>
+ *
+ * For now, the Policy object retrieves the public key from the
+ * X.509 certificate on disk that corresponds to the signedBy
+ * alias specified in the Policy config file. For reasons of
+ * efficiency, the Policy object keeps a hashtable of certs already
+ * read in. This could be replaced by a secure internal key
+ * store.
+ *
+ * <p>
+ * For example, the entry
+ * <pre>
+ * permission java.io.File "/tmp", "read,write",
+ * signedBy "Duke";
+ * </pre>
+ * is represented internally
+ * <pre>
+ *
+ * FilePermission f = new FilePermission("/tmp", "read,write");
+ * PublicKey p = publickeys.get("Duke");
+ * URL u = InetAddress.getLocalHost();
+ * CodeBase c = new CodeBase( p, u );
+ * pe = new PolicyEntry(f, c);
+ * </pre>
+ *
+ * @author Marianne Mueller
+ * @author Roland Schemers
+ * @see java.security.CodeSource
+ * @see java.security.Policy
+ * @see java.security.Permissions
+ * @see java.security.ProtectionDomain
+ */
+ private static class PolicyEntry {
+
+ CodeSource codesource;
+ Vector<Permission> permissions;
+
+ /**
+ * Given a Permission and a CodeSource, create a policy entry.
+ *
+ * XXX Decide if/how to add validity fields and "purpose" fields to
+ * XXX policy entries
+ *
+ * @param cs the CodeSource, which encapsulates the URL and the public
+ * key attributes from the policy config file. Validity checks
+ * are performed on the public key before PolicyEntry is called.
+ *
+ */
+ PolicyEntry(CodeSource cs) {
+ this.codesource = cs;
+ this.permissions = new Vector<Permission>();
+ }
+
+ /**
+ * add a Permission object to this entry.
+ */
+ void add(Permission p) {
+ permissions.addElement(p);
+ }
+
+ /**
+ * Return the CodeSource for this policy entry
+ */
+ CodeSource getCodeSource() {
+ return this.codesource;
+ }
+
+ @Override
+ public String toString(){
+ StringBuffer sb = new StringBuffer();
+ sb.append(rb.getString("LPARAM"));
+ sb.append(getCodeSource());
+ sb.append("\n");
+ for (int j = 0; j < permissions.size(); j++) {
+ Permission p = permissions.elementAt(j);
+ sb.append(rb.getString("SPACE"));
+ sb.append(rb.getString("SPACE"));
+ sb.append(p);
+ sb.append(rb.getString("NEWLINE"));
+ }
+ sb.append(rb.getString("RPARAM"));
+ sb.append(rb.getString("NEWLINE"));
+ return sb.toString();
+ }
+
+ }
+}
+
+@SuppressWarnings("deprecation")
+class PolicyPermissions extends PermissionCollection {
+
+ private static final long serialVersionUID = -1954188373270545523L;
+
+ private CodeSource codesource;
+ private Permissions perms;
+ private AuthPolicyFile policy;
+ private boolean notInit; // have we pulled in the policy permissions yet?
+ private Vector<Permission> additionalPerms;
+
+ PolicyPermissions(AuthPolicyFile policy,
+ CodeSource codesource)
+ {
+ this.codesource = codesource;
+ this.policy = policy;
+ this.perms = null;
+ this.notInit = true;
+ this.additionalPerms = null;
+ }
+
+ @Override
+ public void add(Permission permission) {
+ if (isReadOnly())
+ throw new SecurityException
+ (AuthPolicyFile.rb.getString
+ ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection"));
+
+ if (perms == null) {
+ if (additionalPerms == null) {
+ additionalPerms = new Vector<Permission>();
+ }
+ additionalPerms.add(permission);
+ } else {
+ perms.add(permission);
+ }
+ }
+
+ private synchronized void init() {
+ if (notInit) {
+ if (perms == null) {
+ perms = new Permissions();
+ }
+ if (additionalPerms != null) {
+ Enumeration<Permission> e = additionalPerms.elements();
+ while (e.hasMoreElements()) {
+ perms.add(e.nextElement());
+ }
+ additionalPerms = null;
+ }
+ policy.getPermissions(perms, codesource);
+ notInit = false;
+ }
+ }
+
+ @Override
+ public boolean implies(Permission permission) {
+ if (notInit) {
+ init();
+ }
+ return perms.implies(permission);
+ }
+
+ @Override
+ public Enumeration<Permission> elements() {
+ if (notInit) {
+ init();
+ }
+ return perms.elements();
+ }
+
+ @Override
+ public String toString() {
+ if (notInit) {
+ init();
+ }
+ return perms.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/ConfigFile.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2000, 2013, 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 sun.security.provider;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.Security;
+import java.security.URIParameter;
+import java.text.MessageFormat;
+import java.util.*;
+import javax.security.auth.AuthPermission;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.ConfigurationSpi;
+import sun.security.util.Debug;
+import sun.security.util.PropertyExpander;
+import sun.security.util.ResourcesMgr;
+
+/**
+ * This class represents a default implementation for
+ * {@code javax.security.auth.login.Configuration}.
+ *
+ * <p> This object stores the runtime login configuration representation,
+ * and is the amalgamation of multiple static login configurations that
+ * resides in files. The algorithm for locating the login configuration
+ * file(s) and reading their information into this {@code Configuration}
+ * object is:
+ *
+ * <ol>
+ * <li>
+ * Loop through the security properties,
+ * <i>login.config.url.1</i>, <i>login.config.url.2</i>, ...,
+ * <i>login.config.url.X</i>.
+ * Each property value specifies a {@code URL} pointing to a
+ * login configuration file to be loaded. Read in and load
+ * each configuration.
+ *
+ * <li>
+ * The {@code java.lang.System} property
+ * <i>java.security.auth.login.config</i>
+ * may also be set to a {@code URL} pointing to another
+ * login configuration file
+ * (which is the case when a user uses the -D switch at runtime).
+ * If this property is defined, and its use is allowed by the
+ * security property file (the Security property,
+ * <i>policy.allowSystemProperty</i> is set to <i>true</i>),
+ * also load that login configuration.
+ *
+ * <li>
+ * If the <i>java.security.auth.login.config</i> property is defined using
+ * "==" (rather than "="), then ignore all other specified
+ * login configurations and only load this configuration.
+ *
+ * <li>
+ * If no system or security properties were set, try to read from the file,
+ * ${user.home}/.java.login.config, where ${user.home} is the value
+ * represented by the "user.home" System property.
+ * </ol>
+ *
+ * <p> The configuration syntax supported by this implementation
+ * is exactly that syntax specified in the
+ * {@code javax.security.auth.login.Configuration} class.
+ *
+ * @see javax.security.auth.login.LoginContext
+ * @see java.security.Security security properties
+ */
+public final class ConfigFile extends Configuration {
+
+ private final Spi spi;
+
+ public ConfigFile() {
+ spi = new Spi();
+ }
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(String appName) {
+ return spi.engineGetAppConfigurationEntry(appName);
+ }
+
+ @Override
+ public synchronized void refresh() {
+ spi.engineRefresh();
+ }
+
+ public final static class Spi extends ConfigurationSpi {
+
+ private URL url;
+ private boolean expandProp = true;
+ private Map<String, List<AppConfigurationEntry>> configuration;
+ private int linenum;
+ private StreamTokenizer st;
+ private int lookahead;
+
+ private static Debug debugConfig = Debug.getInstance("configfile");
+ private static Debug debugParser = Debug.getInstance("configparser");
+
+ /**
+ * Creates a new {@code ConfigurationSpi} object.
+ *
+ * @throws SecurityException if the {@code ConfigurationSpi} can not be
+ * initialized
+ */
+ public Spi() {
+ try {
+ init();
+ } catch (IOException ioe) {
+ throw new SecurityException(ioe);
+ }
+ }
+
+ /**
+ * Creates a new {@code ConfigurationSpi} object from the specified
+ * {@code URI}.
+ *
+ * @param uri the {@code URI}
+ * @throws SecurityException if the {@code ConfigurationSpi} can not be
+ * initialized
+ * @throws NullPointerException if {@code uri} is null
+ */
+ public Spi(URI uri) {
+ // only load config from the specified URI
+ try {
+ url = uri.toURL();
+ init();
+ } catch (IOException ioe) {
+ throw new SecurityException(ioe);
+ }
+ }
+
+ public Spi(final Configuration.Parameters params) throws IOException {
+
+ // call in a doPrivileged
+ //
+ // we have already passed the Configuration.getInstance
+ // security check. also this class is not freely accessible
+ // (it is in the "sun" package).
+
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws IOException {
+ if (params == null) {
+ init();
+ } else {
+ if (!(params instanceof URIParameter)) {
+ throw new IllegalArgumentException
+ ("Unrecognized parameter: " + params);
+ }
+ URIParameter uriParam = (URIParameter)params;
+ url = uriParam.getURI().toURL();
+ init();
+ }
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException pae) {
+ throw (IOException)pae.getException();
+ }
+
+ // if init() throws some other RuntimeException,
+ // let it percolate up naturally.
+ }
+
+ /**
+ * Read and initialize the entire login Configuration from the
+ * configured URL.
+ *
+ * @throws IOException if the Configuration can not be initialized
+ * @throws SecurityException if the caller does not have permission
+ * to initialize the Configuration
+ */
+ private void init() throws IOException {
+
+ boolean initialized = false;
+
+ // For policy.expandProperties, check if either a security or system
+ // property is set to false (old code erroneously checked the system
+ // prop so we must check both to preserve compatibility).
+ String expand = Security.getProperty("policy.expandProperties");
+ if (expand == null) {
+ expand = System.getProperty("policy.expandProperties");
+ }
+ if ("false".equals(expand)) {
+ expandProp = false;
+ }
+
+ // new configuration
+ Map<String, List<AppConfigurationEntry>> newConfig = new HashMap<>();
+
+ if (url != null) {
+ /**
+ * If the caller specified a URI via Configuration.getInstance,
+ * we only read from that URI
+ */
+ if (debugConfig != null) {
+ debugConfig.println("reading " + url);
+ }
+ init(url, newConfig);
+ configuration = newConfig;
+ return;
+ }
+
+ /**
+ * Caller did not specify URI via Configuration.getInstance.
+ * Read from URLs listed in the java.security properties file.
+ */
+ String allowSys = Security.getProperty("policy.allowSystemProperty");
+
+ if ("true".equalsIgnoreCase(allowSys)) {
+ String extra_config = System.getProperty
+ ("java.security.auth.login.config");
+ if (extra_config != null) {
+ boolean overrideAll = false;
+ if (extra_config.startsWith("=")) {
+ overrideAll = true;
+ extra_config = extra_config.substring(1);
+ }
+ try {
+ extra_config = PropertyExpander.expand(extra_config);
+ } catch (PropertyExpander.ExpandException peee) {
+ throw ioException("Unable.to.properly.expand.config",
+ extra_config);
+ }
+
+ URL configURL = null;
+ try {
+ configURL = new URL(extra_config);
+ } catch (MalformedURLException mue) {
+ File configFile = new File(extra_config);
+ if (configFile.exists()) {
+ configURL = configFile.toURI().toURL();
+ } else {
+ throw ioException(
+ "extra.config.No.such.file.or.directory.",
+ extra_config);
+ }
+ }
+
+ if (debugConfig != null) {
+ debugConfig.println("reading "+configURL);
+ }
+ init(configURL, newConfig);
+ initialized = true;
+ if (overrideAll) {
+ if (debugConfig != null) {
+ debugConfig.println("overriding other policies!");
+ }
+ configuration = newConfig;
+ return;
+ }
+ }
+ }
+
+ int n = 1;
+ String config_url;
+ while ((config_url = Security.getProperty
+ ("login.config.url."+n)) != null) {
+ try {
+ config_url = PropertyExpander.expand
+ (config_url).replace(File.separatorChar, '/');
+ if (debugConfig != null) {
+ debugConfig.println("\tReading config: " + config_url);
+ }
+ init(new URL(config_url), newConfig);
+ initialized = true;
+ } catch (PropertyExpander.ExpandException peee) {
+ throw ioException("Unable.to.properly.expand.config",
+ config_url);
+ }
+ n++;
+ }
+
+ if (initialized == false && n == 1 && config_url == null) {
+
+ // get the config from the user's home directory
+ if (debugConfig != null) {
+ debugConfig.println("\tReading Policy " +
+ "from ~/.java.login.config");
+ }
+ config_url = System.getProperty("user.home");
+ String userConfigFile = config_url + File.separatorChar +
+ ".java.login.config";
+
+ // No longer throws an exception when there's no config file
+ // at all. Returns an empty Configuration instead.
+ if (new File(userConfigFile).exists()) {
+ init(new File(userConfigFile).toURI().toURL(), newConfig);
+ }
+ }
+
+ configuration = newConfig;
+ }
+
+ private void init(URL config,
+ Map<String, List<AppConfigurationEntry>> newConfig)
+ throws IOException {
+
+ try (InputStreamReader isr
+ = new InputStreamReader(getInputStream(config), "UTF-8")) {
+ readConfig(isr, newConfig);
+ } catch (FileNotFoundException fnfe) {
+ if (debugConfig != null) {
+ debugConfig.println(fnfe.toString());
+ }
+ throw new IOException(ResourcesMgr.getString
+ ("Configuration.Error.No.such.file.or.directory",
+ "sun.security.util.AuthResources"));
+ }
+ }
+
+ /**
+ * Retrieve an entry from the Configuration using an application name
+ * as an index.
+ *
+ * @param applicationName the name used to index the Configuration.
+ * @return an array of AppConfigurationEntries which correspond to
+ * the stacked configuration of LoginModules for this
+ * application, or null if this application has no configured
+ * LoginModules.
+ */
+ @Override
+ public AppConfigurationEntry[] engineGetAppConfigurationEntry
+ (String applicationName) {
+
+ List<AppConfigurationEntry> list = null;
+ synchronized (configuration) {
+ list = configuration.get(applicationName);
+ }
+
+ if (list == null || list.size() == 0) {
+ return null;
+ }
+
+ AppConfigurationEntry[] entries =
+ new AppConfigurationEntry[list.size()];
+ Iterator<AppConfigurationEntry> iterator = list.iterator();
+ for (int i = 0; iterator.hasNext(); i++) {
+ AppConfigurationEntry e = iterator.next();
+ entries[i] = new AppConfigurationEntry(e.getLoginModuleName(),
+ e.getControlFlag(),
+ e.getOptions());
+ }
+ return entries;
+ }
+
+ /**
+ * Refresh and reload the Configuration by re-reading all of the
+ * login configurations.
+ *
+ * @throws SecurityException if the caller does not have permission
+ * to refresh the Configuration.
+ */
+ @Override
+ public synchronized void engineRefresh() {
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(
+ new AuthPermission("refreshLoginConfiguration"));
+ }
+
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ try {
+ init();
+ } catch (IOException ioe) {
+ throw new SecurityException(ioe.getLocalizedMessage(),
+ ioe);
+ }
+ return null;
+ }
+ });
+ }
+
+ private void readConfig(Reader reader,
+ Map<String, List<AppConfigurationEntry>> newConfig)
+ throws IOException {
+
+ linenum = 1;
+
+ if (!(reader instanceof BufferedReader)) {
+ reader = new BufferedReader(reader);
+ }
+
+ st = new StreamTokenizer(reader);
+ st.quoteChar('"');
+ st.wordChars('$', '$');
+ st.wordChars('_', '_');
+ st.wordChars('-', '-');
+ st.wordChars('*', '*');
+ st.lowerCaseMode(false);
+ st.slashSlashComments(true);
+ st.slashStarComments(true);
+ st.eolIsSignificant(true);
+
+ lookahead = nextToken();
+ while (lookahead != StreamTokenizer.TT_EOF) {
+ parseLoginEntry(newConfig);
+ }
+ }
+
+ private void parseLoginEntry(
+ Map<String, List<AppConfigurationEntry>> newConfig)
+ throws IOException {
+
+ List<AppConfigurationEntry> configEntries = new LinkedList<>();
+
+ // application name
+ String appName = st.sval;
+ lookahead = nextToken();
+
+ if (debugParser != null) {
+ debugParser.println("\tReading next config entry: " + appName);
+ }
+
+ match("{");
+
+ // get the modules
+ while (peek("}") == false) {
+ // get the module class name
+ String moduleClass = match("module class name");
+
+ // controlFlag (required, optional, etc)
+ LoginModuleControlFlag controlFlag;
+ String sflag = match("controlFlag").toUpperCase();
+ switch (sflag) {
+ case "REQUIRED":
+ controlFlag = LoginModuleControlFlag.REQUIRED;
+ break;
+ case "REQUISITE":
+ controlFlag = LoginModuleControlFlag.REQUISITE;
+ break;
+ case "SUFFICIENT":
+ controlFlag = LoginModuleControlFlag.SUFFICIENT;
+ break;
+ case "OPTIONAL":
+ controlFlag = LoginModuleControlFlag.OPTIONAL;
+ break;
+ default:
+ throw ioException(
+ "Configuration.Error.Invalid.control.flag.flag",
+ sflag);
+ }
+
+ // get the args
+ Map<String, String> options = new HashMap<>();
+ while (peek(";") == false) {
+ String key = match("option key");
+ match("=");
+ try {
+ options.put(key, expand(match("option value")));
+ } catch (PropertyExpander.ExpandException peee) {
+ throw new IOException(peee.getLocalizedMessage());
+ }
+ }
+
+ lookahead = nextToken();
+
+ // create the new element
+ if (debugParser != null) {
+ debugParser.println("\t\t" + moduleClass + ", " + sflag);
+ for (String key : options.keySet()) {
+ debugParser.println("\t\t\t" + key +
+ "=" + options.get(key));
+ }
+ }
+ configEntries.add(new AppConfigurationEntry(moduleClass,
+ controlFlag,
+ options));
+ }
+
+ match("}");
+ match(";");
+
+ // add this configuration entry
+ if (newConfig.containsKey(appName)) {
+ throw ioException(
+ "Configuration.Error.Can.not.specify.multiple.entries.for.appName",
+ appName);
+ }
+ newConfig.put(appName, configEntries);
+ }
+
+ private String match(String expect) throws IOException {
+
+ String value = null;
+
+ switch(lookahead) {
+ case StreamTokenizer.TT_EOF:
+ throw ioException(
+ "Configuration.Error.expected.expect.read.end.of.file.",
+ expect);
+
+ case '"':
+ case StreamTokenizer.TT_WORD:
+ if (expect.equalsIgnoreCase("module class name") ||
+ expect.equalsIgnoreCase("controlFlag") ||
+ expect.equalsIgnoreCase("option key") ||
+ expect.equalsIgnoreCase("option value")) {
+ value = st.sval;
+ lookahead = nextToken();
+ } else {
+ throw ioException(
+ "Configuration.Error.Line.line.expected.expect.found.value.",
+ new Integer(linenum), expect, st.sval);
+ }
+ break;
+
+ case '{':
+ if (expect.equalsIgnoreCase("{")) {
+ lookahead = nextToken();
+ } else {
+ throw ioException(
+ "Configuration.Error.Line.line.expected.expect.",
+ new Integer(linenum), expect, st.sval);
+ }
+ break;
+
+ case ';':
+ if (expect.equalsIgnoreCase(";")) {
+ lookahead = nextToken();
+ } else {
+ throw ioException(
+ "Configuration.Error.Line.line.expected.expect.",
+ new Integer(linenum), expect, st.sval);
+ }
+ break;
+
+ case '}':
+ if (expect.equalsIgnoreCase("}")) {
+ lookahead = nextToken();
+ } else {
+ throw ioException(
+ "Configuration.Error.Line.line.expected.expect.",
+ new Integer(linenum), expect, st.sval);
+ }
+ break;
+
+ case '=':
+ if (expect.equalsIgnoreCase("=")) {
+ lookahead = nextToken();
+ } else {
+ throw ioException(
+ "Configuration.Error.Line.line.expected.expect.",
+ new Integer(linenum), expect, st.sval);
+ }
+ break;
+
+ default:
+ throw ioException(
+ "Configuration.Error.Line.line.expected.expect.found.value.",
+ new Integer(linenum), expect, st.sval);
+ }
+ return value;
+ }
+
+ private boolean peek(String expect) {
+ switch (lookahead) {
+ case ',':
+ return expect.equalsIgnoreCase(",");
+ case ';':
+ return expect.equalsIgnoreCase(";");
+ case '{':
+ return expect.equalsIgnoreCase("{");
+ case '}':
+ return expect.equalsIgnoreCase("}");
+ default:
+ return false;
+ }
+ }
+
+ private int nextToken() throws IOException {
+ int tok;
+ while ((tok = st.nextToken()) == StreamTokenizer.TT_EOL) {
+ linenum++;
+ }
+ return tok;
+ }
+
+ private InputStream getInputStream(URL url) throws IOException {
+ if ("file".equalsIgnoreCase(url.getProtocol())) {
+ // Compatibility notes:
+ //
+ // Code changed from
+ // String path = url.getFile().replace('/', File.separatorChar);
+ // return new FileInputStream(path);
+ //
+ // The original implementation would search for "/tmp/a%20b"
+ // when url is "file:///tmp/a%20b". This is incorrect. The
+ // current codes fix this bug and searches for "/tmp/a b".
+ // For compatibility reasons, when the file "/tmp/a b" does
+ // not exist, the file named "/tmp/a%20b" will be tried.
+ //
+ // This also means that if both file exists, the behavior of
+ // this method is changed, and the current codes choose the
+ // correct one.
+ try {
+ return url.openStream();
+ } catch (Exception e) {
+ String file = url.getPath();
+ if (url.getHost().length() > 0) { // For Windows UNC
+ file = "//" + url.getHost() + file;
+ }
+ if (debugConfig != null) {
+ debugConfig.println("cannot read " + url +
+ ", try " + file);
+ }
+ return new FileInputStream(file);
+ }
+ } else {
+ return url.openStream();
+ }
+ }
+
+ private String expand(String value)
+ throws PropertyExpander.ExpandException, IOException {
+
+ if (value.isEmpty()) {
+ return value;
+ }
+
+ if (!expandProp) {
+ return value;
+ }
+ String s = PropertyExpander.expand(value);
+ if (s == null || s.length() == 0) {
+ throw ioException(
+ "Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
+ new Integer(linenum), value);
+ }
+ return s;
+ }
+
+ private IOException ioException(String resourceKey, Object... args) {
+ MessageFormat form = new MessageFormat(ResourcesMgr.getString
+ (resourceKey, "sun.security.util.AuthResources"));
+ return new IOException(form.format(args));
+ }
+ }
+}
--- a/jdk/src/share/classes/sun/security/provider/ConfigSpiFile.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,693 +0,0 @@
-/*
- * Copyright (c) 2000, 2012, 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 sun.security.provider;
-
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.Security;
-import java.security.URIParameter;
-import java.text.MessageFormat;
-import java.util.*;
-import javax.security.auth.AuthPermission;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.ConfigurationSpi;
-import sun.security.util.Debug;
-import sun.security.util.PropertyExpander;
-import sun.security.util.ResourcesMgr;
-
-/**
- * This class represents a default implementation for
- * {@code javax.security.auth.login.Configuration}.
- *
- * <p> This object stores the runtime login configuration representation,
- * and is the amalgamation of multiple static login
- * configurations that resides in files.
- * The algorithm for locating the login configuration file(s) and reading their
- * information into this {@code Configuration} object is:
- *
- * <ol>
- * <li>
- * Loop through the security properties,
- * <i>login.config.url.1</i>, <i>login.config.url.2</i>, ...,
- * <i>login.config.url.X</i>.
- * Each property value specifies a <code>URL</code> pointing to a
- * login configuration file to be loaded. Read in and load
- * each configuration.
- *
- * <li>
- * The {@code java.lang.System} property
- * <i>java.security.auth.login.config</i>
- * may also be set to a {@code URL} pointing to another
- * login configuration file
- * (which is the case when a user uses the -D switch at runtime).
- * If this property is defined, and its use is allowed by the
- * security property file (the Security property,
- * <i>policy.allowSystemProperty</i> is set to <i>true</i>),
- * also load that login configuration.
- *
- * <li>
- * If the <i>java.security.auth.login.config</i> property is defined using
- * "==" (rather than "="), then ignore all other specified
- * login configurations and only load this configuration.
- *
- * <li>
- * If no system or security properties were set, try to read from the file,
- * ${user.home}/.java.login.config, where ${user.home} is the value
- * represented by the "user.home" System property.
- * </ol>
- *
- * <p> The configuration syntax supported by this implementation
- * is exactly that syntax specified in the
- * {@code javax.security.auth.login.Configuration} class.
- *
- * @see javax.security.auth.login.LoginContext
- * @see java.security.Security security properties
- */
-public final class ConfigSpiFile extends ConfigurationSpi {
-
- private URL url;
- private boolean expandProp = true;
- private Map<String, List<AppConfigurationEntry>> configuration;
- private int linenum;
- private StreamTokenizer st;
- private int lookahead;
-
- private static Debug debugConfig = Debug.getInstance("configfile");
- private static Debug debugParser = Debug.getInstance("configparser");
-
- /**
- * Create a new {@code Configuration} object.
- *
- * @throws SecurityException if the {@code Configuration} can not be
- * initialized
- */
- public ConfigSpiFile() {
- try {
- init();
- } catch (IOException ioe) {
- throw new SecurityException(ioe);
- }
- }
-
- /**
- * Create a new {@code Configuration} object from the specified {@code URI}.
- *
- * @param uri the {@code URI}
- * @throws SecurityException if the {@code Configuration} can not be
- * initialized
- * @throws NullPointerException if {@code uri} is null
- */
- public ConfigSpiFile(URI uri) {
- // only load config from the specified URI
- try {
- url = uri.toURL();
- init();
- } catch (IOException ioe) {
- throw new SecurityException(ioe);
- }
- }
-
- public ConfigSpiFile(final Configuration.Parameters params)
- throws IOException {
-
- // call in a doPrivileged
- //
- // we have already passed the Configuration.getInstance
- // security check. also this class is not freely accessible
- // (it is in the "sun" package).
-
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
- public Void run() throws IOException {
- if (params == null) {
- init();
- } else {
- if (!(params instanceof URIParameter)) {
- throw new IllegalArgumentException
- ("Unrecognized parameter: " + params);
- }
- URIParameter uriParam = (URIParameter)params;
- url = uriParam.getURI().toURL();
- init();
- }
- return null;
- }
- });
- } catch (PrivilegedActionException pae) {
- throw (IOException)pae.getException();
- }
-
- // if init() throws some other RuntimeException,
- // let it percolate up naturally.
- }
-
- /**
- * Read and initialize the entire login Configuration from the configured
- * URL.
- *
- * @throws IOException if the Configuration can not be initialized
- * @throws SecurityException if the caller does not have permission
- * to initialize the Configuration
- */
- private void init() throws IOException {
-
- boolean initialized = false;
-
- // For policy.expandProperties, check if either a security or system
- // property is set to false (old code erroneously checked the system
- // prop so we must check both to preserve compatibility).
- String expand = Security.getProperty("policy.expandProperties");
- if (expand == null) {
- expand = System.getProperty("policy.expandProperties");
- }
- if ("false".equals(expand)) {
- expandProp = false;
- }
-
- // new configuration
- Map<String, List<AppConfigurationEntry>> newConfig = new HashMap<>();
-
- if (url != null) {
- /**
- * If the caller specified a URI via Configuration.getInstance,
- * we only read from that URI
- */
- if (debugConfig != null) {
- debugConfig.println("reading " + url);
- }
- init(url, newConfig);
- configuration = newConfig;
- return;
- }
-
- /**
- * Caller did not specify URI via Configuration.getInstance.
- * Read from URLs listed in the java.security properties file.
- */
- String allowSys = Security.getProperty("policy.allowSystemProperty");
-
- if ("true".equalsIgnoreCase(allowSys)) {
- String extra_config = System.getProperty
- ("java.security.auth.login.config");
- if (extra_config != null) {
- boolean overrideAll = false;
- if (extra_config.startsWith("=")) {
- overrideAll = true;
- extra_config = extra_config.substring(1);
- }
- try {
- extra_config = PropertyExpander.expand(extra_config);
- } catch (PropertyExpander.ExpandException peee) {
- MessageFormat form = new MessageFormat
- (ResourcesMgr.getString
- ("Unable.to.properly.expand.config",
- "sun.security.util.AuthResources"));
- Object[] source = {extra_config};
- throw new IOException(form.format(source));
- }
-
- URL configURL = null;
- try {
- configURL = new URL(extra_config);
- } catch (MalformedURLException mue) {
- File configFile = new File(extra_config);
- if (configFile.exists()) {
- configURL = configFile.toURI().toURL();
- } else {
- MessageFormat form = new MessageFormat
- (ResourcesMgr.getString
- ("extra.config.No.such.file.or.directory.",
- "sun.security.util.AuthResources"));
- Object[] source = {extra_config};
- throw new IOException(form.format(source));
- }
- }
-
- if (debugConfig != null) {
- debugConfig.println("reading "+configURL);
- }
- init(configURL, newConfig);
- initialized = true;
- if (overrideAll) {
- if (debugConfig != null) {
- debugConfig.println("overriding other policies!");
- }
- configuration = newConfig;
- return;
- }
- }
- }
-
- int n = 1;
- String config_url;
- while ((config_url = Security.getProperty
- ("login.config.url."+n)) != null) {
- try {
- config_url = PropertyExpander.expand
- (config_url).replace(File.separatorChar, '/');
- if (debugConfig != null) {
- debugConfig.println("\tReading config: " + config_url);
- }
- init(new URL(config_url), newConfig);
- initialized = true;
- } catch (PropertyExpander.ExpandException peee) {
- MessageFormat form = new MessageFormat
- (ResourcesMgr.getString
- ("Unable.to.properly.expand.config",
- "sun.security.util.AuthResources"));
- Object[] source = {config_url};
- throw new IOException(form.format(source));
- }
- n++;
- }
-
- if (initialized == false && n == 1 && config_url == null) {
-
- // get the config from the user's home directory
- if (debugConfig != null) {
- debugConfig.println("\tReading Policy " +
- "from ~/.java.login.config");
- }
- config_url = System.getProperty("user.home");
- String userConfigFile = config_url +
- File.separatorChar + ".java.login.config";
-
- // No longer throws an exception when there's no config file
- // at all. Returns an empty Configuration instead.
- if (new File(userConfigFile).exists()) {
- init(new File(userConfigFile).toURI().toURL(),
- newConfig);
- }
- }
-
- configuration = newConfig;
- }
-
- private void init(URL config,
- Map<String, List<AppConfigurationEntry>> newConfig)
- throws IOException {
-
- try (InputStreamReader isr
- = new InputStreamReader(getInputStream(config), "UTF-8")) {
- readConfig(isr, newConfig);
- } catch (FileNotFoundException fnfe) {
- if (debugConfig != null) {
- debugConfig.println(fnfe.toString());
- }
- throw new IOException(ResourcesMgr.getString
- ("Configuration.Error.No.such.file.or.directory",
- "sun.security.util.AuthResources"));
- }
- }
-
- /**
- * Retrieve an entry from the Configuration using an application name
- * as an index.
- *
- * @param applicationName the name used to index the Configuration.
- * @return an array of AppConfigurationEntries which correspond to
- * the stacked configuration of LoginModules for this
- * application, or null if this application has no configured
- * LoginModules.
- */
- @Override
- public AppConfigurationEntry[] engineGetAppConfigurationEntry
- (String applicationName) {
-
- List<AppConfigurationEntry> list = null;
- synchronized (configuration) {
- list = configuration.get(applicationName);
- }
-
- if (list == null || list.size() == 0)
- return null;
-
- AppConfigurationEntry[] entries =
- new AppConfigurationEntry[list.size()];
- Iterator<AppConfigurationEntry> iterator = list.iterator();
- for (int i = 0; iterator.hasNext(); i++) {
- AppConfigurationEntry e = iterator.next();
- entries[i] = new AppConfigurationEntry(e.getLoginModuleName(),
- e.getControlFlag(),
- e.getOptions());
- }
- return entries;
- }
-
- /**
- * Refresh and reload the Configuration by re-reading all of the
- * login configurations.
- *
- * @throws SecurityException if the caller does not have permission
- * to refresh the Configuration.
- */
- @Override
- public synchronized void engineRefresh() {
-
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkPermission(new AuthPermission("refreshLoginConfiguration"));
-
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- try {
- init();
- } catch (IOException ioe) {
- throw new SecurityException(ioe.getLocalizedMessage(), ioe);
- }
- return null;
- }
- });
- }
-
- private void readConfig(Reader reader,
- Map<String, List<AppConfigurationEntry>> newConfig)
- throws IOException {
-
- linenum = 1;
-
- if (!(reader instanceof BufferedReader))
- reader = new BufferedReader(reader);
-
- st = new StreamTokenizer(reader);
- st.quoteChar('"');
- st.wordChars('$', '$');
- st.wordChars('_', '_');
- st.wordChars('-', '-');
- st.wordChars('*', '*');
- st.lowerCaseMode(false);
- st.slashSlashComments(true);
- st.slashStarComments(true);
- st.eolIsSignificant(true);
-
- lookahead = nextToken();
- while (lookahead != StreamTokenizer.TT_EOF) {
- parseLoginEntry(newConfig);
- }
- }
-
- private void parseLoginEntry(
- Map<String, List<AppConfigurationEntry>> newConfig)
- throws IOException {
-
- List<AppConfigurationEntry> configEntries = new LinkedList<>();
-
- // application name
- String appName = st.sval;
- lookahead = nextToken();
-
- if (debugParser != null) {
- debugParser.println("\tReading next config entry: " + appName);
- }
-
- match("{");
-
- // get the modules
- while (peek("}") == false) {
- // get the module class name
- String moduleClass = match("module class name");
-
- // controlFlag (required, optional, etc)
- AppConfigurationEntry.LoginModuleControlFlag controlFlag;
- String sflag = match("controlFlag").toUpperCase();
- switch (sflag) {
- case "REQUIRED":
- controlFlag =
- AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
- break;
- case "REQUISITE":
- controlFlag =
- AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;
- break;
- case "SUFFICIENT":
- controlFlag =
- AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
- break;
- case "OPTIONAL":
- controlFlag =
- AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
- break;
- default:
- MessageFormat form = new MessageFormat(
- ResourcesMgr.getString
- ("Configuration.Error.Invalid.control.flag.flag",
- "sun.security.util.AuthResources"));
- Object[] source = {sflag};
- throw new IOException(form.format(source));
- }
-
- // get the args
- Map<String, String> options = new HashMap<>();
- while (peek(";") == false) {
- String key = match("option key");
- match("=");
- try {
- options.put(key, expand(match("option value")));
- } catch (PropertyExpander.ExpandException peee) {
- throw new IOException(peee.getLocalizedMessage());
- }
- }
-
- lookahead = nextToken();
-
- // create the new element
- if (debugParser != null) {
- debugParser.println("\t\t" + moduleClass + ", " + sflag);
- for (String key : options.keySet()) {
- debugParser.println("\t\t\t" + key +
- "=" + options.get(key));
- }
- }
- configEntries.add(new AppConfigurationEntry(moduleClass,
- controlFlag, options));
- }
-
- match("}");
- match(";");
-
- // add this configuration entry
- if (newConfig.containsKey(appName)) {
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Can.not.specify.multiple.entries.for.appName",
- "sun.security.util.AuthResources"));
- Object[] source = {appName};
- throw new IOException(form.format(source));
- }
- newConfig.put(appName, configEntries);
- }
-
- private String match(String expect) throws IOException {
-
- String value = null;
-
- switch(lookahead) {
- case StreamTokenizer.TT_EOF:
-
- MessageFormat form1 = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.expected.expect.read.end.of.file.",
- "sun.security.util.AuthResources"));
- Object[] source1 = {expect};
- throw new IOException(form1.format(source1));
-
- case '"':
- case StreamTokenizer.TT_WORD:
-
- if (expect.equalsIgnoreCase("module class name") ||
- expect.equalsIgnoreCase("controlFlag") ||
- expect.equalsIgnoreCase("option key") ||
- expect.equalsIgnoreCase("option value")) {
- value = st.sval;
- lookahead = nextToken();
- } else {
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Line.line.expected.expect.found.value.",
- "sun.security.util.AuthResources"));
- Object[] source = {new Integer(linenum), expect, st.sval};
- throw new IOException(form.format(source));
- }
- break;
-
- case '{':
-
- if (expect.equalsIgnoreCase("{")) {
- lookahead = nextToken();
- } else {
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Line.line.expected.expect.",
- "sun.security.util.AuthResources"));
- Object[] source = {new Integer(linenum), expect, st.sval};
- throw new IOException(form.format(source));
- }
- break;
-
- case ';':
-
- if (expect.equalsIgnoreCase(";")) {
- lookahead = nextToken();
- } else {
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Line.line.expected.expect.",
- "sun.security.util.AuthResources"));
- Object[] source = {new Integer(linenum), expect, st.sval};
- throw new IOException(form.format(source));
- }
- break;
-
- case '}':
-
- if (expect.equalsIgnoreCase("}")) {
- lookahead = nextToken();
- } else {
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Line.line.expected.expect.",
- "sun.security.util.AuthResources"));
- Object[] source = {new Integer(linenum), expect, st.sval};
- throw new IOException(form.format(source));
- }
- break;
-
- case '=':
-
- if (expect.equalsIgnoreCase("=")) {
- lookahead = nextToken();
- } else {
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Line.line.expected.expect.",
- "sun.security.util.AuthResources"));
- Object[] source = {new Integer(linenum), expect, st.sval};
- throw new IOException(form.format(source));
- }
- break;
-
- default:
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Line.line.expected.expect.found.value.",
- "sun.security.util.AuthResources"));
- Object[] source = {new Integer(linenum), expect, st.sval};
- throw new IOException(form.format(source));
- }
- return value;
- }
-
- private boolean peek(String expect) {
- boolean found = false;
-
- switch (lookahead) {
- case ',':
- if (expect.equalsIgnoreCase(","))
- found = true;
- break;
- case ';':
- if (expect.equalsIgnoreCase(";"))
- found = true;
- break;
- case '{':
- if (expect.equalsIgnoreCase("{"))
- found = true;
- break;
- case '}':
- if (expect.equalsIgnoreCase("}"))
- found = true;
- break;
- default:
- }
- return found;
- }
-
- private int nextToken() throws IOException {
- int tok;
- while ((tok = st.nextToken()) == StreamTokenizer.TT_EOL) {
- linenum++;
- }
- return tok;
- }
-
- private InputStream getInputStream(URL url) throws IOException {
- if ("file".equalsIgnoreCase(url.getProtocol())) {
- // Compatibility notes:
- //
- // Code changed from
- // String path = url.getFile().replace('/', File.separatorChar);
- // return new FileInputStream(path);
- //
- // The original implementation would search for "/tmp/a%20b"
- // when url is "file:///tmp/a%20b". This is incorrect. The
- // current codes fix this bug and searches for "/tmp/a b".
- // For compatibility reasons, when the file "/tmp/a b" does
- // not exist, the file named "/tmp/a%20b" will be tried.
- //
- // This also means that if both file exists, the behavior of
- // this method is changed, and the current codes choose the
- // correct one.
- try {
- return url.openStream();
- } catch (Exception e) {
- String file = url.getPath();
- if (url.getHost().length() > 0) { // For Windows UNC
- file = "//" + url.getHost() + file;
- }
- if (debugConfig != null) {
- debugConfig.println("cannot read " + url +
- ", try " + file);
- }
- return new FileInputStream(file);
- }
- } else {
- return url.openStream();
- }
- }
-
- private String expand(String value)
- throws PropertyExpander.ExpandException, IOException {
-
- if (value.isEmpty()) {
- return value;
- }
-
- if (expandProp) {
-
- String s = PropertyExpander.expand(value);
-
- if (s == null || s.length() == 0) {
- MessageFormat form = new MessageFormat(ResourcesMgr.getString
- ("Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
- "sun.security.util.AuthResources"));
- Object[] source = {new Integer(linenum), value};
- throw new IOException(form.format(source));
- }
- return s;
- } else {
- return value;
- }
- }
-}
--- a/jdk/src/share/classes/sun/security/provider/DSAPublicKey.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/provider/DSAPublicKey.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -37,6 +37,7 @@
import sun.security.x509.X509Key;
import sun.security.x509.AlgIdDSA;
+import sun.security.util.BitArray;
import sun.security.util.Debug;
import sun.security.util.DerValue;
import sun.security.util.DerInputStream;
@@ -88,8 +89,9 @@
algid = new AlgIdDSA(p, q, g);
try {
- key = new DerValue(DerValue.tag_Integer,
+ byte[] keyArray = new DerValue(DerValue.tag_Integer,
y.toByteArray()).toByteArray();
+ setKey(new BitArray(keyArray.length*8, keyArray));
encode();
} catch (IOException e) {
throw new InvalidKeyException("could not DER encode y: " +
@@ -142,7 +144,7 @@
protected void parseKeyBits() throws InvalidKeyException {
try {
- DerInputStream in = new DerInputStream(key);
+ DerInputStream in = new DerInputStream(getKey().toByteArray());
y = in.getBigInteger();
} catch (IOException e) {
throw new InvalidKeyException("Invalid key: y value\n" +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/SubjectCodeSource.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 1999, 2013, 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 sun.security.provider;
+
+import java.net.URL;
+import java.util.*;
+import java.security.CodeSource;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.lang.reflect.Constructor;
+
+import javax.security.auth.Subject;
+import sun.security.provider.PolicyParser.PrincipalEntry;
+
+/**
+ * <p> This <code>SubjectCodeSource</code> class contains
+ * a <code>URL</code>, signer certificates, and either a <code>Subject</code>
+ * (that represents the <code>Subject</code> in the current
+ * <code>AccessControlContext</code>), or a linked list of Principals
+ * (that represent a "subject" in a <code>Policy</code>).
+ *
+ */
+class SubjectCodeSource extends CodeSource implements java.io.Serializable {
+
+ private static final long serialVersionUID = 6039418085604715275L;
+
+ private static final java.util.ResourceBundle rb =
+ java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
+ public java.util.ResourceBundle run() {
+ return (java.util.ResourceBundle.getBundle
+ ("sun.security.util.AuthResources"));
+ }
+ });
+
+ private Subject subject;
+ private LinkedList<PrincipalEntry> principals;
+ private static final Class[] PARAMS = { String.class };
+ private static final sun.security.util.Debug debug =
+ sun.security.util.Debug.getInstance("auth", "\t[Auth Access]");
+ private ClassLoader sysClassLoader;
+
+ /**
+ * Creates a new <code>SubjectCodeSource</code>
+ * with the given <code>Subject</code>, principals, <code>URL</code>,
+ * and signers (Certificates). The <code>Subject</code>
+ * represents the <code>Subject</code> associated with the current
+ * <code>AccessControlContext</code>.
+ * The Principals are given as a <code>LinkedList</code>
+ * of <code>PolicyParser.PrincipalEntry</code> objects.
+ * Typically either a <code>Subject</code> will be provided,
+ * or a list of <code>principals</code> will be provided
+ * (not both).
+ *
+ * <p>
+ *
+ * @param subject the <code>Subject</code> associated with this
+ * <code>SubjectCodeSource</code> <p>
+ *
+ * @param url the <code>URL</code> associated with this
+ * <code>SubjectCodeSource</code> <p>
+ *
+ * @param certs the signers associated with this
+ * <code>SubjectCodeSource</code> <p>
+ */
+ SubjectCodeSource(Subject subject,
+ LinkedList<PrincipalEntry> principals,
+ URL url, Certificate[] certs) {
+
+ super(url, certs);
+ this.subject = subject;
+ this.principals = (principals == null ?
+ new LinkedList<PrincipalEntry>() :
+ new LinkedList<PrincipalEntry>(principals));
+ sysClassLoader = java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return ClassLoader.getSystemClassLoader();
+ }
+ });
+ }
+
+ /**
+ * Get the Principals associated with this <code>SubjectCodeSource</code>.
+ * The Principals are retrieved as a <code>LinkedList</code>
+ * of <code>PolicyParser.PrincipalEntry</code> objects.
+ *
+ * <p>
+ *
+ * @return the Principals associated with this
+ * <code>SubjectCodeSource</code> as a <code>LinkedList</code>
+ * of <code>PolicyParser.PrincipalEntry</code> objects.
+ */
+ LinkedList<PrincipalEntry> getPrincipals() {
+ return principals;
+ }
+
+ /**
+ * Get the <code>Subject</code> associated with this
+ * <code>SubjectCodeSource</code>. The <code>Subject</code>
+ * represents the <code>Subject</code> associated with the
+ * current <code>AccessControlContext</code>.
+ *
+ * <p>
+ *
+ * @return the <code>Subject</code> associated with this
+ * <code>SubjectCodeSource</code>.
+ */
+ Subject getSubject() {
+ return subject;
+ }
+
+ /**
+ * Returns true if this <code>SubjectCodeSource</code> object "implies"
+ * the specified <code>CodeSource</code>.
+ * More specifically, this method makes the following checks.
+ * If any fail, it returns false. If they all succeed, it returns true.
+ *
+ * <p>
+ * <ol>
+ * <li> The provided codesource must not be <code>null</code>.
+ * <li> codesource must be an instance of <code>SubjectCodeSource</code>.
+ * <li> super.implies(codesource) must return true.
+ * <li> for each principal in this codesource's principal list:
+ * <ol>
+ * <li> if the principal is an instanceof
+ * <code>Principal</code>, then the principal must
+ * imply the provided codesource's <code>Subject</code>.
+ * <li> if the principal is not an instanceof
+ * <code>Principal</code>, then the provided
+ * codesource's <code>Subject</code> must have an
+ * associated <code>Principal</code>, <i>P</i>, where
+ * P.getClass().getName equals principal.principalClass,
+ * and P.getName() equals principal.principalName.
+ * </ol>
+ * </ol>
+ *
+ * <p>
+ *
+ * @param codesource the <code>CodeSource</code> to compare against.
+ *
+ * @return true if this <code>SubjectCodeSource</code> implies the
+ * the specified <code>CodeSource</code>.
+ */
+ public boolean implies(CodeSource codesource) {
+
+ LinkedList<PrincipalEntry> subjectList = null;
+
+ if (codesource == null ||
+ !(codesource instanceof SubjectCodeSource) ||
+ !(super.implies(codesource))) {
+
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: FAILURE 1");
+ return false;
+ }
+
+ SubjectCodeSource that = (SubjectCodeSource)codesource;
+
+ // if the principal list in the policy "implies"
+ // the Subject associated with the current AccessControlContext,
+ // then return true
+
+ if (this.principals == null) {
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: PASS 1");
+ return true;
+ }
+
+ if (that.getSubject() == null ||
+ that.getSubject().getPrincipals().size() == 0) {
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: FAILURE 2");
+ return false;
+ }
+
+ ListIterator<PrincipalEntry> li = this.principals.listIterator(0);
+ while (li.hasNext()) {
+ PrincipalEntry pppe = li.next();
+ try {
+
+ // use new Principal.implies method
+
+ Class<?> pClass = Class.forName(pppe.principalClass,
+ true, sysClassLoader);
+ if (!Principal.class.isAssignableFrom(pClass)) {
+ // not the right subtype
+ throw new ClassCastException(pppe.principalClass +
+ " is not a Principal");
+ }
+ Constructor<?> c = pClass.getConstructor(PARAMS);
+ Principal p = (Principal)c.newInstance(new Object[] {
+ pppe.principalName });
+
+ if (!p.implies(that.getSubject())) {
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: FAILURE 3");
+ return false;
+ } else {
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: PASS 2");
+ return true;
+ }
+ } catch (Exception e) {
+
+ // simply compare Principals
+
+ if (subjectList == null) {
+
+ if (that.getSubject() == null) {
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: " +
+ "FAILURE 4");
+ return false;
+ }
+ Iterator<Principal> i =
+ that.getSubject().getPrincipals().iterator();
+
+ subjectList = new LinkedList<PrincipalEntry>();
+ while (i.hasNext()) {
+ Principal p = i.next();
+ PrincipalEntry spppe = new PrincipalEntry
+ (p.getClass().getName(), p.getName());
+ subjectList.add(spppe);
+ }
+ }
+
+ if (!subjectListImpliesPrincipalEntry(subjectList, pppe)) {
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: FAILURE 5");
+ return false;
+ }
+ }
+ }
+
+ if (debug != null)
+ debug.println("\tSubjectCodeSource.implies: PASS 3");
+ return true;
+ }
+
+ /**
+ * This method returns, true, if the provided <i>subjectList</i>
+ * "contains" the <code>Principal</code> specified
+ * in the provided <i>pppe</i> argument.
+ *
+ * Note that the provided <i>pppe</i> argument may have
+ * wildcards (*) for the <code>Principal</code> class and name,
+ * which need to be considered.
+ *
+ * <p>
+ *
+ * @param subjectList a list of PolicyParser.PrincipalEntry objects
+ * that correspond to all the Principals in the Subject currently
+ * on this thread's AccessControlContext. <p>
+ *
+ * @param pppe the Principals specified in a grant entry.
+ *
+ * @return true if the provided <i>subjectList</i> "contains"
+ * the <code>Principal</code> specified in the provided
+ * <i>pppe</i> argument.
+ */
+ private boolean subjectListImpliesPrincipalEntry(
+ LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) {
+
+ ListIterator<PrincipalEntry> li = subjectList.listIterator(0);
+ while (li.hasNext()) {
+ PrincipalEntry listPppe = li.next();
+
+ if (pppe.getPrincipalClass().equals
+ (PrincipalEntry.WILDCARD_CLASS) ||
+ pppe.getPrincipalClass().equals(listPppe.getPrincipalClass()))
+ {
+ if (pppe.getPrincipalName().equals
+ (PrincipalEntry.WILDCARD_NAME) ||
+ pppe.getPrincipalName().equals(listPppe.getPrincipalName()))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tests for equality between the specified object and this
+ * object. Two <code>SubjectCodeSource</code> objects are considered equal
+ * if their locations are of identical value, if the two sets of
+ * Certificates are of identical values, and if the
+ * Subjects are equal, and if the PolicyParser.PrincipalEntry values
+ * are of identical values. It is not required that
+ * the Certificates or PolicyParser.PrincipalEntry values
+ * be in the same order.
+ *
+ * <p>
+ *
+ * @param obj the object to test for equality with this object.
+ *
+ * @return true if the objects are considered equal, false otherwise.
+ */
+ public boolean equals(Object obj) {
+
+ if (obj == this)
+ return true;
+
+ if (super.equals(obj) == false)
+ return false;
+
+ if (!(obj instanceof SubjectCodeSource))
+ return false;
+
+ SubjectCodeSource that = (SubjectCodeSource)obj;
+
+ // the principal lists must match
+ try {
+ if (this.getSubject() != that.getSubject())
+ return false;
+ } catch (SecurityException se) {
+ return false;
+ }
+
+ if ((this.principals == null && that.principals != null) ||
+ (this.principals != null && that.principals == null))
+ return false;
+
+ if (this.principals != null && that.principals != null) {
+ if (!this.principals.containsAll(that.principals) ||
+ !that.principals.containsAll(this.principals))
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return a hashcode for this <code>SubjectCodeSource</code>.
+ *
+ * <p>
+ *
+ * @return a hashcode for this <code>SubjectCodeSource</code>.
+ */
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ /**
+ * Return a String representation of this <code>SubjectCodeSource</code>.
+ *
+ * <p>
+ *
+ * @return a String representation of this <code>SubjectCodeSource</code>.
+ */
+ public String toString() {
+ String returnMe = super.toString();
+ if (getSubject() != null) {
+ if (debug != null) {
+ final Subject finalSubject = getSubject();
+ returnMe = returnMe + "\n" +
+ java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<String>() {
+ public String run() {
+ return finalSubject.toString();
+ }
+ });
+ } else {
+ returnMe = returnMe + "\n" + getSubject().toString();
+ }
+ }
+ if (principals != null) {
+ ListIterator<PrincipalEntry> li = principals.listIterator();
+ while (li.hasNext()) {
+ PrincipalEntry pppe = li.next();
+ returnMe = returnMe + rb.getString("NEWLINE") +
+ pppe.getPrincipalClass() + " " +
+ pppe.getPrincipalName();
+ }
+ }
+ return returnMe;
+ }
+}
--- a/jdk/src/share/classes/sun/security/provider/SunEntries.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/provider/SunEntries.java Wed Jul 05 19:09:26 2017 +0200
@@ -242,7 +242,7 @@
* Configuration
*/
map.put("Configuration.JavaLoginConfig",
- "sun.security.provider.ConfigSpiFile");
+ "sun.security.provider.ConfigFile$Spi");
/*
* CertPathBuilder
--- a/jdk/src/share/classes/sun/security/rsa/RSAPadding.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/rsa/RSAPadding.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013 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
@@ -458,7 +458,7 @@
private void mgf1(byte[] seed, int seedOfs, int seedLen,
byte[] out, int outOfs, int maskLen) throws BadPaddingException {
byte[] C = new byte[4]; // 32 bit counter
- byte[] digest = new byte[20]; // 20 bytes is length of SHA-1 digest
+ byte[] digest = new byte[mgfMd.getDigestLength()];
while (maskLen > 0) {
mgfMd.update(seed, seedOfs, seedLen);
mgfMd.update(C);
--- a/jdk/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -67,9 +67,10 @@
DerOutputStream out = new DerOutputStream();
out.putInteger(n);
out.putInteger(e);
- DerValue val =
- new DerValue(DerValue.tag_Sequence, out.toByteArray());
- key = val.toByteArray();
+ byte[] keyArray =
+ new DerValue(DerValue.tag_Sequence,
+ out.toByteArray()).toByteArray();
+ setKey(new BitArray(keyArray.length*8, keyArray));
} catch (IOException exc) {
// should never occur
throw new InvalidKeyException(exc);
@@ -104,7 +105,7 @@
*/
protected void parseKeyBits() throws InvalidKeyException {
try {
- DerInputStream in = new DerInputStream(key);
+ DerInputStream in = new DerInputStream(getKey().toByteArray());
DerValue derValue = in.getDerValue();
if (derValue.tag != DerValue.tag_Sequence) {
throw new IOException("Not a SEQUENCE");
--- a/jdk/src/share/classes/sun/security/rsa/RSASignature.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/rsa/RSASignature.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -244,12 +244,14 @@
}
// set parameter, not supported. See JCA doc
+ @Deprecated
protected void engineSetParameter(String param, Object value)
throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported");
}
// get parameter, not supported. See JCA doc
+ @Deprecated
protected Object engineGetParameter(String param)
throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported");
--- a/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -57,7 +57,8 @@
private final KerberosClientKeyExchange impl = createImpl();
private KerberosClientKeyExchange createImpl() {
- if (getClass() == KerberosClientKeyExchange.class) {
+ if (implClass != null &&
+ getClass() == KerberosClientKeyExchange.class) {
try {
return (KerberosClientKeyExchange)implClass.newInstance();
} catch (InstantiationException e) {
@@ -69,8 +70,11 @@
return null;
}
- public KerberosClientKeyExchange() {
- // empty
+ // This constructor will be called when constructing an instance of its
+ // subclass -- KerberosClientKeyExchangeImpl. Please won't check the
+ // value of impl variable in this constructor.
+ protected KerberosClientKeyExchange() {
+ // please won't check the value of impl variable
}
public KerberosClientKeyExchange(String serverName, boolean isLoopback,
@@ -85,8 +89,9 @@
}
public KerberosClientKeyExchange(ProtocolVersion protocolVersion,
- ProtocolVersion clientVersion, SecureRandom rand,
- HandshakeInStream input, AccessControlContext acc, Object serverKeys) throws IOException {
+ ProtocolVersion clientVersion, SecureRandom rand,
+ HandshakeInStream input, AccessControlContext acc,
+ Object serverKeys) throws IOException {
if (impl != null) {
init(protocolVersion, clientVersion, rand, input, acc, serverKeys);
@@ -101,7 +106,7 @@
}
@Override
- public int messageLength() {
+ public int messageLength() {
return impl.messageLength();
}
@@ -125,11 +130,13 @@
}
public void init(ProtocolVersion protocolVersion,
- ProtocolVersion clientVersion, SecureRandom rand,
- HandshakeInStream input, AccessControlContext acc, Object ServiceCreds) throws IOException {
+ ProtocolVersion clientVersion, SecureRandom rand,
+ HandshakeInStream input, AccessControlContext acc,
+ Object ServiceCreds) throws IOException {
if (impl != null) {
- impl.init(protocolVersion, clientVersion, rand, input, acc, ServiceCreds);
+ impl.init(protocolVersion, clientVersion,
+ rand, input, acc, ServiceCreds);
}
}
--- a/jdk/src/share/classes/sun/security/x509/AlgIdDSA.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/x509/AlgIdDSA.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -96,7 +96,7 @@
* Default constructor. The OID and parameters must be
* deserialized before this algorithm ID is used.
*/
- // XXX deprecated for general use
+ @Deprecated
public AlgIdDSA () {}
AlgIdDSA (DerValue val) throws IOException
--- a/jdk/src/share/classes/sun/security/x509/X509Key.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/security/x509/X509Key.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -79,6 +79,7 @@
* Added to keep the byte[] key form consistent with the BitArray
* form. Can de deleted when byte[] key is deleted.
*/
+ @Deprecated
private int unusedBits = 0;
/* BitArray form of key */
--- a/jdk/src/share/classes/sun/text/resources/FormatData.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/text/resources/FormatData.java Wed Jul 05 19:09:26 2017 +0200
@@ -858,6 +858,9 @@
}
},
{ "DateTimePatternChars", "GyMdkHmsSEDFwWahKzZ" },
+
+ // Workaround for islamic-umalqura name support (JDK-8015986)
+ { "calendarname.islamic-umalqura", "Islamic Umm al-Qura Calendar" },
};
}
}
--- a/jdk/src/share/classes/sun/text/resources/ar/FormatData_ar.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/text/resources/ar/FormatData_ar.java Wed Jul 05 19:09:26 2017 +0200
@@ -264,6 +264,10 @@
}
},
{ "DateTimePatternChars", "GanjkHmsSEDFwWxhKzZ" },
+
+ // Workaround for islamic-umalqura name support (JDK-8015986)
+ { "calendarname.islamic-umalqura",
+ "\u0644\u062a\u0642\u0648\u064a\u0645 \u0627\u0644\u0647\u062c\u0631\u064a\u060c \u0623\u0645 \u0627\u0644\u0642\u0631\u0649" },
};
}
}
--- a/jdk/src/share/classes/sun/tools/jar/Main.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java Wed Jul 05 19:09:26 2017 +0200
@@ -47,7 +47,7 @@
class Main {
String program;
PrintStream out, err;
- String fname, mname, ename, pname;
+ String fname, mname, ename;
String zname = "";
String[] files;
String rootjar = null;
@@ -78,9 +78,6 @@
static final String MANIFEST_DIR = "META-INF/";
static final String VERSION = "1.0";
- // valid values for Profile attribute
- private static final String[] PROFILES = { "compact1", "compact2", "compact3" };
-
private static ResourceBundle rsrc;
/**
@@ -187,14 +184,6 @@
if (ename != null) {
addMainClass(manifest, ename);
}
- if (pname != null) {
- if (!addProfileName(manifest, pname)) {
- if (in != null) {
- in.close();
- }
- return false;
- }
- }
}
OutputStream out;
if (fname != null) {
@@ -372,9 +361,6 @@
case 'e':
ename = args[count++];
break;
- case 'p':
- pname = args[count++];
- break;
default:
error(formatMsg("error.illegal.option",
String.valueOf(flags.charAt(i))));
@@ -424,7 +410,7 @@
usageError();
return false;
} else if (uflag) {
- if ((mname != null) || (ename != null) || (pname != null)) {
+ if ((mname != null) || (ename != null)) {
/* just want to update the manifest */
return true;
} else {
@@ -558,7 +544,7 @@
|| (Mflag && isManifestEntry)) {
continue;
} else if (isManifestEntry && ((newManifest != null) ||
- (ename != null) || (pname != null))) {
+ (ename != null))) {
foundManifest = true;
if (newManifest != null) {
// Don't read from the newManifest InputStream, as we
@@ -616,7 +602,7 @@
updateOk = false;
}
}
- } else if (ename != null || pname != null) {
+ } else if (ename != null) {
if (!updateManifest(new Manifest(), zos)) {
updateOk = false;
}
@@ -651,11 +637,6 @@
if (ename != null) {
addMainClass(m, ename);
}
- if (pname != null) {
- if (!addProfileName(m, pname)) {
- return false;
- }
- }
ZipEntry e = new ZipEntry(MANIFEST_NAME);
e.setTime(System.currentTimeMillis());
if (flag0) {
@@ -713,28 +694,6 @@
global.put(Attributes.Name.MAIN_CLASS, mainApp);
}
- private boolean addProfileName(Manifest m, String profile) {
- // check profile name
- boolean found = false;
- int i = 0;
- while (i < PROFILES.length) {
- if (profile.equals(PROFILES[i])) {
- found = true;
- break;
- }
- i++;
- }
- if (!found) {
- error(formatMsg("error.bad.pvalue", profile));
- return false;
- }
-
- // overrides any existing Profile attribute
- Attributes global = m.getMainAttributes();
- global.put(Attributes.Name.PROFILE, profile);
- return true;
- }
-
private boolean isAmbiguousMainClass(Manifest m) {
if (ename != null) {
Attributes global = m.getMainAttributes();
--- a/jdk/src/share/classes/sun/tools/jar/resources/jar.properties Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jar/resources/jar.properties Wed Jul 05 19:09:26 2017 +0200
@@ -36,8 +36,6 @@
error.bad.eflag=\
'e' flag and manifest with the 'Main-Class' attribute cannot be specified \n\
together!
-error.bad.pvalue=\
- bad value for 'Profile' attribute: {0}
error.nosuch.fileordir=\
{0} : no such file or directory
error.write.file=\
@@ -79,7 +77,6 @@
\ \ -m include manifest information from specified manifest file\n\
\ \ -e specify application entry point for stand-alone application \n\
\ \ bundled into an executable jar file\n\
-\ \ -p specify profile name\n\
\ \ -0 store only; use no ZIP compression\n\
\ \ -M do not create a manifest file for the entries\n\
\ \ -i generate index information for the specified jar files\n\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/tools/jconsole/ExceptionSafePlugin.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2013, 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 sun.tools.jconsole;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.SwingWorker;
+
+import com.sun.tools.jconsole.JConsolePlugin;
+
+/**
+ * Proxy that shields GUI from plug-in exceptions.
+ *
+ */
+final class ExceptionSafePlugin extends JConsolePlugin {
+
+ private static boolean ignoreExceptions;
+ private final JConsolePlugin plugin;
+
+ public ExceptionSafePlugin(JConsolePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public Map<String, JPanel> getTabs() {
+ try {
+ return plugin.getTabs();
+ } catch (RuntimeException e) {
+ handleException(e);
+ }
+ return new HashMap<>();
+ }
+
+ @Override
+ public SwingWorker<?, ?> newSwingWorker() {
+ try {
+ return plugin.newSwingWorker();
+ } catch (RuntimeException e) {
+ handleException(e);
+ }
+ return null;
+ }
+
+ @Override
+ public void dispose() {
+ try {
+ plugin.dispose();
+ } catch (RuntimeException e) {
+ handleException(e);
+ }
+ }
+
+ public void executeSwingWorker(SwingWorker<?, ?> sw) {
+ try {
+ sw.execute();
+ } catch (RuntimeException e) {
+ handleException(e);
+ }
+ }
+
+ private void handleException(Exception e) {
+ if (JConsole.isDebug()) {
+ System.err.println("Plug-in exception:");
+ e.printStackTrace();
+ } else {
+ if (!ignoreExceptions) {
+ showExceptionDialog(e);
+ }
+ }
+ }
+
+ private void showExceptionDialog(Exception e) {
+ Object[] buttonTexts = {
+ Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_OK,
+ Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT,
+ Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE
+ };
+
+ String message = String.format(
+ Messages.PLUGIN_EXCEPTION_DIALOG_MESSAGE,
+ plugin.getClass().getSimpleName(),
+ String.valueOf(e.getMessage())
+ );
+
+ int buttonIndex = JOptionPane.showOptionDialog(
+ null,
+ message,
+ Messages.PLUGIN_EXCEPTION_DIALOG_TITLE,
+ JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.ERROR_MESSAGE,
+ null,
+ buttonTexts,
+ buttonTexts[0]
+ );
+
+ if (buttonIndex == 1) {
+ System.exit(0);
+ }
+ ignoreExceptions = buttonIndex == 2;
+ }
+}
--- a/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -228,6 +228,7 @@
if (ev.getStateChange() == ItemEvent.SELECTED) {
Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
plotterPanel.setPlotter(plotter);
+ plotterPanel.repaint();
}
}
--- a/jdk/src/share/classes/sun/tools/jconsole/Messages.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/Messages.java Wed Jul 05 19:09:26 2017 +0200
@@ -240,6 +240,11 @@
public static String PLOTTER_ACCESSIBLE_NAME_NO_DATA;
public static String PLOTTER_SAVE_AS_MENU_ITEM;
public static String PLOTTER_TIME_RANGE_MENU;
+ public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT;
+ public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE;
+ public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_OK;
+ public static String PLUGIN_EXCEPTION_DIALOG_MESSAGE;
+ public static String PLUGIN_EXCEPTION_DIALOG_TITLE;
public static String PROBLEM_ADDING_LISTENER;
public static String PROBLEM_DISPLAYING_MBEAN;
public static String PROBLEM_INVOKING;
--- a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -71,7 +71,7 @@
// Each VMPanel has its own instance of the JConsolePlugin
// A map of JConsolePlugin to the previous SwingWorker
- private Map<JConsolePlugin, SwingWorker<?, ?>> plugins = null;
+ private Map<ExceptionSafePlugin, SwingWorker<?, ?>> plugins = null;
private boolean pluginTabsAdded = false;
// Update these only on the EDT
@@ -107,10 +107,10 @@
}
}
- plugins = new LinkedHashMap<JConsolePlugin, SwingWorker<?, ?>>();
+ plugins = new LinkedHashMap<ExceptionSafePlugin, SwingWorker<?, ?>>();
for (JConsolePlugin p : JConsole.getPlugins()) {
p.setContext(proxyClient);
- plugins.put(p, null);
+ plugins.put(new ExceptionSafePlugin(p), null);
}
Utilities.updateTransparency(this);
@@ -566,7 +566,7 @@
}
// plugin GUI update
- for (JConsolePlugin p : plugins.keySet()) {
+ for (ExceptionSafePlugin p : plugins.keySet()) {
SwingWorker<?, ?> sw = p.newSwingWorker();
SwingWorker<?, ?> prevSW = plugins.get(p);
// schedule SwingWorker to run only if the previous
@@ -575,7 +575,7 @@
if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) {
plugins.put(p, sw);
if (sw != null) {
- sw.execute();
+ p.executeSwingWorker(sw);
}
}
}
--- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties Wed Jul 05 19:09:26 2017 +0200
@@ -137,14 +137,14 @@
MBEANS=MBeans
MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=&Clear
MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=Clear notifications
-MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=Composite Navigation {0}/{1}
-MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=Composite Navigation
+MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=Composite Data Navigation {0}/{1}
+MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=Composite Data Navigation
MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=&Refresh
MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=Refresh attributes
MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=&Subscribe
MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Start listening for notifications
-MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=Tabular Navigation {0}/{1}
-MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=Tabular Navigation
+MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=Tabular Data Navigation {0}/{1}
+MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=Tabular Data Navigation
MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=&Unsubscribe
MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Stop listening for notifications
MANAGE_HOTSPOT_MBEANS_IN_COLON_=Manage Hotspot MBeans in:
@@ -198,6 +198,11 @@
PLOTTER_ACCESSIBLE_NAME_NO_DATA=No data plotted.
PLOTTER_SAVE_AS_MENU_ITEM=Save data &as...
PLOTTER_TIME_RANGE_MENU=&Time Range
+PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT=Exit
+PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE=Ignore
+PLUGIN_EXCEPTION_DIALOG_BUTTON_OK=OK
+PLUGIN_EXCEPTION_DIALOG_MESSAGE=An unexpected exception has occurred in %s:\n\n%s\n\nStart with -debug for details. Ignore will suppress further exceptions.
+PLUGIN_EXCEPTION_DIALOG_TITLE=Plug-in exception
PROBLEM_ADDING_LISTENER=Problem adding listener
PROBLEM_DISPLAYING_MBEAN=Problem displaying MBean
PROBLEM_INVOKING=Problem invoking
--- a/jdk/src/share/classes/sun/util/resources/lv/CurrencyNames_lv_LV.properties Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/classes/sun/util/resources/lv/CurrencyNames_lv_LV.properties Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2013, 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
@@ -35,4 +35,5 @@
# This notice and attribution to Taligent may not be removed.
# Taligent is a registered trademark of Taligent, Inc.
+EUR=\u20AC
LVL=Ls
--- a/jdk/src/share/lib/security/java.security-linux Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-linux Wed Jul 05 19:09:26 2017 +0200
@@ -132,7 +132,7 @@
# Class to instantiate as the javax.security.auth.login.Configuration
# provider.
#
-login.configuration.provider=com.sun.security.auth.login.ConfigFile
+login.configuration.provider=sun.security.provider.ConfigFile
#
# Default login configuration file
--- a/jdk/src/share/lib/security/java.security-macosx Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-macosx Wed Jul 05 19:09:26 2017 +0200
@@ -133,7 +133,7 @@
# Class to instantiate as the javax.security.auth.login.Configuration
# provider.
#
-login.configuration.provider=com.sun.security.auth.login.ConfigFile
+login.configuration.provider=sun.security.provider.ConfigFile
#
# Default login configuration file
--- a/jdk/src/share/lib/security/java.security-solaris Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-solaris Wed Jul 05 19:09:26 2017 +0200
@@ -134,7 +134,7 @@
# Class to instantiate as the javax.security.auth.login.Configuration
# provider.
#
-login.configuration.provider=com.sun.security.auth.login.ConfigFile
+login.configuration.provider=sun.security.provider.ConfigFile
#
# Default login configuration file
--- a/jdk/src/share/lib/security/java.security-windows Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-windows Wed Jul 05 19:09:26 2017 +0200
@@ -133,7 +133,7 @@
# Class to instantiate as the javax.security.auth.login.Configuration
# provider.
#
-login.configuration.provider=com.sun.security.auth.login.ConfigFile
+login.configuration.provider=sun.security.provider.ConfigFile
#
# Default login configuration file
--- a/jdk/src/share/native/java/io/RandomAccessFile.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/native/java/io/RandomAccessFile.c Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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,7 +123,7 @@
}
JNIEXPORT void JNICALL
-Java_java_io_RandomAccessFile_seek(JNIEnv *env,
+Java_java_io_RandomAccessFile_seek0(JNIEnv *env,
jobject this, jlong pos) {
FD fd;
--- a/jdk/src/share/native/sun/font/sunFont.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/native/sun/font/sunFont.c Wed Jul 05 19:09:26 2017 +0200
@@ -71,13 +71,17 @@
void initLCDGammaTables();
/* placeholder for extern variable */
+static int initialisedFontIDs = 0;
FontManagerNativeIDs sunFontIDs;
-JNIEXPORT void JNICALL
-Java_sun_font_SunFontManager_initIDs
- (JNIEnv *env, jclass cls) {
+static void initFontIDs(JNIEnv *env) {
+
+ jclass tmpClass;
- jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont");
+ if (initialisedFontIDs) {
+ return;
+ }
+ tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont");
sunFontIDs.ttReadBlockMID =
(*env)->GetMethodID(env, tmpClass, "readBlock",
"(Ljava/nio/ByteBuffer;II)I");
@@ -173,9 +177,20 @@
(*env)->GetFieldID(env, tmpClass, "lcdSubPixPos", "Z");
initLCDGammaTables();
+
+ initialisedFontIDs = 1;
}
-JNIEXPORT FontManagerNativeIDs getSunFontIDs() {
+JNIEXPORT void JNICALL
+Java_sun_font_SunFontManager_initIDs
+ (JNIEnv *env, jclass cls) {
+
+ initFontIDs(env);
+}
+
+JNIEXPORT FontManagerNativeIDs getSunFontIDs(JNIEnv *env) {
+
+ initFontIDs(env);
return sunFontIDs;
}
--- a/jdk/src/share/native/sun/font/sunfontids.h Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/native/sun/font/sunfontids.h Wed Jul 05 19:09:26 2017 +0200
@@ -84,7 +84,7 @@
/* Note: we share variable in the context of fontmanager lib
but we need access method to use it from separate rasterizer lib */
extern FontManagerNativeIDs sunFontIDs;
-JNIEXPORT FontManagerNativeIDs getSunFontIDs();
+JNIEXPORT FontManagerNativeIDs getSunFontIDs(JNIEnv* env);
#ifdef __cplusplus
}
--- a/jdk/src/share/native/sun/security/krb5/nativeccache.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/share/native/sun/security/krb5/nativeccache.c Wed Jul 05 19:09:26 2017 +0200
@@ -264,13 +264,21 @@
}
+int isIn(krb5_enctype e, int n, jint* etypes)
+{
+ int i;
+ for (i=0; i<n; i++) {
+ if (e == etypes[i]) return 1;
+ }
+ return 0;
+}
/*
* Class: sun_security_krb5_Credentials
* Method: acquireDefaultNativeCreds
- * Signature: ()Lsun/security/krb5/Credentials;
+ * Signature: ([I])Lsun/security/krb5/Credentials;
*/
JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds
-(JNIEnv *env, jclass krbcredsClass)
+(JNIEnv *env, jclass krbcredsClass, jintArray jetypes)
{
jobject krbCreds = NULL;
krb5_error_code err = 0;
@@ -280,6 +288,9 @@
krb5_flags flags = 0;
krb5_context kcontext = NULL;
+ int netypes;
+ jint *etypes = NULL;
+
/* Initialize the Kerberos 5 context */
err = krb5_init_context (&kcontext);
@@ -295,6 +306,9 @@
err = krb5_cc_start_seq_get (kcontext, ccache, &cursor);
}
+ netypes = (*env)->GetArrayLength(env, jetypes);
+ etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL);
+
if (!err) {
while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) {
char *serverName = NULL;
@@ -305,7 +319,8 @@
}
if (!err) {
- if (strncmp (serverName, "krbtgt", strlen("krbtgt")) == 0) {
+ if (strncmp (serverName, "krbtgt", sizeof("krbtgt")-1) == 0 &&
+ isIn(creds.keyblock.enctype, netypes, etypes)) {
jobject ticket, clientPrincipal, targetPrincipal, encryptionKey;
jobject ticketFlags, startTime, endTime;
jobject authTime, renewTillTime, hostAddresses;
@@ -321,7 +336,7 @@
targetPrincipal = BuildClientPrincipal(env, kcontext, creds.server);
if (targetPrincipal == NULL) goto cleanup;
- // Build a com.ibm.security.krb5.Ticket
+ // Build a sun/security/krb5/internal/Ticket
ticket = BuildTicket(env, &creds.ticket);
if (ticket == NULL) goto cleanup;
@@ -353,7 +368,7 @@
krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>",
"(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
if (krbcredsConstructor == 0) {
- printf("Couldn't find com.ibm.security.krb5.Credentials constructor\n");
+ printf("Couldn't find sun.security.krb5.internal.Ticket constructor\n");
break;
}
}
@@ -409,6 +424,10 @@
printiferr (err, "while finishing ticket retrieval");
}
+ if (etypes != NULL) {
+ (*env)->ReleaseIntArrayElements(env, jetypes, etypes, 0);
+ }
+
krb5_free_context (kcontext);
return krbCreds;
}
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd Wed Jul 05 19:09:26 2017 +0200
@@ -64,11 +64,59 @@
private /* final */ InputStream stdout;
private /* final */ InputStream stderr;
+ private static enum LaunchMechanism {
+ FORK(1),
+ POSIX_SPAWN(2);
+
+ private int value;
+ LaunchMechanism(int x) {value = x;}
+ };
+
+ /* On BSD, the default is to spawn */
+ private static final LaunchMechanism launchMechanism;
+ private static byte[] helperpath;
+
+ private static byte[] toCString(String s) {
+ if (s == null)
+ return null;
+ byte[] bytes = s.getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length-1] = (byte)0;
+ return result;
+ }
+
+ static {
+ launchMechanism = AccessController.doPrivileged(
+ new PrivilegedAction<LaunchMechanism>()
+ {
+ public LaunchMechanism run() {
+ String javahome = System.getProperty("java.home");
+
+ helperpath = toCString(javahome + "/lib/jspawnhelper");
+ String s = System.getProperty(
+ "jdk.lang.Process.launchMechanism", "posix_spawn");
+
+ try {
+ return LaunchMechanism.valueOf(s.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new Error(s + " is not a supported " +
+ "process launch mechanism on this platform.");
+ }
+ }
+ });
+ }
+
/* this is for the reaping thread */
private native int waitForProcessExit(int pid);
/**
- * Create a process using fork(2) and exec(2).
+ * Create a process. Depending on the mode flag, this is done by
+ * one of the following mechanisms.
+ * - fork(2) and exec(2)
+ * - posix_spawn(2)
*
* @param fds an array of three file descriptors.
* Indexes 0, 1, and 2 correspond to standard input,
@@ -81,7 +129,8 @@
* output.
* @return the pid of the subprocess
*/
- private native int forkAndExec(byte[] prog,
+ private native int forkAndExec(int mode, byte[] helperpath,
+ byte[] prog,
byte[] argBlock, int argc,
byte[] envBlock, int envc,
byte[] dir,
@@ -133,7 +182,9 @@
final boolean redirectErrorStream)
throws IOException {
- pid = forkAndExec(prog,
+ pid = forkAndExec(launchMechanism.value,
+ helperpath,
+ prog,
argBlock, argc,
envBlock, envc,
dir,
@@ -212,13 +263,13 @@
}
return exitcode;
}
-
+
@Override
- public synchronized boolean waitFor(long timeout, TimeUnit unit)
- throws InterruptedException
+ public synchronized boolean waitFor(long timeout, TimeUnit unit)
+ throws InterruptedException
{
if (hasExited) return true;
- if (timeout <= 0) return false;
+ if (timeout <= 0) return false;
long timeoutAsNanos = unit.toNanos(timeout);
long startTime = System.nanoTime();
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux Wed Jul 05 19:09:26 2017 +0200
@@ -64,11 +64,61 @@
private /* final */ InputStream stdout;
private /* final */ InputStream stderr;
+ private static enum LaunchMechanism {
+ FORK(1),
+ VFORK(3);
+
+ private int value;
+ LaunchMechanism(int x) {value = x;}
+ };
+
+ /* default is VFORK on Linux */
+ private static final LaunchMechanism launchMechanism;
+ private static byte[] helperpath;
+
+ private static byte[] toCString(String s) {
+ if (s == null)
+ return null;
+ byte[] bytes = s.getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length-1] = (byte)0;
+ return result;
+ }
+
+ static {
+ launchMechanism = AccessController.doPrivileged(
+ new PrivilegedAction<LaunchMechanism>()
+ {
+ public LaunchMechanism run() {
+ String javahome = System.getProperty("java.home");
+ String osArch = System.getProperty("os.arch");
+
+ helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
+ String s = System.getProperty(
+ "jdk.lang.Process.launchMechanism", "vfork");
+
+ try {
+ return LaunchMechanism.valueOf(s.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new Error(s + " is not a supported " +
+ "process launch mechanism on this platform.");
+ }
+ }
+ });
+ }
+
/* this is for the reaping thread */
private native int waitForProcessExit(int pid);
/**
- * Create a process using fork(2) and exec(2).
+ * Create a process. Depending on the mode flag, this is done by
+ * one of the following mechanisms.
+ * - fork(2) and exec(2)
+ * - clone(2) and exec(2)
+ * - vfork(2) and exec(2)
*
* @param fds an array of three file descriptors.
* Indexes 0, 1, and 2 correspond to standard input,
@@ -81,7 +131,8 @@
* output.
* @return the pid of the subprocess
*/
- private native int forkAndExec(byte[] prog,
+ private native int forkAndExec(int mode, byte[] helperpath,
+ byte[] prog,
byte[] argBlock, int argc,
byte[] envBlock, int envc,
byte[] dir,
@@ -133,7 +184,9 @@
final boolean redirectErrorStream)
throws IOException {
- pid = forkAndExec(prog,
+ pid = forkAndExec(launchMechanism.value,
+ helperpath,
+ prog,
argBlock, argc,
envBlock, envc,
dir,
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris Wed Jul 05 19:09:26 2017 +0200
@@ -27,6 +27,8 @@
import java.io.*;
import java.util.concurrent.TimeUnit;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/* java.lang.Process subclass in the UNIX environment.
*
@@ -46,11 +48,65 @@
private DeferredCloseInputStream stdout_inner_stream;
private InputStream stderr_stream;
+ private static enum LaunchMechanism {
+ FORK(1),
+ POSIX_SPAWN(2);
+
+ private int value;
+ LaunchMechanism(int x) {value = x;}
+ };
+
+ /* On Solaris, the default is to spawn */
+ private static final LaunchMechanism launchMechanism;
+ private static byte[] helperpath;
+
+ private static byte[] toCString(String s) {
+ if (s == null)
+ return null;
+ byte[] bytes = s.getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length-1] = (byte)0;
+ return result;
+ }
+
+ static {
+ launchMechanism = AccessController.doPrivileged(
+ new PrivilegedAction<LaunchMechanism>()
+ {
+ public LaunchMechanism run() {
+ String javahome = System.getProperty("java.home");
+ String osArch = System.getProperty("os.arch");
+ if (osArch.equals("x86")) {
+ osArch = "i386";
+ } else if (osArch.equals("x86_64")) {
+ osArch = "amd64";
+ }
+
+ helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
+ String s = System.getProperty(
+ "jdk.lang.Process.launchMechanism", "posix_spawn");
+
+ try {
+ return LaunchMechanism.valueOf(s.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new Error(s + " is not a supported " +
+ "process launch mechanism on this platform.");
+ }
+ }
+ });
+ }
+
/* this is for the reaping thread */
private native int waitForProcessExit(int pid);
/**
- * Create a process using fork(2) and exec(2).
+ * Create a process. Depending on the mode flag, this is done by
+ * one of the following mechanisms.
+ * - fork(2) and exec(2)
+ * - posix_spawn(2)
*
* @param std_fds array of file descriptors. Indexes 0, 1, and
* 2 correspond to standard input, standard output and
@@ -62,7 +118,8 @@
* if and only if it is <em>not</em> -1 on output.
* @return the pid of the subprocess
*/
- private native int forkAndExec(byte[] prog,
+ private native int forkAndExec(int mode, byte[] helperpath,
+ byte[] prog,
byte[] argBlock, int argc,
byte[] envBlock, int envc,
byte[] dir,
@@ -77,7 +134,9 @@
final int[] std_fds,
final boolean redirectErrorStream)
throws IOException {
- pid = forkAndExec(prog,
+ pid = forkAndExec(launchMechanism.value,
+ helperpath,
+ prog,
argBlock, argc,
envBlock, envc,
dir,
--- a/jdk/src/solaris/classes/sun/print/AttributeClass.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/classes/sun/print/AttributeClass.java Wed Jul 05 19:09:26 2017 +0200
@@ -24,6 +24,7 @@
*/
package sun.print;
+import java.util.Objects;
import java.io.ByteArrayInputStream;
public class AttributeClass {
@@ -248,11 +249,24 @@
return myName;
}
+ @Override
public boolean equals(Object obj) {
- return
- obj != null &&
- obj instanceof AttributeClass &&
- obj.toString().equals (((AttributeClass) obj).toString());
+ if (!(obj instanceof AttributeClass)) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ AttributeClass acObj = (AttributeClass) obj;
+ return myType == acObj.getType() &&
+ Objects.equals(myName, acObj.getName()) &&
+ Objects.equals(myValue, acObj.getObjectValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(myType, myName, myValue);
}
public String toString() {
--- a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Wed Jul 05 19:09:26 2017 +0200
@@ -245,7 +245,7 @@
continue;
}
if ((defaultPrintService != null)
- && printers[p].equals(defaultPrintService.getName())) {
+ && printers[p].equals(getPrinterDestName(defaultPrintService))) {
printerList.add(defaultPrintService);
defaultIndex = printerList.size() - 1;
} else {
@@ -270,11 +270,12 @@
} else {
int j;
for (j=0; j<printServices.length; j++) {
- if ((printServices[j] != null) &&
- (printers[p].equals(printServices[j].getName()))) {
- printerList.add(printServices[j]);
- printServices[j] = null;
- break;
+ if (printServices[j] != null) {
+ if (printers[p].equals(getPrinterDestName(printServices[j]))) {
+ printerList.add(printServices[j]);
+ printServices[j] = null;
+ break;
+ }
}
}
@@ -360,6 +361,17 @@
return true;
}
+ /*
+ * Gets the printer name compatible with the list of printers returned by
+ * the system when we query default or all the available printers.
+ */
+ private String getPrinterDestName(PrintService ps) {
+ if (isMac()) {
+ return ((IPPPrintService)ps).getDest();
+ }
+ return ps.getName();
+ }
+
/* On a network with many (hundreds) of network printers, it
* can save several seconds if you know all you want is a particular
* printer, to ask for that printer rather than retrieving all printers.
@@ -369,10 +381,12 @@
if (name == null || name.equals("") || !checkPrinterName(name)) {
return null;
}
- /* check is all printers are already available */
+ /* check if all printers are already available */
if (printServices != null) {
for (PrintService printService : printServices) {
- if (printService.getName().equals(name)) {
+ PrinterName printerName =
+ (PrinterName)printService.getAttribute(PrinterName.class);
+ if (printerName.getValue().equals(name)) {
return printService;
}
}
@@ -567,7 +581,7 @@
defaultPrintService = null;
if (printServices != null) {
for (int j=0; j<printServices.length; j++) {
- if (defaultPrinter.equals(printServices[j].getName())) {
+ if (defaultPrinter.equals(getPrinterDestName(printServices[j]))) {
defaultPrintService = printServices[j];
break;
}
--- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c Wed Jul 05 19:09:26 2017 +0200
@@ -43,32 +43,15 @@
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
-#include <errno.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
-#ifdef __APPLE__
-#include <crt_externs.h>
-#define environ (*_NSGetEnviron())
-#else
-/* This is one of the rare times it's more portable to declare an
- * external symbol explicitly, rather than via a system header.
- * The declaration is standardized as part of UNIX98, but there is
- * no standard (not even de-facto) header file where the
- * declaration is to be found. See:
- * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
- * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
- *
- * "All identifiers in this volume of IEEE Std 1003.1-2001, except
- * environ, are defined in at least one of the headers" (!)
- */
-extern char **environ;
+#if defined(__solaris__) || defined(_ALLBSD_SOURCE)
+#include <spawn.h>
#endif
+#include "childproc.h"
+
/*
- * There are 3 possible strategies we might use to "fork":
+ * There are 4 possible strategies we might use to "fork":
*
* - fork(2). Very portable and reliable but subject to
* failure due to overcommit (see the documentation on
@@ -103,68 +86,21 @@
* http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311
* but the glibc maintainers closed it as WONTFIX.
*
+ * - posix_spawn(). While posix_spawn() is a fairly elaborate and
+ * complicated system call, it can't quite do everything that the old
+ * fork()/exec() combination can do, so the only feasible way to do
+ * this, is to use posix_spawn to launch a new helper executable
+ * "jprochelper", which in turn execs the target (after cleaning
+ * up file-descriptors etc.) The end result is the same as before,
+ * a child process linked to the parent in the same way, but it
+ * avoids the problem of duplicating the parent (VM) process
+ * address space temporarily, before launching the target command.
+ *
* Based on the above analysis, we are currently using vfork() on
- * Linux and fork() on other Unix systems, but the code to use clone()
- * remains.
+ * Linux and spawn() on other Unix systems, but the code to use clone()
+ * and fork() remains.
*/
-#define START_CHILD_USE_CLONE 0 /* clone() currently disabled; see above. */
-
-#ifndef START_CHILD_USE_CLONE
- #ifdef __linux__
- #define START_CHILD_USE_CLONE 1
- #else
- #define START_CHILD_USE_CLONE 0
- #endif
-#endif
-
-/* By default, use vfork() on Linux. */
-#ifndef START_CHILD_USE_VFORK
- #ifdef __linux__
- #define START_CHILD_USE_VFORK 1
- #else
- #define START_CHILD_USE_VFORK 0
- #endif
-#endif
-
-#if START_CHILD_USE_CLONE
-#include <sched.h>
-#define START_CHILD_SYSTEM_CALL "clone"
-#elif START_CHILD_USE_VFORK
-#define START_CHILD_SYSTEM_CALL "vfork"
-#else
-#define START_CHILD_SYSTEM_CALL "fork"
-#endif
-
-#ifndef STDIN_FILENO
-#define STDIN_FILENO 0
-#endif
-
-#ifndef STDOUT_FILENO
-#define STDOUT_FILENO 1
-#endif
-
-#ifndef STDERR_FILENO
-#define STDERR_FILENO 2
-#endif
-
-#ifndef SA_NOCLDSTOP
-#define SA_NOCLDSTOP 0
-#endif
-
-#ifndef SA_RESTART
-#define SA_RESTART 0
-#endif
-
-#define FAIL_FILENO (STDERR_FILENO + 1)
-
-/* TODO: Refactor. */
-#define RESTARTABLE(_cmd, _result) do { \
- do { \
- _result = _cmd; \
- } while((_result == -1) && (errno == EINTR)); \
-} while(0)
-
static void
setSIGCHLDHandler(JNIEnv *env)
@@ -266,17 +202,10 @@
return pathv;
}
-/**
- * The cached and split version of the JDK's effective PATH.
- * (We don't support putenv("PATH=...") in native code)
- */
-static const char * const *parentPathv;
-
JNIEXPORT void JNICALL
Java_java_lang_UNIXProcess_init(JNIEnv *env, jclass clazz)
{
parentPathv = effectivePathv(env);
-
setSIGCHLDHandler(env);
}
@@ -343,96 +272,6 @@
}
}
-static ssize_t
-restartableWrite(int fd, const void *buf, size_t count)
-{
- ssize_t result;
- RESTARTABLE(write(fd, buf, count), result);
- return result;
-}
-
-static int
-restartableDup2(int fd_from, int fd_to)
-{
- int err;
- RESTARTABLE(dup2(fd_from, fd_to), err);
- return err;
-}
-
-static int
-restartableClose(int fd)
-{
- int err;
- RESTARTABLE(close(fd), err);
- return err;
-}
-
-static int
-closeSafely(int fd)
-{
- return (fd == -1) ? 0 : restartableClose(fd);
-}
-
-static int
-isAsciiDigit(char c)
-{
- return c >= '0' && c <= '9';
-}
-
-#ifdef _ALLBSD_SOURCE
-#define FD_DIR "/dev/fd"
-#define dirent64 dirent
-#define readdir64 readdir
-#else
-#define FD_DIR "/proc/self/fd"
-#endif
-
-static int
-closeDescriptors(void)
-{
- DIR *dp;
- struct dirent64 *dirp;
- int from_fd = FAIL_FILENO + 1;
-
- /* We're trying to close all file descriptors, but opendir() might
- * itself be implemented using a file descriptor, and we certainly
- * don't want to close that while it's in use. We assume that if
- * opendir() is implemented using a file descriptor, then it uses
- * the lowest numbered file descriptor, just like open(). So we
- * close a couple explicitly. */
-
- restartableClose(from_fd); /* for possible use by opendir() */
- restartableClose(from_fd + 1); /* another one for good luck */
-
- if ((dp = opendir(FD_DIR)) == NULL)
- return 0;
-
- /* We use readdir64 instead of readdir to work around Solaris bug
- * 6395699: /proc/self/fd fails to report file descriptors >= 1024 on Solaris 9
- */
- while ((dirp = readdir64(dp)) != NULL) {
- int fd;
- if (isAsciiDigit(dirp->d_name[0]) &&
- (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2)
- restartableClose(fd);
- }
-
- closedir(dp);
-
- return 1;
-}
-
-static int
-moveDescriptor(int fd_from, int fd_to)
-{
- if (fd_from != fd_to) {
- if ((restartableDup2(fd_from, fd_to) == -1) ||
- (restartableClose(fd_from) == -1))
- return -1;
- }
- return 0;
-}
-
static const char *
getBytes(JNIEnv *env, jbyteArray arr)
{
@@ -448,19 +287,6 @@
}
static void
-initVectorFromBlock(const char**vector, const char* block, int count)
-{
- int i;
- const char *p;
- for (i = 0, p = block; i < count; i++) {
- /* Invariant: p always points to the start of a C string. */
- vector[i] = p;
- while (*(p++));
- }
- vector[count] = NULL;
-}
-
-static void
throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
{
static const char * const format = "error=%d, %s";
@@ -503,182 +329,6 @@
}
#endif /* DEBUG_PROCESS */
-/**
- * Exec FILE as a traditional Bourne shell script (i.e. one without #!).
- * If we could do it over again, we would probably not support such an ancient
- * misfeature, but compatibility wins over sanity. The original support for
- * this was imported accidentally from execvp().
- */
-static void
-execve_as_traditional_shell_script(const char *file,
- const char *argv[],
- const char *const envp[])
-{
- /* Use the extra word of space provided for us in argv by caller. */
- const char *argv0 = argv[0];
- const char *const *end = argv;
- while (*end != NULL)
- ++end;
- memmove(argv+2, argv+1, (end-argv) * sizeof (*end));
- argv[0] = "/bin/sh";
- argv[1] = file;
- execve(argv[0], (char **) argv, (char **) envp);
- /* Can't even exec /bin/sh? Big trouble, but let's soldier on... */
- memmove(argv+1, argv+2, (end-argv) * sizeof (*end));
- argv[0] = argv0;
-}
-
-/**
- * Like execve(2), except that in case of ENOEXEC, FILE is assumed to
- * be a shell script and the system default shell is invoked to run it.
- */
-static void
-execve_with_shell_fallback(const char *file,
- const char *argv[],
- const char *const envp[])
-{
-#if START_CHILD_USE_CLONE || START_CHILD_USE_VFORK
- /* shared address space; be very careful. */
- execve(file, (char **) argv, (char **) envp);
- if (errno == ENOEXEC)
- execve_as_traditional_shell_script(file, argv, envp);
-#else
- /* unshared address space; we can mutate environ. */
- environ = (char **) envp;
- execvp(file, (char **) argv);
-#endif
-}
-
-/**
- * 'execvpe' should have been included in the Unix standards,
- * and is a GNU extension in glibc 2.10.
- *
- * JDK_execvpe is identical to execvp, except that the child environment is
- * specified via the 3rd argument instead of being inherited from environ.
- */
-static void
-JDK_execvpe(const char *file,
- const char *argv[],
- const char *const envp[])
-{
- if (envp == NULL || (char **) envp == environ) {
- execvp(file, (char **) argv);
- return;
- }
-
- if (*file == '\0') {
- errno = ENOENT;
- return;
- }
-
- if (strchr(file, '/') != NULL) {
- execve_with_shell_fallback(file, argv, envp);
- } else {
- /* We must search PATH (parent's, not child's) */
- char expanded_file[PATH_MAX];
- int filelen = strlen(file);
- int sticky_errno = 0;
- const char * const * dirs;
- for (dirs = parentPathv; *dirs; dirs++) {
- const char * dir = *dirs;
- int dirlen = strlen(dir);
- if (filelen + dirlen + 2 >= PATH_MAX) {
- errno = ENAMETOOLONG;
- continue;
- }
- memcpy(expanded_file, dir, dirlen);
- if (expanded_file[dirlen - 1] != '/')
- expanded_file[dirlen++] = '/';
- memcpy(expanded_file + dirlen, file, filelen);
- expanded_file[dirlen + filelen] = '\0';
- execve_with_shell_fallback(expanded_file, argv, envp);
- /* There are 3 responses to various classes of errno:
- * return immediately, continue (especially for ENOENT),
- * or continue with "sticky" errno.
- *
- * From exec(3):
- *
- * If permission is denied for a file (the attempted
- * execve returned EACCES), these functions will continue
- * searching the rest of the search path. If no other
- * file is found, however, they will return with the
- * global variable errno set to EACCES.
- */
- switch (errno) {
- case EACCES:
- sticky_errno = errno;
- /* FALLTHRU */
- case ENOENT:
- case ENOTDIR:
-#ifdef ELOOP
- case ELOOP:
-#endif
-#ifdef ESTALE
- case ESTALE:
-#endif
-#ifdef ENODEV
- case ENODEV:
-#endif
-#ifdef ETIMEDOUT
- case ETIMEDOUT:
-#endif
- break; /* Try other directories in PATH */
- default:
- return;
- }
- }
- if (sticky_errno != 0)
- errno = sticky_errno;
- }
-}
-
-/*
- * Reads nbyte bytes from file descriptor fd into buf,
- * The read operation is retried in case of EINTR or partial reads.
- *
- * Returns number of bytes read (normally nbyte, but may be less in
- * case of EOF). In case of read errors, returns -1 and sets errno.
- */
-static ssize_t
-readFully(int fd, void *buf, size_t nbyte)
-{
- ssize_t remaining = nbyte;
- for (;;) {
- ssize_t n = read(fd, buf, remaining);
- if (n == 0) {
- return nbyte - remaining;
- } else if (n > 0) {
- remaining -= n;
- if (remaining <= 0)
- return nbyte;
- /* We were interrupted in the middle of reading the bytes.
- * Unlikely, but possible. */
- buf = (void *) (((char *)buf) + n);
- } else if (errno == EINTR) {
- /* Strange signals like SIGJVM1 are possible at any time.
- * See http://www.dreamsongs.com/WorseIsBetter.html */
- } else {
- return -1;
- }
- }
-}
-
-typedef struct _ChildStuff
-{
- int in[2];
- int out[2];
- int err[2];
- int fail[2];
- int fds[3];
- const char **argv;
- const char **envv;
- const char *pdir;
- jboolean redirectErrorStream;
-#if START_CHILD_USE_CLONE
- void *clone_stack;
-#endif
-} ChildStuff;
-
static void
copyPipe(int from[2], int to[2])
{
@@ -686,97 +336,67 @@
to[1] = from[1];
}
-/**
- * Child process after a successful fork() or clone().
- * This function must not return, and must be prepared for either all
- * of its address space to be shared with its parent, or to be a copy.
- * It must not modify global variables such as "environ".
+/* arg is an array of pointers to 0 terminated strings. array is terminated
+ * by a null element.
+ *
+ * *nelems and *nbytes receive the number of elements of array (incl 0)
+ * and total number of bytes (incl. 0)
+ * Note. An empty array will have one null element
+ * But if arg is null, then *nelems set to 0, and *nbytes to 0
*/
-static int
-childProcess(void *arg)
+static void arraysize(const char * const *arg, int *nelems, int *nbytes)
{
- const ChildStuff* p = (const ChildStuff*) arg;
-
- /* Close the parent sides of the pipes.
- Closing pipe fds here is redundant, since closeDescriptors()
- would do it anyways, but a little paranoia is a good thing. */
- if ((closeSafely(p->in[1]) == -1) ||
- (closeSafely(p->out[0]) == -1) ||
- (closeSafely(p->err[0]) == -1) ||
- (closeSafely(p->fail[0]) == -1))
- goto WhyCantJohnnyExec;
-
- /* Give the child sides of the pipes the right fileno's. */
- /* Note: it is possible for in[0] == 0 */
- if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0],
- STDIN_FILENO) == -1) ||
- (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1],
- STDOUT_FILENO) == -1))
- goto WhyCantJohnnyExec;
-
- if (p->redirectErrorStream) {
- if ((closeSafely(p->err[1]) == -1) ||
- (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1))
- goto WhyCantJohnnyExec;
- } else {
- if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2],
- STDERR_FILENO) == -1)
- goto WhyCantJohnnyExec;
+ int i, bytes, count;
+ const char * const *a = arg;
+ char *p;
+ int *q;
+ if (arg == 0) {
+ *nelems = 0;
+ *nbytes = 0;
+ return;
}
+ /* count the array elements and number of bytes */
+ for (count=0, bytes=0; *a != 0; count++, a++) {
+ bytes += strlen(*a)+1;
+ }
+ *nbytes = bytes;
+ *nelems = count+1;
+}
- if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1)
- goto WhyCantJohnnyExec;
-
- /* close everything */
- if (closeDescriptors() == 0) { /* failed, close the old way */
- int max_fd = (int)sysconf(_SC_OPEN_MAX);
- int fd;
- for (fd = FAIL_FILENO + 1; fd < max_fd; fd++)
- if (restartableClose(fd) == -1 && errno != EBADF)
- goto WhyCantJohnnyExec;
- }
-
- /* change to the new working directory */
- if (p->pdir != NULL && chdir(p->pdir) < 0)
- goto WhyCantJohnnyExec;
-
- if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1)
- goto WhyCantJohnnyExec;
+/* copy the strings from arg[] into buf, starting at given offset
+ * return new offset to next free byte
+ */
+static int copystrings(char *buf, int offset, const char * const *arg) {
+ char *p;
+ const char * const *a;
+ int count=0;
- JDK_execvpe(p->argv[0], p->argv, p->envv);
-
- WhyCantJohnnyExec:
- /* We used to go to an awful lot of trouble to predict whether the
- * child would fail, but there is no reliable way to predict the
- * success of an operation without *trying* it, and there's no way
- * to try a chdir or exec in the parent. Instead, all we need is a
- * way to communicate any failure back to the parent. Easy; we just
- * send the errno back to the parent over a pipe in case of failure.
- * The tricky thing is, how do we communicate the *success* of exec?
- * We use FD_CLOEXEC together with the fact that a read() on a pipe
- * yields EOF when the write ends (we have two of them!) are closed.
- */
- {
- int errnum = errno;
- restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum));
+ if (arg == 0) {
+ return offset;
}
- restartableClose(FAIL_FILENO);
- _exit(-1);
- return 0; /* Suppress warning "no return value from function" */
+ for (p=buf+offset, a=arg; *a != 0; a++) {
+ int len = strlen(*a) +1;
+ memcpy(p, *a, len);
+ p += len;
+ count += len;
+ }
+ return offset+count;
}
/**
- * Start a child process running function childProcess.
- * This function only returns in the parent.
* We are unusually paranoid; use of clone/vfork is
* especially likely to tickle gcc/glibc bugs.
*/
#ifdef __attribute_noinline__ /* See: sys/cdefs.h */
__attribute_noinline__
#endif
+
+#define START_CHILD_USE_CLONE 0 /* clone() currently disabled; see above. */
+
+#ifdef START_CHILD_USE_CLONE
static pid_t
-startChild(ChildStuff *c) {
-#if START_CHILD_USE_CLONE
+cloneChild(ChildStuff *c) {
+#ifdef __linux__
#define START_CHILD_CLONE_STACK_SIZE (64 * 1024)
/*
* See clone(2).
@@ -790,33 +410,161 @@
c->clone_stack + START_CHILD_CLONE_STACK_SIZE,
CLONE_VFORK | CLONE_VM | SIGCHLD, c);
#else
- #if START_CHILD_USE_VFORK
+/* not available on Solaris / Mac */
+ assert(0);
+ return -1;
+#endif
+}
+#endif
+
+static pid_t
+vforkChild(ChildStuff *c) {
+ volatile pid_t resultPid;
+
/*
* We separate the call to vfork into a separate function to make
* very sure to keep stack of child from corrupting stack of parent,
* as suggested by the scary gcc warning:
* warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork'
*/
- volatile pid_t resultPid = vfork();
- #else
+ resultPid = vfork();
+
+ if (resultPid == 0) {
+ childProcess(c);
+ }
+ assert(resultPid != 0); /* childProcess never returns */
+ return resultPid;
+}
+
+static pid_t
+forkChild(ChildStuff *c) {
+ pid_t resultPid;
+
/*
* From Solaris fork(2): In Solaris 10, a call to fork() is
* identical to a call to fork1(); only the calling thread is
* replicated in the child process. This is the POSIX-specified
* behavior for fork().
*/
- pid_t resultPid = fork();
- #endif
- if (resultPid == 0)
+ resultPid = fork();
+
+ if (resultPid == 0) {
childProcess(c);
+ }
assert(resultPid != 0); /* childProcess never returns */
return resultPid;
-#endif /* ! START_CHILD_USE_CLONE */
+}
+
+#if defined(__solaris__) || defined(_ALLBSD_SOURCE)
+static pid_t
+spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
+ pid_t resultPid;
+ jboolean isCopy;
+ int i, offset, rval, bufsize, magic;
+ char *buf, buf1[16];
+ char *hlpargs[2];
+ SpawnInfo sp;
+
+ /* need to tell helper which fd is for receiving the childstuff
+ * and which fd to send response back on
+ */
+ snprintf(buf1, sizeof(buf1), "%d:%d", c->childenv[0], c->fail[1]);
+ /* put the fd string as argument to the helper cmd */
+ hlpargs[0] = buf1;
+ hlpargs[1] = 0;
+
+ /* Following items are sent down the pipe to the helper
+ * after it is spawned.
+ * All strings are null terminated. All arrays of strings
+ * have an empty string for termination.
+ * - the ChildStuff struct
+ * - the SpawnInfo struct
+ * - the argv strings array
+ * - the envv strings array
+ * - the home directory string
+ * - the parentPath string
+ * - the parentPathv array
+ */
+ /* First calculate the sizes */
+ arraysize(c->argv, &sp.nargv, &sp.argvBytes);
+ bufsize = sp.argvBytes;
+ arraysize(c->envv, &sp.nenvv, &sp.envvBytes);
+ bufsize += sp.envvBytes;
+ sp.dirlen = c->pdir == 0 ? 0 : strlen(c->pdir)+1;
+ bufsize += sp.dirlen;
+ arraysize(parentPathv, &sp.nparentPathv, &sp.parentPathvBytes);
+ bufsize += sp.parentPathvBytes;
+ /* We need to clear FD_CLOEXEC if set in the fds[].
+ * Files are created FD_CLOEXEC in Java.
+ * Otherwise, they will be closed when the target gets exec'd */
+ for (i=0; i<3; i++) {
+ if (c->fds[i] != -1) {
+ int flags = fcntl(c->fds[i], F_GETFD);
+ if (flags & FD_CLOEXEC) {
+ fcntl(c->fds[i], F_SETFD, flags & (~1));
+ }
+ }
+ }
+
+ rval = posix_spawn(&resultPid, helperpath, 0, 0, (char * const *) hlpargs, environ);
+
+ if (rval != 0) {
+ return -1;
+ }
+
+ /* now the lengths are known, copy the data */
+ buf = NEW(char, bufsize);
+ if (buf == 0) {
+ return -1;
+ }
+ offset = copystrings(buf, 0, &c->argv[0]);
+ offset = copystrings(buf, offset, &c->envv[0]);
+ memcpy(buf+offset, c->pdir, sp.dirlen);
+ offset += sp.dirlen;
+ offset = copystrings(buf, offset, parentPathv);
+ assert(offset == bufsize);
+
+ magic = magicNumber();
+
+ /* write the two structs and the data buffer */
+ write(c->childenv[1], (char *)&magic, sizeof(magic)); // magic number first
+ write(c->childenv[1], (char *)c, sizeof(*c));
+ write(c->childenv[1], (char *)&sp, sizeof(sp));
+ write(c->childenv[1], buf, bufsize);
+ free(buf);
+
+ /* In this mode an external main() in invoked which calls back into
+ * childProcess() in this file, rather than directly
+ * via the statement below */
+ return resultPid;
+}
+#endif
+
+/*
+ * Start a child process running function childProcess.
+ * This function only returns in the parent.
+ */
+static pid_t
+startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
+ switch (c->mode) {
+ case MODE_VFORK:
+ return vforkChild(c);
+ case MODE_FORK:
+ return forkChild(c);
+#if defined(__solaris__) || defined(_ALLBSD_SOURCE)
+ case MODE_POSIX_SPAWN:
+ return spawnChild(env, process, c, helperpath);
+#endif
+ default:
+ return -1;
+ }
}
JNIEXPORT jint JNICALL
Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
jobject process,
+ jint mode,
+ jbyteArray helperpath,
jbyteArray prog,
jbyteArray argBlock, jint argc,
jbyteArray envBlock, jint envc,
@@ -826,32 +574,35 @@
{
int errnum;
int resultPid = -1;
- int in[2], out[2], err[2], fail[2];
+ int in[2], out[2], err[2], fail[2], childenv[2];
jint *fds = NULL;
+ const char *phelperpath = NULL;
const char *pprog = NULL;
const char *pargBlock = NULL;
const char *penvBlock = NULL;
ChildStuff *c;
in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1;
+ childenv[0] = childenv[1] = -1;
if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
c->argv = NULL;
c->envv = NULL;
c->pdir = NULL;
-#if START_CHILD_USE_CLONE
c->clone_stack = NULL;
-#endif
/* Convert prog + argBlock into a char ** argv.
* Add one word room for expansion of argv for use by
* execve_as_traditional_shell_script.
+ * This word is also used when using spawn mode
*/
assert(prog != NULL && argBlock != NULL);
+ if ((phelperpath = getBytes(env, helperpath)) == NULL) goto Catch;
if ((pprog = getBytes(env, prog)) == NULL) goto Catch;
if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch;
if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch;
c->argv[0] = pprog;
+ c->argc = argc + 2;
initVectorFromBlock(c->argv+1, pargBlock, argc);
if (envBlock != NULL) {
@@ -872,6 +623,7 @@
if ((fds[0] == -1 && pipe(in) < 0) ||
(fds[1] == -1 && pipe(out) < 0) ||
(fds[2] == -1 && pipe(err) < 0) ||
+ (pipe(childenv) < 0) ||
(pipe(fail) < 0)) {
throwIOException(env, errno, "Bad file descriptor");
goto Catch;
@@ -884,18 +636,29 @@
copyPipe(out, c->out);
copyPipe(err, c->err);
copyPipe(fail, c->fail);
+ copyPipe(childenv, c->childenv);
c->redirectErrorStream = redirectErrorStream;
+ c->mode = mode;
- resultPid = startChild(c);
+ resultPid = startChild(env, process, c, phelperpath);
assert(resultPid != 0);
if (resultPid < 0) {
- throwIOException(env, errno, START_CHILD_SYSTEM_CALL " failed");
+ switch (c->mode) {
+ case MODE_VFORK:
+ throwIOException(env, errno, "vfork failed");
+ break;
+ case MODE_FORK:
+ throwIOException(env, errno, "fork failed");
+ break;
+ case MODE_POSIX_SPAWN:
+ throwIOException(env, errno, "spawn failed");
+ break;
+ }
goto Catch;
}
-
- restartableClose(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */
+ close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec (childproc.c) */
switch (readFully(fail[0], &errnum, sizeof(errnum))) {
case 0: break; /* Exec succeeded */
@@ -913,18 +676,18 @@
fds[2] = (err[0] != -1) ? err[0] : -1;
Finally:
-#if START_CHILD_USE_CLONE
free(c->clone_stack);
-#endif
/* Always clean up the child's side of the pipes */
closeSafely(in [0]);
closeSafely(out[1]);
closeSafely(err[1]);
- /* Always clean up fail descriptors */
+ /* Always clean up fail and childEnv descriptors */
closeSafely(fail[0]);
closeSafely(fail[1]);
+ closeSafely(childenv[0]);
+ closeSafely(childenv[1]);
releaseBytes(env, prog, pprog);
releaseBytes(env, argBlock, pargBlock);
@@ -942,9 +705,9 @@
Catch:
/* Clean up the parent's side of the pipes in case of failure only */
- closeSafely(in [1]);
- closeSafely(out[0]);
- closeSafely(err[0]);
+ closeSafely(in [1]); in[1] = -1;
+ closeSafely(out[0]); out[0] = -1;
+ closeSafely(err[0]); err[0] = -1;
goto Finally;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/java/lang/childproc.c Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include "childproc.h"
+
+
+ssize_t
+restartableWrite(int fd, const void *buf, size_t count)
+{
+ ssize_t result;
+ RESTARTABLE(write(fd, buf, count), result);
+ return result;
+}
+
+int
+restartableDup2(int fd_from, int fd_to)
+{
+ int err;
+ RESTARTABLE(dup2(fd_from, fd_to), err);
+ return err;
+}
+
+int
+closeSafely(int fd)
+{
+ return (fd == -1) ? 0 : close(fd);
+}
+
+int
+isAsciiDigit(char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+#ifdef _ALLBSD_SOURCE
+#define FD_DIR "/dev/fd"
+#define dirent64 dirent
+#define readdir64 readdir
+#else
+#define FD_DIR "/proc/self/fd"
+#endif
+
+int
+closeDescriptors(void)
+{
+ DIR *dp;
+ struct dirent64 *dirp;
+ int from_fd = FAIL_FILENO + 1;
+
+ /* We're trying to close all file descriptors, but opendir() might
+ * itself be implemented using a file descriptor, and we certainly
+ * don't want to close that while it's in use. We assume that if
+ * opendir() is implemented using a file descriptor, then it uses
+ * the lowest numbered file descriptor, just like open(). So we
+ * close a couple explicitly. */
+
+ close(from_fd); /* for possible use by opendir() */
+ close(from_fd + 1); /* another one for good luck */
+
+ if ((dp = opendir(FD_DIR)) == NULL)
+ return 0;
+
+ /* We use readdir64 instead of readdir to work around Solaris bug
+ * 6395699: /proc/self/fd fails to report file descriptors >= 1024 on Solaris 9
+ */
+ while ((dirp = readdir64(dp)) != NULL) {
+ int fd;
+ if (isAsciiDigit(dirp->d_name[0]) &&
+ (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2)
+ close(fd);
+ }
+
+ closedir(dp);
+
+ return 1;
+}
+
+int
+moveDescriptor(int fd_from, int fd_to)
+{
+ if (fd_from != fd_to) {
+ if ((restartableDup2(fd_from, fd_to) == -1) ||
+ (close(fd_from) == -1))
+ return -1;
+ }
+ return 0;
+}
+
+int
+magicNumber() {
+ return 43110;
+}
+
+/*
+ * Reads nbyte bytes from file descriptor fd into buf,
+ * The read operation is retried in case of EINTR or partial reads.
+ *
+ * Returns number of bytes read (normally nbyte, but may be less in
+ * case of EOF). In case of read errors, returns -1 and sets errno.
+ */
+ssize_t
+readFully(int fd, void *buf, size_t nbyte)
+{
+ ssize_t remaining = nbyte;
+ for (;;) {
+ ssize_t n = read(fd, buf, remaining);
+ if (n == 0) {
+ return nbyte - remaining;
+ } else if (n > 0) {
+ remaining -= n;
+ if (remaining <= 0)
+ return nbyte;
+ /* We were interrupted in the middle of reading the bytes.
+ * Unlikely, but possible. */
+ buf = (void *) (((char *)buf) + n);
+ } else if (errno == EINTR) {
+ /* Strange signals like SIGJVM1 are possible at any time.
+ * See http://www.dreamsongs.com/WorseIsBetter.html */
+ } else {
+ return -1;
+ }
+ }
+}
+
+void
+initVectorFromBlock(const char**vector, const char* block, int count)
+{
+ int i;
+ const char *p;
+ for (i = 0, p = block; i < count; i++) {
+ /* Invariant: p always points to the start of a C string. */
+ vector[i] = p;
+ while (*(p++));
+ }
+ vector[count] = NULL;
+}
+
+/**
+ * Exec FILE as a traditional Bourne shell script (i.e. one without #!).
+ * If we could do it over again, we would probably not support such an ancient
+ * misfeature, but compatibility wins over sanity. The original support for
+ * this was imported accidentally from execvp().
+ */
+void
+execve_as_traditional_shell_script(const char *file,
+ const char *argv[],
+ const char *const envp[])
+{
+ /* Use the extra word of space provided for us in argv by caller. */
+ const char *argv0 = argv[0];
+ const char *const *end = argv;
+ while (*end != NULL)
+ ++end;
+ memmove(argv+2, argv+1, (end-argv) * sizeof(*end));
+ argv[0] = "/bin/sh";
+ argv[1] = file;
+ execve(argv[0], (char **) argv, (char **) envp);
+ /* Can't even exec /bin/sh? Big trouble, but let's soldier on... */
+ memmove(argv+1, argv+2, (end-argv) * sizeof(*end));
+ argv[0] = argv0;
+}
+
+/**
+ * Like execve(2), except that in case of ENOEXEC, FILE is assumed to
+ * be a shell script and the system default shell is invoked to run it.
+ */
+void
+execve_with_shell_fallback(int mode, const char *file,
+ const char *argv[],
+ const char *const envp[])
+{
+ if (mode == MODE_CLONE || mode == MODE_VFORK) {
+ /* shared address space; be very careful. */
+ execve(file, (char **) argv, (char **) envp);
+ if (errno == ENOEXEC)
+ execve_as_traditional_shell_script(file, argv, envp);
+ } else {
+ /* unshared address space; we can mutate environ. */
+ environ = (char **) envp;
+ execvp(file, (char **) argv);
+ }
+}
+
+/**
+ * 'execvpe' should have been included in the Unix standards,
+ * and is a GNU extension in glibc 2.10.
+ *
+ * JDK_execvpe is identical to execvp, except that the child environment is
+ * specified via the 3rd argument instead of being inherited from environ.
+ */
+void
+JDK_execvpe(int mode, const char *file,
+ const char *argv[],
+ const char *const envp[])
+{
+ if (envp == NULL || (char **) envp == environ) {
+ execvp(file, (char **) argv);
+ return;
+ }
+
+ if (*file == '\0') {
+ errno = ENOENT;
+ return;
+ }
+
+ if (strchr(file, '/') != NULL) {
+ execve_with_shell_fallback(mode, file, argv, envp);
+ } else {
+ /* We must search PATH (parent's, not child's) */
+ char expanded_file[PATH_MAX];
+ int filelen = strlen(file);
+ int sticky_errno = 0;
+ const char * const * dirs;
+ for (dirs = parentPathv; *dirs; dirs++) {
+ const char * dir = *dirs;
+ int dirlen = strlen(dir);
+ if (filelen + dirlen + 2 >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ memcpy(expanded_file, dir, dirlen);
+ if (expanded_file[dirlen - 1] != '/')
+ expanded_file[dirlen++] = '/';
+ memcpy(expanded_file + dirlen, file, filelen);
+ expanded_file[dirlen + filelen] = '\0';
+ execve_with_shell_fallback(mode, expanded_file, argv, envp);
+ /* There are 3 responses to various classes of errno:
+ * return immediately, continue (especially for ENOENT),
+ * or continue with "sticky" errno.
+ *
+ * From exec(3):
+ *
+ * If permission is denied for a file (the attempted
+ * execve returned EACCES), these functions will continue
+ * searching the rest of the search path. If no other
+ * file is found, however, they will return with the
+ * global variable errno set to EACCES.
+ */
+ switch (errno) {
+ case EACCES:
+ sticky_errno = errno;
+ /* FALLTHRU */
+ case ENOENT:
+ case ENOTDIR:
+#ifdef ELOOP
+ case ELOOP:
+#endif
+#ifdef ESTALE
+ case ESTALE:
+#endif
+#ifdef ENODEV
+ case ENODEV:
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+#endif
+ break; /* Try other directories in PATH */
+ default:
+ return;
+ }
+ }
+ if (sticky_errno != 0)
+ errno = sticky_errno;
+ }
+}
+
+/**
+ * Child process after a successful fork() or clone().
+ * This function must not return, and must be prepared for either all
+ * of its address space to be shared with its parent, or to be a copy.
+ * It must not modify global variables such as "environ".
+ */
+int
+childProcess(void *arg)
+{
+ const ChildStuff* p = (const ChildStuff*) arg;
+
+ /* Close the parent sides of the pipes.
+ Closing pipe fds here is redundant, since closeDescriptors()
+ would do it anyways, but a little paranoia is a good thing. */
+ if ((closeSafely(p->in[1]) == -1) ||
+ (closeSafely(p->out[0]) == -1) ||
+ (closeSafely(p->err[0]) == -1) ||
+ (closeSafely(p->childenv[0]) == -1) ||
+ (closeSafely(p->childenv[1]) == -1) ||
+ (closeSafely(p->fail[0]) == -1))
+ goto WhyCantJohnnyExec;
+
+ /* Give the child sides of the pipes the right fileno's. */
+ /* Note: it is possible for in[0] == 0 */
+ if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0],
+ STDIN_FILENO) == -1) ||
+ (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1],
+ STDOUT_FILENO) == -1))
+ goto WhyCantJohnnyExec;
+
+ if (p->redirectErrorStream) {
+ if ((closeSafely(p->err[1]) == -1) ||
+ (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1))
+ goto WhyCantJohnnyExec;
+ } else {
+ if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2],
+ STDERR_FILENO) == -1)
+ goto WhyCantJohnnyExec;
+ }
+
+ if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1)
+ goto WhyCantJohnnyExec;
+
+ /* close everything */
+ if (closeDescriptors() == 0) { /* failed, close the old way */
+ int max_fd = (int)sysconf(_SC_OPEN_MAX);
+ int fd;
+ for (fd = FAIL_FILENO + 1; fd < max_fd; fd++)
+ if (close(fd) == -1 && errno != EBADF)
+ goto WhyCantJohnnyExec;
+ }
+
+ /* change to the new working directory */
+ if (p->pdir != NULL && chdir(p->pdir) < 0)
+ goto WhyCantJohnnyExec;
+
+ if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1)
+ goto WhyCantJohnnyExec;
+
+ JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv);
+
+ WhyCantJohnnyExec:
+ /* We used to go to an awful lot of trouble to predict whether the
+ * child would fail, but there is no reliable way to predict the
+ * success of an operation without *trying* it, and there's no way
+ * to try a chdir or exec in the parent. Instead, all we need is a
+ * way to communicate any failure back to the parent. Easy; we just
+ * send the errno back to the parent over a pipe in case of failure.
+ * The tricky thing is, how do we communicate the *success* of exec?
+ * We use FD_CLOEXEC together with the fact that a read() on a pipe
+ * yields EOF when the write ends (we have two of them!) are closed.
+ */
+ {
+ int errnum = errno;
+ restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum));
+ }
+ close(FAIL_FILENO);
+ _exit(-1);
+ return 0; /* Suppress warning "no return value from function" */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/java/lang/childproc.h Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#ifndef CHILDPROC_MD_H
+#define CHILDPROC_MD_H
+
+#include <sys/types.h>
+
+#ifdef __APPLE__
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#else
+/* This is one of the rare times it's more portable to declare an
+ * external symbol explicitly, rather than via a system header.
+ * The declaration is standardized as part of UNIX98, but there is
+ * no standard (not even de-facto) header file where the
+ * declaration is to be found. See:
+ * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
+ *
+ * "All identifiers in this volume of IEEE Std 1003.1-2001, except
+ * environ, are defined in at least one of the headers" (!)
+ */
+extern char **environ;
+#endif
+
+#ifdef __linux__
+#include <sched.h>
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef SA_NOCLDSTOP
+#define SA_NOCLDSTOP 0
+#endif
+
+#ifndef SA_RESTART
+#define SA_RESTART 0
+#endif
+
+#define FAIL_FILENO (STDERR_FILENO + 1)
+
+/* TODO: Refactor. */
+#define RESTARTABLE(_cmd, _result) do { \
+ do { \
+ _result = _cmd; \
+ } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
+/* These numbers must be the same as the Enum in UNIXProcess.java
+ * Must be a better way of doing this.
+ */
+#define MODE_FORK 1
+#define MODE_POSIX_SPAWN 2
+#define MODE_VFORK 3
+#define MODE_CLONE 4
+
+typedef struct _ChildStuff
+{
+ int in[2];
+ int out[2];
+ int err[2];
+ int fail[2];
+ int childenv[2];
+ int fds[3];
+ int mode;
+ const char **argv;
+ int argc;
+ const char **envv;
+ const char *pdir;
+ int redirectErrorStream;
+ void *clone_stack;
+} ChildStuff;
+
+/* following used in addition when mode is SPAWN */
+typedef struct _SpawnInfo {
+ int nargv; /* number of argv array elements */
+ int argvBytes; /* total number of bytes in argv array */
+ int nenvv; /* number of envv array elements */
+ int envvBytes; /* total number of bytes in envv array */
+ int dirlen; /* length of home directory string */
+ int nparentPathv; /* number of elements in parentPathv array */
+ int parentPathvBytes; /* total number of bytes in parentPathv array */
+} SpawnInfo;
+
+/**
+ * The cached and split version of the JDK's effective PATH.
+ * (We don't support putenv("PATH=...") in native code)
+ */
+const char * const *parentPathv;
+
+ssize_t restartableWrite(int fd, const void *buf, size_t count);
+int restartableDup2(int fd_from, int fd_to);
+int closeSafely(int fd);
+int isAsciiDigit(char c);
+int closeDescriptors(void);
+int moveDescriptor(int fd_from, int fd_to);
+
+int magicNumber();
+ssize_t readFully(int fd, void *buf, size_t nbyte);
+void initVectorFromBlock(const char**vector, const char* block, int count);
+void execve_as_traditional_shell_script(const char *file,
+ const char *argv[],
+ const char *const envp[]);
+void execve_with_shell_fallback(int mode, const char *file,
+ const char *argv[],
+ const char *const envp[]);
+void JDK_execvpe(int mode, const char *file,
+ const char *argv[],
+ const char *const envp[]);
+int childProcess(void *arg);
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/java/lang/jspawnhelper.c Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "childproc.h"
+
+extern int errno;
+
+#define ALLOC(X,Y) { \
+ void *mptr; \
+ mptr = malloc (Y); \
+ if (mptr == 0) { \
+ error (fdout, ERR_MALLOC); \
+ } \
+ X = mptr; \
+}
+
+#define ERR_MALLOC 1
+#define ERR_PIPE 2
+#define ERR_ARGS 3
+
+void error (int fd, int err) {
+ write (fd, &err, sizeof(err));
+ exit (1);
+}
+
+void shutItDown() {
+ fprintf(stdout, "This command is not for general use and should ");
+ fprintf(stdout, "only be run as the result of a call to\n");
+ fprintf(stdout, "ProcessBuilder.start() or Runtime.exec() in a java ");
+ fprintf(stdout, "application\n");
+ _exit(1);
+}
+
+/*
+ * read the following off the pipefd
+ * - the ChildStuff struct
+ * - the SpawnInfo struct
+ * - the data strings for fields in ChildStuff
+ */
+void initChildStuff (int fdin, int fdout, ChildStuff *c) {
+ int n;
+ int argvBytes, nargv, envvBytes, nenvv;
+ int dirlen;
+ char *buf;
+ SpawnInfo sp;
+ int bufsize, offset=0;
+ int magic;
+ int res;
+
+ res = readFully (fdin, &magic, sizeof(magic));
+ if (res != 4 || magic != magicNumber()) {
+ error (fdout, ERR_PIPE);
+ }
+
+ if (readFully (fdin, c, sizeof(*c)) == -1) {
+ error (fdout, ERR_PIPE);
+ }
+
+ if (readFully (fdin, &sp, sizeof(sp)) == -1) {
+ error (fdout, ERR_PIPE);
+ }
+
+ bufsize = sp.argvBytes + sp.envvBytes +
+ sp.dirlen + sp.parentPathvBytes;
+
+ ALLOC(buf, bufsize);
+
+ if (readFully (fdin, buf, bufsize) == -1) {
+ error (fdout, ERR_PIPE);
+ }
+
+ /* Initialize argv[] */
+ ALLOC(c->argv, sizeof(char *) * sp.nargv);
+ initVectorFromBlock (c->argv, buf+offset, sp.nargv-1);
+ offset += sp.argvBytes;
+
+ /* Initialize envv[] */
+ if (sp.nenvv == 0) {
+ c->envv = 0;
+ } else {
+ ALLOC(c->envv, sizeof(char *) * sp.nenvv);
+ initVectorFromBlock (c->envv, buf+offset, sp.nenvv-1);
+ offset += sp.envvBytes;
+ }
+
+ /* Initialize pdir */
+ if (sp.dirlen == 0) {
+ c->pdir = 0;
+ } else {
+ c->pdir = buf+offset;
+ offset += sp.dirlen;
+ }
+
+ /* Initialize parentPathv[] */
+ ALLOC(parentPathv, sizeof (char *) * sp.nparentPathv)
+ initVectorFromBlock ((const char**)parentPathv, buf+offset, sp.nparentPathv-1);
+ offset += sp.parentPathvBytes;
+}
+
+int main(int argc, char *argv[]) {
+ ChildStuff c;
+ int t;
+ struct stat buf;
+ /* argv[0] contains the fd number to read all the child info */
+ int r, fdin, fdout;
+
+ r = sscanf (argv[argc-1], "%d:%d", &fdin, &fdout);
+ if (r == 2 && fcntl(fdin, F_GETFD) != -1) {
+ fstat(fdin, &buf);
+ if (!S_ISFIFO(buf.st_mode))
+ shutItDown();
+ } else {
+ shutItDown();
+ }
+ initChildStuff (fdin, fdout, &c);
+
+ childProcess (&c);
+ return 0; /* NOT REACHED */
+}
--- a/jdk/src/solaris/native/java/net/NetworkInterface.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/native/java/net/NetworkInterface.c Wed Jul 05 19:09:26 2017 +0200
@@ -563,11 +563,9 @@
if ((sock = openSocketWithFallback(env, name_utf)) < 0) {
(*env)->ReleaseStringUTFChars(env, name, name_utf);
- return -1;
+ return -1;
}
- name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
-
ret = getFlags(sock, name_utf, &flags);
close(sock);
--- a/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -346,13 +346,19 @@
awt_GetComponent(JNIEnv* env, void* platformInfo)
{
Window window = (Window)platformInfo;
- Widget widget = NULL;
jobject peer = NULL;
jobject target = NULL;
AWT_LOCK();
- target = (*env)->GetObjectField(env, peer, targetID);
+ if (window != None) {
+ peer = JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit",
+ "windowToXWindow", "(J)Lsun/awt/X11/XBaseWindow;", (jlong)window).l;
+ }
+ if ((peer != NULL) &&
+ (JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) {
+ target = (*env)->GetObjectField(env, peer, targetID);
+ }
if (target == NULL) {
JNU_ThrowNullPointerException(env, "NullPointerException");
@@ -360,7 +366,6 @@
return (jobject)NULL;
}
-
AWT_UNLOCK();
return target;
--- a/jdk/src/windows/classes/java/lang/ProcessImpl.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java Wed Jul 05 19:09:26 2017 +0200
@@ -491,8 +491,10 @@
/**
* Create a process using the win32 function CreateProcess.
+ * The method is synchronized due to MS kb315939 problem.
+ * All native handles should restore the inherit flag at the end of call.
*
- * @param cmdstr the Windows commandline
+ * @param cmdstr the Windows command line
* @param envblock NUL-separated, double-NUL-terminated list of
* environment strings in VAR=VALUE form
* @param dir the working directory of the process, or null if
@@ -508,7 +510,7 @@
* @param redirectErrorStream redirectErrorStream attribute
* @return the native subprocess HANDLE returned by CreateProcess
*/
- private static native long create(String cmdstr,
+ private static synchronized native long create(String cmdstr,
String envblock,
String dir,
long[] stdHandles,
--- a/jdk/src/windows/native/java/io/Console_md.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/java/io/Console_md.c Wed Jul 05 19:09:26 2017 +0200
@@ -38,12 +38,10 @@
{
if (hStdIn == INVALID_HANDLE_VALUE &&
(hStdIn = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
- JNU_ThrowIOExceptionWithLastError(env, "Open Console input failed");
return JNI_FALSE;
}
if (hStdOut == INVALID_HANDLE_VALUE &&
(hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
- JNU_ThrowIOExceptionWithLastError(env, "Open Console output failed");
return JNI_FALSE;
}
if (GetFileType(hStdIn) != FILE_TYPE_CHAR ||
--- a/jdk/src/windows/native/java/io/canonicalize_md.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/java/io/canonicalize_md.c Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, 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
@@ -179,6 +179,10 @@
wdots(WCHAR *start)
{
WCHAR *p = start;
+ // Skip "\\.\" prefix
+ if (wcslen(p) > 4 && !wcsncmp(p, L"\\\\.\\", 4))
+ p = p + 4;
+
while (*p) {
if ((p = wcschr(p, L'.')) == NULL) // find next occurence of '.'
return 0; // no more dots
--- a/jdk/src/windows/native/java/io/io_util_md.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/java/io/io_util_md.c Wed Jul 05 19:09:26 2017 +0200
@@ -251,12 +251,6 @@
free(pathbuf);
if (h == INVALID_HANDLE_VALUE) {
- int error = GetLastError();
- if (error == ERROR_TOO_MANY_OPEN_FILES) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "IOException",
- "Too many open files");
- return -1;
- }
throwFileNotFoundException(env, path);
return -1;
}
--- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c Wed Jul 05 19:09:26 2017 +0200
@@ -113,6 +113,233 @@
CloseHandle(handle);
}
+static BOOL hasInheritFlag(HANDLE handle)
+{
+ DWORD mask;
+ if (GetHandleInformation(handle, &mask)) {
+ return mask & HANDLE_FLAG_INHERIT;
+ }
+ return FALSE;
+}
+
+#define HANDLE_STORAGE_SIZE 6
+#define OFFSET_READ 0
+#define OFFSET_WRITE 1
+//long signed version of INVALID_HANDLE_VALUE
+#define JAVA_INVALID_HANDLE_VALUE ((jlong) -1)
+#define OPPOSITE_END(offset) (offset==OFFSET_READ ? OFFSET_WRITE : OFFSET_READ)
+
+/* Pipe holder structure */
+typedef struct _STDHOLDER {
+ HANDLE pipe[2];
+ int offset;
+} STDHOLDER;
+
+/* Responsible for correct initialization of the [pHolder] structure
+ (that is used for handles recycling) if needs,
+ and appropriate setup of IOE handle [phStd] for child process based
+ on created pipe or Java handle. */
+static BOOL initHolder(
+ JNIEnv *env,
+ jlong *pjhandles, /* IN OUT - the handle form Java,
+ that can be a file, console or undefined */
+ STDHOLDER *pHolder, /* OUT - initialized structure that holds pipe
+ handles */
+ HANDLE *phStd /* OUT - initialized handle for child process */
+) {
+ /* Here we test the value from Java against invalid
+ handle value. We are not using INVALID_HANDLE_VALUE macro
+ due to double signed/unsigned and 32/64bit ambiguity.
+ Otherwise it will be easy to get the wrong
+ value 0x00000000FFFFFFFF
+ instead 0xFFFFFFFFFFFFFFFF. */
+ if (*pjhandles != JAVA_INVALID_HANDLE_VALUE) {
+ /* Java file or console redirection */
+ *phStd = (HANDLE) *pjhandles;
+ /* Here we set the related Java stream (Process.getXXXXStream())
+ to [ProcessBuilder.NullXXXXStream.INSTANCE] value.
+ The initial Java handle [*pjhandles] will be closed in
+ ANY case. It is not a handle leak. */
+ *pjhandles = JAVA_INVALID_HANDLE_VALUE;
+ } else {
+ /* Creation of parent-child pipe */
+ if (!CreatePipe(
+ &pHolder->pipe[OFFSET_READ],
+ &pHolder->pipe[OFFSET_WRITE],
+ NULL, /* we would like to inherit
+ default process access,
+ instead of 'Everybody' access */
+ PIPE_SIZE))
+ {
+ win32Error(env, L"CreatePipe");
+ return FALSE;
+ } else {
+ /* [thisProcessEnd] has no the inherit flag because
+ the [lpPipeAttributes] param of [CreatePipe]
+ had the NULL value. */
+ HANDLE thisProcessEnd = pHolder->pipe[OPPOSITE_END(pHolder->offset)];
+ *phStd = pHolder->pipe[pHolder->offset];
+ *pjhandles = (jlong) thisProcessEnd;
+ }
+ }
+ /* Pipe handle will be closed in the [releaseHolder] call,
+ file handle will be closed in Java.
+ The long-live handle need to restore the inherit flag,
+ we do it later in the [prepareIOEHandleState] call. */
+ SetHandleInformation(
+ *phStd,
+ HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
+ return TRUE;
+}
+
+/* Smart recycling of pipe handles in [pHolder]. For the failed
+ create process attempts, both ends of pipe need to be released.
+ The [complete] has the [TRUE] value in the failed attempt. */
+static void releaseHolder(BOOL complete, STDHOLDER *pHolder) {
+ closeSafely(pHolder->pipe[pHolder->offset]);
+ if (complete) {
+ /* Error occur, close this process pipe end */
+ closeSafely(pHolder->pipe[OPPOSITE_END(pHolder->offset)]);
+ }
+}
+
+/* Stores and drops the inherit flag of handles that should not
+ be shared with the child process by default, but can hold the
+ inherit flag due to MS process birth specific. */
+static void prepareIOEHandleState(
+ HANDLE *stdIOE,
+ BOOL *inherit)
+{
+ int i;
+ for (i = 0; i < HANDLE_STORAGE_SIZE; ++i) {
+ HANDLE hstd = stdIOE[i];
+ if (INVALID_HANDLE_VALUE != hstd && hasInheritFlag(hstd)) {
+ /* FALSE by default */
+ inherit[i] = TRUE;
+ /* Java does not need implicit inheritance for IOE handles,
+ so we drop inherit flag that probably was installed by
+ previous CreateProcess call that launched current process.
+ We will return the handle state back after CreateProcess call.
+ By clearing inherit flag we prevent "greedy grandchild" birth.
+ The explicit inheritance for child process IOE handles is
+ implemented in the [initHolder] call. */
+ SetHandleInformation(hstd, HANDLE_FLAG_INHERIT, 0);
+ }
+ }
+}
+
+/* Restores the inheritance flag of handles from stored values. */
+static void restoreIOEHandleState(
+ const HANDLE *stdIOE,
+ const BOOL *inherit)
+{
+ /* The set of current process standard IOE handles and
+ the set of child process IOE handles can intersect.
+ To restore the inherit flag right, we use backward
+ array iteration. */
+ int i;
+ for (i = HANDLE_STORAGE_SIZE - 1; i >= 0; --i)
+ if (INVALID_HANDLE_VALUE != stdIOE[i]) {
+ /* Restore inherit flag for any case.
+ The handle can be changed by explicit inheritance.*/
+ SetHandleInformation(stdIOE[i],
+ HANDLE_FLAG_INHERIT,
+ inherit[i] ? HANDLE_FLAG_INHERIT : 0);
+ }
+}
+
+/* Please, read about the MS inheritance problem
+ http://support.microsoft.com/kb/315939
+ and critical section/synchronized block solution. */
+static jlong processCreate(
+ JNIEnv *env,
+ const jchar *pcmd,
+ const jchar *penvBlock,
+ const jchar *pdir,
+ jlong *handles,
+ jboolean redirectErrorStream)
+{
+ jlong ret = 0L;
+ STARTUPINFOW si = {sizeof(si)};
+
+ /* Handles for which the inheritance flag must be restored. */
+ HANDLE stdIOE[HANDLE_STORAGE_SIZE] = {
+ /* Current process standard IOE handles: JDK-7147084 */
+ INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE,
+ /* Child process IOE handles: JDK-6921885 */
+ (HANDLE)handles[0], (HANDLE)handles[1], (HANDLE)handles[2]};
+ BOOL inherit[HANDLE_STORAGE_SIZE] = {
+ FALSE, FALSE, FALSE,
+ FALSE, FALSE, FALSE};
+
+ {
+ /* Extraction of current process standard IOE handles */
+ DWORD idsIOE[3] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE};
+ int i;
+ for (i = 0; i < 3; ++i)
+ /* Should not be closed by CloseHandle! */
+ stdIOE[i] = GetStdHandle(idsIOE[i]);
+ }
+
+ prepareIOEHandleState(stdIOE, inherit);
+ {
+ /* Input */
+ STDHOLDER holderIn = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_READ};
+ if (initHolder(env, &handles[0], &holderIn, &si.hStdInput)) {
+
+ /* Output */
+ STDHOLDER holderOut = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_WRITE};
+ if (initHolder(env, &handles[1], &holderOut, &si.hStdOutput)) {
+
+ /* Error */
+ STDHOLDER holderErr = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_WRITE};
+ BOOL success;
+ if (redirectErrorStream) {
+ si.hStdError = si.hStdOutput;
+ /* Here we set the error stream to [ProcessBuilder.NullInputStream.INSTANCE]
+ value. That is in accordance with Java Doc for the redirection case.
+ The Java file for the [ handles[2] ] will be closed in ANY case. It is not
+ a handle leak. */
+ handles[2] = JAVA_INVALID_HANDLE_VALUE;
+ success = TRUE;
+ } else {
+ success = initHolder(env, &handles[2], &holderErr, &si.hStdError);
+ }
+
+ if (success) {
+ PROCESS_INFORMATION pi;
+ DWORD processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
+
+ si.dwFlags = STARTF_USESTDHANDLES;
+ if (!CreateProcessW(
+ NULL, /* executable name */
+ (LPWSTR)pcmd, /* command line */
+ NULL, /* process security attribute */
+ NULL, /* thread security attribute */
+ TRUE, /* inherits system handles */
+ processFlag, /* selected based on exe type */
+ (LPVOID)penvBlock,/* environment block */
+ (LPCWSTR)pdir, /* change to the new current directory */
+ &si, /* (in) startup information */
+ &pi)) /* (out) process information */
+ {
+ win32Error(env, L"CreateProcess");
+ } else {
+ closeSafely(pi.hThread);
+ ret = (jlong)pi.hProcess;
+ }
+ }
+ releaseHolder(ret == 0, &holderErr);
+ releaseHolder(ret == 0, &holderOut);
+ }
+ releaseHolder(ret == 0, &holderIn);
+ }
+ }
+ restoreIOEHandleState(stdIOE, inherit);
+
+ return ret;
+}
+
JNIEXPORT jlong JNICALL
Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored,
jstring cmd,
@@ -121,138 +348,35 @@
jlongArray stdHandles,
jboolean redirectErrorStream)
{
- HANDLE inRead = INVALID_HANDLE_VALUE;
- HANDLE inWrite = INVALID_HANDLE_VALUE;
- HANDLE outRead = INVALID_HANDLE_VALUE;
- HANDLE outWrite = INVALID_HANDLE_VALUE;
- HANDLE errRead = INVALID_HANDLE_VALUE;
- HANDLE errWrite = INVALID_HANDLE_VALUE;
- SECURITY_ATTRIBUTES sa;
- PROCESS_INFORMATION pi;
- STARTUPINFOW si;
- const jchar* pcmd = NULL;
- const jchar* pdir = NULL;
- const jchar* penvBlock = NULL;
- jlong *handles = NULL;
jlong ret = 0;
- DWORD processFlag;
-
- assert(cmd != NULL);
- pcmd = (*env)->GetStringChars(env, cmd, NULL);
- if (pcmd == NULL) goto Catch;
-
- if (dir != 0) {
- pdir = (*env)->GetStringChars(env, dir, NULL);
- if (pdir == NULL) goto Catch;
- }
- if (envBlock != NULL) {
- penvBlock = ((*env)->GetStringChars(env, envBlock, NULL));
- if (penvBlock == NULL) goto Catch;
- }
- assert(stdHandles != NULL);
- handles = (*env)->GetLongArrayElements(env, stdHandles, NULL);
- if (handles == NULL) goto Catch;
-
- memset(&si, 0, sizeof(si));
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESTDHANDLES;
-
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = 0;
- sa.bInheritHandle = TRUE;
-
- if (handles[0] != (jlong) -1) {
- si.hStdInput = (HANDLE) handles[0];
- handles[0] = (jlong) -1;
- } else {
- if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) {
- win32Error(env, L"CreatePipe");
- goto Catch;
- }
- si.hStdInput = inRead;
- SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, 0);
- handles[0] = (jlong) inWrite;
- }
- SetHandleInformation(si.hStdInput,
- HANDLE_FLAG_INHERIT,
- HANDLE_FLAG_INHERIT);
-
- if (handles[1] != (jlong) -1) {
- si.hStdOutput = (HANDLE) handles[1];
- handles[1] = (jlong) -1;
- } else {
- if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) {
- win32Error(env, L"CreatePipe");
- goto Catch;
+ if (cmd != NULL && stdHandles != NULL) {
+ const jchar *pcmd = (*env)->GetStringChars(env, cmd, NULL);
+ if (pcmd != NULL) {
+ const jchar *penvBlock = (envBlock != NULL)
+ ? (*env)->GetStringChars(env, envBlock, NULL)
+ : NULL;
+ const jchar *pdir = (dir != NULL)
+ ? (*env)->GetStringChars(env, dir, NULL)
+ : NULL;
+ jlong *handles = (*env)->GetLongArrayElements(env, stdHandles, NULL);
+ if (handles != NULL) {
+ ret = processCreate(
+ env,
+ pcmd,
+ penvBlock,
+ pdir,
+ handles,
+ redirectErrorStream);
+ (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);
+ }
+ if (pdir != NULL)
+ (*env)->ReleaseStringChars(env, dir, pdir);
+ if (penvBlock != NULL)
+ (*env)->ReleaseStringChars(env, envBlock, penvBlock);
+ (*env)->ReleaseStringChars(env, cmd, pcmd);
}
- si.hStdOutput = outWrite;
- SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, 0);
- handles[1] = (jlong) outRead;
}
- SetHandleInformation(si.hStdOutput,
- HANDLE_FLAG_INHERIT,
- HANDLE_FLAG_INHERIT);
-
- if (redirectErrorStream) {
- si.hStdError = si.hStdOutput;
- handles[2] = (jlong) -1;
- } else if (handles[2] != (jlong) -1) {
- si.hStdError = (HANDLE) handles[2];
- handles[2] = (jlong) -1;
- } else {
- if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) {
- win32Error(env, L"CreatePipe");
- goto Catch;
- }
- si.hStdError = errWrite;
- SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, 0);
- handles[2] = (jlong) errRead;
- }
- SetHandleInformation(si.hStdError,
- HANDLE_FLAG_INHERIT,
- HANDLE_FLAG_INHERIT);
-
- processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
- ret = CreateProcessW(0, /* executable name */
- (LPWSTR)pcmd, /* command line */
- 0, /* process security attribute */
- 0, /* thread security attribute */
- TRUE, /* inherits system handles */
- processFlag, /* selected based on exe type */
- (LPVOID)penvBlock,/* environment block */
- (LPCWSTR)pdir, /* change to the new current directory */
- &si, /* (in) startup information */
- &pi); /* (out) process information */
- if (!ret) {
- win32Error(env, L"CreateProcess");
- goto Catch;
- }
-
- CloseHandle(pi.hThread);
- ret = (jlong)pi.hProcess;
-
- Finally:
- /* Always clean up the child's side of the pipes */
- closeSafely(inRead);
- closeSafely(outWrite);
- closeSafely(errWrite);
-
- if (pcmd != NULL)
- (*env)->ReleaseStringChars(env, cmd, pcmd);
- if (pdir != NULL)
- (*env)->ReleaseStringChars(env, dir, pdir);
- if (penvBlock != NULL)
- (*env)->ReleaseStringChars(env, envBlock, penvBlock);
- if (handles != NULL)
- (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);
return ret;
-
- Catch:
- /* Clean up the parent's side of the pipes in case of failure only */
- closeSafely(inWrite);
- closeSafely(outRead);
- closeSafely(errRead);
- goto Finally;
}
JNIEXPORT jint JNICALL
--- a/jdk/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c Wed Jul 05 19:09:26 2017 +0200
@@ -67,12 +67,13 @@
J2dTraceLn(J2D_TRACE_INFO, "WGLSurfaceData_initOps");
- if (oglsdo == NULL) {
- JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+ if (wglsdo == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "creating native wgl ops");
return;
}
- if (wglsdo == NULL) {
- JNU_ThrowOutOfMemoryError(env, "creating native wgl ops");
+ if (oglsdo == NULL) {
+ free(wglsdo);
+ JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
return;
}
--- a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c Wed Jul 05 19:09:26 2017 +0200
@@ -367,11 +367,12 @@
/*
* Class: sun_security_krb5_Credentials
* Method: acquireDefaultNativeCreds
- * Signature: ()Lsun/security/krb5/Credentials;
+ * Signature: ([I])Lsun/security/krb5/Credentials;
*/
JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds(
JNIEnv *env,
- jclass krbcredsClass) {
+ jclass krbcredsClass,
+ jintArray jetypes) {
KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL;
@@ -387,9 +388,12 @@
jobject ticketFlags, startTime, endTime, krbCreds = NULL;
jobject authTime, renewTillTime, hostAddresses = NULL;
KERB_EXTERNAL_TICKET *msticket;
- int ignore_cache = 0;
+ int found_in_cache = 0;
FILETIME Now, EndTime, LocalEndTime;
+ int i, netypes;
+ jint *etypes = NULL;
+
while (TRUE) {
if (krbcredsConstructor == 0) {
@@ -456,31 +460,33 @@
// got the native MS TGT
msticket = &(TktCacheResponse->Ticket);
+ netypes = (*env)->GetArrayLength(env, jetypes);
+ etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL);
+
// check TGT validity
- switch (msticket->SessionKey.KeyType) {
- case KERB_ETYPE_DES_CBC_CRC:
- case KERB_ETYPE_DES_CBC_MD5:
- case KERB_ETYPE_NULL:
- case KERB_ETYPE_RC4_HMAC_NT:
- GetSystemTimeAsFileTime(&Now);
- EndTime.dwLowDateTime = msticket->EndTime.LowPart;
- EndTime.dwHighDateTime = msticket->EndTime.HighPart;
- FileTimeToLocalFileTime(&EndTime, &LocalEndTime);
- if (CompareFileTime(&Now, &LocalEndTime) >= 0) {
- ignore_cache = 1;
- }
- if (msticket->TicketFlags & KERB_TICKET_FLAGS_invalid) {
- ignore_cache = 1;
- }
- break;
- case KERB_ETYPE_RC4_MD4:
- default:
- // not supported
- ignore_cache = 1;
- break;
+ if (native_debug) {
+ printf("LSA: TICKET SessionKey KeyType is %d\n", msticket->SessionKey.KeyType);
}
- if (ignore_cache) {
+ if ((msticket->TicketFlags & KERB_TICKET_FLAGS_invalid) == 0) {
+ GetSystemTimeAsFileTime(&Now);
+ EndTime.dwLowDateTime = msticket->EndTime.LowPart;
+ EndTime.dwHighDateTime = msticket->EndTime.HighPart;
+ FileTimeToLocalFileTime(&EndTime, &LocalEndTime);
+ if (CompareFileTime(&Now, &LocalEndTime) < 0) {
+ for (i=0; i<netypes; i++) {
+ if (etypes[i] == msticket->SessionKey.KeyType) {
+ found_in_cache = 1;
+ if (native_debug) {
+ printf("LSA: Valid etype found: %d\n", etypes[i]);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found_in_cache) {
if (native_debug) {
printf("LSA: MS TGT in cache is invalid/not supported; request new ticket\n");
}
@@ -494,34 +500,41 @@
}
pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
- pTicketRequest->EncryptionType = KERB_ETYPE_DES_CBC_MD5;
pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE;
- Status = LsaCallAuthenticationPackage(
- LogonHandle,
- PackageId,
- pTicketRequest,
- requestSize,
- &pTicketResponse,
- &responseSize,
- &SubStatus
- );
+ for (i=0; i<netypes; i++) {
+ pTicketRequest->EncryptionType = etypes[i];
+ Status = LsaCallAuthenticationPackage(
+ LogonHandle,
+ PackageId,
+ pTicketRequest,
+ requestSize,
+ &pTicketResponse,
+ &responseSize,
+ &SubStatus
+ );
- if (native_debug) {
- printf("LSA: Response size is %d\n", responseSize);
- }
+ if (native_debug) {
+ printf("LSA: Response size is %d for %d\n", responseSize, etypes[i]);
+ }
- if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) {
- if (!LSA_SUCCESS(Status)) {
- ShowNTError("LsaCallAuthenticationPackage", Status);
- } else {
- ShowNTError("Protocol status", SubStatus);
+ if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) {
+ if (!LSA_SUCCESS(Status)) {
+ ShowNTError("LsaCallAuthenticationPackage", Status);
+ } else {
+ ShowNTError("Protocol status", SubStatus);
+ }
+ continue;
}
+
+ // got the native MS Kerberos TGT
+ msticket = &(pTicketResponse->Ticket);
break;
}
+ }
- // got the native MS Kerberos TGT
- msticket = &(pTicketResponse->Ticket);
+ if (etypes != NULL) {
+ (*env)->ReleaseIntArrayElements(env, jetypes, etypes, 0);
}
/*
@@ -644,7 +657,7 @@
hostAddresses);
break;
- } // end of WHILE
+ } // end of WHILE. This WHILE will never loop.
// clean up resources
if (TktCacheResponse != NULL) {
--- a/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -91,7 +91,7 @@
* Code copied to target process
*/
#pragma check_stack (off)
-static DWORD WINAPI thread_func(DataBlock *pData)
+DWORD WINAPI jvm_attach_thread_func(DataBlock *pData)
{
HINSTANCE h;
EnqueueOperationFunc addr;
@@ -117,8 +117,8 @@
}
}
-/* This function marks the end of thread_func. */
-static void thread_end (void) {
+/* This function marks the end of jvm_attach_thread_func. */
+void jvm_attach_thread_func_end (void) {
}
#pragma check_stack
@@ -152,10 +152,10 @@
DWORD len;
jbyteArray array;
- len = (DWORD)((LPBYTE) thread_end - (LPBYTE) thread_func);
+ len = (DWORD)((LPBYTE) jvm_attach_thread_func_end - (LPBYTE) jvm_attach_thread_func);
array= (*env)->NewByteArray(env, (jsize)len);
if (array != NULL) {
- (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&thread_func);
+ (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&jvm_attach_thread_func);
}
return array;
}
--- a/jdk/src/windows/native/sun/windows/awt_Cursor.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Cursor.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -391,9 +391,16 @@
DASSERT(hCursor);
- AwtCursor::setPData(self, ptr_to_jlong(new AwtCursor(env, hCursor, self, xHotSpot,
- yHotSpot, nW, nH, nSS, cols,
- (BYTE *)andMaskPtr)));
+ try {
+ AwtCursor::setPData(self, ptr_to_jlong(new AwtCursor(env, hCursor, self, xHotSpot,
+ yHotSpot, nW, nH, nSS, cols,
+ (BYTE *)andMaskPtr)));
+ } catch (...) {
+ if (cols) {
+ delete[] cols;
+ }
+ throw;
+ }
CATCH_BAD_ALLOC;
}
--- a/jdk/src/windows/native/sun/windows/awt_Font.cpp Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Font.cpp Wed Jul 05 19:09:26 2017 +0200
@@ -510,6 +510,11 @@
jobject font = env->GetObjectField(fontMetrics, AwtFont::fontID);
AwtFont* awtFont = AwtFont::GetFont(env, font);
+ if (!awtFont) {
+ /* failed to get font */
+ return;
+ }
+
HDC hDC = ::GetDC(0);
DASSERT(hDC != NULL);
--- a/jdk/test/ProblemList.txt Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/ProblemList.txt Wed Jul 05 19:09:26 2017 +0200
@@ -131,13 +131,6 @@
# 7196801
java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all
-# 8015780
-java/lang/reflect/Method/GenericStringTest.java generic-all
-
-# 8019845 due to memleak not related to the tested fix
-java/lang/instrument/RedefineBigClass.sh linux-x64
-java/lang/instrument/RetransformBigClass.sh linux-x64
-
# 8021230
java/lang/ThreadLocal/ThreadLocalSupplierTest.java generic-all
@@ -296,9 +289,6 @@
sun/security/krb5/auto/BadKdc3.java solaris-sparcv9
sun/security/krb5/auto/BadKdc4.java solaris-sparcv9
-# 7194428
-sun/security/mscapi/ShortRSAKey1024.sh windows-all
-
############################################################################
# jdk_sound
@@ -315,9 +305,6 @@
# jdk_time
-# 8016623
-java/time/test/java/time/format/TestDateTimeTextProvider.java generic-all
-
############################################################################
# jdk_tools
@@ -335,8 +322,6 @@
# Tests take too long, on sparcs see 7143279
tools/pack200/CommandLineTests.java solaris-all, macosx-all
tools/pack200/Pack200Test.java solaris-all, macosx-all
-# 8015666
-tools/pack200/TimeStamp.java generic-all
# 8007410
tools/launcher/FXLauncherTest.java linux-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8020081 8022669
+ * @summary encryption/decryption test for using OAEPPadding with
+ * OAEPParameterSpec specified and not specified during a Cipher.init().
+ * @author Anthony Scarpino
+ */
+
+import java.util.Arrays;
+
+import java.security.Security;
+import java.security.Provider;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.MGF1ParameterSpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.spec.PSource;
+
+
+public class TestOAEPPadding {
+ private static RSAPrivateKey privateKey;
+ private static RSAPublicKey publicKey;
+ static Provider cp;
+ static boolean failed = false;
+
+ public static void main(String args[]) throws Exception {
+ cp = Security.getProvider("SunJCE");
+ System.out.println("Testing provider " + cp.getName() + "...");
+ Provider kfp = Security.getProvider("SunRsaSign");
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", kfp);
+ kpg.initialize(2048);
+ KeyPair kp = kpg.generateKeyPair();
+ privateKey = (RSAPrivateKey)kp.getPrivate();
+ publicKey = (RSAPublicKey)kp.getPublic();
+
+ // Test using a spec with each digest algorithm case
+ // MD5
+ test(new OAEPParameterSpec("MD5", "MGF1",
+ MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("MD5", "MGF1",
+ MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("MD5", "MGF1",
+ MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("MD5", "MGF1",
+ MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("MD5", "MGF1",
+ MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ // SHA1
+ test(new OAEPParameterSpec("SHA1", "MGF1",
+ MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA1", "MGF1",
+ MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA1", "MGF1",
+ MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA1", "MGF1",
+ MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA1", "MGF1",
+ MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ // For default OAEPParameterSpec case (SHA1)
+ test(null);
+ // SHA-224
+ test(new OAEPParameterSpec("SHA-224", "MGF1",
+ MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-224", "MGF1",
+ MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-224", "MGF1",
+ MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-224", "MGF1",
+ MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-224", "MGF1",
+ MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ // SHA-256
+ test(new OAEPParameterSpec("SHA-256", "MGF1",
+ MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-256", "MGF1",
+ MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-256", "MGF1",
+ MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-256", "MGF1",
+ MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-256", "MGF1",
+ MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ // SHA-384
+ test(new OAEPParameterSpec("SHA-384", "MGF1",
+ MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-384", "MGF1",
+ MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-384", "MGF1",
+ MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-384", "MGF1",
+ MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-384", "MGF1",
+ MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ // SHA-512
+ test(new OAEPParameterSpec("SHA-512", "MGF1",
+ MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-512", "MGF1",
+ MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-512", "MGF1",
+ MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-512", "MGF1",
+ MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-512", "MGF1",
+ MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ if (failed) {
+ throw new Exception("Test failed");
+ }
+ }
+
+ /*
+ * Test with one byte, the max bytes, and the max + 1 bytes allowed by
+ * the RSA key size and the digest algorithm
+ */
+ static void test(OAEPParameterSpec spec) throws Exception {
+ int dlen = 0;
+ String algo;
+
+ // For default OAEPParameterSpec case (SHA1)
+ if (spec == null) {
+ dlen = 20;
+ algo = "Default";
+ } else {
+ // Use the digest algorith provided in the spec
+ algo = spec.getDigestAlgorithm();
+ if (algo.equals("MD5")) {
+ dlen = 16;
+ } else if (algo.equals("SHA1")) {
+ dlen = 20;
+ } else if (algo.equals("SHA-224")) {
+ dlen = 28;
+ } else if (algo.equals("SHA-256")) {
+ dlen = 32;
+ } else if (algo.equals("SHA-384")) {
+ dlen = 48;
+ } else if (algo.equals("SHA-512")) {
+ dlen = 64;
+ }
+ }
+
+ // OAEP maximum length for a given digest algorith & RSA key length
+ int max = ((publicKey.getModulus().bitLength() / 8) - (2 * dlen) - 2);
+
+ // Test with data length of 1
+ try {
+ testEncryptDecrypt(spec, 1);
+ } catch (Exception e) {
+ System.out.println(algo + " failed with data length of 1");
+ e.printStackTrace();
+ failed = true;
+ }
+
+ // Test with data length of maximum allowed
+ try {
+ testEncryptDecrypt(spec, max);
+ } catch (Exception e) {
+ System.out.println(algo + " failed with data length of " + max);
+ e.printStackTrace();
+ failed = true;
+ }
+
+ // Test with data length of maximum allowed + 1
+ try {
+ testEncryptDecrypt(spec, max + 1);
+ throw new Exception();
+ } catch (IllegalBlockSizeException ie) {
+ // expected to fail
+ } catch (Exception e) {
+ System.err.println(algo + " failed with data length of " +
+ (max + 1));
+ e.printStackTrace();
+ failed = true;
+
+ }
+ }
+
+ private static void testEncryptDecrypt(OAEPParameterSpec spec,
+ int dataLength) throws Exception {
+
+ System.out.print("Testing OAEP with hash ");
+ if (spec != null) {
+ System.out.print(spec.getDigestAlgorithm() + " and MGF " +
+ ((MGF1ParameterSpec)spec.getMGFParameters()).
+ getDigestAlgorithm());
+ } else {
+ System.out.print("Default");
+ }
+ System.out.println(", " + dataLength + " bytes");
+
+ Cipher c = Cipher.getInstance("RSA/ECB/OAEPPadding", cp);
+ if (spec != null) {
+ c.init(Cipher.ENCRYPT_MODE, publicKey, spec);
+ } else {
+ c.init(Cipher.ENCRYPT_MODE, publicKey);
+ }
+
+ byte[] data = new byte[dataLength];
+ byte[] enc = c.doFinal(data);
+ if (spec != null) {
+ c.init(Cipher.DECRYPT_MODE, privateKey, spec);
+ } else {
+ c.init(Cipher.DECRYPT_MODE, privateKey);
+ }
+ byte[] dec = c.doFinal(enc);
+ if (Arrays.equals(data, dec) == false) {
+ throw new Exception("Data does not match");
+ }
+ }
+}
--- a/jdk/test/com/sun/jdi/sde/TemperatureTableTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/com/sun/jdi/sde/TemperatureTableTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -7,7 +7,7 @@
* @author Robert Field
*
* @library ..
- * @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE
+ * @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE HelloWorld
* @run compile TemperatureTableTest.java
* @run compile -g TemperatureTableServlet.java
* @run main TemperatureTableTest
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/8013611/JDK8013611.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, 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
+ @bug 8013611
+ @summary Tests showing a modal dialog with requesting focus in frame.
+ @author Anton.Tarasov: area=awt.focus
+ @library ../../regtesthelpers
+ @build Util
+ @run main JDK8013611
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import test.java.awt.regtesthelpers.Util;
+
+import java.awt.*;
+
+public class JDK8013611 extends JFrame {
+ static JTextField textField = new JTextField("text");
+ static JButton button1 = new JButton("button1");
+ static JButton button2 = new JButton("button2");
+ static Robot robot;
+
+ static JDialog dialog;
+ static JButton button3 = new JButton("button3");
+
+ public static void main(String[] args) {
+ robot = Util.createRobot();
+
+ JDK8013611 frame = new JDK8013611();
+ frame.setLayout(new FlowLayout());
+ frame.add(textField);
+ frame.add(button1);
+ frame.add(button2);
+ frame.pack();
+
+ dialog = new JDialog(frame, true);
+ dialog.add(button3);
+ dialog.pack();
+
+ textField.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ dialog.setVisible(true);
+ }
+ });
+
+ button1.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ button2.requestFocusInWindow();
+ }
+ });
+
+ frame.setVisible(true);
+
+ frame.test();
+ }
+
+ public void test() {
+ if (!testFocused(textField)) {
+ Util.clickOnComp(textField, robot);
+ if (!testFocused(textField)) {
+ throw new RuntimeException("Error: couldn't focus " + textField);
+ }
+ }
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+
+ if (!testFocused(button3)) {
+ throw new RuntimeException("Test failed: dialog didn't get focus!");
+ }
+
+ System.out.println("Test passed.");
+ }
+
+ boolean testFocused(Component c) {
+ for (int i=0; i<10; i++) {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == c) {
+ return true;
+ }
+ Util.waitForIdle(robot);
+ }
+ return false;
+ }
+}
--- a/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java Wed Jul 05 19:09:26 2017 +0200
@@ -37,7 +37,7 @@
*/
public final class Test8004859 {
- private static Shape[] clips = {new Rectangle(0, 0, 1, 1), new Rectangle(
+ private static Shape[] clips = {new Rectangle(0, 0, -1, -1), new Rectangle(
100, 100, -100, -100)};
private static boolean status = true;
--- a/jdk/test/java/io/File/WinDeviceName.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/io/File/WinDeviceName.java Wed Jul 05 19:09:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, 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
@@ -22,11 +22,12 @@
*/
/* @test
- @bug 6176051
- @summary Check isFile's handling of Windows device names
+ @bug 6176051 4858457
+ @summary Check whether reserved names are handled correctly on Windows
*/
import java.io.File;
+import java.io.IOException;
public class WinDeviceName {
private static String devnames[] = {
@@ -35,22 +36,38 @@
"LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
"CLOCK$"
};
- public static void main(String[] args) throws Exception {
+ public static void main(String[] args) {
String osName = System.getProperty("os.name");
if (!osName.startsWith("Windows")) {
return;
}
+
for (int i = 0; i < devnames.length; i++) {
- if (new File(devnames[i]).isFile() ||
- new File(devnames[i] + ".txt").isFile()) {
- if ("CLOCK$".equals(devnames[i]) &&
- (osName.startsWith("Windows 9") ||
- osName.startsWith("Windows Me"))) {
- //"CLOCK$" is a reserved device name for NT
- continue;
+ String names[] = { devnames[i], devnames[i] + ".TXT",
+ devnames[i].toLowerCase(),
+ devnames[i].toLowerCase() + ".txt" };
+
+ for (String name : names) {
+ File f = new File(name);
+ if (f.isFile()) {
+ if ("CLOCK$".equals(devnames[i]) &&
+ (osName.startsWith("Windows 9") ||
+ osName.startsWith("Windows Me"))) {
+ //"CLOCK$" is a reserved device name for NT
+ continue;
+ }
+ throw new RuntimeException("isFile() returns true for " +
+ "Device name " + devnames[i]);
}
- throw new Exception("isFile() returns true for Device name "
- + devnames[i]);
+
+ if (!"CLOCK$".equals(devnames[i])) {
+ try {
+ System.out.println((new File(name)).getCanonicalPath());
+ } catch(IOException ie) {
+ throw new RuntimeException("Fail to get canonical " +
+ "path for " + name);
+ }
+ }
}
}
}
--- a/jdk/test/java/lang/Math/ExactArithTests.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/Math/ExactArithTests.java Wed Jul 05 19:09:26 2017 +0200
@@ -132,7 +132,56 @@
fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
}
}
+ try {
+ // Test incrementExact
+ int inc = Math.incrementExact(x);
+ long inc2 = (long) x + 1L;
+ if ((int) inc2 != inc2) {
+ fail("FAIL: int Math.incrementExact(" + x + ") = " + inc + "; expected Arithmetic exception");
+ } else if (inc != inc2) {
+ fail("FAIL: long Math.incrementExact(" + x + ") = " + inc + "; expected: " + inc2);
+ }
+ } catch (ArithmeticException ex) {
+ long inc2 = (long) x + 1L;
+ if ((int) inc2 == inc2) {
+ fail("FAIL: int Math.incrementExact(" + x + ")" + "; Unexpected exception: " + ex);
+ }
+ }
+
+ try {
+ // Test decrementExact
+ int dec = Math.decrementExact(x);
+ long dec2 = (long) x - 1L;
+ if ((int) dec2 != dec2) {
+ fail("FAIL: int Math.decrementExact(" + x + ") = " + dec + "; expected Arithmetic exception");
+ } else if (dec != dec2) {
+ fail("FAIL: long Math.decrementExact(" + x + ") = " + dec + "; expected: " + dec2);
+ }
+ } catch (ArithmeticException ex) {
+ long dec2 = (long) x - 1L;
+ if ((int) dec2 == dec2) {
+ fail("FAIL: int Math.decrementExact(" + x + ")" + "; Unexpected exception: " + ex);
+
+ }
+ }
+
+ try {
+ // Test negateExact
+ int neg = Math.negateExact(x);
+ long neg2 = -((long)x) ;
+ if ((int) neg2 != neg2) {
+ fail("FAIL: int Math.negateExact(" + x + ") = " + neg + "; expected Arithmetic exception");
+ } else if (neg != neg2) {
+ fail("FAIL: long Math.negateExact(" + x + ") = " + neg + "; expected: " + neg2);
+ }
+ } catch (ArithmeticException ex) {
+ long neg2 = (long) x - 1L;
+ if ((int) neg2 == neg2) {
+ fail("FAIL: int Math.negateExact(" + x + ")" + "; Unexpected exception: " + ex);
+
+ }
+ }
}
/**
@@ -225,6 +274,39 @@
}
try {
+ // Test incrementExact
+ resultBig = xBig.add(BigInteger.ONE);
+ long inc = Math.incrementExact(x);
+ checkResult("long Math.incrementExact", x, 1L, inc, resultBig);
+ } catch (ArithmeticException ex) {
+ if (inLongRange(resultBig)) {
+ fail("FAIL: long Math.incrementExact(" + x + "); Unexpected exception: " + ex);
+ }
+ }
+
+ try {
+ // Test decrementExact
+ resultBig = xBig.subtract(BigInteger.ONE);
+ long dec = Math.decrementExact(x);
+ checkResult("long Math.decrementExact", x, 1L, dec, resultBig);
+ } catch (ArithmeticException ex) {
+ if (inLongRange(resultBig)) {
+ fail("FAIL: long Math.decrementExact(" + x + "); Unexpected exception: " + ex);
+ }
+ }
+
+ try {
+ // Test negateExact
+ resultBig = xBig.negate();
+ long dec = Math.negateExact(x);
+ checkResult("long Math.negateExact", x, 0L, dec, resultBig);
+ } catch (ArithmeticException ex) {
+ if (inLongRange(resultBig)) {
+ fail("FAIL: long Math.negateExact(" + x + "); Unexpected exception: " + ex);
+ }
+ }
+
+ try {
// Test toIntExact
int value = Math.toIntExact(x);
if ((long)value != x) {
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,9 +26,10 @@
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
- * 4947220 7018606 7034570 4244896
+ * 4947220 7018606 7034570 4244896 5049299
* @summary Basic tests for Process and Environment Variable code
* @run main/othervm/timeout=300 Basic
+ * @run main/othervm/timeout=300 -Djdk.lang.Process.launchMechanism=fork Basic
* @author Martin Buchholz
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ProcessBuilder/InheritIOEHandle.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 7147084
+ * @run main/othervm InheritIOEHandle
+ * @summary inherit IOE handles and MS CreateProcess limitations (kb315939)
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class InheritIOEHandle {
+ private static enum APP {
+ B, C;
+ }
+ private static File stopC = new File(".\\StopC.txt");
+ private static String SIGNAL = "After call child process";
+ private static String JAVA_EXE = System.getProperty("java.home")
+ + File.separator + "bin"
+ + File.separator + "java";
+
+ private static String[] getCommandArray(String processName) {
+ String[] cmdArray = {
+ JAVA_EXE,
+ "-cp",
+ System.getProperty("java.class.path"),
+ InheritIOEHandle.class.getName(),
+ processName
+ };
+ return cmdArray;
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (!System.getProperty("os.name").startsWith("Windows")) {
+ return;
+ }
+
+ if (args.length > 0) {
+ APP app = APP.valueOf(args[0]);
+ switch (app) {
+ case B:
+ performB();
+ break;
+ case C:
+ performC();
+ break;
+ }
+ return;
+ }
+ performA();
+ }
+
+ private static void performA() {
+ try {
+ stopC.delete();
+
+ ProcessBuilder builder = new ProcessBuilder(
+ getCommandArray(APP.B.name()));
+ builder.redirectErrorStream(true);
+
+ Process process = builder.start();
+
+ process.getOutputStream().close();
+ process.getErrorStream().close();
+
+ try (BufferedReader in = new BufferedReader( new InputStreamReader(
+ process.getInputStream(), "utf-8")))
+ {
+ String result;
+ while ((result = in.readLine()) != null) {
+ if (!SIGNAL.equals(result)) {
+ throw new Error("Catastrophe in process B! Bad output.");
+ }
+ }
+ }
+
+ // If JDK-7147084 is not fixed that point is unreachable.
+
+ // write signal file
+ stopC.createNewFile();
+
+ System.err.println("Read stream finished.");
+ } catch (IOException ex) {
+ throw new Error("Catastrophe in process A!", ex);
+ }
+ }
+
+ private static void performB() {
+ try {
+ ProcessBuilder builder = new ProcessBuilder(
+ getCommandArray(APP.C.name()));
+
+ Process process = builder.start();
+
+ process.getInputStream().close();
+ process.getOutputStream().close();
+ process.getErrorStream().close();
+
+ System.out.println(SIGNAL);
+
+ // JDK-7147084 subject:
+ // Process C inherits the [System.out] handle and
+ // handle close in B does not finalize the streaming for A.
+ // (handle reference count > 1).
+ } catch (IOException ex) {
+ throw new Error("Catastrophe in process B!", ex);
+ }
+ }
+
+ private static void performC() {
+ // If JDK-7147084 is not fixed the loop is 5min long.
+ for (int i = 0; i < 5*60; ++i) {
+ try {
+ Thread.sleep(1000);
+ // check for sucess
+ if (stopC.exists())
+ break;
+ } catch (InterruptedException ex) {
+ // that is ok. Longer sleep - better effect.
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ProcessBuilder/SiblingIOEHandle.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 6921885
+ * @run main/othervm SiblingIOEHandle
+ * @summary inherit IOE handles and MS CreateProcess limitations (kb315939)
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+public class SiblingIOEHandle {
+ private static enum APP {
+ B, C;
+ }
+ private static File stopC = new File(".\\StopCs.txt");
+ private static String SIGNAL = "B child reported.";
+ private static String JAVA_EXE = System.getProperty("java.home")
+ + File.separator + "bin"
+ + File.separator + "java";
+
+ private static String[] getCommandArray(String processName) {
+ String[] cmdArray = {
+ JAVA_EXE,
+ "-cp",
+ System.getProperty("java.class.path"),
+ SiblingIOEHandle.class.getName(),
+ processName
+ };
+ return cmdArray;
+ }
+
+ public static void main(String[] args) {
+ if (!System.getProperty("os.name").startsWith("Windows")) {
+ return;
+ }
+
+ if (args.length > 0) {
+ APP app = APP.valueOf(args[0]);
+ switch (app) {
+ case B:
+ performB();
+ break;
+ case C:
+ performC();
+ break;
+ }
+ return;
+ }
+ performA(true);
+ performA(false);
+ }
+
+ static boolean procClaunched = false;
+
+ private static void waitAbit() {
+ try {
+ Thread.sleep(0);
+ } catch (InterruptedException ex) {
+ // that was long enough
+ }
+ }
+ private static boolean waitBarrier(CyclicBarrier barrier) {
+ while (true) try {
+ barrier.await();
+ return true;
+ } catch (InterruptedException ex) {
+ continue;
+ } catch (BrokenBarrierException ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ private static void performA(boolean fileOut) {
+ try {
+ stopC.delete();
+ ProcessBuilder builderB = new ProcessBuilder(
+ getCommandArray(APP.B.name()));
+
+ File outB = null;
+ if (fileOut) {
+ outB = new File("outB.txt");
+ builderB.redirectOutput(outB);
+ }
+ builderB.redirectErrorStream(true);
+
+ final CyclicBarrier barrier = new CyclicBarrier(2);
+ Thread procCRunner = new Thread(new Runnable() {
+ @Override public void run() {
+ try {
+ if (waitBarrier(barrier)) {
+ waitAbit();
+ // Run process C next to B ASAP to make an attempt
+ // to capture the B-process IOE handles in C process.
+ Runtime.getRuntime().exec(getCommandArray(APP.C.name()));
+ procClaunched = true;
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ });
+ procCRunner.start();
+
+
+ if (!waitBarrier(barrier)) {
+ throw new Error("Catastrophe in process A! Synchronization failed.");
+ }
+ // Run process B first.
+ Process processB = builderB.start();
+
+ while (true) try {
+ procCRunner.join();
+ break;
+ } catch (InterruptedException ex) {
+ continue;
+ }
+
+ if (!procClaunched) {
+ throw new Error("Catastrophe in process A! C was not launched.");
+ }
+
+ processB.getOutputStream().close();
+ processB.getErrorStream().close();
+
+ if (fileOut) {
+ try {
+ processB.waitFor();
+ } catch (InterruptedException ex) {
+ throw new Error("Catastrophe in process B! B hung up.");
+ }
+ System.err.println("Trying to delete [outB.txt].");
+ if (!outB.delete()) {
+ throw new Error("Greedy brother C deadlock! File share.");
+ }
+ System.err.println("Succeeded in delete [outB.txt].");
+ } else {
+ System.err.println("Read stream start.");
+ try (BufferedReader in = new BufferedReader( new InputStreamReader(
+ processB.getInputStream(), "utf-8")))
+ {
+ String result;
+ while ((result = in.readLine()) != null) {
+ if (!SIGNAL.equals(result)) {
+ throw new Error("Catastrophe in process B! Bad output.");
+ }
+ }
+ }
+ System.err.println("Read stream finished.");
+ }
+ // If JDK-6921885 is not fixed that point is unreachable.
+ // Test timeout exception.
+
+ // write signal file to stop C process.
+ stopC.createNewFile();
+ } catch (IOException ex) {
+ throw new Error("Catastrophe in process A!", ex);
+ }
+ }
+
+ private static void performB() {
+ System.out.println(SIGNAL);
+ }
+
+ private static void performC() {
+ // If JDK-7147084 is not fixed the loop is 5min long.
+ for (int i = 0; i < 5*60; ++i) {
+ try {
+ Thread.sleep(1000);
+ // check for sucess
+ if (stopC.exists())
+ break;
+ } catch (InterruptedException ex) {
+ // that is ok. Longer sleep - better effect.
+ }
+ }
+ }
+}
--- a/jdk/test/java/lang/invoke/AccessControlTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/invoke/AccessControlTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -28,7 +28,7 @@
* @library ../../../..
* @build test.java.lang.invoke.AccessControlTest
* @build test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote
- * @run junit/othervm test.java.lang.invoke.AccessControlTest
+ * @run testng/othervm test.java.lang.invoke.AccessControlTest
*/
package test.java.lang.invoke;
@@ -36,12 +36,14 @@
import java.lang.invoke.*;
import java.lang.reflect.*;
import java.util.*;
-import org.junit.*;
+import org.testng.*;
+import org.testng.annotations.*;
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodHandles.Lookup.*;
import static java.lang.invoke.MethodType.*;
-import static org.junit.Assert.*;
+import static org.testng.Assert.*;
+
import test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote;
--- a/jdk/test/java/lang/invoke/ClassValueTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/invoke/ClassValueTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,20 +26,14 @@
/* @test
* @summary tests for class-specific values
* @compile ClassValueTest.java
- * @run junit/othervm test.java.lang.invoke.ClassValueTest
- */
-
-/*
- Manually:
- $ $JAVA7X_HOME/bin/javac -d foo -cp $JUNIT4_JAR test/java/lang/invoke/ClassValueTest.java
- $ $JAVA7X_HOME/bin/java -cp foo:$JUNIT4_JAR org.junit.runner.JUnitCore test.java.lang.invoke.ClassValueTest
- Output: .testAdd => 1000 : Integer
+ * @run testng/othervm test.java.lang.invoke.ClassValueTest
*/
package test.java.lang.invoke;
-import org.junit.*;
-import static org.junit.Assert.*;
+import org.testng.*;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.*;
/**
* @author jrose
--- a/jdk/test/java/lang/invoke/InvokeGenericTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/invoke/InvokeGenericTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,7 +26,7 @@
/* @test
* @summary unit tests for java.lang.invoke.MethodHandle.invoke
* @compile InvokeGenericTest.java
- * @run junit/othervm test.java.lang.invoke.InvokeGenericTest
+ * @run testng/othervm test.java.lang.invoke.InvokeGenericTest
*/
package test.java.lang.invoke;
@@ -36,10 +36,9 @@
import static java.lang.invoke.MethodType.*;
import java.lang.reflect.*;
import java.util.*;
-import org.junit.*;
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
-
+import org.testng.*;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.*;
/**
*
@@ -71,7 +70,7 @@
String testName;
static int allPosTests, allNegTests;
int posTests, negTests;
- @After
+ @AfterMethod
public void printCounts() {
if (verbosity >= 2 && (posTests | negTests) != 0) {
System.out.println();
--- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,19 +26,9 @@
/* @test
* @summary example code used in javadoc for java.lang.invoke API
* @compile JavaDocExamplesTest.java
- * @run junit/othervm test.java.lang.invoke.JavaDocExamplesTest
+ * @run testng/othervm test.java.lang.invoke.JavaDocExamplesTest
*/
-/*
----- To run outside jtreg:
-$ $JAVA7X_HOME/bin/javac -cp $JUNIT4_JAR -d /tmp/Classes \
- $DAVINCI/sources/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
-$ $JAVA7X_HOME/bin/java -cp $JUNIT4_JAR:/tmp/Classes \
- -DJavaDocExamplesTest.verbosity=1 \
- test.java.lang.invoke.JavaDocExamplesTest
-----
-*/
-
package test.java.lang.invoke;
import java.lang.invoke.*;
@@ -47,22 +37,21 @@
import java.util.*;
-import org.junit.*;
-import static org.junit.Assert.*;
-
+import org.testng.*;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.*;
/**
* @author jrose
*/
public class JavaDocExamplesTest {
- /** Wrapper for running the JUnit tests in this module.
- * Put JUnit on the classpath!
+ /** Wrapper for running the TestNG tests in this module.
+ * Put TestNG on the classpath!
*/
public static void main(String... ignore) throws Throwable {
- System.out.println("can run this as:");
- System.out.println("$ java org.junit.runner.JUnitCore "+JavaDocExamplesTest.class.getName());
new JavaDocExamplesTest().run();
}
+
public void run() throws Throwable {
testFindVirtual();
testPermuteArguments();
--- a/jdk/test/java/lang/invoke/MethodTypeTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/invoke/MethodTypeTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -24,7 +24,7 @@
/* @test
* @summary unit tests for java.lang.invoke.MethodType
* @compile MethodTypeTest.java
- * @run junit/othervm test.java.lang.invoke.MethodTypeTest
+ * @run testng/othervm test.java.lang.invoke.MethodTypeTest
*/
package test.java.lang.invoke;
@@ -34,8 +34,9 @@
import java.lang.reflect.Method;
import java.util.*;
-import org.junit.*;
-import static org.junit.Assert.*;
+import org.testng.*;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.*;
/**
*
@@ -53,7 +54,7 @@
private MethodType[] GALLERY;
private Method compareTo;
- @Before
+ @BeforeMethod
public void setUp() throws Exception {
rtype = void.class;
ptypes = new Class<?>[] { int.class, String.class };
@@ -94,7 +95,7 @@
};
}
- @After
+ @AfterMethod
public void tearDown() throws Exception {
}
--- a/jdk/test/java/lang/invoke/PermuteArgsTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/invoke/PermuteArgsTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,7 +25,7 @@
/* @test
* @summary unit tests for method handles which permute their arguments
- * @run junit/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
+ * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
*/
/* Examples of manual runs:
* java -DPermuteArgsTest.{DRY_RUN=true,MAX_ARITY=253} test.java.lang.invoke.PermuteArgsTest
@@ -35,7 +35,8 @@
package test.java.lang.invoke;
-import org.junit.*;
+import org.testng.*;
+import org.testng.annotations.*;
import java.util.*;
import java.lang.reflect.*;
--- a/jdk/test/java/lang/invoke/ThrowExceptionsTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/invoke/ThrowExceptionsTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,12 +25,13 @@
/* @test
* @summary unit tests for method handles which permute their arguments
- * @run junit test.java.lang.invoke.ThrowExceptionsTest
+ * @run testng test.java.lang.invoke.ThrowExceptionsTest
*/
package test.java.lang.invoke;
-import org.junit.*;
+import org.testng.*;
+import org.testng.annotations.*;
import java.util.*;
import java.lang.reflect.*;
--- a/jdk/test/java/lang/reflect/Method/GenericStringTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/lang/reflect/Method/GenericStringTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -48,10 +48,18 @@
if (egs != null) {
String actual = method.toGenericString();
System.out.println(actual);
- if (! egs.value().equals(actual)) {
- failures++;
- System.err.printf("ERROR: Expected ''%s''; got ''%s''.\n",
- egs.value(), actual);
+ if (method.isBridge()) {
+ if (! egs.bridgeValue().equals(actual)) {
+ failures++;
+ System.err.printf("ERROR: Expected ''%s''; got ''%s''.\n",
+ egs.value(), actual);
+ }
+ } else {
+ if (! egs.value().equals(actual)) {
+ failures++;
+ System.err.printf("ERROR: Expected ''%s''; got ''%s''.\n",
+ egs.value(), actual);
+ }
}
}
@@ -117,7 +125,8 @@
class Roebling implements Comparable<Roebling> {
@ExpectedGenericString(
- "public int Roebling.compareTo(Roebling)")
+ value="public int Roebling.compareTo(Roebling)",
+ bridgeValue="public int Roebling.compareTo(java.lang.Object)")
public int compareTo(Roebling r) {
throw new IllegalArgumentException();
}
@@ -154,9 +163,11 @@
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedGenericString {
String value();
+ String bridgeValue() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedString {
String value();
}
+
--- a/jdk/test/java/math/BigInteger/BigIntegerTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/math/BigInteger/BigIntegerTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -74,10 +74,10 @@
static final int ORDER_SMALL = 60;
static final int ORDER_MEDIUM = 100;
- // #bits for testing Karatsuba and Burnikel-Ziegler
+ // #bits for testing Karatsuba
static final int ORDER_KARATSUBA = 1800;
- // #bits for testing Toom-Cook
- static final int ORDER_TOOM_COOK = 3000;
+ // #bits for testing Toom-Cook and Burnikel-Ziegler
+ static final int ORDER_TOOM_COOK = 4000;
// #bits for testing Karatsuba squaring
static final int ORDER_KARATSUBA_SQUARE = 3200;
// #bits for testing Toom-Cook squaring
@@ -964,12 +964,12 @@
nextProbablePrime();
arithmetic(order1); // small numbers
- arithmetic(order3); // Karatsuba / Burnikel-Ziegler range
- arithmetic(order4); // Toom-Cook range
+ arithmetic(order3); // Karatsuba range
+ arithmetic(order4); // Toom-Cook / Burnikel-Ziegler range
divideAndRemainder(order1); // small numbers
- divideAndRemainder(order3); // Karatsuba / Burnikel-Ziegler range
- divideAndRemainder(order4); // Toom-Cook range
+ divideAndRemainder(order3); // Karatsuba range
+ divideAndRemainder(order4); // Toom-Cook / Burnikel-Ziegler range
pow(order1);
pow(order3);
@@ -989,8 +989,8 @@
byteArrayConv(order1);
modInv(order1); // small numbers
- modInv(order3); // Karatsuba / Burnikel-Ziegler range
- modInv(order4); // Toom-Cook range
+ modInv(order3); // Karatsuba range
+ modInv(order4); // Toom-Cook / Burnikel-Ziegler range
modExp(order1, order2);
modExp2(order1);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/IDN/IllegalArg.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8020842
+ * @summary IDN do not throw IAE when hostname ends with a trailing dot
+ */
+
+import java.net.*;
+
+public class IllegalArg {
+
+ public static void main(String[] args) throws Exception {
+ String[] illegalNames = {
+ "com..net",
+ "com..",
+ ".com",
+ ".com."
+ };
+
+ String[] legalNames = {
+ "example.com",
+ "com\u3002",
+ "com.",
+ "."
+ };
+
+ for (String name : illegalNames) {
+ try {
+ IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES);
+ throw new Exception(
+ "Expected to get IllegalArgumentException for " + name);
+ } catch (IllegalArgumentException iae) {
+ // That's the right behavior.
+ }
+
+ try {
+ IDN.toASCII(name);
+ throw new Exception(
+ "Expected to get IllegalArgumentException for " + name);
+ } catch (IllegalArgumentException iae) {
+ // That's the right behavior.
+ }
+ }
+
+ for (String name : legalNames) {
+ System.out.println("Convering " + name);
+ System.out.println(IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/NetworkInterface/MemLeakTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8022584
+ * @summary Some NetworkInterface methods can leak native memory
+ * @run main/othervm/timeout=700 MemLeakTest
+ */
+
+/* Note: the test can cause a memory leak that's why othervm option is required
+ */
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Collection;
+import java.util.Collections;
+
+public class MemLeakTest {
+
+ /**
+ * Memory leak is assumed, if application consumes more than specified amount of memory during its execution.
+ * The number is given in Kb.
+ */
+ private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32Mb
+
+ public static void main(String[] args)
+ throws Exception {
+
+ if (!System.getProperty("os.name").equals("Linux")) {
+ System.out.println("Test only runs on Linux");
+ return;
+ }
+
+ // warm up
+ accessNetInterfaces(3);
+
+ long vMemBefore = getVMemSize();
+ accessNetInterfaces(500_000);
+ long vMemAfter = getVMemSize();
+
+ long vMemDelta = vMemAfter - vMemBefore;
+ if (vMemDelta > MEM_LEAK_THRESHOLD) {
+ throw new Exception("FAIL: Virtual memory usage increased by " + vMemDelta + "Kb " +
+ "(greater than " + MEM_LEAK_THRESHOLD + "Kb)");
+ }
+
+ System.out.println("PASS: Virtual memory usage increased by " + vMemDelta + "Kb " +
+ "(not greater than " + MEM_LEAK_THRESHOLD + "Kb)");
+ }
+
+ private static void accessNetInterfaces(int times) {
+ try {
+ Collection<NetworkInterface> interfaces =
+ Collections.list(NetworkInterface.getNetworkInterfaces());
+ for (int i = 0; i != times; ++i) {
+ for (NetworkInterface netInterface : interfaces) {
+ netInterface.getMTU();
+ netInterface.isLoopback();
+ netInterface.isUp();
+ netInterface.isPointToPoint();
+ netInterface.supportsMulticast();
+ }
+ }
+ } catch (SocketException ignore) {}
+ }
+
+ /**
+ * Returns size of virtual memory allocated to the process in Kb.
+ * Linux specific. On other platforms and in case of any errors returns 0.
+ */
+ private static long getVMemSize() {
+
+ // Refer to the Linux proc(5) man page for details about /proc/self/stat file
+ //
+ // In short, this file contains status information about the current process
+ // written in one line. The fields are separated with spaces.
+ // The 23rd field is defined as 'vsize %lu Virtual memory size in bytes'
+
+ try (FileReader fileReader = new FileReader("/proc/self/stat");
+ BufferedReader bufferedReader = new BufferedReader(fileReader)) {
+ String line = bufferedReader.readLine();
+ return Long.parseLong(line.split(" ")[22]) / 1024;
+ } catch (Exception ignore) {}
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/ServerSocket/SelectFdsLimit.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8021820
+ * @summary The total number of file descriptors is limited to
+ * 1024(FDSET_SIZE) on MacOSX (the size of fd array passed to select()
+ * call in java.net classes is limited to this value).
+ * @run main/othervm SelectFdsLimit
+ * @author aleksej.efimov@oracle.com
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ServerSocket;
+import java.net.SocketTimeoutException;
+
+
+/*
+ * Test must be run in othervm mode to ensure that all files
+ * opened by openFiles() are closed propertly.
+*/
+public class SelectFdsLimit {
+ static final int FDTOOPEN = 1023;
+ static final String TESTFILE = "testfile";
+ static FileInputStream [] testFIS;
+
+ static void prepareTestEnv() throws IOException {
+ File fileToCreate = new File(TESTFILE);
+ if (!fileToCreate.exists())
+ if (!fileToCreate.createNewFile())
+ throw new RuntimeException("Can't create test file");
+ }
+
+ //If there will be some problem (i.e. ulimits on number of opened files will fail)
+ //then this method will fail with exception and test will be considered as
+ //failed. But allocated fds will be released because the test is executed by
+ //dedicated VM (@run main/othervm).
+ static void openFiles(int fn, File f) throws FileNotFoundException, IOException {
+ testFIS = new FileInputStream[FDTOOPEN];
+ for (;;) {
+ if (0 == fn)
+ break;
+ FileInputStream fis = new FileInputStream(f);
+ testFIS[--fn] = fis;
+ }
+ }
+
+ public static void main(String [] args) throws IOException, FileNotFoundException {
+
+ //The bug 8021820 is a Mac specific and because of that test will pass on all
+ //other platforms
+ if (!System.getProperty("os.name").contains("OS X")) {
+ return;
+ }
+
+ //Create test directory with test files
+ prepareTestEnv();
+
+ //Consume FD ids for this java process to overflow the 1024
+ openFiles(FDTOOPEN,new File(TESTFILE));
+
+ //Wait for incoming connection and make the select() used in java.net
+ //classes fail the limitation on FDSET_SIZE
+ ServerSocket socket = new ServerSocket(0);
+
+ //Set the minimal timeout, no one is
+ //going to connect to this server socket
+ socket.setSoTimeout(1);
+
+ // The accept() call will throw SocketException if the
+ // select() has failed due to limitation on fds size,
+ // indicating test failure. A SocketTimeoutException
+ // is expected, so it is caught and ignored, and the test
+ // passes.
+ try {
+ socket.accept();
+ } catch (SocketTimeoutException e) { }
+ }
+}
--- a/jdk/test/java/net/URLClassLoader/profiles/Basic.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-import java.net.*;
-import java.io.File;
-import java.util.jar.*;
-
-/**
- * Attempts to load classes or resources from a JAR file. The load should succeed
- * if the runtime supports the profile indicated by the Profile attribute, fail
- * with UnsupportedProfileException otherwise.
- */
-
-public class Basic {
-
- static int indexOf(String profile) {
- if (profile == null || "compact1".equals(profile)) return 1;
- if ("compact2".equals(profile)) return 2;
- if ("compact3".equals(profile)) return 3;
- if ("".equals(profile)) return 4;
- return Integer.MAX_VALUE; // unknown profile name
- }
-
- public static void main(String[] args) throws Exception {
- if (args.length < 2)
- throw new RuntimeException("Usage: java <jarfile> <classname>");
- String jar = args[0];
- String cn = args[1];
-
- File lib = new File(jar);
- URL url = lib.toURI().toURL();
- URL urls[] = { url };
-
- // ## replace this if there is a standard way to determine the profile
- String thisProfile = sun.misc.Version.profileName();
-
- String jarProfile = null;
- try (JarFile jf = new JarFile(lib)) {
- Manifest manifest = jf.getManifest();
- if (manifest != null) {
- Attributes mainAttrs = manifest.getMainAttributes();
- if (mainAttrs != null) {
- jarProfile = mainAttrs.getValue(Attributes.Name.PROFILE);
- }
- }
- }
-
- boolean shouldFail = indexOf(thisProfile) < indexOf(jarProfile);
-
- try (URLClassLoader cl = new URLClassLoader(urls)) {
- System.out.format("Loading %s from %s ...%n", cn, jar);
- Class<?> c = Class.forName(cn, true, cl);
- System.out.println(c);
- if (shouldFail)
- throw new RuntimeException("UnsupportedProfileException expected");
- } catch (UnsupportedProfileException x) {
- if (!shouldFail)
- throw x;
- System.out.println("UnsupportedProfileException thrown as expected");
- }
-
- try (URLClassLoader cl = new URLClassLoader(urls)) {
- System.out.format("Loading resource from %s ...%n", jar);
- URL r = cl.findResource("META-INF/MANIFEST.MF");
- System.out.println(r);
- if (shouldFail)
- throw new RuntimeException("UnsupportedProfileException expected");
- } catch (UnsupportedProfileException x) {
- if (!shouldFail)
- throw x;
- System.out.println("UnsupportedProfileException thrown as expected");
- }
- }
-}
-
--- a/jdk/test/java/net/URLClassLoader/profiles/Lib.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package lib;
-
-public class Lib {
- private Lib() { }
-
- public static void doSomething() { }
-}
--- a/jdk/test/java/net/URLClassLoader/profiles/basic.sh Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-#
-# Copyright (c) 2012, 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
-# @bug 8003255
-# @compile -XDignore.symbol.file Basic.java Lib.java
-# @summary Test that UnsupportedProfileException thrown when attempting to
-# load classes or resources from a JAR file with the Profile attribute
-# @run shell basic.sh
-
-if [ -z "$TESTJAVA" ]; then
- if [ $# -lt 1 ]; then exit 1; fi
- TESTJAVA=$1; shift
- COMPILEJAVA=$TESTJAVA
- TESTSRC=`pwd`
- TESTCLASSES=`pwd`
-fi
-
-echo "Creating GoodLib.jar ..."
-echo "Profile: compact3" > good.mf
-$COMPILEJAVA/bin/jar cvfm GoodLib.jar good.mf -C $TESTCLASSES lib
-
-echo "Create BadLib.jar ..."
-echo "Profile: badname" > bad.mf
-$COMPILEJAVA/bin/jar cvfm BadLib.jar bad.mf -C $TESTCLASSES lib
-
-# remove classes so that they aren't on the classpath
-rm -rf $TESTCLASSES/lib
-
-echo "Test with GoodLib.jar ..."
-$TESTJAVA/bin/java -cp $TESTCLASSES Basic GoodLib.jar lib.Lib
-
-echo "Test with BadLib.jar ..."
-$TESTJAVA/bin/java -cp $TESTCLASSES Basic BadLib.jar lib.Lib
-
--- a/jdk/test/java/nio/channels/ServerSocketChannel/AdaptServerSocket.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/AdaptServerSocket.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,7 +35,7 @@
public class AdaptServerSocket {
static java.io.PrintStream out = System.out;
-
+ static volatile boolean clientStarted = false;
static volatile Exception clientException = null;
static volatile Thread client = null;
@@ -44,15 +44,14 @@
{
Thread t = new Thread() {
public void run() {
- try {
- Socket so = new Socket();
+ try (Socket so = new Socket()) {
out.println("client: " + so);
+ clientStarted = true;
if (dally > 0)
Thread.sleep(dally);
so.connect(new InetSocketAddress(port));
if (Thread.interrupted()) {
out.println("client interrupted");
- so.close();
return;
}
out.println("client: " + so);
@@ -61,7 +60,6 @@
a += 1;
so.getOutputStream().write(a);
out.println("client: wrote " + a);
- so.close();
} catch (Exception x) {
if (x instanceof InterruptedException)
return;
@@ -78,43 +76,44 @@
static void test(int clientDally, int timeout, boolean shouldTimeout)
throws Exception
{
+ clientStarted = false;
out.println();
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ServerSocket sso = ssc.socket();
- out.println("created: " + ssc);
- out.println(" " + sso);
- if (timeout != 0)
- sso.setSoTimeout(timeout);
- out.println("timeout: " + sso.getSoTimeout());
- sso.bind(null);
- out.println("bound: " + ssc);
- out.println(" " + sso);
- startClient(sso.getLocalPort(), clientDally);
- Thread.sleep(10);
+ try (ServerSocketChannel ssc = ServerSocketChannel.open();
+ ServerSocket sso = ssc.socket()) {
+ out.println("created: " + ssc);
+ out.println(" " + sso);
+ if (timeout != 0)
+ sso.setSoTimeout(timeout);
+ out.println("timeout: " + sso.getSoTimeout());
+ sso.bind(null);
+ out.println("bound: " + ssc);
+ out.println(" " + sso);
+ startClient(sso.getLocalPort(), clientDally);
+ while (!clientStarted) {
+ Thread.sleep(20);
+ }
+ Socket so = null;
+ try {
+ so = sso.accept();
+ } catch (SocketTimeoutException x) {
+ if (shouldTimeout)
+ out.println("Accept timed out, as expected");
+ else
+ throw x;
+ }
+ if (shouldTimeout && (so != null))
+ throw new Exception("Accept did not time out");
- Socket so = null;
- try {
- so = sso.accept();
- } catch (SocketTimeoutException x) {
- if (shouldTimeout)
- out.println("Accept timed out, as expected");
- else
- throw x;
+ if (so != null) {
+ int a = 42;
+ so.getOutputStream().write(a);
+ int b = so.getInputStream().read();
+ if (b != a + 1)
+ throw new Exception("Read incorrect data");
+ out.println("server: read " + b);
+ }
}
- if (shouldTimeout && (so != null))
- throw new Exception("Accept did not time out");
-
- if (so != null) {
- int a = 42;
- so.getOutputStream().write(a);
- int b = so.getInputStream().read();
- if (b != a + 1)
- throw new Exception("Read incorrect data");
- out.println("server: read " + b);
- sso.close();
- }
-
client.interrupt();
client.join();
if (clientException != null)
--- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java Wed Jul 05 19:09:26 2017 +0200
@@ -148,7 +148,7 @@
@DataProvider(name = "calendarDisplayName")
Object[][] data_of_calendarDisplayNames() {
return new Object[][] {
- {"Hijrah", "Hijrah-umalqura"},
+ {"Hijrah", "Islamic Umm al-Qura Calendar"},
{"ISO", "ISO"},
{"Japanese", "Japanese Calendar"},
{"Minguo", "Minguo Calendar"},
--- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Jul 05 19:09:26 2017 +0200
@@ -438,13 +438,13 @@
// Test to verify the formatted dates
@Test(dataProvider="patternMonthNames")
public void test_ofPattern(int year, int month, int day, String expected) {
- DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy");
+ DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy", Locale.US);
assertEquals(test.format(HijrahDate.of(year, month, day)), expected);
}
// Data provider for localized dates
@DataProvider(name="chronoDateTimes")
- Object[][] data_chronodatetimes() {
+ Object[][] data_chronodatetimes() {
return new Object[][] {
{1432, 12, 29, "Safar 1, 1434 AH"},
{1433, 1, 30, "Safar 30, 1434 AH"},
@@ -463,7 +463,7 @@
hdt = hdt.plus(1, ChronoUnit.HOURS);
hdt = hdt.plus(1, ChronoUnit.MINUTES);
hdt = hdt.plus(1, ChronoUnit.SECONDS);
- DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.forLanguageTag("en-US"));
+ DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.US);
assertEquals(df.format(hdt), expected);
}
--- a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java Wed Jul 05 19:09:26 2017 +0200
@@ -110,7 +110,7 @@
// Chronology, Locale, Chronology Name
{ ISO8601, Locale.ENGLISH, "ISO" }, // No data in CLDR; Use Id.
{ BUDDHIST, Locale.ENGLISH, "Buddhist Calendar" },
- { HIJRAH, Locale.ENGLISH, "Hijrah-umalqura" }, // No data in CLDR; Use Id.
+ { HIJRAH, Locale.ENGLISH, "Islamic Umm al-Qura Calendar" }, // JDK-8015986
{ JAPANESE, Locale.ENGLISH, "Japanese Calendar" },
{ MINGUO, Locale.ENGLISH, "Minguo Calendar" },
@@ -121,6 +121,10 @@
{ ISO8601, thTH, "ISO" }, // No data in CLDR; Use Id.
{ JAPANESE, thTH, "\u0e1b\u0e0f\u0e34\u0e17\u0e34\u0e19\u0e0d\u0e35\u0e48\u0e1b\u0e38\u0e48\u0e19" },
{ BUDDHIST, thTH, "\u0e1b\u0e0f\u0e34\u0e17\u0e34\u0e19\u0e1e\u0e38\u0e17\u0e18" },
+
+ { HIJRAH, ARABIC, "\u0644\u062a\u0642\u0648\u064a\u0645 "
+ + "\u0627\u0644\u0647\u062c\u0631\u064a\u060c "
+ + "\u0623\u0645 \u0627\u0644\u0642\u0631\u0649" }, // JDK-8015986
};
}
--- a/jdk/test/java/time/test/java/util/TestFormatter.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/time/test/java/util/TestFormatter.java Wed Jul 05 19:09:26 2017 +0200
@@ -22,16 +22,27 @@
*/
package test.java.util;
+import static org.testng.Assert.assertEquals;
+
import java.time.Instant;
+import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.ZoneId;
+
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.chrono.Chronology;
+
import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalAccessor;
import java.util.*;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import static org.testng.Assert.assertEquals;
/* @test
* @summary Unit test for j.u.Formatter threeten date/time support
@@ -57,18 +68,32 @@
private int total = 0;
private int failure = 0;
- private boolean verbose = true;
+ private boolean verbose = false;
- @Test
- public void test () {
+ @DataProvider(name = "calendarsByLocale")
+ Object[][] data_calendars() {
+ return new Object[][] {
+ {"en_US"},
+ {"th_TH"},
+ {"ja-JP-u-ca-japanese"},
+ };
+ }
+ @Test(dataProvider="calendarsByLocale")
+ public void test (String calendarLocale) {
+ failure = 0;
int N = 12;
//locales = Locale.getAvailableLocales();
Locale[] locales = new Locale[] {
Locale.ENGLISH, Locale.FRENCH, Locale.JAPANESE, Locale.CHINESE};
Random r = new Random();
- ZonedDateTime zdt0 = ZonedDateTime.now();
- ZonedDateTime[] zdts = new ZonedDateTime[] {
+
+ Locale calLocale = Locale.forLanguageTag(calendarLocale);
+ Chronology chrono = Chronology.ofLocale(calLocale);
+ ChronoLocalDate now = chrono.dateNow();
+ ChronoLocalDateTime<?> ldt0 = now.atTime(LocalTime.now());
+ ChronoZonedDateTime<?> zdt0 = ldt0.atZone(ZoneId.systemDefault());
+ ChronoZonedDateTime<?>[] zdts = new ChronoZonedDateTime<?>[] {
zdt0,
zdt0.withZoneSameLocal(ZoneId.of("UTC")),
zdt0.withZoneSameLocal(ZoneId.of("GMT")),
@@ -76,11 +101,11 @@
};
while (N-- > 0) {
- for (ZonedDateTime zdt : zdts) {
- zdt = zdt.withDayOfYear(r.nextInt(365) + 1)
+ for (ChronoZonedDateTime<?> zdt : zdts) {
+ zdt = zdt.with(ChronoField.DAY_OF_YEAR, (r.nextInt(365) + 1))
.with(ChronoField.SECOND_OF_DAY, r.nextInt(86400));
Instant instant = zdt.toInstant();
- Calendar cal = Calendar.getInstance();
+ Calendar cal = Calendar.getInstance(calLocale);
cal.setTimeInMillis(instant.toEpochMilli());
cal.setTimeZone(TimeZone.getTimeZone(zdt.getZone()));
for (Locale locale : locales) {
@@ -106,8 +131,19 @@
}
private String getClassName(Object o) {
- Class c = o.getClass();
- return c.getName().substring(c.getPackage().getName().length() + 1);
+ Class<?> c = o.getClass();
+ String clname = c.getName().substring(c.getPackage().getName().length() + 1);
+ if (o instanceof TemporalAccessor) {
+ Chronology chrono = ((TemporalAccessor)o).query(TemporalQuery.chronology());
+ if (chrono != null) {
+ clname = clname + "(" + chrono.getId() + ")";
+ }
+ }
+ if (o instanceof Calendar) {
+ String type = ((Calendar)o).getCalendarType();
+ clname = clname + "(" + type + ")";
+ }
+ return clname;
}
private String test(String fmtStr, Locale locale,
@@ -115,12 +151,12 @@
String out = new Formatter(
new StringBuilder(), locale).format(fmtStr, dt).out().toString();
if (verbose) {
- System.out.printf("%-18s : %s%n", getClassName(dt), out);
+ System.out.printf("%-24s : %s%n", getClassName(dt), out);
}
if (expected != null && !out.equals(expected)) {
- System.out.printf("=====>%-18s : %s [ FAILED expected: %s ]%n",
+ System.out.printf("%-24s actual: %s%n FAILED; expected: %s%n",
getClassName(dt), out, expected);
- new RuntimeException().printStackTrace();
+ new RuntimeException().printStackTrace(System.out);
failure++;
}
total++;
@@ -135,24 +171,29 @@
}
private void testDate(String fmtStr, Locale locale,
- ZonedDateTime zdt, Calendar cal) {
+ ChronoZonedDateTime<?> zdt, Calendar cal) {
printFmtStr(locale, fmtStr);
String expected = test(fmtStr, locale, null, cal);
test(fmtStr, locale, expected, zdt);
- test(fmtStr, locale, expected, zdt.toOffsetDateTime());
test(fmtStr, locale, expected, zdt.toLocalDateTime());
test(fmtStr, locale, expected, zdt.toLocalDate());
+ if (zdt instanceof ZonedDateTime) {
+ test(fmtStr, locale, expected, ((ZonedDateTime)zdt).toOffsetDateTime());
+ }
}
private void testTime(String fmtStr, Locale locale,
- ZonedDateTime zdt, Calendar cal) {
+ ChronoZonedDateTime<?> zdt, Calendar cal) {
printFmtStr(locale, fmtStr);
String expected = test(fmtStr, locale, null, cal);
test(fmtStr, locale, expected, zdt);
- test(fmtStr, locale, expected, zdt.toOffsetDateTime());
test(fmtStr, locale, expected, zdt.toLocalDateTime());
- test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime());
test(fmtStr, locale, expected, zdt.toLocalTime());
+ if (zdt instanceof ZonedDateTime) {
+ OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime();
+ test(fmtStr, locale, expected, odt);
+ test(fmtStr, locale, expected, odt.toOffsetTime());
+ }
}
private String toZoneIdStr(String expected) {
@@ -164,7 +205,7 @@
.replaceAll("GMT|UTC|UT", "Z");
}
- private void testZoneId(Locale locale, ZonedDateTime zdt, Calendar cal) {
+ private void testZoneId(Locale locale, ChronoZonedDateTime<?> zdt, Calendar cal) {
String fmtStr = "z:[%tz] z:[%1$Tz] Z:[%1$tZ] Z:[%1$TZ]";
printFmtStr(locale, fmtStr);
String expected = toZoneIdStr(test(fmtStr, locale, null, cal));
@@ -174,8 +215,11 @@
cal0.setTimeInMillis(zdt.toInstant().toEpochMilli());
cal0.setTimeZone(TimeZone.getTimeZone("GMT" + zdt.getOffset().getId()));
expected = toZoneOffsetStr(test(fmtStr, locale, null, cal0));
- test(fmtStr, locale, expected, zdt.toOffsetDateTime());
- test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime());
+ if (zdt instanceof ZonedDateTime) {
+ OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime();
+ test(fmtStr, locale, expected, odt);
+ test(fmtStr, locale, expected, odt.toOffsetTime());
+ }
// datetime + zid
fmtStr = "c:[%tc] c:[%1$Tc]";
@@ -185,12 +229,15 @@
}
private void testInstant(Locale locale, Instant instant,
- ZonedDateTime zdt, Calendar cal) {
+ ChronoZonedDateTime<?> zdt, Calendar cal) {
String fmtStr = "s:[%ts] s:[%1$Ts] Q:[%1$tQ] Q:[%1$TQ]";
printFmtStr(locale, fmtStr);
String expected = test(fmtStr, locale, null, cal);
test(fmtStr, locale, expected, instant);
test(fmtStr, locale, expected, zdt);
- test(fmtStr, locale, expected, zdt.toOffsetDateTime());
+ if (zdt instanceof ZonedDateTime) {
+ OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime();
+ test(fmtStr, locale, expected, odt);
+ }
}
}
--- a/jdk/test/java/util/Collection/ListDefaults.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/Collection/ListDefaults.java Wed Jul 05 19:09:26 2017 +0200
@@ -49,6 +49,7 @@
/**
* @test
+ * @bug 8023367
* @library testlibrary
* @build CollectionAsserts CollectionSupplier
* @run testng ListDefaults
@@ -100,6 +101,7 @@
@DataProvider(name="listProvider", parallel=true)
public static Object[][] listCases() {
final List<Object[]> cases = new LinkedList<>();
+ cases.add(new Object[] { Collections.emptyList() });
cases.add(new Object[] { new ArrayList<>() });
cases.add(new Object[] { new LinkedList<>() });
cases.add(new Object[] { new Vector<>() });
@@ -128,6 +130,11 @@
list.removeIf(null);
fail("expected NPE not thrown");
} catch (NullPointerException npe) {}
+ try {
+ list.sort(null);
+ } catch (Throwable t) {
+ fail("Exception not expected: " + t);
+ }
}
@Test
--- a/jdk/test/java/util/Collection/MOAT.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/Collection/MOAT.java Wed Jul 05 19:09:26 2017 +0200
@@ -30,7 +30,6 @@
* @summary Run many tests on many Collection and Map implementations
* @author Martin Buchholz
* @run main MOAT
- * @run main/othervm -XX:+AggressiveOpts MOAT
*/
/* Mother Of All (Collection) Tests
--- a/jdk/test/java/util/Comparator/TypeTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/Comparator/TypeTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -75,7 +75,7 @@
}
}
- public static void main(String[] args) {
+ public void testOrder() {
Manager m1 = new Manager("Manager", 2, 2000);
Manager m2 = new Manager("Manager", 4, 1300);
--- a/jdk/test/java/util/Currency/tablea1.txt Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/Currency/tablea1.txt Wed Jul 05 19:09:26 2017 +0200
@@ -1,12 +1,12 @@
#
#
-# Amendments up until ISO 4217 AMENDMENT NUMBER 155
-# (As of 11 April 2013)
+# Amendments up until ISO 4217 AMENDMENT NUMBER 156
+# (As of 23 July 2013)
#
# Version
FILEVERSION=1
-DATAVERSION=155
+DATAVERSION=156
# ISO 4217 currency data
AF AFN 971 2
@@ -135,7 +135,7 @@
KW KWD 414 3
KG KGS 417 2
LA LAK 418 2
-LV LVL 428 2
+LV LVL 428 2 2013-12-31-22-00-00 EUR 978 2
LB LBP 422 2
#LS ZAR 710 2
LS LSL 426 2
--- a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8020156 8020009
+ * @bug 8020156 8020009 8022326
* @run testng SpliteratorCharacteristics
*/
@@ -32,80 +32,134 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
import java.util.Spliterator;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentSkipListSet;
import static org.testng.Assert.*;
@Test
public class SpliteratorCharacteristics {
- public void testTreeMap() {
- TreeMap<Integer, String> tm = new TreeMap<>();
- tm.put(1, "4");
- tm.put(2, "3");
- tm.put(3, "2");
- tm.put(4, "1");
+ // TreeMap
- assertCharacteristics(tm.keySet(),
- Spliterator.SIZED | Spliterator.DISTINCT |
- Spliterator.SORTED | Spliterator.ORDERED);
- assertNullComparator(tm.keySet());
-
- assertCharacteristics(tm.values(),
- Spliterator.SIZED | Spliterator.ORDERED);
- assertISEComparator(tm.values());
-
- assertCharacteristics(tm.entrySet(),
- Spliterator.SIZED | Spliterator.DISTINCT |
- Spliterator.SORTED | Spliterator.ORDERED);
- assertNotNullComparator(tm.entrySet());
+ public void testTreeMap() {
+ assertSortedMapCharacteristics(new TreeMap<>(),
+ Spliterator.SIZED | Spliterator.DISTINCT |
+ Spliterator.SORTED | Spliterator.ORDERED);
}
public void testTreeMapWithComparator() {
- TreeMap<Integer, String> tm = new TreeMap<>(Comparator.<Integer>reverseOrder());
- tm.put(1, "4");
- tm.put(2, "3");
- tm.put(3, "2");
- tm.put(4, "1");
-
- assertCharacteristics(tm.keySet(),
- Spliterator.SIZED | Spliterator.DISTINCT |
- Spliterator.SORTED | Spliterator.ORDERED);
- assertNotNullComparator(tm.keySet());
-
- assertCharacteristics(tm.values(),
- Spliterator.SIZED | Spliterator.ORDERED);
- assertISEComparator(tm.values());
-
- assertCharacteristics(tm.entrySet(),
- Spliterator.SIZED | Spliterator.DISTINCT |
- Spliterator.SORTED | Spliterator.ORDERED);
- assertNotNullComparator(tm.entrySet());
+ assertSortedMapCharacteristics(new TreeMap<>(Comparator.reverseOrder()),
+ Spliterator.SIZED | Spliterator.DISTINCT |
+ Spliterator.SORTED | Spliterator.ORDERED);
}
- public void testTreeSet() {
- TreeSet<Integer> ts = new TreeSet<>();
- ts.addAll(Arrays.asList(1, 2, 3, 4));
+
+ // TreeSet
- assertCharacteristics(ts,
- Spliterator.SIZED | Spliterator.DISTINCT |
- Spliterator.SORTED | Spliterator.ORDERED);
- assertNullComparator(ts);
+ public void testTreeSet() {
+ assertSortedSetCharacteristics(new TreeSet<>(),
+ Spliterator.SIZED | Spliterator.DISTINCT |
+ Spliterator.SORTED | Spliterator.ORDERED);
}
public void testTreeSetWithComparator() {
- TreeSet<Integer> ts = new TreeSet<>(Comparator.reverseOrder());
- ts.addAll(Arrays.asList(1, 2, 3, 4));
+ assertSortedSetCharacteristics(new TreeSet<>(Comparator.reverseOrder()),
+ Spliterator.SIZED | Spliterator.DISTINCT |
+ Spliterator.SORTED | Spliterator.ORDERED);
+ }
+
+
+ // ConcurrentSkipListMap
+
+ public void testConcurrentSkipListMap() {
+ assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(),
+ Spliterator.CONCURRENT | Spliterator.NONNULL |
+ Spliterator.DISTINCT | Spliterator.SORTED |
+ Spliterator.ORDERED);
+ }
- assertCharacteristics(ts,
- Spliterator.SIZED | Spliterator.DISTINCT |
- Spliterator.SORTED | Spliterator.ORDERED);
- assertNotNullComparator(ts);
+ public void testConcurrentSkipListMapWithComparator() {
+ assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(Comparator.<Integer>reverseOrder()),
+ Spliterator.CONCURRENT | Spliterator.NONNULL |
+ Spliterator.DISTINCT | Spliterator.SORTED |
+ Spliterator.ORDERED);
+ }
+
+
+ // ConcurrentSkipListSet
+
+ public void testConcurrentSkipListSet() {
+ assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(),
+ Spliterator.CONCURRENT | Spliterator.NONNULL |
+ Spliterator.DISTINCT | Spliterator.SORTED |
+ Spliterator.ORDERED);
+ }
+
+ public void testConcurrentSkipListSetWithComparator() {
+ assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(Comparator.reverseOrder()),
+ Spliterator.CONCURRENT | Spliterator.NONNULL |
+ Spliterator.DISTINCT | Spliterator.SORTED |
+ Spliterator.ORDERED);
}
+ //
+
+ void assertSortedMapCharacteristics(SortedMap<Integer, String> m, int keyCharacteristics) {
+ initMap(m);
+
+ boolean hasComparator = m.comparator() != null;
+
+ Set<Integer> keys = m.keySet();
+ assertCharacteristics(keys, keyCharacteristics);
+ if (hasComparator) {
+ assertNotNullComparator(keys);
+ }
+ else {
+ assertNullComparator(keys);
+ }
+
+ assertCharacteristics(m.values(),
+ keyCharacteristics & ~(Spliterator.DISTINCT | Spliterator.SORTED));
+ assertISEComparator(m.values());
+
+ assertCharacteristics(m.entrySet(), keyCharacteristics);
+ assertNotNullComparator(m.entrySet());
+ }
+
+ void assertSortedSetCharacteristics(SortedSet<Integer> s, int keyCharacteristics) {
+ initSet(s);
+
+ boolean hasComparator = s.comparator() != null;
+
+ assertCharacteristics(s, keyCharacteristics);
+ if (hasComparator) {
+ assertNotNullComparator(s);
+ }
+ else {
+ assertNullComparator(s);
+ }
+ }
+
+ void initMap(Map<Integer, String> m) {
+ m.put(1, "4");
+ m.put(2, "3");
+ m.put(3, "2");
+ m.put(4, "1");
+ }
+
+ void initSet(Set<Integer> s) {
+ s.addAll(Arrays.asList(1, 2, 3, 4));
+ }
+
void assertCharacteristics(Collection<?> c, int expectedCharacteristics) {
assertCharacteristics(c.spliterator(), expectedCharacteristics);
}
--- a/jdk/test/java/util/Spliterator/SpliteratorCollisions.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/Spliterator/SpliteratorCollisions.java Wed Jul 05 19:09:26 2017 +0200
@@ -148,7 +148,6 @@
List<Object[]> data = new ArrayList<>();
for (int size : SIZES) {
List<HashableInteger> exp = listIntRange(size, true);
- exp.add(0, null);
SpliteratorDataBuilder<HashableInteger> db = new SpliteratorDataBuilder<>(data, exp);
// Maps
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarInputStream/ExtraFileInMetaInf.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8021788
+ * @summary JarInputStream doesn't provide certificates for some file under META-INF
+ */
+
+import java.util.jar.*;
+import java.io.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ExtraFileInMetaInf {
+ public static void main(String args[]) throws Exception {
+
+ // Create a zip file with 2 entries
+ try (ZipOutputStream zos =
+ new ZipOutputStream(new FileOutputStream("x.jar"))) {
+ zos.putNextEntry(new ZipEntry("META-INF/SUB/file"));
+ zos.write(new byte[10]);
+ zos.putNextEntry(new ZipEntry("x"));
+ zos.write(new byte[10]);
+ zos.close();
+ }
+
+ // Sign it
+ new File("ks").delete();
+ sun.security.tools.keytool.Main.main(
+ ("-keystore ks -storepass changeit -keypass changeit " +
+ "-alias a -dname CN=A -genkeypair").split(" "));
+ sun.security.tools.jarsigner.Main.main(
+ "-keystore ks -storepass changeit x.jar a".split(" "));
+
+ // Check if the entries are signed
+ try (JarInputStream jis =
+ new JarInputStream(new FileInputStream("x.jar"))) {
+ JarEntry je;
+ while ((je = jis.getNextJarEntry()) != null) {
+ String name = je.toString();
+ if (name.equals("META-INF/SUB/file") || name.equals("x")) {
+ while (jis.read(new byte[1000]) >= 0);
+ if (je.getCertificates() == null) {
+ throw new Exception(name + " not signed");
+ }
+ }
+ }
+ }
+ }
+}
--- a/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -57,9 +57,32 @@
private static int numFail = 0;
private static List<String> msgs = new ArrayList<>();
+ // This test has been falling in timeout - so we're adding some
+ // time stamp here and there to help diagnose whether it's a
+ // simple system slowness or whether there's a deeper issue,
+ // like a deadlock. The timeout issue should be fixed now,
+ // but we leave the time stamps in case it reappears.
+ //
+ static final long stamp = System.currentTimeMillis();
+ private static String getTimeStamp() {
+ long time = System.currentTimeMillis();
+ long delta = time - stamp;
+ long min = delta/60000;
+ long sec = (delta - min * 60000) / 10000;
+ long msec = delta - min * 60000 - sec * 1000;
+ return (min == 0 ? "" : (min + " min. ")) +
+ (sec == 0 ? "" : (sec + " sec. ")) +
+ (msec == 0 ? "" : (msec + "ms."));
+ }
+
public static void main(String[] args) throws Throwable {
+ System.out.println("ResourceBundleSearchTest starting: "+getTimeStamp());
ResourceBundleSearchTest test = new ResourceBundleSearchTest();
- test.runTests();
+ try {
+ test.runTests();
+ } finally {
+ System.out.println("ResourceBundleSearchTest terminated: "+getTimeStamp());
+ }
}
private void runTests() throws Throwable {
@@ -77,15 +100,19 @@
urls[0] = Paths.get(testDir, "resources").toUri().toURL();
URLClassLoader rbClassLoader = new URLClassLoader(urls);
+ int testnb = 1;
+ System.out.println("ResourceBundleSearchTest starting test #"+(testnb++)+": "+getTimeStamp());
// Test 1 - can we find a Logger bundle from doing a stack search?
// We shouldn't be able to
assertFalse(testGetBundleFromStackSearch(), "1-testGetBundleFromStackSearch");
+ System.out.println("ResourceBundleSearchTest starting test #"+(testnb++)+": "+getTimeStamp());
// Test 2 - can we find a Logger bundle off of the Thread context class
// loader? We should be able to.
assertTrue(testGetBundleFromTCCL(TCCL_TEST_BUNDLE, rbClassLoader),
"2-testGetBundleFromTCCL");
+ System.out.println("ResourceBundleSearchTest starting test #"+(testnb++)+": "+getTimeStamp());
// Test 3 - Can we find a Logger bundle from the classpath? We should be
// able to. We'll first check to make sure the setup is correct and
// it actually is on the classpath before checking whether logging
@@ -99,21 +126,25 @@
+ " on the classpath");
}
+ System.out.println("ResourceBundleSearchTest starting test #"+(testnb++)+": "+getTimeStamp());
// Test 4 - we should be able to find a bundle from the caller's
// classloader, but only one level up.
assertTrue(testGetBundleFromCallersClassLoader(),
"4-testGetBundleFromCallersClassLoader");
+ System.out.println("ResourceBundleSearchTest starting test #"+(testnb++)+": "+getTimeStamp());
// Test 5 - this ensures that getAnonymousLogger(String rbName)
// can find the bundle from the caller's classloader
assertTrue(testGetAnonymousLogger(), "5-testGetAnonymousLogger");
+ System.out.println("ResourceBundleSearchTest starting test #"+(testnb++)+": "+getTimeStamp());
// Test 6 - first call getLogger("myLogger").
// Then call getLogger("myLogger","bundleName") from a different ClassLoader
// Make sure we find the bundle
assertTrue(testGetBundleFromSecondCallersClassLoader(),
"6-testGetBundleFromSecondCallersClassLoader");
+ System.out.println("ResourceBundleSearchTest generating report: "+getTimeStamp());
report();
}
@@ -132,6 +163,7 @@
public void assertTrue(boolean testResult, String testName) {
if (testResult) {
numPass++;
+ System.out.println("PASSED: " + testName);
} else {
numFail++;
System.out.println("FAILED: " + testName
@@ -142,6 +174,7 @@
public void assertFalse(boolean testResult, String testName) {
if (!testResult) {
numPass++;
+ System.out.println("PASSED: " + testName);
} else {
numFail++;
System.out.println("FAILED: " + testName
@@ -170,12 +203,10 @@
debug("Looking for " + bundleName + " using TCCL");
LoggingThread lr = new LoggingThread(bundleName, setOnTCCL);
lr.start();
- synchronized (lr) {
- try {
- lr.wait();
- } catch (InterruptedException ex) {
- throw ex;
- }
+ try {
+ lr.join();
+ } catch (InterruptedException ex) {
+ throw ex;
}
msgs.add(lr.msg);
return lr.foundBundle;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestMode.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+/**
+ * Runtime modes of test execution.
+ */
+public enum LambdaTestMode {
+ /**
+ * Execution mode with no particular runtime constraints.
+ */
+ NORMAL,
+
+ /**
+ * Execution mode where tests are executed for testing lambda serialization
+ * and deserialization.
+ *
+ * <p>This mode may be queried by tests or data supplied by data
+ * providers, which cannot otherwise be assigned to the test group
+ * <em>serialization-hostile</em>, to not execute or declare
+ * serialization-hostile code or data.
+ *
+ * <p>This mode is enabled if the boolean system property
+ * {@code org.openjdk.java.util.stream.sand.mode} is declared with a
+ * {@code true} value.
+ */
+ SERIALIZATION;
+
+ /**
+ * {@code true} if tests are executed in the mode for testing lambda
+ * Serialization ANd Deserialization (SAND).
+ */
+ private static final boolean IS_LAMBDA_SERIALIZATION_MODE =
+ Boolean.getBoolean("org.openjdk.java.util.stream.sand.mode");
+
+ /**
+ *
+ * @return the mode of test execution.
+ */
+ public static LambdaTestMode getMode() {
+ return IS_LAMBDA_SERIALIZATION_MODE ? SERIALIZATION : NORMAL;
+ }
+
+ /**
+ *
+ * @return {@code true} if normal test mode.
+ */
+ public static boolean isNormalMode() {
+ return getMode() == NORMAL;
+ }
+}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java Wed Jul 05 19:09:26 2017 +0200
@@ -96,8 +96,14 @@
list.add(streamDataDescr("DelegatingStream(ArrayList):" + name,
() -> new ArrayList<>(intsAsList).stream()));
List<Integer> aList = new ArrayList<>(intsAsList);
- list.add(collectionDataDescr("ArrayList.Sublist:" + name,
- (ints.length) <= 1 ? aList.subList(0, 0) : aList.subList(1, ints.length / 2)));
+ if (LambdaTestMode.isNormalMode()) {
+ // Only include sub-lists for normal test execution mode
+ // This data is serialization-hostile since the state of the
+ // deserialized sub-list will be out of sync with the
+ // enclosing list.
+ list.add(collectionDataDescr("ArrayList.Sublist:" + name,
+ (ints.length) <= 1 ? aList.subList(0, 0) : aList.subList(1, ints.length / 2)));
+ }
list.add(collectionDataDescr("LinkedList:" + name, new LinkedList<>(intsAsList)));
list.add(collectionDataDescr("HashSet:" + name, new HashSet<>(intsAsList)));
list.add(collectionDataDescr("LinkedHashSet:" + name, new LinkedHashSet<>(intsAsList)));
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,6 +25,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@@ -52,6 +53,7 @@
import org.testng.annotations.Test;
+import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.groupingByConcurrent;
import static java.util.stream.Collectors.partitioningBy;
@@ -603,4 +605,17 @@
new PartitionAssertion<>(classifier,
new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
}
+
+ @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+ public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+ List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
+ List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::<Integer>unmodifiableList)));
+ assertEquals(asList, asImmutableList);
+ try {
+ asImmutableList.add(0);
+ fail("Expecting immutable result");
+ }
+ catch (UnsupportedOperationException ignored) { }
+ }
+
}
--- a/jdk/test/java/util/zip/TestExtraTime.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/java/util/zip/TestExtraTime.java Wed Jul 05 19:09:26 2017 +0200
@@ -23,14 +23,19 @@
/**
* @test
- * @bug 4759491 6303183 7012868
+ * @bug 4759491 6303183 7012868 8015666
* @summary Test ZOS and ZIS timestamp in extra field correctly
*/
import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@@ -41,14 +46,32 @@
File src = new File(System.getProperty("test.src", "."), "TestExtraTime.java");
if (src.exists()) {
- long mtime = src.lastModified();
- test(mtime, null);
- test(10, null); // ms-dos 1980 epoch problem
- test(mtime, TimeZone.getTimeZone("Asia/Shanghai"));
+ long time = src.lastModified();
+ FileTime mtime = FileTime.from(time, TimeUnit.MILLISECONDS);
+ FileTime atime = FileTime.from(time + 300000, TimeUnit.MILLISECONDS);
+ FileTime ctime = FileTime.from(time - 300000, TimeUnit.MILLISECONDS);
+ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+
+ test(mtime, null, null, null);
+ // ms-dos 1980 epoch problem
+ test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null);
+ // non-default tz
+ test(mtime, null, null, tz);
+
+ test(mtime, atime, null, null);
+ test(mtime, null, ctime, null);
+ test(mtime, atime, ctime, null);
+
+ test(mtime, atime, null, tz);
+ test(mtime, null, ctime, tz);
+ test(mtime, atime, ctime, tz);
}
}
- private static void test(long mtime, TimeZone tz) throws Throwable {
+ static void test(FileTime mtime, FileTime atime, FileTime ctime,
+ TimeZone tz) throws Throwable {
+ System.out.printf("--------------------%nTesting: [%s]/[%s]/[%s]%n",
+ mtime, atime, ctime);
TimeZone tz0 = TimeZone.getDefault();
if (tz != null) {
TimeZone.setDefault(tz);
@@ -57,23 +80,55 @@
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry ze = new ZipEntry("TestExtreTime.java");
- ze.setTime(mtime);
+ ze.setLastModifiedTime(mtime);
+ if (atime != null)
+ ze.setLastAccessTime(atime);
+ if (ctime != null)
+ ze.setCreationTime(ctime);
zos.putNextEntry(ze);
zos.write(new byte[] { 1,2 ,3, 4});
zos.close();
if (tz != null) {
TimeZone.setDefault(tz0);
}
+ // ZipInputStream
ZipInputStream zis = new ZipInputStream(
new ByteArrayInputStream(baos.toByteArray()));
ze = zis.getNextEntry();
zis.close();
+ check(mtime, atime, ctime, ze);
- System.out.printf("%tc => %tc%n", mtime, ze.getTime());
+ // ZipFile
+ Path zpath = Paths.get(System.getProperty("test.dir", "."),
+ "TestExtraTimp.zip");
+ Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
+ ZipFile zf = new ZipFile(zpath.toFile());
+ ze = zf.getEntry("TestExtreTime.java");
+ // ZipFile read entry from cen, which does not have a/ctime,
+ // for now.
+ check(mtime, null, null, ze);
+ zf.close();
+ Files.delete(zpath);
+ }
- if (TimeUnit.MILLISECONDS.toSeconds(mtime) !=
- TimeUnit.MILLISECONDS.toSeconds(ze.getTime()))
- throw new RuntimeException("Timestamp storing failed!");
-
+ static void check(FileTime mtime, FileTime atime, FileTime ctime,
+ ZipEntry ze) {
+ /*
+ System.out.printf(" mtime [%tc]: [%tc]/[%tc]%n",
+ mtime.to(TimeUnit.MILLISECONDS),
+ ze.getTime(),
+ ze.getLastModifiedTime().to(TimeUnit.MILLISECONDS));
+ */
+ if (mtime.to(TimeUnit.SECONDS) !=
+ ze.getLastModifiedTime().to(TimeUnit.SECONDS))
+ throw new RuntimeException("Timestamp: storing mtime failed!");
+ if (atime != null &&
+ atime.to(TimeUnit.SECONDS) !=
+ ze.getLastAccessTime().to(TimeUnit.SECONDS))
+ throw new RuntimeException("Timestamp: storing atime failed!");
+ if (ctime != null &&
+ ctime.to(TimeUnit.SECONDS) !=
+ ze.getCreationTime().to(TimeUnit.SECONDS))
+ throw new RuntimeException("Timestamp: storing ctime failed!");
}
}
--- a/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,11 +35,12 @@
import javax.swing.*;
public class ActionListenerCalledTwiceTest {
- static String menuItems[] = { "Item1", "Item2", "Item3" };
+ static String menuItems[] = { "Item1", "Item2", "Item3", "Item4" };
static KeyStroke keyStrokes[] = {
KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK),
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_MASK),
+ KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.META_MASK)
};
static volatile int listenerCallCounter = 0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/parsers/8022548/JDK8022548.xml Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<?xml-stylesheet type="text/xsl" href="../resources/style/pagex.xsl"?>
+
+<my:doc xmlns:my="http://www.jenitennison.com/" xmlns="http://www.w3.org/1999/xhtml">
+
+ <p>
+ These pages are all about XSLT, an XML-based language for translating one set of XML into another set of XML, or into HTML. Of course, there are all sorts of <my:link href="#links">other pages</my:link> around that cover XSLT. Jeni's XSLT Pages, though, are dedicated to helping people understand and make the most of using XSLT.
+</p>
+ <p>
+ My warmest thanks to all those people who post interesting problems on <my:link href="http://www.mulberytech.com/xsl/xsl-list/">XSL-List</my:link>, and especially to those of you that have encouraged me to set up this site through your kind emails.
+</p>
+
+</my:doc>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/parsers/8022548/JDK8022548.xsl Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,618 @@
+<?xml version="1.0" encoding='UTF-8'?>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0"
+ xmlns:my="http://www.jenitennison.com/"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:dcq="http://purl.org/dc/qualifiers/1.0/"
+ xmlns:vcf="http://www.ietf.org/internet-drafts/draft-dawson-vcard-xml-dtd-03.txt"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ exclude-result-prefixes="rdf dc dcq my html vcf msxsl">
+
+<xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
+ cdata-section-elements="script"
+ indent="no"
+ method="xml"
+ encoding='UTF-8'/>
+
+<xsl:param name="dynamic" select="'true'" />
+<xsl:param name="base" select="'/'" />
+
+<xsl:variable name="supports-document" select="function-available('document')" />
+<xsl:variable name="supports-keys" select="function-available('key')" />
+
+<xsl:variable name="default-title" select='"Jeni's XML Site"' />
+
+<xsl:template match="my:doc">
+ <xsl:variable name="metadata" select="/*/rdf:RDF" />
+ <xsl:variable name="uri" select="$metadata/rdf:Description[1]/@about" />
+ <html>
+ <head>
+ <title>
+ <xsl:call-template name="get-metadata">
+ <xsl:with-param name="what" select="'title'" />
+ <xsl:with-param name="about" select="$uri" />
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="get-metadata">
+ <xsl:with-param name="what" select="'link'" />
+ <xsl:with-param name="about" select="$uri" />
+ </xsl:call-template>
+ <link rel="alternate" type="text/xml" href="{$uri}" />
+ <xsl:call-template name="get-metadata">
+ <xsl:with-param name="what" select="'rights'" />
+ <xsl:with-param name="about" select="$uri" />
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:if test="$dynamic = 'false'">
+ <p id="xml-link">
+ Try the <a href="{$uri}">XML version</a> of this page.
+ If you have problems with it, consult the
+ <a href="/compatibility.html">compatibility page</a>.
+ </p>
+ </xsl:if>
+ <xsl:apply-templates />
+ <xsl:apply-templates select="." mode="colophon" />
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="html:h1">
+ <h1>
+ <xsl:apply-templates />
+ <xsl:call-template name="insert-navigation" />
+ </h1>
+</xsl:template>
+
+<xsl:template name="insert-navigation">
+ <xsl:variable name="metadata" select="/*/rdf:RDF" />
+ <xsl:variable name="uri" select="$metadata/rdf:Description[1]/@about" />
+ <xsl:if test="$uri != concat($base, 'index.xml')">
+ <span id="link-top">
+ <a class="img">
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <xsl:when test="$dynamic = 'true'">/index.xml</xsl:when>
+
+ <xsl:otherwise>/index.html</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <img src="{$base}resources/icons/top.gif" width="29" height="29" />
+ </a>
+ </span>
+ <span id="link-up">
+ <a class="img">
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <xsl:when test="contains($uri, 'index.xml')">
+ <xsl:choose>
+ <xsl:when test="$dynamic = 'true'">../index.xml</xsl:when>
+ <xsl:otherwise>../index.html</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$dynamic = 'true'">index.xml</xsl:when>
+ <xsl:otherwise>index.html</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <img src="{$base}resources/icons/up.gif" width="29" height="29" />
+ </a>
+ </span>
+</xsl:if>
+</xsl:template>
+
+
+<xsl:template match="rdf:RDF" />
+
+<xsl:template name="get-metadata">
+ <xsl:param name="what" />
+ <xsl:param name="about" select="/*/rdf:RDF/rdf:Description/@about" />
+ <xsl:variable name="metadata" select="/*/rdf:RDF" />
+ <xsl:variable name="type">
+ <xsl:choose>
+ <xsl:when test="contains($what, '::')">
+ <xsl:value-of select="substring-before($what, '::')" />
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$what" /></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="mode">
+ <xsl:choose>
+ <xsl:when test="contains($what, '::')">
+ <xsl:value-of select="substring-after($what, '::')" />
+ </xsl:when>
+ <xsl:otherwise />
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:apply-templates select="$metadata/rdf:Description[@about = $about or
+ (@aboutEachPrefix != '' and starts-with($about, @aboutEachPrefix))]/*[local-name() = $type]">
+ <xsl:with-param name="mode" select="$mode" />
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="rdf:Description/*">
+ <xsl:param name="mode" />
+ <xsl:choose>
+ <xsl:when test="@rdf:resource != ''">
+ <xsl:call-template name="get-metadata">
+ <xsl:with-param name="about" select="@rdf:resource" />
+ <xsl:with-param name="what" select="$mode" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$mode = '' and @rdf:value != ''">
+ <xsl:value-of select="@rdf:value" />
+ </xsl:when>
+ <xsl:when test="$mode = '' and *">
+ <xsl:apply-templates />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="." mode="get-metadata">
+ <xsl:with-param name="mode" select="$mode" />
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="html:link" mode="get-metadata">
+ <link>
+ <xsl:copy-of select="@*" />
+ </link>
+</xsl:template>
+
+<xsl:template match="dc:rights" mode="get-metadata">
+ <xsl:comment>
+ <xsl:value-of select="." />
+ </xsl:comment>
+</xsl:template>
+
+<xsl:template match="dc:date" mode="get-metadata">
+ <xsl:param name="mode" select="''" />
+ <xsl:if test="$mode = @dcq:dateType">
+ <xsl:value-of select="@rdf:value" />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="vcf:vCard" mode="get-metadata">
+ <xsl:param name="mode" select="''" />
+ <xsl:choose>
+ <xsl:when test="$mode = 'mailto-link'">
+ <xsl:call-template name="link">
+ <xsl:with-param name="link">
+ <xsl:choose>
+ <xsl:when test="vcf:email[contains(@email.type, 'PREF')]">
+ <xsl:value-of select="vcf:email[contains(@email.type, 'PREF')]" />
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="vcf:email[1]" /></xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ <xsl:with-param name="value">
+ <xsl:apply-templates select="vcf:n" mode="full" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$mode = 'name'">
+ <xsl:apply-templates select="vcf:n" mode="full" />
+ </xsl:when>
+ <xsl:otherwise />
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="vcf:n" mode="full">
+ <xsl:if test="vcf:prefix">
+ <xsl:value-of select="vcf:prefix" /><xsl:text> </xsl:text>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="../vcf:nickname">
+ <xsl:value-of select="../vcf:nickname" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="vcf:given" />
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="vcf:family" />
+</xsl:template>
+
+<xsl:template match="html:*">
+ <xsl:element name="{local-name()}">
+ <xsl:copy-of select="@*" />
+ <xsl:apply-templates />
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="my:vars">
+ <dl>
+ <xsl:apply-templates />
+ </dl>
+</xsl:template>
+
+<xsl:template match="my:var">
+ <dt id="{translate(my:name, ' ', '-')}">
+ <xsl:text/>$<xsl:value-of select="my:name" />
+ <xsl:choose>
+ <xsl:when test="my:value">
+ <xsl:text/> = <xsl:apply-templates select="my:value" />
+ </xsl:when>
+ <xsl:when test="my:default">
+ <xsl:text/> [= <xsl:apply-templates select="my:default" />]<xsl:text/>
+ </xsl:when>
+ </xsl:choose>
+ </dt>
+ <dd>
+ <xsl:if test="my:desc"><xsl:apply-templates select="my:desc" /></xsl:if>
+ <xsl:if test="my:option">
+ <ul>
+ <xsl:apply-templates select="my:option" />
+ </ul>
+ </xsl:if>
+ <xsl:apply-templates select="my:defn" />
+ </dd>
+</xsl:template>
+
+<xsl:template match="my:option">
+ <li><xsl:apply-templates select="my:value" />: <xsl:apply-templates select="my:desc" /></li>
+</xsl:template>
+
+<xsl:template match="my:value | my:default">
+ <xsl:choose>
+ <xsl:when test="@type">
+ <span class="{@type}">
+ <xsl:choose>
+ <xsl:when test="@type = 'string'">'<xsl:value-of select="." />'</xsl:when>
+ <xsl:when test="@type = 'rtf'">"<xsl:value-of select="." />"</xsl:when>
+ <xsl:otherwise><xsl:value-of select="." /></xsl:otherwise>
+ </xsl:choose>
+ </span>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="." />
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="my:post">
+ <div class="post">
+ <xsl:apply-templates />
+ </div>
+</xsl:template>
+
+<xsl:template match="my:response">
+ <div class="response">
+ <xsl:apply-templates />
+ </div>
+</xsl:template>
+
+<xsl:template match="my:question">
+ <div class="question">
+ <p>
+ <xsl:call-template name="insert-icon">
+ <xsl:with-param name="icon" select="'question'" />
+ <xsl:with-param name="active" select="false()" />
+ </xsl:call-template>
+ <xsl:text> </xsl:text>
+ <xsl:apply-templates select="*[1]/node()" />
+ </p>
+ <xsl:apply-templates select="*[position() > 1]"/>
+ </div>
+</xsl:template>
+
+<xsl:template match="my:example | my:defn">
+ <pre>
+ <xsl:apply-templates />
+ </pre>
+</xsl:template>
+
+<xsl:template match="my:example[parent::my:aside and ancestor::my:example]">
+ <xsl:choose>
+ <xsl:when test="$dynamic = 'true'">
+ <pre>
+ <xsl:apply-templates />
+ </pre>
+ </xsl:when>
+ <xsl:otherwise>
+ <span class="example">
+ <xsl:apply-templates />
+ </span>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="my:example[parent::my:aside and not(ancestor::my:example)]">
+ <xsl:call-template name="split-and-code">
+ <xsl:with-param name="text" select="string(.)" />
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="split-and-code">
+ <xsl:param name="text" />
+ <br />
+ <xsl:choose>
+ <xsl:when test="contains($text, '
')">
+ <code><xsl:value-of select="substring-before($text, '
')" /></code>
+ <xsl:call-template name="split-and-code">
+ <xsl:with-param name="text" select="substring-after($text, '
')" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <code><xsl:value-of select="$text" /></code>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="my:aside">
+ <xsl:choose>
+ <xsl:when test="$dynamic = 'true'">
+ <span class="note"
+ ><img src="{$base}resources/icons/note.gif" height="17" width="13" border="0"
+ style="z-index: 2;"
+ onmouseover="javascript:{generate-id()}.style.visibility='visible';"
+ onmouseout="javascript:{generate-id()}.style.visibility='hidden';"
+ /><span class="popup" id="{generate-id()}"
+ onmouseover="javascript:{generate-id()}.style.visibility='visible';"
+ onmouseout="javascript:{generate-id()}.style.visibility='hidden';">
+ <xsl:apply-templates />
+ </span
+ ></span>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ <span class="note">[<xsl:apply-templates />]</span>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="my:quote">
+ <blockquote uri="{@href}">
+ <xsl:apply-templates />
+ </blockquote>
+ <p class="byline">
+ <xsl:text>[From </xsl:text>
+ <xsl:call-template name="link">
+ <xsl:with-param name="link" select="@href" />
+ <xsl:with-param name="value">
+ <xsl:value-of select="@href" />
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:text>]</xsl:text>
+ </p>
+</xsl:template>
+
+<xsl:template match="my:icon">
+ <xsl:call-template name="insert-icon">
+ <xsl:with-param name="icon" select="@name" />
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="insert-icon">
+ <xsl:param name="icon" select="'goto'" />
+ <xsl:param name="active" select="true()" />
+ <img src="{$base}resources/icons/{$icon}.gif" height="28" width="28" border="0">
+ <xsl:attribute name="src">
+ <xsl:value-of select="$base" />
+ <xsl:text>resources/icons/</xsl:text>
+ <xsl:if test="not($active)">click-</xsl:if>
+ <xsl:value-of select="$icon" />
+ <xsl:text>.gif</xsl:text>
+ </xsl:attribute>
+ <xsl:if test="$active">
+ <xsl:attribute name="onmouseover">javascript:this.src='<xsl:value-of select="$base" />resources/icons/over-<xsl:value-of select="$icon" />.gif'</xsl:attribute>
+ <xsl:attribute name="onclick">javascript:this.src='<xsl:value-of select="$base" />resources/icons/click-<xsl:value-of select="$icon" />.gif'</xsl:attribute>
+ <xsl:attribute name="onmouseout">javascript:this.src='<xsl:value-of select="$base" />resources/icons/<xsl:value-of select="$icon" />.gif'</xsl:attribute>
+ </xsl:if>
+ </img>
+</xsl:template>
+
+<xsl:template match="my:links">
+ <xsl:choose>
+ <xsl:when test="parent::html:dd">
+ <xsl:apply-templates select="my:link" mode="list" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="columnise">
+ <xsl:with-param name="max-height" select="3" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="columnise">
+ <xsl:param name="max-height" select="5" />
+ <xsl:param name="max-width" select="3" />
+ <xsl:variable name="no-items" select="count(*)" />
+ <xsl:variable name="width">
+ <xsl:choose>
+ <xsl:when test="$no-items > $max-height * $max-width">
+ <xsl:value-of select="$max-width" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="ceiling($no-items div $max-height)" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="height" select="ceiling($no-items div $width)" />
+ <table>
+ <colgroup span="{$width}" />
+ <tr>
+ <xsl:for-each select="*[position() = 1 or position() mod $height = 1]">
+ <td>
+ <xsl:apply-templates select=". | following-sibling::*[position() < $height]" mode="list" />
+ </td>
+ </xsl:for-each>
+ </tr>
+ </table>
+</xsl:template>
+
+<xsl:template match="my:link" mode="list">
+ <p class="link">
+ <xsl:call-template name="link">
+ <xsl:with-param name="link" select="@href" />
+ <xsl:with-param name="value">
+ <xsl:value-of select="." />
+ </xsl:with-param>
+ <xsl:with-param name="addicon" select="true()" />
+ </xsl:call-template>
+ </p>
+</xsl:template>
+
+<xsl:template match="my:link">
+ <xsl:apply-templates select="." mode="link" />
+</xsl:template>
+
+<xsl:template match="*[@href][. != '']" mode="link">
+ <xsl:call-template name="link">
+ <xsl:with-param name="link" select="@href" />
+ <xsl:with-param name="value">
+ <xsl:apply-templates />
+ </xsl:with-param>
+ <xsl:with-param name="addicon" select="@addicon" />
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="*[@href][. = '']" mode="link">
+ <xsl:call-template name="link">
+ <xsl:with-param name="link" select="@href" />
+ <xsl:with-param name="value">
+ <xsl:value-of select="@href" />
+ </xsl:with-param>
+ <xsl:with-param name="addicon" select="@addicon" />
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="text()|@*" mode="link">
+ <xsl:call-template name="link">
+ <xsl:with-param name="link" select="." />
+ <xsl:with-param name="value">
+ <xsl:value-of select="." />
+ </xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="link">
+ <xsl:param name="link" />
+ <xsl:param name="value" />
+ <xsl:param name="addicon" select="''" />
+ <xsl:variable name="uri">
+ <xsl:call-template name="full-uri">
+ <xsl:with-param name="uri" select="$link" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="class">
+ <xsl:call-template name="uri-class">
+ <xsl:with-param name="uri" select="$uri" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="$addicon">
+ <a href="{$uri}">
+ <xsl:attribute name="class">
+ <xsl:text>img </xsl:text>
+ <xsl:value-of select="$class" />
+ </xsl:attribute>
+ <xsl:call-template name="insert-icon">
+ <xsl:with-param name="icon">
+ <xsl:call-template name="icon-type">
+ <xsl:with-param name="uri" select="$uri" />
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </a>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ <a href="{$uri}">
+ <xsl:if test="$class != ''">
+ <xsl:attribute name="class">
+ <xsl:value-of select="$class" />
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:copy-of select="$value" />
+ </a>
+</xsl:template>
+
+<xsl:template name="full-uri">
+ <xsl:param name="uri" />
+ <xsl:variable name="partial-uri">
+ <xsl:choose>
+ <xsl:when test="$dynamic='false' and
+ substring($uri, string-length($uri) - 3, 4) = '.xml'">
+ <xsl:value-of select="concat(substring($uri, 1, string-length($uri) - 4), '.html')" />
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$uri" /></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="starts-with($partial-uri, 'www')">
+ <xsl:text>http://</xsl:text><xsl:value-of select="$partial-uri" />
+ </xsl:when>
+ <xsl:when test="contains($partial-uri, '@') and not(starts-with($partial-uri, 'mailto:'))">
+ <xsl:text>mailto:</xsl:text><xsl:value-of select="$partial-uri" />
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$partial-uri" /></xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="uri-class">
+ <xsl:param name="uri" />
+ <xsl:choose>
+ <xsl:when test="starts-with($uri, 'http://') and not(starts-with($uri, $base))">offsite</xsl:when>
+ <xsl:when test="starts-with($uri, 'mailto:')">mailto</xsl:when>
+ <xsl:when test="starts-with($uri, '#')">local</xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="icon-type">
+ <xsl:param name="uri" />
+ <xsl:variable name="url">
+ <xsl:choose>
+ <xsl:when test="starts-with($uri, 'http://')"><xsl:value-of select="substring-after($uri, 'http://')" /></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$uri" /></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="(not(contains($url, '/')) and starts-with($url, 'www.')) or (contains($url, '/') and not(substring-after($url, '/')))">home</xsl:when>
+ <xsl:when test="contains($url, '@')">mail</xsl:when>
+ <xsl:otherwise>goto</xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="/*" mode="colophon">
+ <xsl:variable name="metadata" select="/*/rdf:RDF" />
+ <xsl:variable name="uri" select="$metadata/rdf:Description[1]/@about" />
+ <div id="colophon">
+ <hr class="final" />
+ <p>
+ <xsl:apply-templates select="$uri" mode="link" />
+ <xsl:variable name="modified">
+ <xsl:call-template name="get-metadata">
+ <xsl:with-param name="what" select="'date::modified'" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string($modified)">
+ <xsl:text> last modified </xsl:text>
+ <xsl:copy-of select="$modified" />
+ </xsl:if>
+ <xsl:variable name="creator">
+ <xsl:call-template name="get-metadata">
+ <xsl:with-param name="what" select="'creator::vCard::mailto-link'" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:text> by </xsl:text>
+ <xsl:choose>
+ <xsl:when test="string($creator)">
+ <xsl:copy-of select="$creator" />
+ </xsl:when>
+ <xsl:otherwise>
+ <a href="mailto:mail@jenitennison.com" class="mailto">Jeni Tennison</a>
+ </xsl:otherwise>
+ </xsl:choose>
+ </p>
+ </div>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/parsers/8022548/TestBase.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,73 @@
+
+import java.security.Policy;
+
+/**
+ *
+ *
+ * @author huizhe.wang@oracle.com
+ */
+public class TestBase {
+ public String filePath;
+ boolean hasSM;
+ String curdir;
+ Policy origPolicy;
+
+ String testName;
+ String errMsg;
+
+ int passed = 0, failed = 0;
+
+ /**
+ * Creates a new instance of StreamReader
+ */
+ public TestBase(String name) {
+ testName = name;
+ }
+
+ //junit @Override
+ protected void setUp() {
+ if (System.getSecurityManager() != null) {
+ hasSM = true;
+ System.setSecurityManager(null);
+ }
+
+ filePath = System.getProperty("test.src");
+ if (filePath == null) {
+ //current directory
+ filePath = System.getProperty("user.dir");
+ }
+ origPolicy = Policy.getPolicy();
+
+ }
+
+ //junit @Override
+ public void tearDown() {
+ // turn off security manager and restore policy
+ System.setSecurityManager(null);
+ Policy.setPolicy(origPolicy);
+ if (hasSM) {
+ System.setSecurityManager(new SecurityManager());
+ }
+ System.out.println("\nNumber of tests passed: " + passed);
+ System.out.println("Number of tests failed: " + failed + "\n");
+
+ if (errMsg != null ) {
+ throw new RuntimeException(errMsg);
+ }
+ }
+
+ void fail(String msg) {
+ if (errMsg == null) {
+ errMsg = msg;
+ } else {
+ errMsg = errMsg + "\n" + msg;
+ }
+ failed++;
+ }
+
+ void success(String msg) {
+ passed++;
+ System.out.println(msg);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/parsers/8022548/XOMParserTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013, 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 @bug 8022548
+ * @summary test that a parser can use DTDConfiguration
+ * @run main XOMParserTest
+ */
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.parsers.*;
+import java.io.*;
+import javax.xml.transform.*;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import org.xml.sax.InputSource;
+
+/**
+ * <p>Test {@link javax.xml.transform.Transformer} for JDK-8022548: SPECJVM2008
+ * has errors introduced in 7u40-b34
+ *
+ * Test XOM is supported after jaxp 1.5 </p>
+ *
+ * @author Joe Wang <huizhe.wang@oracle.com>
+ *
+ */
+public class XOMParserTest extends TestBase {
+
+ public XOMParserTest(String name) {
+ super(name);
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ XOMParserTest test = new XOMParserTest("XOM parser test");
+ test.setUp();
+ test.testTransform();
+ test.tearDown();
+ }
+
+ public final void testTransform() {
+
+ try {
+
+ String inFilename = filePath + "/JDK8022548.xml";
+ String xslFilename = filePath + "/JDK8022548.xsl";
+ String outFilename = filePath + "/JDK8022548.out";
+
+ StringWriter sw = new StringWriter();
+ // Create transformer factory
+ TransformerFactory factory = TransformerFactory.newInstance();
+ // set the translet name
+// factory.setAttribute("translet-name", "myTranslet");
+
+ // set the destination directory
+// factory.setAttribute("destination-directory", "c:\\temp");
+// factory.setAttribute("generate-translet", Boolean.TRUE);
+
+ // Use the factory to create a template containing the xsl file
+ Templates template = factory.newTemplates(new StreamSource(new FileInputStream(xslFilename)));
+ // Use the template to create a transformer
+ Transformer xformer = template.newTransformer();
+ // Prepare the input and output files
+ Source source = new StreamSource(new FileInputStream(inFilename));
+ Result result = new StreamResult(new FileOutputStream(outFilename));
+ //Result result = new StreamResult(sw);
+ // Apply the xsl file to the source file and write the result to the output file
+ xformer.transform(source, result);
+
+ /**
+ * String out = sw.toString(); if (out.indexOf("<p>") < 0 ) {
+ * fail(out); }
+ */
+ String canonicalizedFileName = outFilename + ".canonicalized";
+ canonicalize(outFilename, canonicalizedFileName);
+ } catch (Exception e) {
+ // unexpected failure
+ fail(e.getMessage());
+ }
+ }
+
+ public void canonicalize(String inName, String outName) {
+ try (//FileOutputStream outStream = new FileOutputStream(outName);
+ FileInputStream inputStream = new FileInputStream(inName);) {
+ JDK15XML1_0Parser parser = new JDK15XML1_0Parser();
+ parser.parse(new InputSource(inputStream));
+ success("test passed");
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ }
+
+ class JDK15XML1_0Parser extends SAXParser {
+
+ JDK15XML1_0Parser() throws org.xml.sax.SAXException {
+
+ super(new DTDConfiguration());
+ // workaround for Java 1.5 beta 2 bugs
+ com.sun.org.apache.xerces.internal.util.SecurityManager manager =
+ new com.sun.org.apache.xerces.internal.util.SecurityManager();
+ setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY, manager);
+
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, 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
+ @bug 7173464
+ @summary Clipboard.getAvailableDataFlavors: Comparison method violates contract
+ @author Petr Pchelko
+ @run main DataFlavorComparatorTest
+*/
+
+import sun.awt.datatransfer.DataTransferer;
+
+import java.awt.datatransfer.DataFlavor;
+
+public class DataFlavorComparatorTest {
+
+ public static void main(String[] args) {
+ DataTransferer.DataFlavorComparator comparator = new DataTransferer.DataFlavorComparator();
+ DataFlavor flavor1 = DataFlavor.imageFlavor;
+ DataFlavor flavor2 = DataFlavor.selectionHtmlFlavor;
+ if (comparator.compare(flavor1, flavor2) == 0) {
+ throw new RuntimeException(flavor1.getMimeType() + " and " + flavor2.getMimeType() +
+ " should not be equal");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 8020842
+ * @summary SNIHostName does not throw IAE when hostname ends
+ * with a trailing dot
+ */
+
+import javax.net.ssl.SNIHostName;
+
+public class IllegalSNIName {
+
+ public static void main(String[] args) throws Exception {
+ String[] illegalNames = {
+ "example\u3003\u3002com",
+ "example..com",
+ "com\u3002",
+ "com.",
+ "."
+ };
+
+ for (String name : illegalNames) {
+ try {
+ SNIHostName hostname = new SNIHostName(name);
+ throw new Exception(
+ "Expected to get IllegalArgumentException for " + name);
+ } catch (IllegalArgumentException iae) {
+ // That's the right behavior.
+ }
+ }
+ }
+}
--- a/jdk/test/sun/text/resources/LocaleData Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/text/resources/LocaleData Wed Jul 05 19:09:26 2017 +0200
@@ -7679,3 +7679,5 @@
FormatData/pt/MonthAbbreviations/10=nov
FormatData/pt/MonthAbbreviations/11=dez
+# bug 8021121
+CurrencyNames/lv_LV/EUR=\u20AC
--- a/jdk/test/sun/text/resources/LocaleDataTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,7 +35,7 @@
* 6645405 6650730 6910489 6573250 6870908 6585666 6716626 6914413 6916787
* 6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495
* 7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
- * 7114053 7074882 7040556 8013836
+ * 7114053 7074882 7040556 8013836 8021121
* @summary Verify locale data
*
*/
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION Wed Jul 05 19:09:26 2017 +0200
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2013c
+tzdata2013d
--- a/jdk/test/sun/util/calendar/zi/tzdata/africa Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/africa Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -875,12 +875,18 @@
# announced that year's Ramadan daylight-saving transitions would be
# 2012-07-20 and 2012-08-20; see
# <http://www.mmsp.gov.ma/fr/actualites.aspx?id=288>.
-#
+
+# From Andrew Paprocki (2013-07-02):
+# Morocco announced that the year's Ramadan daylight-savings
+# transitions would be 2013-07-07 and 2013-08-10; see:
+# http://www.maroc.ma/en/news/morocco-suspends-daylight-saving-time-july-7-aug10
+
+# From Paul Eggert (2013-07-03):
# To estimate what the Moroccan government will do in future years,
-# transition dates for 2013 through 2021 were determined by running
+# transition dates for 2014 through 2021 were determined by running
# the following program under GNU Emacs 24.3:
#
-# (let ((islamic-year 1434))
+# (let ((islamic-year 1435))
# (while (< islamic-year 1444)
# (let ((a
# (calendar-gregorian-from-absolute
@@ -933,8 +939,8 @@
Rule Morocco 2012 max - Sep lastSun 3:00 0 -
Rule Morocco 2012 only - Jul 20 3:00 0 -
Rule Morocco 2012 only - Aug 20 2:00 1:00 S
-Rule Morocco 2013 only - Jul 9 3:00 0 -
-Rule Morocco 2013 only - Aug 8 2:00 1:00 S
+Rule Morocco 2013 only - Jul 7 3:00 0 -
+Rule Morocco 2013 only - Aug 10 2:00 1:00 S
Rule Morocco 2014 only - Jun 29 3:00 0 -
Rule Morocco 2014 only - Jul 29 2:00 1:00 S
Rule Morocco 2015 only - Jun 18 3:00 0 -
--- a/jdk/test/sun/util/calendar/zi/tzdata/antarctica Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/antarctica Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -1235,39 +1235,21 @@
Rule Zion 2012 only - Mar Fri>=26 2:00 1:00 D
Rule Zion 2012 only - Sep 23 2:00 0 S
-# From Ephraim Silverberg (2012-10-18):
-# Yesterday, the Interior Ministry Committee, after more than a year
-# past, approved sending the proposed June 2011 changes to the Time
-# Decree Law back to the Knesset for second and third (final) votes
-# before the upcoming elections on Jan. 22, 2013. Hence, although the
-# changes are not yet law, they are expected to be so before February 2013.
+# From Ephraim Silverberg (2013-06-27):
+# On June 23, 2013, the Israeli government approved changes to the
+# Time Decree Law. The next day, the changes passed the First Reading
+# in the Knesset. The law is expected to pass the Second and Third
+# (final) Readings by the beginning of September 2013.
#
-# As of 2013, DST starts at 02:00 on the Friday before the last Sunday in March.
-# DST ends at 02:00 on the first Sunday after October 1, unless it occurs on the
-# second day of the Jewish Rosh Hashana holiday, in which case DST ends a day
-# later (i.e. at 02:00 the first Monday after October 2).
-# [Rosh Hashana holidays are factored in until 2100.]
-
-# From Ephraim Silverberg (2012-11-05):
-# The Knesset passed today (in second and final readings) the amendment to the
-# Time Decree Law making the changes ... law.
+# As of 2013, DST starts at 02:00 on the Friday before the last Sunday
+# in March. DST ends at 02:00 on the last Sunday of October.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Zion 2013 max - Mar Fri>=23 2:00 1:00 D
-Rule Zion 2013 2026 - Oct Sun>=2 2:00 0 S
-Rule Zion 2027 only - Oct Mon>=3 2:00 0 S
-Rule Zion 2028 max - Oct Sun>=2 2:00 0 S
-# The following rules are commented out for now, as they break older
-# versions of zic that support only signed 32-bit timestamps, i.e.,
-# through 2038-01-19 03:14:07 UTC.
-#Rule Zion 2028 2053 - Oct Sun>=2 2:00 0 S
-#Rule Zion 2054 only - Oct Mon>=3 2:00 0 S
-#Rule Zion 2055 2080 - Oct Sun>=2 2:00 0 S
-#Rule Zion 2081 only - Oct Mon>=3 2:00 0 S
-#Rule Zion 2082 max - Oct Sun>=2 2:00 0 S
+Rule Zion 2013 max - Oct lastSun 2:00 0 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Jerusalem 2:20:56 - LMT 1880
+Zone Asia/Jerusalem 2:20:54 - LMT 1880
2:20:40 - JMT 1918 # Jerusalem Mean Time?
2:00 Zion I%sT
@@ -2570,8 +2552,8 @@
Rule Syria 2007 only - Mar lastFri 0:00 1:00 S
# From Jesper Norgard (2007-10-27):
# The sister center ICARDA of my work CIMMYT is confirming that Syria DST will
-# not take place 1.st November at 0:00 o'clock but 1.st November at 24:00 or
-# rather Midnight between Thursday and Friday. This does make more sence than
+# not take place 1st November at 0:00 o'clock but 1st November at 24:00 or
+# rather Midnight between Thursday and Friday. This does make more sense than
# having it between Wednesday and Thursday (two workdays in Syria) since the
# weekend in Syria is not Saturday and Sunday, but Friday and Saturday. So now
# it is implemented at midnight of the last workday before weekend...
--- a/jdk/test/sun/util/calendar/zi/tzdata/australasia Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/australasia Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -253,10 +253,16 @@
# - Macquarie Island will stay on UTC+11 for winter and therefore not
# switch back from daylight savings time when other parts of Australia do
# on 4 April.
+#
+# From Arthur David Olson (2013-05-23):
+# The 1919 transition is overspecified below so pre-2013 zics
+# will produce a binary file with an EST-type as the first 32-bit type;
+# this is required for correct handling of times before 1916 by
+# pre-2013 versions of localtime.
Zone Antarctica/Macquarie 0 - zzz 1899 Nov
10:00 - EST 1916 Oct 1 2:00
10:00 1:00 EST 1917 Feb
- 10:00 Aus EST 1919 Apr
+ 10:00 Aus EST 1919 Apr 1 0:00s
0 - zzz 1948 Mar 25
10:00 Aus EST 1967
10:00 AT EST 2010 Apr 4 3:00
@@ -1498,12 +1504,12 @@
# From Paul Eggert (2000-01-08):
# IATA SSIM (1999-09) says DST ends 0100 local time. Go with McDow.
-# From the BBC World Service (1998-10-31 11:32 UTC):
+# From the BBC World Service in
+# http://news.bbc.co.uk/2/hi/asia-pacific/205226.stm (1998-10-31 16:03 UTC):
# The Fijiian government says the main reasons for the time change is to
-# improve productivity and reduce road accidents. But correspondents say it
-# also hopes the move will boost Fiji's ability to compete with other pacific
-# islands in the effort to attract tourists to witness the dawning of the new
-# millenium.
+# improve productivity and reduce road accidents.... [T]he move is also
+# intended to boost Fiji's ability to attract tourists to witness the dawning
+# of the new millennium.
# http://www.fiji.gov.fj/press/2000_09/2000_09_13-05.shtml (2000-09-13)
# reports that Fiji has discontinued DST.
@@ -1648,7 +1654,7 @@
# Shanks & Pottenger say the transition was on 1968-10-01; go with Mundell.
# From Eric Ulevik (1999-05-03):
-# Tonga's director of tourism, who is also secretary of the National Millenium
+# Tonga's director of tourism, who is also secretary of the National Millennium
# Committee, has a plan to get Tonga back in front.
# He has proposed a one-off move to tropical daylight saving for Tonga from
# October to March, which has won approval in principle from the Tongan
--- a/jdk/test/sun/util/calendar/zi/tzdata/backward Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/backward Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/etcetera Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/etcetera Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -546,7 +546,7 @@
# It seems that Paris, Monaco, Rule France, Rule Belgium all agree on
# 2:00 standard time, e.g. 3:00 local time. However there are no
# countries that use C-Eur rules in September 1945, so the only items
-# affected are apparently these ficticious zones that translates acronyms
+# affected are apparently these fictitious zones that translate acronyms
# CET and MET:
#
# Zone CET 1:00 C-Eur CE%sT
@@ -2802,9 +2802,9 @@
# Ukraine
#
-# From Igor Karpov, who works for the Ukranian Ministry of Justice,
+# From Igor Karpov, who works for the Ukrainian Ministry of Justice,
# via Garrett Wollman (2003-01-27):
-# BTW, I've found the official document on this matter. It's goverment
+# BTW, I've found the official document on this matter. It's government
# regulations number 509, May 13, 1996. In my poor translation it says:
# "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday
# of March at 3am the time is changing to 4am and each last Sunday of
@@ -2838,7 +2838,7 @@
# time this year after all.
#
# From Udo Schwedt (2011-10-18):
-# As far as I understand, the recent change to the Ukranian time zone
+# As far as I understand, the recent change to the Ukrainian time zone
# (Europe/Kiev) to introduce permanent daylight saving time (similar
# to Russia) was reverted today:
#
--- a/jdk/test/sun/util/calendar/zi/tzdata/factory Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/factory Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/iso3166.tab Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/iso3166.tab Wed Jul 05 19:09:26 2017 +0200
@@ -1,39 +1,37 @@
#
# 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.
#
-# <pre>
+# ISO 3166 alpha-2 country codes
+#
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
-# ISO 3166 alpha-2 country codes
#
-# From Paul Eggert (2006-09-27):
+# From Paul Eggert (2013-05-27):
#
# This file contains a table with the following columns:
# 1. ISO 3166-1 alpha-2 country code, current as of
-# ISO 3166-1 Newsletter VI-1 (2007-09-21). See:
-# <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
-# ISO 3166 Maintenance agency (ISO 3166/MA)
-# </a>.
+# ISO 3166-1 Newsletter VI-15 (2013-05-10). See: Updates on ISO 3166
+# http://www.iso.org/iso/home/standards/country_codes/updates_on_iso_3166.htm
# 2. The usual English name for the country,
# chosen so that alphabetic sorting of subsets produces helpful lists.
# This is not the same as the English name in the ISO 3166 tables.
@@ -43,8 +41,9 @@
#
# Lines beginning with `#' are comments.
#
-# From Arthur David Olson (2011-08-17):
-# Resynchronized today with the ISO 3166 site (adding SS for South Sudan).
+# This table is intended as an aid for users, to help them select time
+# zone data appropriate for their practical needs. It is not intended
+# to take or endorse any position on legal or territorial claims.
#
#country-
#code country name
@@ -77,7 +76,7 @@
BM Bermuda
BN Brunei
BO Bolivia
-BQ Bonaire Sint Eustatius & Saba
+BQ Bonaire, St Eustatius & Saba
BR Brazil
BS Bahamas
BT Bhutan
@@ -258,7 +257,7 @@
SS South Sudan
ST Sao Tome & Principe
SV El Salvador
-SX Sint Maarten
+SX St Maarten (Dutch part)
SY Syria
SZ Swaziland
TC Turks & Caicos Is
--- a/jdk/test/sun/util/calendar/zi/tzdata/leapseconds Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/leapseconds Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/northamerica Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/northamerica Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/pacificnew Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/pacificnew Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/solar87 Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/solar87 Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/solar88 Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/solar88 Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/solar89 Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/solar89 Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/southamerica Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/southamerica Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
@@ -994,7 +994,7 @@
# adopted by the same states as before.
Rule Brazil 2007 only - Oct Sun>=8 0:00 1:00 S
# From Frederico A. C. Neves (2008-09-10):
-# Acording to this decree
+# According to this decree
# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm">
# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm
# </a>
@@ -1226,7 +1226,7 @@
# http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651
# </a>
#
-# This is not yet reflected in the offical "cambio de hora" site, but
+# This is not yet reflected in the official "cambio de hora" site, but
# probably will be soon:
# <a href="http://www.horaoficial.cl/cambio.htm">
# http://www.horaoficial.cl/cambio.htm
--- a/jdk/test/sun/util/calendar/zi/tzdata/systemv Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/systemv Wed Jul 05 19:09:26 2017 +0200
@@ -1,22 +1,22 @@
#
# 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.
--- a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab Wed Jul 05 19:09:26 2017 +0200
@@ -1,41 +1,44 @@
#
# 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.
#
-# <pre>
+# TZ zone descriptions
+#
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
#
-# TZ zone descriptions
-#
-# From Paul Eggert (1996-08-05):
+# From Paul Eggert (2013-05-27):
#
# This file contains a table with the following columns:
# 1. ISO 3166 2-character country code. See the file `iso3166.tab'.
+# This identifies a country that overlaps the zone. The country may
+# overlap other zones and the zone may overlap other countries.
# 2. Latitude and longitude of the zone's principal location
# in ISO 6709 sign-degrees-minutes-seconds format,
# either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
# first latitude (+ is north), then longitude (+ is east).
+# This location need not lie within the column-1 country.
# 3. Zone name used in value of TZ environment variable.
+# Please see the 'Theory' file for how zone names are chosen.
# 4. Comments; present if and only if the country has multiple rows.
#
# Columns are separated by a single tab.
@@ -45,6 +48,10 @@
#
# Lines beginning with `#' are comments.
#
+# This table is intended as an aid for users, to help them select time
+# zone data appropriate for their practical needs. It is not intended
+# to take or endorse any position on legal or territorial claims.
+#
#country-
#code coordinates TZ comments
AD +4230+00131 Europe/Andorra
@@ -239,7 +246,7 @@
ID -0507+11924 Asia/Makassar east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor
ID -0232+14042 Asia/Jayapura west New Guinea (Irian Jaya) & Malukus (Moluccas)
IE +5320-00615 Europe/Dublin
-IL +3146+03514 Asia/Jerusalem
+IL +314650+0351326 Asia/Jerusalem
IM +5409-00428 Europe/Isle_of_Man
IN +2232+08822 Asia/Kolkata
IO -0720+07225 Indian/Chagos
--- a/jdk/test/tools/jar/AddAndUpdateProfile.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @bug 8003255
- * @compile -XDignore.symbol.file AddAndUpdateProfile.java
- * @run main AddAndUpdateProfile
- * @summary Basic test of jar tool "p" option to add or update the Profile
- * attribute in the main manifest of a JAR file
- */
-
-import java.util.jar.*;
-import static java.util.jar.Attributes.Name.*;
-import java.nio.file.*;
-import java.io.IOException;
-
-import sun.tools.jar.Main;
-
-public class AddAndUpdateProfile {
- static boolean doJar(String... args) {
- System.out.print("jar");
- for (String arg: args)
- System.out.print(" " + arg);
- System.out.println("");
-
- Main jartool = new Main(System.out, System.err, "jar");
- return jartool.run(args);
- }
-
- static void jar(String... args) {
- if (!doJar(args))
- throw new RuntimeException("jar command failed");
- }
-
- static void jarExpectingFail(String... args) {
- if (doJar(args))
- throw new RuntimeException("jar command not expected to succeed");
- }
-
- static void checkMainAttribute(String jarfile, Attributes.Name name,
- String expectedValue)
- throws IOException
- {
- try (JarFile jf = new JarFile(jarfile)) {
- Manifest mf = jf.getManifest();
- if (mf == null && expectedValue != null)
- throw new RuntimeException("Manifest not found");
- if (mf != null) {
- String actual = mf.getMainAttributes().getValue(name);
- if (actual != null) {
- if (!actual.equals(expectedValue))
- throw new RuntimeException("Profile attribute has unexpected value");
- } else {
- if (expectedValue != null)
- throw new RuntimeException("Profile attribute should not be present");
- }
- }
- }
- }
-
- public static void main(String[] args) throws Exception {
- Path entry = Files.createFile(Paths.get("xfoo"));
- String jarfile = "xFoo.jar";
- try {
-
- // create JAR file with Profile attribute
- jar("cfp", jarfile, "compact1", entry.toString());
- checkMainAttribute(jarfile, PROFILE, "compact1");
-
- // attempt to create JAR file with Profile attribute and bad value
- jarExpectingFail("cfp", jarfile, "garbage", entry.toString());
- jarExpectingFail("cfp", jarfile, "Compact1", entry.toString());
- jarExpectingFail("cfp", jarfile, "COMPACT1", entry.toString());
-
- // update value of Profile attribute
- jar("ufp", jarfile, "compact2");
- checkMainAttribute(jarfile, PROFILE, "compact2");
-
- // attempt to update value of Profile attribute to bad value
- // (update should not change the JAR file)
- jarExpectingFail("ufp", jarfile, "garbage");
- checkMainAttribute(jarfile, PROFILE, "compact2");
- jarExpectingFail("ufp", jarfile, "COMPACT1");
- checkMainAttribute(jarfile, PROFILE, "compact2");
-
- // create JAR file with both a Main-Class and Profile attribute
- jar("cfep", jarfile, "Foo", "compact1", entry.toString());
- checkMainAttribute(jarfile, MAIN_CLASS, "Foo");
- checkMainAttribute(jarfile, PROFILE, "compact1");
-
- // update value of Profile attribute
- jar("ufp", jarfile, "compact2");
- checkMainAttribute(jarfile, PROFILE, "compact2");
-
- // create JAR file without Profile attribute
- jar("cf", jarfile, entry.toString());
- checkMainAttribute(jarfile, PROFILE, null);
-
- // update value of Profile attribute
- jar("ufp", jarfile, "compact3");
- checkMainAttribute(jarfile, PROFILE, "compact3");
-
- } finally {
- Files.deleteIfExists(Paths.get(jarfile));
- Files.delete(entry);
- }
- }
-
-}
--- a/jdk/test/tools/launcher/profiles/Basic.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @bug 8003255
- * @compile -XDignore.symbol.file Basic.java Main.java Logging.java
- * @run main Basic
- * @summary Test the launcher checks the Profile attribute of executable JAR
- * files. Also checks that libraries that specify the Profile attribute
- * are not loaded if the runtime does not support the required profile.
- */
-
-import java.io.*;
-import java.util.jar.*;
-import static java.util.jar.JarFile.MANIFEST_NAME;
-import java.util.zip.*;
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-
-public class Basic {
-
- static final String MANIFEST_DIR = "META-INF/";
-
- static final String JAVA_HOME = System.getProperty("java.home");
- static final String OS_NAME = System.getProperty("os.name");
- static final String OS_ARCH = System.getProperty("os.arch");
-
- static final String JAVA_CMD =
- OS_NAME.startsWith("Windows") ? "java.exe" : "java";
-
- static final boolean NEED_D64 =
- OS_NAME.equals("SunOS") &&
- (OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
-
- /**
- * Creates a JAR file with the given attributes and the given entries.
- * Class files are assumed to be in ${test.classes}. Note that this this
- * method cannot use the "jar" tool as it may not be present in the image.
- */
- static void createJarFile(String jarfile,
- String mainAttributes,
- String... entries)
- throws IOException
- {
- // create Manifest
- Manifest manifest = new Manifest();
- Attributes jarAttrs = manifest.getMainAttributes();
- jarAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
- if (mainAttributes.length() > 0) {
- for (String attr: mainAttributes.split(",")) {
- String[] s = attr.split("=");
- jarAttrs.put(new Attributes.Name(s[0]), s[1]);
- }
- }
-
- try (OutputStream out = Files.newOutputStream(Paths.get(jarfile));
- ZipOutputStream zos = new JarOutputStream(out))
- {
- // add manifest directory and manifest file
- ZipEntry e = new JarEntry(MANIFEST_DIR);
- e.setTime(System.currentTimeMillis());
- e.setSize(0);
- e.setCrc(0);
- zos.putNextEntry(e);
- e = new ZipEntry(MANIFEST_NAME);
- e.setTime(System.currentTimeMillis());
- zos.putNextEntry(e);
- manifest.write(zos);
- zos.closeEntry();
-
- // entries in JAR file
- for (String entry: entries) {
- e = new JarEntry(entry);
- Path path;
- if (entry.endsWith(".class")) {
- path = Paths.get(System.getProperty("test.classes"), entry);
- } else {
- path = Paths.get(entry);
- }
- BasicFileAttributes attrs =
- Files.readAttributes(path, BasicFileAttributes.class);
- e.setTime(attrs.lastModifiedTime().toMillis());
- if (attrs.size() == 0) {
- e.setMethod(ZipEntry.STORED);
- e.setSize(0);
- e.setCrc(0);
- }
- zos.putNextEntry(e);
- if (attrs.isRegularFile())
- Files.copy(path, zos);
- zos.closeEntry();
- }
- }
- }
-
- /**
- * Execute the given executable JAR file with the given arguments. This
- * method blocks until the launched VM terminates. Any output or error
- * message from the launched VM are printed to System.out. Returns the
- * exit value.
- */
- static int exec(String jf, String... args) throws IOException {
- StringBuilder sb = new StringBuilder();
- sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
- if (NEED_D64)
- sb.append(" -d64");
- sb.append(" -jar ");
- sb.append(Paths.get(jf).toAbsolutePath());
- for (String arg: args) {
- sb.append(' ');
- sb.append(arg);
- }
- String[] cmd = sb.toString().split(" ");
- ProcessBuilder pb = new ProcessBuilder(cmd);
- pb.redirectErrorStream(true);
- Process p = pb.start();
- BufferedReader reader =
- new BufferedReader(new InputStreamReader(p.getInputStream()));
- String line;
- while ((line = reader.readLine()) != null) {
- System.out.println(line);
- }
- try {
- return p.waitFor();
- } catch (InterruptedException e) {
- throw new RuntimeException("Should not happen");
- }
- }
-
- static void checkRun(String jf, String... args) throws IOException {
- if (exec(jf) != 0)
- throw new RuntimeException(jf + " failed!!!");
- }
-
- static void checkRunFail(String jf, String... args) throws IOException {
- if (exec(jf) == 0)
- throw new RuntimeException(jf + " did not fail!!!");
- System.out.println("Failed as expected");
- }
-
- public static void main(String[] args) throws IOException {
- // ## replace this if there is a standard way to determine the profile
- String profile = sun.misc.Version.profileName();
-
- int thisProfile = 4;
- if ("compact1".equals(profile)) thisProfile = 1;
- if ("compact2".equals(profile)) thisProfile = 2;
- if ("compact3".equals(profile)) thisProfile = 3;
-
- // "library" JAR file used by the test
- createJarFile("Logging.jar", "", "Logging.class");
-
- // Executable JAR file without the Profile attribute
- if (thisProfile <= 3) {
- createJarFile("Main.jar",
- "Main-Class=Main,Class-Path=Logging.jar",
- "Main.class");
- checkRunFail("Main.jar");
- }
-
- // Executable JAR file with Profile attribute, Library JAR file without
- for (int p=1; p<=3; p++) {
- String attrs = "Main-Class=Main,Class-Path=Logging.jar" +
- ",Profile=compact" + p;
- createJarFile("Main.jar", attrs, "Main.class");
- if (p <= thisProfile) {
- checkRun("Main.jar");
- } else {
- checkRunFail("Main.jar");
- }
- }
-
- // Executable JAR file with Profile attribute that has invalid profile
- // name, including incorrect case.
- createJarFile("Main.jar",
- "Main-Class=Main,Class-Path=Logging.jar,Profile=BadName",
- "Main.class");
- checkRunFail("Main.jar");
-
- createJarFile("Main.jar",
- "Main-Class=Main,Class-Path=Logging.jar,Profile=Compact1",
- "Main.class");
- checkRunFail("Main.jar");
-
- // Executable JAR file and Librrary JAR file with Profile attribute
- createJarFile("Main.jar",
- "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
- "Main.class");
- for (int p=1; p<=3; p++) {
- String attrs = "Profile=compact" + p;
- createJarFile("Logging.jar", attrs, "Logging.class");
- if (p <= thisProfile) {
- checkRun("Main.jar");
- } else {
- checkRunFail("Main.jar");
- }
- }
-
- // Executable JAR file and Library JAR with Profile attribute, value
- // of Profile not recognized
- createJarFile("Logging.jar", "Profile=BadName", "Logging.class");
- createJarFile("Main.jar",
- "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
- "Main.class");
- checkRunFail("Main.jar");
-
- System.out.println("TEST PASSED.");
- }
-
-}
--- a/jdk/test/tools/launcher/profiles/Logging.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-public class Logging {
- private Logging() { }
-
- public static void log(String msg) {
- System.out.println(msg);
- }
-}
--- a/jdk/test/tools/launcher/profiles/Main.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-public class Main {
- private Main() { }
-
- public static void main(String[] args) {
- Logging.log("main running");
- }
-}
--- a/jdk/test/tools/launcher/profiles/VersionCheck.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @bug 8003256
- * @compile -XDignore.symbol.file VersionCheck.java
- * @run main VersionCheck
- * @summary Tests that "java -version" includes the name of the profile and that
- * it matches the name in the release file
- */
-
-import java.nio.file.*;
-import java.io.*;
-import java.util.Properties;
-
-public class VersionCheck {
-
- static final String JAVA_HOME = System.getProperty("java.home");
- static final String OS_NAME = System.getProperty("os.name");
- static final String OS_ARCH = System.getProperty("os.arch");
-
- static final String JAVA_CMD =
- OS_NAME.startsWith("Windows") ? "java.exe" : "java";
-
- static final boolean NEED_D64 =
- OS_NAME.equals("SunOS") &&
- (OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
-
- /**
- * Returns {@code true} if the given class is present.
- */
- static boolean isPresent(String cn) {
- try {
- Class.forName(cn);
- return true;
- } catch (ClassNotFoundException ignore) {
- return false;
- }
- }
-
- /**
- * Determines the profile by checking whether specific classes are present.
- * Returns the empty string if this runtime does not appear to be a profile
- * of Java SE.
- */
- static String probeProfile() {
- if (isPresent("java.awt.Window"))
- return "";
- if (isPresent("java.lang.management.ManagementFactory"))
- return "compact3";
- if (isPresent("java.sql.DriverManager"))
- return "compact2";
- return "compact1";
- }
-
- /**
- * Execs java with the given parameters. The method blocks until the
- * process terminates. Returns a {@code ByteArrayOutputStream} with any
- * stdout or stderr from the process.
- */
- static ByteArrayOutputStream execJava(String... args)
- throws IOException
- {
- StringBuilder sb = new StringBuilder();
- sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
- if (NEED_D64)
- sb.append(" -d64");
- for (String arg: args) {
- sb.append(' ');
- sb.append(arg);
- }
- String[] cmd = sb.toString().split(" ");
- ProcessBuilder pb = new ProcessBuilder(cmd);
- pb.redirectErrorStream(true);
- Process p = pb.start();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buf = new byte[1024];
- int n;
- do {
- n = p.getInputStream().read(buf);
- if (n > 0)
- baos.write(buf, 0, n);
- } while (n > 0);
- try {
- int exitCode = p.waitFor();
- if (exitCode != 0)
- throw new RuntimeException("Exit code: " + exitCode);
- } catch (InterruptedException e) {
- throw new RuntimeException("Should not happen");
- }
- return baos;
- }
-
- public static void main(String[] args) throws IOException {
- String reported = sun.misc.Version.profileName();
- String probed = probeProfile();
- if (!reported.equals(probed)) {
- throw new RuntimeException("sun.misc.Version reports: " + reported
- + ", but probing reports: " + probed);
- }
-
- String profile = probed;
- boolean isFullJre = (profile.length() == 0);
-
- // check that java -version includes "profile compactN"
- String expected = "profile " + profile;
- System.out.println("Checking java -version ...");
- ByteArrayOutputStream baos = execJava("-version");
- ByteArrayInputStream bain = new ByteArrayInputStream(baos.toByteArray());
- BufferedReader reader = new BufferedReader(new InputStreamReader(bain));
- boolean found = false;
- String line;
- while ((line = reader.readLine()) != null) {
- if (line.contains(expected)) {
- found = true;
- break;
- }
- }
- if (found && isFullJre)
- throw new RuntimeException(expected + " found in java -version output");
- if (!found && !isFullJre)
- throw new RuntimeException("java -version did not include " + expected);
-
- // check that the profile name matches the release file
- System.out.println("Checking release file ...");
- Properties props = new Properties();
-
- Path home = Paths.get(JAVA_HOME);
- if (home.getFileName().toString().equals("jre"))
- home = home.getParent();
- Path release = home.resolve("release");
- try (InputStream in = Files.newInputStream(release)) {
- props.load(in);
- }
- String value = props.getProperty("JAVA_PROFILE");
- if (isFullJre) {
- if (value != null)
- throw new RuntimeException("JAVA_PROFILE should not be present");
- } else {
- if (value == null)
- throw new RuntimeException("JAVA_PROFILE not present in release file");
- if (!value.equals("\"" + profile + "\""))
- throw new RuntimeException("Unexpected value of JAVA_PROFILE: " + value);
- }
-
- System.out.println("Test passed.");
- }
-}
--- a/jdk/test/tools/pack200/TimeStamp.java Fri Aug 23 14:17:49 2013 -0700
+++ b/jdk/test/tools/pack200/TimeStamp.java Wed Jul 05 19:09:26 2017 +0200
@@ -88,6 +88,7 @@
unpackNative(packFile, pstFile);
verifyJar(goldenFile, pstFile);
pstFile.delete();
+ Utils.cleanup();
}
static void unpackNative(File packFile, File outFile) {
@@ -149,7 +150,6 @@
Utils.close(jf1);
Utils.close(jf2);
}
- Utils.cleanup();
if (errors > 0) {
throw new RuntimeException("FAIL:" + errors + " error(s) encounted");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/vm/verifier/defaultMethods/DefaultMethodRegressionTests.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ */
+
+/**
+ * @test
+ * @bug 8003639
+ * @summary defaultMethod resolution and verification
+ * @run main DefaultMethodRegressionTests
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This set of classes/interfaces (K/I/C) is specially designed to expose a
+ * bug in the JVM where it did not find some overloaded methods in some
+ * specific situations. (fixed by hotspot changeset ffb9316fd9ed).
+ */
+interface K {
+ int bbb(Long l);
+}
+
+interface I extends K {
+ default void aaa() {}
+ default void aab() {}
+ default void aac() {}
+
+ default int bbb(Integer i) { return 22; }
+ default int bbb(Float f) { return 33; }
+ default int bbb(Long l) { return 44; }
+ default int bbb(Double d) { return 55; }
+ default int bbb(String s) { return 66; }
+
+ default void caa() {}
+ default void cab() {}
+ default void cac() {}
+}
+
+class C implements I {}
+
+public class DefaultMethodRegressionTests {
+ public static void main(String... args) {
+ new DefaultMethodRegressionTests().run(args);
+ }
+ void run(String... args) {
+ testLostOverloadedMethod();
+ System.out.println("testLostOverloadedMethod: OK");
+ testInferenceVerifier();
+ System.out.println("testInferenceVerifier: OK");
+ }
+ void testLostOverloadedMethod() {
+ C c = new C();
+ assertEquals(c.bbb(new Integer(1)), 22);
+ assertEquals(c.bbb(new Float(1.1)), 33);
+ assertEquals(c.bbb(new Long(1L)), 44);
+ assertEquals(c.bbb(new Double(0.01)), 55);
+ assertEquals(c.bbb(new String("")), 66);
+ }
+ // Test to ensure that the inference verifier accepts older classfiles
+ // with classes that implement interfaces with defaults.
+ void testInferenceVerifier() {
+ // interface I { int m() default { return 99; } }
+ byte I_bytes[] = {
+ (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x34,
+ 0x00, 0x08, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07,
+ 0x01, 0x00, 0x03, 0x66, 0x6f, 0x6f, 0x01, 0x00,
+ 0x03, 0x28, 0x29, 0x49, 0x01, 0x00, 0x04, 0x43,
+ 0x6f, 0x64, 0x65, 0x01, 0x00, 0x01, 0x49, 0x01,
+ 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+ 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+ 0x63, 0x74, 0x06, 0x00, 0x00, 0x01, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01,
+ 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x03, 0x10, 0x63, (byte)0xac, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ // public class C implements I {} /* -target 1.5 */
+ byte C_bytes[] = {
+ (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x0c, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x07,
+ 0x00, 0x09, 0x07, 0x00, 0x0a, 0x07, 0x00, 0x0b,
+ 0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74,
+ 0x3e, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x01,
+ 0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x0c, 0x00,
+ 0x05, 0x00, 0x06, 0x01, 0x00, 0x01, 0x43, 0x01,
+ 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+ 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+ 0x63, 0x74, 0x01, 0x00, 0x01, 0x49, 0x00, 0x21,
+ 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
+ 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
+ 0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x05, 0x2a, (byte)0xb7, 0x00, 0x01, (byte)0xb1, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ ClassLoader cl = new ClassLoader() {
+ protected Class<?> findClass(String name) {
+ if (name.equals("I")) {
+ return defineClass("I", I_bytes, 0, I_bytes.length);
+ } else if (name.equals("C")) {
+ return defineClass("C", C_bytes, 0, C_bytes.length);
+ } else {
+ return null;
+ }
+ }
+ };
+ try {
+ Class.forName("C", true, cl);
+ } catch (Exception e) {
+ // unmodified verifier will throw VerifyError
+ throw new RuntimeException(e);
+ }
+ }
+ void assertEquals(Object o1, Object o2) {
+ System.out.print("Expected: " + o1);
+ System.out.println(", Obtained: " + o2);
+ if (!o1.equals(o2)) {
+ throw new RuntimeException("got unexpected values");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/vm/verifier/defaultMethods/DefaultMethodRegressionTestsRun.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/**
+ * @test
+ * @bug 8003639
+ * @summary defaultMethod resolution and verification using an URLClassLoader
+ * @compile -XDignore.symbol.file=true DefaultMethodRegressionTestsRun.java
+ * @run main DefaultMethodRegressionTestsRun
+ */
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+/**
+ * This test is a variant of DefaultMethodRegressionTests, this one creates
+ * an URLClassLoader to load the support classes.
+ *
+ */
+public class DefaultMethodRegressionTestsRun {
+ public static void main(String... args) throws Exception {
+ File scratchDir = new File(".");
+ File testDir = new File(scratchDir, "testdir");
+ testDir.mkdirs();
+ File srcFile = new File(new File(System.getProperty("test.src")),
+ "DefaultMethodRegressionTests.java");
+ String[] javacargs = {
+ srcFile.getAbsolutePath(),
+ "-d",
+ testDir.getAbsolutePath()
+ };
+ com.sun.tools.javac.Main.compile(javacargs);
+ runClass(testDir, "DefaultMethodRegressionTests");
+ }
+ static void runClass(
+ File classPath,
+ String classname) throws Exception {
+ URL[] urls = {classPath.toURI().toURL()};
+ ClassLoader loader = new URLClassLoader(urls);
+ Class<?> c = loader.loadClass(classname);
+
+ Class<?>[] argTypes = new Class<?>[]{String[].class};
+ Object[] methodArgs = new Object[]{null};
+
+ Method method = c.getMethod("main", argTypes);
+ method.invoke(c, methodArgs);
+ }
+}
--- a/nashorn/.hgtags Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/.hgtags Wed Jul 05 19:09:26 2017 +0200
@@ -213,3 +213,4 @@
a302b05d0ee460679501dc01004f70eb395fadf5 jdk8-b101
e966ff0a3ffef8a687eaf5a14167bb595b623d02 jdk8-b102
414203de4374e1964a9918c38a95fb245010a9f1 jdk8-b103
+afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104
--- a/nashorn/exclude/exclude_list_cc.txt Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/exclude/exclude_list_cc.txt Wed Jul 05 19:09:26 2017 +0200
@@ -3,4 +3,5 @@
<excludeList>
<test id="JDK-8014647.js" />
<test id="javaclassoverrides.js" />
+ <test id="JDK-8020809.js" />
</excludeList>
--- a/nashorn/make/project.properties Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/make/project.properties Wed Jul 05 19:09:26 2017 +0200
@@ -222,11 +222,16 @@
run.test.user.language=tr
run.test.user.country=TR
-# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
-run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country}
+run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError
+
+#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
+# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
-#-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
-run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main}
+# turn on assertions for tests
+run.test.jvmargs.main=${run.test.jvmargs.common} -ea
+
+#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
+run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.common}
run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy
--- a/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java Wed Jul 05 19:09:26 2017 +0200
@@ -85,12 +85,12 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicReference;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
+import jdk.internal.dynalink.support.Lookup;
/**
* A relinkable call site that maintains a chain of linked method handles. In the default implementation, up to 8 method
@@ -103,6 +103,9 @@
* handle is always at the start of the chain.
*/
public class ChainedCallSite extends AbstractRelinkableCallSite {
+ private static final MethodHandle PRUNE = Lookup.findOwnSpecial(MethodHandles.lookup(), "prune", MethodHandle.class,
+ MethodHandle.class);
+
private final AtomicReference<LinkedList<GuardedInvocation>> invocations = new AtomicReference<>();
/**
@@ -194,18 +197,4 @@
private MethodHandle prune(MethodHandle relink) {
return relinkInternal(null, relink, false);
}
-
- private static final MethodHandle PRUNE;
- static {
- try {
- PRUNE = MethodHandles.lookup().findSpecial(ChainedCallSite.class, "prune", MethodType.methodType(
- MethodHandle.class, MethodHandle.class), ChainedCallSite.class);
- // NOTE: using two catch blocks so we don't introduce a reference to 1.7 ReflectiveOperationException, allowing
- // Dynalink to be used on 1.6 JVMs with Remi's backport library.
- } catch(IllegalAccessException e) {
- throw new AssertionError(e.getMessage(), e); // Can not happen
- } catch(NoSuchMethodException e) {
- throw new AssertionError(e.getMessage(), e); // Can not happen
- }
- }
}
--- a/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java Wed Jul 05 19:09:26 2017 +0200
@@ -84,6 +84,8 @@
package jdk.internal.dynalink;
import java.lang.invoke.MutableCallSite;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -97,6 +99,7 @@
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.support.AutoDiscovery;
import jdk.internal.dynalink.support.BottomGuardingDynamicLinker;
+import jdk.internal.dynalink.support.ClassLoaderGetterContextProvider;
import jdk.internal.dynalink.support.CompositeGuardingDynamicLinker;
import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker;
import jdk.internal.dynalink.support.LinkerServicesImpl;
@@ -117,7 +120,9 @@
*/
public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8;
- private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ private boolean classLoaderExplicitlySet = false;
+ private ClassLoader classLoader;
+
private List<? extends GuardingDynamicLinker> prioritizedLinkers;
private List<? extends GuardingDynamicLinker> fallbackLinkers;
private int runtimeContextArgCount = 0;
@@ -126,12 +131,13 @@
/**
* Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread
- * context class loader at the time of the constructor invocation will be used.
+ * context class loader at the time of {@link #createLinker()} invocation will be used.
*
* @param classLoader the class loader used for the autodiscovery of available linkers.
*/
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
+ classLoaderExplicitlySet = true;
}
/**
@@ -260,7 +266,8 @@
addClasses(knownLinkerClasses, prioritizedLinkers);
addClasses(knownLinkerClasses, fallbackLinkers);
- final List<GuardingDynamicLinker> discovered = AutoDiscovery.loadLinkers(classLoader);
+ final ClassLoader effectiveClassLoader = classLoaderExplicitlySet ? classLoader : getThreadContextClassLoader();
+ final List<GuardingDynamicLinker> discovered = AutoDiscovery.loadLinkers(effectiveClassLoader);
// Now, concatenate ...
final List<GuardingDynamicLinker> linkers =
new ArrayList<>(prioritizedLinkers.size() + discovered.size()
@@ -303,6 +310,15 @@
runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold);
}
+ private static ClassLoader getThreadContextClassLoader() {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ @Override
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
+ }
+
private static void addClasses(Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
List<? extends GuardingDynamicLinker> linkers) {
for(GuardingDynamicLinker linker: linkers) {
--- a/nashorn/src/jdk/internal/dynalink/beans/ClassString.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/beans/ClassString.java Wed Jul 05 19:09:26 2017 +0200
@@ -112,10 +112,6 @@
this(type.parameterArray());
}
- Class<?>[] getClasses() {
- return classes;
- }
-
@Override
public boolean equals(Object other) {
if(!(other instanceof ClassString)) {
--- a/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java Wed Jul 05 19:09:26 2017 +0200
@@ -189,15 +189,17 @@
return type == StaticClass.class;
}
- /*private*/ static final MethodHandle GET_CLASS = new Lookup(MethodHandles.lookup()).findVirtual(StaticClass.class,
- "getRepresentedClass", MethodType.methodType(Class.class));
-
- /*private*/ static final MethodHandle IS_CLASS = new Lookup(MethodHandles.lookup()).findStatic(StaticClassLinker.class,
- "isClass", MethodType.methodType(Boolean.TYPE, Class.class, Object.class));
-
+ /*private*/ static final MethodHandle GET_CLASS;
+ /*private*/ static final MethodHandle IS_CLASS;
/*private*/ static final MethodHandle ARRAY_CTOR = Lookup.PUBLIC.findStatic(Array.class, "newInstance",
MethodType.methodType(Object.class, Class.class, int.class));
+ static {
+ final Lookup lookup = new Lookup(MethodHandles.lookup());
+ GET_CLASS = lookup.findVirtual(StaticClass.class, "getRepresentedClass", MethodType.methodType(Class.class));
+ IS_CLASS = lookup.findOwnStatic("isClass", Boolean.TYPE, Class.class, Object.class);
+ }
+
@SuppressWarnings("unused")
private static boolean isClass(Class<?> clazz, Object obj) {
return obj instanceof StaticClass && ((StaticClass)obj).getRepresentedClass() == clazz;
--- a/nashorn/src/jdk/internal/dynalink/support/Backport.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file, and Oracle licenses the original version of this file under the BSD
- * license:
- */
-/*
- Copyright 2009-2013 Attila Szegedi
-
- Licensed under both the Apache License, Version 2.0 (the "Apache License")
- and the BSD License (the "BSD License"), with licensee being free to
- choose either of the two at their discretion.
-
- You may not use this file except in compliance with either the Apache
- License or the BSD License.
-
- If you choose to use this file in compliance with the Apache License, the
- following notice applies to you:
-
- You may obtain a copy of the Apache License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied. See the License for the specific language governing
- permissions and limitations under the License.
-
- If you choose to use this file in compliance with the BSD License, the
- following notice applies to you:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the copyright holder nor the names of
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package jdk.internal.dynalink.support;
-
-import java.lang.invoke.MethodHandles;
-
-/**
- * @author Attila Szegedi
- */
-public class Backport {
- /**
- * True if Remi's JSR-292 backport agent is active; false if we're using native OpenJDK JSR-292 support.
- */
- public static final boolean inUse = MethodHandles.class.getName().startsWith("jsr292");
-
- private Backport() {
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/internal/dynalink/support/ClassLoaderGetterContextProvider.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010, 2013, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+ Copyright 2009-2013 Attila Szegedi
+
+ Licensed under both the Apache License, Version 2.0 (the "Apache License")
+ and the BSD License (the "BSD License"), with licensee being free to
+ choose either of the two at their discretion.
+
+ You may not use this file except in compliance with either the Apache
+ License or the BSD License.
+
+ If you choose to use this file in compliance with the Apache License, the
+ following notice applies to you:
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ If you choose to use this file in compliance with the BSD License, the
+ following notice applies to you:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package jdk.internal.dynalink.support;
+
+import java.security.AccessControlContext;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+
+/**
+ * This class exposes a canonical {@link AccessControlContext} with a single {@link RuntimePermission} for
+ * {@code "getClassLoader"} permission that is used by other parts of the code to narrow their set of permissions when
+ * they're retrieving class loaders in privileged blocks.
+ */
+public class ClassLoaderGetterContextProvider {
+ /**
+ * Canonical instance of {@link AccessControlContext} with a single {@link RuntimePermission} for
+ * {@code "getClassLoader"} permission.
+ */
+ public static final AccessControlContext GET_CLASS_LOADER_CONTEXT;
+ static {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission("getClassLoader"));
+ GET_CLASS_LOADER_CONTEXT = new AccessControlContext(
+ new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+}
--- a/nashorn/src/jdk/internal/dynalink/support/ClassMap.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/support/ClassMap.java Wed Jul 05 19:09:26 2017 +0200
@@ -85,6 +85,8 @@
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
@@ -122,21 +124,12 @@
protected abstract T computeValue(Class<?> clazz);
/**
- * Returns the class loader that governs the strong referenceability of this class map.
- *
- * @return the class loader that governs the strong referenceability of this class map.
- */
- public ClassLoader getClassLoader() {
- return classLoader;
- }
-
- /**
* Returns the value associated with the class
*
* @param clazz the class
* @return the value associated with the class
*/
- public T get(Class<?> clazz) {
+ public T get(final Class<?> clazz) {
// Check in fastest first - objects we're allowed to strongly reference
final T v = map.get(clazz);
if(v != null) {
@@ -156,8 +149,16 @@
// Not found in either place; create a new value
final T newV = computeValue(clazz);
assert newV != null;
+
+ final ClassLoader clazzLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ @Override
+ public ClassLoader run() {
+ return clazz.getClassLoader();
+ }
+ }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
+
// If allowed to strongly reference, put it in the fast map
- if(Guards.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
+ if(Guards.canReferenceDirectly(classLoader, clazzLoader)) {
final T oldV = map.putIfAbsent(clazz, newV);
return oldV != null ? oldV : newV;
}
--- a/nashorn/src/jdk/internal/dynalink/support/Guards.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/support/Guards.java Wed Jul 05 19:09:26 2017 +0200
@@ -258,23 +258,24 @@
type.changeReturnType(Boolean.TYPE), new int[] { pos });
}
- private static final MethodHandle IS_OF_CLASS = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
- "isOfClass", MethodType.methodType(Boolean.TYPE, Class.class, Object.class));
-
private static final MethodHandle IS_INSTANCE = Lookup.PUBLIC.findVirtual(Class.class, "isInstance",
MethodType.methodType(Boolean.TYPE, Object.class));
- private static final MethodHandle IS_ARRAY = new Lookup(MethodHandles.lookup()).findStatic(Guards.class, "isArray",
- MethodType.methodType(Boolean.TYPE, Object.class));
-
- private static final MethodHandle IS_IDENTICAL = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
- "isIdentical", MethodType.methodType(Boolean.TYPE, Object.class, Object.class));
+ private static final MethodHandle IS_OF_CLASS;
+ private static final MethodHandle IS_ARRAY;
+ private static final MethodHandle IS_IDENTICAL;
+ private static final MethodHandle IS_NULL;
+ private static final MethodHandle IS_NOT_NULL;
- private static final MethodHandle IS_NULL = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
- "isNull", MethodType.methodType(Boolean.TYPE, Object.class));
+ static {
+ final Lookup lookup = new Lookup(MethodHandles.lookup());
- private static final MethodHandle IS_NOT_NULL = new Lookup(MethodHandles.lookup()).findStatic(Guards.class,
- "isNotNull", MethodType.methodType(Boolean.TYPE, Object.class));
+ IS_OF_CLASS = lookup.findOwnStatic("isOfClass", Boolean.TYPE, Class.class, Object.class);
+ IS_ARRAY = lookup.findOwnStatic("isArray", Boolean.TYPE, Object.class);
+ IS_IDENTICAL = lookup.findOwnStatic("isIdentical", Boolean.TYPE, Object.class, Object.class);
+ IS_NULL = lookup.findOwnStatic("isNull", Boolean.TYPE, Object.class);
+ IS_NOT_NULL = lookup.findOwnStatic("isNotNull", Boolean.TYPE, Object.class);
+ }
/**
* Creates a guard method that tests its only argument for being of an exact particular class.
--- a/nashorn/src/jdk/internal/dynalink/support/Lookup.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/support/Lookup.java Wed Jul 05 19:09:26 2017 +0200
@@ -89,7 +89,6 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
/**
* A wrapper around MethodHandles.Lookup that masks checked exceptions in those cases when you're looking up methods
@@ -235,9 +234,8 @@
}
/**
- * Performs a findSpecial on the underlying lookup, except for the backport where it rather uses unreflect. Converts
- * any encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and a
- * {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
+ * Performs a findSpecial on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an
+ * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
*
* @param declaringClass class declaring the method
* @param name the name of the method
@@ -248,13 +246,6 @@
*/
public MethodHandle findSpecial(Class<?> declaringClass, String name, MethodType type) {
try {
- if(Backport.inUse) {
- final Method m = declaringClass.getDeclaredMethod(name, type.parameterArray());
- if(!Modifier.isPublic(declaringClass.getModifiers()) || !Modifier.isPublic(m.getModifiers())) {
- m.setAccessible(true);
- }
- return unreflect(m);
- }
return lookup.findSpecial(declaringClass, name, type, declaringClass);
} catch(IllegalAccessException e) {
final IllegalAccessError ee = new IllegalAccessError("Failed to access special method " + methodDescription(
--- a/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java Wed Jul 05 19:09:26 2017 +0200
@@ -87,6 +87,8 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.WrongMethodTypeException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.LinkedList;
import java.util.List;
import jdk.internal.dynalink.linker.ConversionComparator;
@@ -110,7 +112,7 @@
private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<ClassMap<MethodHandle>>() {
@Override
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
- return new ClassMap<MethodHandle>(sourceType.getClassLoader()) {
+ return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
@Override
protected MethodHandle computeValue(Class<?> targetType) {
try {
@@ -128,7 +130,7 @@
private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<ClassMap<MethodHandle>>() {
@Override
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
- return new ClassMap<MethodHandle>(sourceType.getClassLoader()) {
+ return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
@Override
protected MethodHandle computeValue(Class<?> targetType) {
if(!canAutoConvert(sourceType, targetType)) {
@@ -143,6 +145,15 @@
}
};
+ private static final ClassLoader getClassLoader(final Class<?> clazz) {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ @Override
+ public ClassLoader run() {
+ return clazz.getClassLoader();
+ }
+ }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
+ }
+
/**
* Creates a new type converter factory from the available {@link GuardingTypeConverterFactory} instances.
*
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Jul 05 19:09:26 2017 +0200
@@ -36,10 +36,13 @@
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.charset.Charset;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -71,6 +74,14 @@
*/
public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable {
+ private static AccessControlContext createPermAccCtxt(final String permName) {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission(permName));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext CREATE_CONTEXT_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_CONTEXT);
+ private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_GLOBAL);
private final ScriptEngineFactory factory;
private final Context nashornContext;
@@ -84,16 +95,9 @@
private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages";
- // Without do privileged, under security manager messages can not be loaded.
private static final ResourceBundle MESSAGES_BUNDLE;
static {
- MESSAGES_BUNDLE = AccessController.doPrivileged(
- new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
- }
- });
+ MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
}
private static String getMessage(final String msgId, final String... args) {
@@ -128,7 +132,7 @@
throw e;
}
}
- });
+ }, CREATE_CONTEXT_ACC_CTXT);
// create new global object
this.global = createNashornGlobal();
@@ -340,7 +344,7 @@
throw e;
}
}
- });
+ }, CREATE_GLOBAL_ACC_CTXT);
nashornContext.initGlobal(newGlobal);
@@ -362,10 +366,8 @@
}
private void evalEngineScript() throws ScriptException {
- evalSupportScript("resources/engine.js", NashornException.ENGINE_SCRIPT_SOURCE_NAME);
- }
-
- private void evalSupportScript(final String script, final String name) throws ScriptException {
+ final String script = "resources/engine.js";
+ final String name = NashornException.ENGINE_SCRIPT_SOURCE_NAME;
try {
final InputStream is = AccessController.doPrivileged(
new PrivilegedExceptionAction<InputStream>() {
@@ -380,6 +382,9 @@
eval(isr);
}
} catch (final PrivilegedActionException | IOException e) {
+ if (Context.DEBUG) {
+ e.printStackTrace();
+ }
throw new ScriptException(e);
} finally {
put(ScriptEngine.FILENAME, null);
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Jul 05 19:09:26 2017 +0200
@@ -30,6 +30,7 @@
import java.util.List;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Version;
/**
@@ -136,7 +137,14 @@
@Override
public ScriptEngine getScriptEngine() {
- return new NashornScriptEngine(this, getAppClassLoader());
+ try {
+ return new NashornScriptEngine(this, getAppClassLoader());
+ } catch (final RuntimeException e) {
+ if (Context.DEBUG) {
+ e.printStackTrace();
+ }
+ throw e;
+ }
}
/**
@@ -178,7 +186,7 @@
private static void checkConfigPermission() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.setConfig"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_SET_CONFIG));
}
}
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,14 +25,17 @@
package jdk.nashorn.api.scripting;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -49,6 +52,14 @@
* netscape.javascript.JSObject interface.
*/
public final class ScriptObjectMirror extends JSObject implements Bindings {
+ private static AccessControlContext getContextAccCtxt() {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission(Context.NASHORN_GET_CONTEXT));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
+
private final ScriptObject sobj;
private final ScriptObject global;
@@ -144,7 +155,7 @@
public Context run() {
return Context.getContext();
}
- });
+ }, GET_CONTEXT_ACC_CTXT);
return wrap(context.eval(global, s, null, null, false), global);
}
});
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java Wed Jul 05 19:09:26 2017 +0200
@@ -33,7 +33,7 @@
private final String className;
/** Current class generator */
- private final ClassEmitter classEmitter;
+ private ClassEmitter classEmitter;
private long weight;
@@ -64,7 +64,11 @@
* @param clazz class with code for this compile unit
*/
void setCode(final Class<?> clazz) {
+ clazz.getClass(); // null check
this.clazz = clazz;
+ // Revisit this - refactor to avoid null-ed out non-final fields
+ // null out emitter
+ this.classEmitter = null;
}
/**
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Wed Jul 05 19:09:26 2017 +0200
@@ -489,20 +489,6 @@
}
/**
- * Create a static call, looking up the method handle for it at the same time
- *
- * @param clazz the class
- * @param name the name of the method
- * @param rtype the return type of the method
- * @param ptypes the parameter types of the method
- *
- * @return the call object representing the static call
- */
- public static Call staticCall(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
- return staticCall(MethodHandles.publicLookup(), clazz, name, rtype, ptypes);
- }
-
- /**
* Create a static call, given an explicit lookup, looking up the method handle for it at the same time
*
* @param lookup the lookup
@@ -523,20 +509,6 @@
}
/**
- * Create a virtual call, looking up the method handle for it at the same time
- *
- * @param clazz the class
- * @param name the name of the method
- * @param rtype the return type of the method
- * @param ptypes the parameter types of the method
- *
- * @return the call object representing the virtual call
- */
- public static Call virtualCall(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
- return virtualCall(MethodHandles.publicLookup(), clazz, name, rtype, ptypes);
- }
-
- /**
* Create a virtual call, given an explicit lookup, looking up the method handle for it at the same time
*
* @param lookup the lookup
--- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Wed Jul 05 19:09:26 2017 +0200
@@ -317,7 +317,8 @@
final String className = getClassName(fieldCount);
final String superName = className(ScriptObject.class);
final ClassEmitter classEmitter = newClassEmitter(className, superName);
- final List<String> initFields = addFields(classEmitter, fieldCount);
+
+ addFields(classEmitter, fieldCount);
final MethodEmitter init = newInitMethod(classEmitter);
init.returnVoid();
--- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java Wed Jul 05 19:09:26 2017 +0200
@@ -45,9 +45,11 @@
/** Code generator */
protected final CodeGenerator codegen;
- private final boolean isScope;
- private final boolean hasArguments;
- protected PropertyMap propertyMap;
+ /** Property map */
+ protected PropertyMap propertyMap;
+
+ private final boolean isScope;
+ private final boolean hasArguments;
/**
* Constructor
--- a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java Wed Jul 05 19:09:26 2017 +0200
@@ -99,6 +99,7 @@
case DIV:
case MOD:
case MUL:
+ case SUB:
case ASSIGN_DIV:
case ASSIGN_MOD:
case ASSIGN_MUL:
--- a/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java Wed Jul 05 19:09:26 2017 +0200
@@ -33,6 +33,14 @@
* a {@code break} statement
*/
public interface BreakableNode extends LexicalContextNode {
+ /**
+ * Ensure that any labels in this breakable node are unique so
+ * that new jumps won't go to old parts of the tree. Used for
+ * example for cloning finally blocks
+ *
+ * @param lc the lexical context
+ * @return node after labels have been made unique
+ */
public abstract Node ensureUniqueLabels(final LexicalContext lc);
/**
--- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Wed Jul 05 19:09:26 2017 +0200
@@ -161,13 +161,13 @@
* converting to object, for example if the symbol is used as the left hand side of an
* assignment such as in the code below.</p>
*
- * <pre>{@code
+ * <pre>
* try {
* return 2;
* } finally {
* return 3;
* }
- * }</pre>
+ * }
*
* @return true if can have callsite type
*/
--- a/nashorn/src/jdk/nashorn/internal/ir/LexicalContextNode.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/ir/LexicalContextNode.java Wed Jul 05 19:09:26 2017 +0200
@@ -44,8 +44,14 @@
Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor);
// Would be a default method on Java 8
+ /**
+ * Helper class for accept for items of this lexical context, delegates to the
+ * subclass accept and makes sure that the node is on the context before accepting
+ * and gets popped after accepting (and that the stack is consistent in that the
+ * node has been replaced with the possible new node resulting in visitation)
+ */
static class Acceptor {
- static Node accept(LexicalContextNode node, final NodeVisitor<? extends LexicalContext> visitor) {
+ static Node accept(final LexicalContextNode node, final NodeVisitor<? extends LexicalContext> visitor) {
final LexicalContext lc = visitor.getLexicalContext();
lc.push(node);
final LexicalContextNode newNode = (LexicalContextNode)node.accept(lc, visitor);
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,12 +35,12 @@
import java.lang.invoke.MethodHandles;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.objects.annotations.Attribute;
@@ -72,8 +72,8 @@
*/
@ScriptClass("Global")
public final class Global extends ScriptObject implements GlobalObject, Scope {
- private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
- private static final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
+ private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
+ private final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
/** ECMA 15.1.2.2 parseInt (string , radix) */
@Property(attributes = Attribute.NOT_ENUMERABLE)
@@ -418,7 +418,7 @@
// security check first
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.newGlobal"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
}
// null check on context
@@ -709,6 +709,35 @@
classCache.put(source, new SoftReference<Class<?>>(clazz));
}
+ private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
+ final T obj = map.get(key);
+ if (obj != null) {
+ return obj;
+ }
+
+ try {
+ final T newObj = creator.call();
+ final T existingObj = map.putIfAbsent(key, newObj);
+ return existingObj != null ? existingObj : newObj;
+ } catch (final Exception exp) {
+ throw new RuntimeException(exp);
+ }
+ }
+
+ private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
+
+ @Override
+ public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
+ return getLazilyCreatedValue(key, creator, namedInvokers);
+ }
+
+ private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
+
+ @Override
+ public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
+ return getLazilyCreatedValue(key, creator, dynamicInvokers);
+ }
+
/**
* This is the eval used when 'indirect' eval call is made.
*
@@ -1749,19 +1778,13 @@
}
private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- @Override
- public Void run() {
- for (Field f : scriptEnv.getClass().getFields()) {
- try {
- options.set(f.getName(), f.get(scriptEnv), false);
- } catch (final IllegalArgumentException | IllegalAccessException exp) {
- throw new RuntimeException(exp);
- }
- }
- return null;
+ for (Field f : scriptEnv.getClass().getFields()) {
+ try {
+ options.set(f.getName(), f.get(scriptEnv), false);
+ } catch (final IllegalArgumentException | IllegalAccessException exp) {
+ throw new RuntimeException(exp);
}
- });
+ }
}
private void initTypedArray() {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java Wed Jul 05 19:09:26 2017 +0200
@@ -76,36 +76,21 @@
private Object length;
private Object callee;
- private ArrayData namedArgs;
- // This is lazily initialized - only when delete is invoked at all
+ private final int numMapped;
+ private final int numParams;
+
+ // These are lazily initialized when delete is invoked on a mapped arg or an unmapped argument is set.
+ private ArrayData unmappedArgs;
private BitSet deleted;
NativeArguments(final Object[] arguments, final Object callee, final int numParams, final ScriptObject proto, final PropertyMap map) {
super(proto, map);
setIsArguments();
-
setArray(ArrayData.allocate(arguments));
this.length = arguments.length;
this.callee = callee;
-
- /**
- * Declared number of parameters may be more or less than the actual passed
- * runtime arguments count. We need to truncate or extend with undefined values.
- *
- * Example:
- *
- * // less declared params
- * (function (x) { print(arguments); })(20, 44);
- *
- * // more declared params
- * (function (x, y) { print(arguments); })(3);
- */
- final Object[] newValues = new Object[numParams];
- if (numParams > arguments.length) {
- Arrays.fill(newValues, UNDEFINED);
- }
- System.arraycopy(arguments, 0, newValues, 0, Math.min(newValues.length, arguments.length));
- this.namedArgs = ArrayData.allocate(newValues);
+ this.numMapped = Math.min(numParams, arguments.length);
+ this.numParams = numParams;
}
@Override
@@ -118,7 +103,8 @@
*/
@Override
public Object getArgument(final int key) {
- return namedArgs.has(key) ? namedArgs.getObject(key) : UNDEFINED;
+ assert key >= 0 && key < numParams : "invalid argument index";
+ return isMapped(key) ? getArray().getObject(key) : getUnmappedArg(key);
}
/**
@@ -126,353 +112,36 @@
*/
@Override
public void setArgument(final int key, final Object value) {
- if (namedArgs.has(key)) {
- namedArgs = namedArgs.set(key, value, false);
- }
- }
-
- @Override
- public int getInt(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public int getInt(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public int getInt(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public int getInt(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public long getLong(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public long getLong(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public long getLong(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public long getLong(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public double getDouble(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public double getDouble(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public double getDouble(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public double getDouble(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public Object get(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public Object get(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public Object get(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public Object get(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public void set(final Object key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
+ assert key >= 0 && key < numParams : "invalid argument index";
+ if (isMapped(key)) {
+ setArray(getArray().set(key, value, false));
} else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final Object key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final Object key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final Object key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final double key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
+ setUnmappedArg(key, value);
}
}
@Override
- public void set(final double key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final double key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final double key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public boolean has(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean has(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean has(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean has(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean hasOwnProperty(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
- public boolean hasOwnProperty(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
- public boolean hasOwnProperty(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
- public boolean hasOwnProperty(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
public boolean delete(final int key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final long key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final Object key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
/**
@@ -483,29 +152,27 @@
public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
final int index = ArrayIndex.getArrayIndex(key);
if (index >= 0) {
- final boolean allowed = super.defineOwnProperty(key, propertyDesc, false);
- if (!allowed) {
+ final boolean isMapped = isMapped(index);
+ final Object oldValue = isMapped ? getArray().getObject(index) : null;
+
+ if (!super.defineOwnProperty(key, propertyDesc, false)) {
if (reject) {
throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
}
return false;
}
- if (isMapped(index)) {
+ if (isMapped) {
// When mapped argument is redefined, if new descriptor is accessor property
// or data-non-writable property, we have to "unmap" (unlink).
final PropertyDescriptor desc = toPropertyDescriptor(Global.instance(), propertyDesc);
if (desc.type() == PropertyDescriptor.ACCESSOR) {
- setDeleted(index);
- } else {
- // set "value" from new descriptor to named args
- if (desc.has(PropertyDescriptor.VALUE)) {
- namedArgs = namedArgs.set(index, desc.getValue(), false);
- }
-
- if (desc.has(PropertyDescriptor.WRITABLE) && !desc.isWritable()) {
- setDeleted(index);
- }
+ setDeleted(index, oldValue);
+ } else if (desc.has(PropertyDescriptor.WRITABLE) && !desc.isWritable()) {
+ // delete and set value from new descriptor if it has one, otherwise use old value
+ setDeleted(index, desc.has(PropertyDescriptor.VALUE) ? desc.getValue() : oldValue);
+ } else if (desc.has(PropertyDescriptor.VALUE)) {
+ setArray(getArray().set(index, desc.getValue(), false));
}
}
@@ -519,31 +186,72 @@
// We track deletions using a bit set (delete arguments[index])
private boolean isDeleted(final int index) {
- return (deleted != null) ? deleted.get(index) : false;
+ return deleted != null && deleted.get(index);
+ }
+
+ private void setDeleted(final int index, final Object unmappedValue) {
+ if (deleted == null) {
+ deleted = new BitSet(numMapped);
+ }
+ deleted.set(index, true);
+ setUnmappedArg(index, unmappedValue);
+ }
+
+ private boolean deleteMapped(final int index, final boolean strict) {
+ final Object value = getArray().getObject(index);
+ final boolean success = super.delete(index, strict);
+ if (success) {
+ setDeleted(index, value);
+ }
+ return success;
+ }
+
+ private Object getUnmappedArg(final int key) {
+ assert key >= 0 && key < numParams;
+ return unmappedArgs == null ? UNDEFINED : unmappedArgs.getObject(key);
}
- private void setDeleted(final int index) {
- if (deleted == null) {
- deleted = new BitSet((int)namedArgs.length());
+ private void setUnmappedArg(final int key, final Object value) {
+ assert key >= 0 && key < numParams;
+ if (unmappedArgs == null) {
+ /*
+ * Declared number of parameters may be more or less than the actual passed
+ * runtime arguments count. We need to truncate or extend with undefined values.
+ *
+ * Example:
+ *
+ * // less declared params
+ * (function (x) { print(arguments); })(20, 44);
+ *
+ * // more declared params
+ * (function (x, y) { print(arguments); })(3);
+ */
+ final Object[] newValues = new Object[numParams];
+ System.arraycopy(getArray().asObjectArray(), 0, newValues, 0, numMapped);
+ if (numMapped < numParams) {
+ Arrays.fill(newValues, numMapped, numParams, UNDEFINED);
+ }
+ this.unmappedArgs = ArrayData.allocate(newValues);
}
- deleted.set(index, true);
+ // Set value of argument
+ unmappedArgs = unmappedArgs.set(key, value, false);
}
/**
* Are arguments[index] and corresponding named parameter linked?
*
- * In non-strict mode, arguments[index] and corresponding named param
- * are "linked" or "mapped". Modifications are tacked b/w each other - till
- * (delete arguments[index]) is used. Once deleted, the corresponding arg
- * is no longer 'mapped'. Please note that delete can happen only through
- * the arguments array - named param can not be deleted. (delete is one-way).
+ * In non-strict mode, arguments[index] and corresponding named param are "linked" or "mapped"
+ * if the argument is provided by the caller. Modifications are tacked b/w each other - until
+ * (delete arguments[index]) is used. Once deleted, the corresponding arg is no longer 'mapped'.
+ * Please note that delete can happen only through the arguments array - named param can not
+ * be deleted. (delete is one-way).
*/
private boolean isMapped(final int index) {
- // in named args and not marked as "deleted"
- return namedArgs.has(index) && !isDeleted(index);
+ // in mapped named args and not marked as "deleted"
+ return index >= 0 && index < numMapped && !isDeleted(index);
}
- /**
+ /**
* Factory to create correct Arguments object based on strict mode.
*
* @param arguments the actual arguments array passed
@@ -558,9 +266,8 @@
final ScriptObject proto = global.getObjectPrototype();
if (isStrict) {
return new NativeStrictArguments(arguments, numParams, proto, global.getStrictArgumentsMap());
- } else {
- return new NativeArguments(arguments, callee, numParams, proto, global.getArgumentsMap());
}
+ return new NativeArguments(arguments, callee, numParams, proto, global.getArgumentsMap());
}
/**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Wed Jul 05 19:09:26 2017 +0200
@@ -39,6 +39,7 @@
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.Callable;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
@@ -68,20 +69,88 @@
*/
@ScriptClass("Array")
public final class NativeArray extends ScriptObject {
- private static final InvokeByName JOIN = new InvokeByName("join", ScriptObject.class);
+ private static final Object JOIN = new Object();
+ private static final Object EVERY_CALLBACK_INVOKER = new Object();
+ private static final Object SOME_CALLBACK_INVOKER = new Object();
+ private static final Object FOREACH_CALLBACK_INVOKER = new Object();
+ private static final Object MAP_CALLBACK_INVOKER = new Object();
+ private static final Object FILTER_CALLBACK_INVOKER = new Object();
+ private static final Object REDUCE_CALLBACK_INVOKER = new Object();
+ private static final Object CALL_CMP = new Object();
+ private static final Object TO_LOCALE_STRING = new Object();
+
+ private static InvokeByName getJOIN() {
+ return Global.instance().getInvokeByName(JOIN,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("join", ScriptObject.class);
+ }
+ });
+ }
+
+ private static MethodHandle createIteratorCallbackInvoker(final Object key, final Class<?> rtype) {
+ return Global.instance().getDynamicInvoker(key,
+ new Callable<MethodHandle>() {
+ @Override
+ public MethodHandle call() {
+ return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class,
+ long.class, Object.class);
+ }
+ });
+ }
+
+ private static MethodHandle getEVERY_CALLBACK_INVOKER() {
+ return createIteratorCallbackInvoker(EVERY_CALLBACK_INVOKER, boolean.class);
+ }
+
+ private static MethodHandle getSOME_CALLBACK_INVOKER() {
+ return createIteratorCallbackInvoker(SOME_CALLBACK_INVOKER, boolean.class);
+ }
- private static final MethodHandle EVERY_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
- private static final MethodHandle SOME_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
- private static final MethodHandle FOREACH_CALLBACK_INVOKER = createIteratorCallbackInvoker(void.class);
- private static final MethodHandle MAP_CALLBACK_INVOKER = createIteratorCallbackInvoker(Object.class);
- private static final MethodHandle FILTER_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class);
+ private static MethodHandle getFOREACH_CALLBACK_INVOKER() {
+ return createIteratorCallbackInvoker(FOREACH_CALLBACK_INVOKER, void.class);
+ }
+
+ private static MethodHandle getMAP_CALLBACK_INVOKER() {
+ return createIteratorCallbackInvoker(MAP_CALLBACK_INVOKER, Object.class);
+ }
+
+ private static MethodHandle getFILTER_CALLBACK_INVOKER() {
+ return createIteratorCallbackInvoker(FILTER_CALLBACK_INVOKER, boolean.class);
+ }
- private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
- Object.class, Undefined.class, Object.class, Object.class, long.class, Object.class);
- private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", double.class,
- ScriptFunction.class, Object.class, Object.class, Object.class);
+ private static MethodHandle getREDUCE_CALLBACK_INVOKER() {
+ return Global.instance().getDynamicInvoker(REDUCE_CALLBACK_INVOKER,
+ new Callable<MethodHandle>() {
+ @Override
+ public MethodHandle call() {
+ return Bootstrap.createDynamicInvoker("dyn:call", Object.class, Object.class,
+ Undefined.class, Object.class, Object.class, long.class, Object.class);
+ }
+ });
+ }
- private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class);
+ private static MethodHandle getCALL_CMP() {
+ return Global.instance().getDynamicInvoker(CALL_CMP,
+ new Callable<MethodHandle>() {
+ @Override
+ public MethodHandle call() {
+ return Bootstrap.createDynamicInvoker("dyn:call", double.class,
+ ScriptFunction.class, Object.class, Object.class, Object.class);
+ }
+ });
+ }
+
+ private static InvokeByName getTO_LOCALE_STRING() {
+ return Global.instance().getInvokeByName(TO_LOCALE_STRING,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("toLocaleString", ScriptObject.class, String.class);
+ }
+ });
+ }
// initialized by nasgen
private static PropertyMap $nasgenmap$;
@@ -357,11 +426,12 @@
public static Object toString(final Object self) {
final Object obj = Global.toObject(self);
if (obj instanceof ScriptObject) {
+ final InvokeByName joinInvoker = getJOIN();
final ScriptObject sobj = (ScriptObject)obj;
try {
- final Object join = JOIN.getGetter().invokeExact(sobj);
+ final Object join = joinInvoker.getGetter().invokeExact(sobj);
if (Bootstrap.isCallable(join)) {
- return JOIN.getInvoker().invokeExact(join, sobj);
+ return joinInvoker.getInvoker().invokeExact(join, sobj);
}
} catch (final RuntimeException | Error e) {
throw e;
@@ -393,11 +463,12 @@
try {
if (val instanceof ScriptObject) {
+ final InvokeByName localeInvoker = getTO_LOCALE_STRING();
final ScriptObject sobj = (ScriptObject)val;
- final Object toLocaleString = TO_LOCALE_STRING.getGetter().invokeExact(sobj);
+ final Object toLocaleString = localeInvoker.getGetter().invokeExact(sobj);
if (Bootstrap.isCallable(toLocaleString)) {
- sb.append((String)TO_LOCALE_STRING.getInvoker().invokeExact(toLocaleString, sobj));
+ sb.append((String)localeInvoker.getInvoker().invokeExact(toLocaleString, sobj));
} else {
throw typeError("not.a.function", "toLocaleString");
}
@@ -567,9 +638,9 @@
if (isScriptArray || obj instanceof Iterable || (obj != null && obj.getClass().isArray())) {
final Iterator<Object> iter = arrayLikeIterator(obj, true);
if (iter.hasNext()) {
- for(int i = 0; iter.hasNext(); ++i) {
+ for (int i = 0; iter.hasNext(); ++i) {
final Object value = iter.next();
- if(value == ScriptRuntime.UNDEFINED && isScriptObject && !((ScriptObject)obj).has(i)) {
+ if (value == ScriptRuntime.UNDEFINED && isScriptObject && !((ScriptObject)obj).has(i)) {
// TODO: eventually rewrite arrayLikeIterator to use a three-state enum for handling
// UNDEFINED instead of an "includeUndefined" boolean with states SKIP, INCLUDE,
// RETURN_EMPTY. Until then, this is how we'll make sure that empty elements don't make it
@@ -814,6 +885,7 @@
final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
Collections.sort(list, new Comparator<Object>() {
+ private final MethodHandle call_cmp = getCALL_CMP();
@Override
public int compare(final Object x, final Object y) {
if (x == ScriptRuntime.UNDEFINED && y == ScriptRuntime.UNDEFINED) {
@@ -826,7 +898,7 @@
if (cmp != null) {
try {
- return (int)Math.signum((double)CALL_CMP.invokeExact(cmp, cmpThis, x, y));
+ return (int)Math.signum((double)call_cmp.invokeExact(cmp, cmpThis, x, y));
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
@@ -1103,9 +1175,11 @@
private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, true) {
+ private final MethodHandle everyInvoker = getEVERY_CALLBACK_INVOKER();
+
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
- return (result = (boolean)EVERY_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
+ return (result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self));
}
}.apply();
}
@@ -1121,9 +1195,11 @@
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object some(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) {
+ private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER();
+
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
- return !(result = (boolean)SOME_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self));
+ return !(result = (boolean)someInvoker.invokeExact(callbackfn, thisArg, val, i, self));
}
}.apply();
}
@@ -1139,9 +1215,11 @@
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<Object>(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) {
+ private final MethodHandle forEachInvoker = getFOREACH_CALLBACK_INVOKER();
+
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
- FOREACH_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
+ forEachInvoker.invokeExact(callbackfn, thisArg, val, i, self);
return true;
}
}.apply();
@@ -1158,9 +1236,11 @@
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object map(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) {
+ private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER();
+
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
- final Object r = MAP_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
+ final Object r = mapInvoker.invokeExact(callbackfn, thisArg, val, i, self);
result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r);
return true;
}
@@ -1186,10 +1266,11 @@
public static Object filter(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) {
private long to = 0;
+ private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER();
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
- if ((boolean)FILTER_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)) {
+ if ((boolean)filterInvoker.invokeExact(callbackfn, thisArg, val, i, self)) {
result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val);
}
return true;
@@ -1217,10 +1298,12 @@
//if initial value is ScriptRuntime.UNDEFINED - step forward once.
return new IteratorAction<Object>(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) {
+ private final MethodHandle reduceInvoker = getREDUCE_CALLBACK_INVOKER();
+
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
// TODO: why can't I declare the second arg as Undefined.class?
- result = REDUCE_CALLBACK_INVOKER.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
+ result = reduceInvoker.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
return true;
}
}.apply();
@@ -1273,10 +1356,4 @@
return false;
}
-
- private static MethodHandle createIteratorCallbackInvoker(final Class<?> rtype) {
- return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class,
- long.class, Object.class);
-
- }
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java Wed Jul 05 19:09:26 2017 +0200
@@ -33,6 +33,7 @@
import java.util.Locale;
import java.util.TimeZone;
+import java.util.concurrent.Callable;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
@@ -95,8 +96,17 @@
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
- private static final InvokeByName TO_ISO_STRING = new InvokeByName("toISOString", ScriptObject.class, Object.class,
- Object.class);
+ private static final Object TO_ISO_STRING = new Object();
+
+ private static InvokeByName getTO_ISO_STRING() {
+ return Global.instance().getInvokeByName(TO_ISO_STRING,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("toISOString", ScriptObject.class, Object.class, Object.class);
+ }
+ });
+ }
private double time;
private final TimeZone timezone;
@@ -861,9 +871,10 @@
}
try {
- final Object func = TO_ISO_STRING.getGetter().invokeExact(sobj);
+ final InvokeByName toIsoString = getTO_ISO_STRING();
+ final Object func = toIsoString.getGetter().invokeExact(sobj);
if (Bootstrap.isCallable(func)) {
- return TO_ISO_STRING.getInvoker().invokeExact(func, sobj, key);
+ return toIsoString.getInvoker().invokeExact(func, sobj, key);
}
throw typeError("not.a.function", ScriptRuntime.safeToString(func));
} catch (final RuntimeException | Error e) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Wed Jul 05 19:09:26 2017 +0200
@@ -72,7 +72,7 @@
public static Object getContext(final Object self) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.getContext"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_GET_CONTEXT));
}
return Global.getThisContext();
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,6 +35,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Callable;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -55,9 +56,31 @@
*/
@ScriptClass("JSON")
public final class NativeJSON extends ScriptObject {
- private static final InvokeByName TO_JSON = new InvokeByName("toJSON", ScriptObject.class, Object.class, Object.class);
- private static final MethodHandle REPLACER_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
- ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
+ private static final Object TO_JSON = new Object();
+
+ private static InvokeByName getTO_JSON() {
+ return Global.instance().getInvokeByName(TO_JSON,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("toJSON", ScriptObject.class, Object.class, Object.class);
+ }
+ });
+ }
+
+
+ private static final Object REPLACER_INVOKER = new Object();
+
+ private static MethodHandle getREPLACER_INVOKER() {
+ return Global.instance().getDynamicInvoker(REPLACER_INVOKER,
+ new Callable<MethodHandle>() {
+ @Override
+ public MethodHandle call() {
+ return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+ ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
+ }
+ });
+ }
// initialized by nasgen
@SuppressWarnings("unused")
@@ -187,15 +210,16 @@
try {
if (value instanceof ScriptObject) {
+ final InvokeByName toJSONInvoker = getTO_JSON();
final ScriptObject svalue = (ScriptObject)value;
- final Object toJSON = TO_JSON.getGetter().invokeExact(svalue);
+ final Object toJSON = toJSONInvoker.getGetter().invokeExact(svalue);
if (Bootstrap.isCallable(toJSON)) {
- value = TO_JSON.getInvoker().invokeExact(toJSON, svalue, key);
+ value = toJSONInvoker.getInvoker().invokeExact(toJSON, svalue, key);
}
}
if (state.replacerFunction != null) {
- value = REPLACER_INVOKER.invokeExact(state.replacerFunction, holder, key, value);
+ value = getREPLACER_INVOKER().invokeExact(state.replacerFunction, holder, key, value);
}
} catch(Error|RuntimeException t) {
throw t;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Wed Jul 05 19:09:26 2017 +0200
@@ -36,6 +36,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.Callable;
import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.linker.GuardedInvocation;
@@ -70,7 +71,18 @@
*/
@ScriptClass("Object")
public final class NativeObject {
- private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
+ private static final Object TO_STRING = new Object();
+
+ private static InvokeByName getTO_STRING() {
+ return Global.instance().getInvokeByName(TO_STRING,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("toString", ScriptObject.class);
+ }
+ });
+ }
+
private static final MethodType MIRROR_GETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class);
private static final MethodType MIRROR_SETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class, Object.class);
@@ -101,6 +113,13 @@
} else if (obj instanceof ScriptObjectMirror) {
return ((ScriptObjectMirror)obj).getProto();
} else {
+ final JSType type = JSType.of(obj);
+ if (type == JSType.OBJECT) {
+ // host (Java) objects have null __proto__
+ return null;
+ }
+
+ // must be some JS primitive
throw notAnObject(obj);
}
}
@@ -402,12 +421,13 @@
public static Object toLocaleString(final Object self) {
final Object obj = JSType.toScriptObject(self);
if (obj instanceof ScriptObject) {
+ final InvokeByName toStringInvoker = getTO_STRING();
final ScriptObject sobj = (ScriptObject)self;
try {
- final Object toString = TO_STRING.getGetter().invokeExact(sobj);
+ final Object toString = toStringInvoker.getGetter().invokeExact(sobj);
if (Bootstrap.isCallable(toString)) {
- return TO_STRING.getInvoker().invokeExact(toString, sobj);
+ return toStringInvoker.getInvoker().invokeExact(toString, sobj);
}
} catch (final RuntimeException | Error e) {
throw e;
--- a/nashorn/src/jdk/nashorn/internal/parser/DateParser.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/parser/DateParser.java Wed Jul 05 19:09:26 2017 +0200
@@ -141,7 +141,7 @@
* Try parsing the date string according to the rules laid out in ES5 15.9.1.15.
* The date string must conform to the following format:
*
- * <pre> [('-'|'+')yy]yyyy[-MM[-dd]][hh:mm[:ss[.sss]][Z|(+|-)hh:mm]] </pre>
+ * <pre> [('-'|'+')yy]yyyy[-MM[-dd]][Thh:mm[:ss[.sss]][Z|(+|-)hh:mm]] </pre>
*
* <p>If the string does not contain a time zone offset, the <tt>TIMEZONE</tt> field
* is set to <tt>0</tt> (GMT).</p>
@@ -249,7 +249,7 @@
switch (token) {
case NUMBER:
- if (skip(':')) {
+ if (skipDelimiter(':')) {
// A number followed by ':' is parsed as time
if (!setTimeField(numValue)) {
return false;
@@ -260,14 +260,14 @@
if (token != Token.NUMBER || !setTimeField(numValue)) {
return false;
}
- } while (skip(isSet(SECOND) ? '.' : ':'));
+ } while (skipDelimiter(isSet(SECOND) ? '.' : ':'));
} else {
// Parse as date token
if (!setDateField(numValue)) {
return false;
}
- skip('-');
+ skipDelimiter('-');
}
break;
@@ -297,7 +297,7 @@
break;
}
if (nameValue.type != Name.TIMEZONE_ID) {
- skip('-');
+ skipDelimiter('-');
}
break;
@@ -359,7 +359,18 @@
return pos < length ? string.charAt(pos) : -1;
}
- private boolean skip(final char c) {
+ // Skip delimiter if followed by a number. Used for ISO 8601 formatted dates
+ private boolean skipNumberDelimiter(final char c) {
+ if (pos < length - 1 && string.charAt(pos) == c
+ && Character.getType(string.charAt(pos + 1)) == DECIMAL_DIGIT_NUMBER) {
+ token = null;
+ pos++;
+ return true;
+ }
+ return false;
+ }
+
+ private boolean skipDelimiter(final char c) {
if (pos < length && string.charAt(pos) == c) {
token = null;
pos++;
@@ -452,14 +463,14 @@
switch (currentField) {
case YEAR:
case MONTH:
- return skip('-') || peek() == 'T' || peek() == -1;
+ return skipNumberDelimiter('-') || peek() == 'T' || peek() == -1;
case DAY:
return peek() == 'T' || peek() == -1;
case HOUR:
case MINUTE:
- return skip(':') || endOfTime();
+ return skipNumberDelimiter(':') || endOfTime();
case SECOND:
- return skip('.') || endOfTime();
+ return skipNumberDelimiter('.') || endOfTime();
default:
return true;
}
@@ -515,7 +526,7 @@
private int readTimeZoneOffset() {
final int sign = string.charAt(pos - 1) == '+' ? 1 : -1;
int offset = readNumber(2);
- skip(':');
+ skipDelimiter(':');
offset = offset * 60 + readNumber(2);
return sign * offset;
}
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java Wed Jul 05 19:09:26 2017 +0200
@@ -160,10 +160,10 @@
if (this.scripting) {
this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
@Override
- public void lineInfo(final int line, final int linePosition) {
+ public void lineInfo(final int receiverLine, final int receiverLinePosition) {
// update the parser maintained line information
- Parser.this.line = line;
- Parser.this.linePosition = linePosition;
+ Parser.this.line = receiverLine;
+ Parser.this.linePosition = receiverLinePosition;
}
};
} else {
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Wed Jul 05 19:09:26 2017 +0200
@@ -48,6 +48,7 @@
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.Map;
+
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
@@ -64,6 +65,31 @@
* This class manages the global state of execution. Context is immutable.
*/
public final class Context {
+ // nashorn specific security runtime access permission names
+ /**
+ * Permission needed to pass arbitrary nashorn command line options when creating Context.
+ */
+ public static final String NASHORN_SET_CONFIG = "nashorn.setConfig";
+
+ /**
+ * Permission needed to create Nashorn Context instance.
+ */
+ public static final String NASHORN_CREATE_CONTEXT = "nashorn.createContext";
+
+ /**
+ * Permission needed to create Nashorn Global instance.
+ */
+ public static final String NASHORN_CREATE_GLOBAL = "nashorn.createGlobal";
+
+ /**
+ * Permission to get current Nashorn Context from thread local storage.
+ */
+ public static final String NASHORN_GET_CONTEXT = "nashorn.getContext";
+
+ /**
+ * Permission to use Java reflection/jsr292 from script code.
+ */
+ public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection";
/**
* ContextCodeInstaller that has the privilege of installing classes in the Context.
@@ -139,7 +165,7 @@
public static Context getContext() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.getContext"));
+ sm.checkPermission(new RuntimePermission(NASHORN_GET_CONTEXT));
}
return getContextTrusted();
}
@@ -204,7 +230,20 @@
private static final ClassLoader myLoader = Context.class.getClassLoader();
private static final StructureLoader sharedLoader;
- private static final AccessControlContext NO_PERMISSIONS_CONTEXT;
+
+ private static AccessControlContext createNoPermAccCtxt() {
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
+ }
+
+ private static AccessControlContext createPermAccCtxt(final String permName) {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission(permName));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext NO_PERMISSIONS_ACC_CTXT = createNoPermAccCtxt();
+ private static final AccessControlContext CREATE_LOADER_ACC_CTXT = createPermAccCtxt("createClassLoader");
+ private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(NASHORN_CREATE_GLOBAL);
static {
sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
@@ -212,8 +251,7 @@
public StructureLoader run() {
return new StructureLoader(myLoader, null);
}
- });
- NO_PERMISSIONS_CONTEXT = new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
+ }, CREATE_LOADER_ACC_CTXT);
}
/**
@@ -254,7 +292,7 @@
public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.createContext"));
+ sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT));
}
this.env = new ScriptEnvironment(options, out, err);
@@ -516,7 +554,7 @@
@Override
public ScriptObject run() {
try {
- return createGlobal();
+ return newGlobal();
} catch (final RuntimeException e) {
if (Context.DEBUG) {
e.printStackTrace();
@@ -524,7 +562,9 @@
throw e;
}
}
- });
+ }, CREATE_GLOBAL_ACC_CTXT);
+ // initialize newly created Global instance
+ initGlobal(newGlobal);
setGlobalTrusted(newGlobal);
final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal);
@@ -577,7 +617,7 @@
sm.checkPackageAccess(fullName.substring(0, index));
return null;
}
- }, NO_PERMISSIONS_CONTEXT);
+ }, NO_PERMISSIONS_ACC_CTXT);
}
}
}
@@ -849,6 +889,7 @@
return script;
}
+ @SuppressWarnings("static-method")
private ScriptLoader createNewLoader() {
return AccessController.doPrivileged(
new PrivilegedAction<ScriptLoader>() {
@@ -856,7 +897,7 @@
public ScriptLoader run() {
return new ScriptLoader(sharedLoader, Context.this);
}
- });
+ }, CREATE_LOADER_ACC_CTXT);
}
private long getUniqueScriptId() {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,8 +25,6 @@
package jdk.nashorn.internal.runtime;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -40,16 +38,9 @@
public final class ECMAErrors {
private static final String MESSAGES_RESOURCE = "jdk.nashorn.internal.runtime.resources.Messages";
- // Without do privileged, under security manager messages can not be loaded.
private static final ResourceBundle MESSAGES_BUNDLE;
static {
- MESSAGES_BUNDLE = AccessController.doPrivileged(
- new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
- }
- });
+ MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
}
/** We assume that compiler generates script classes into the known package. */
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,8 +26,10 @@
package jdk.nashorn.internal.runtime;
import java.lang.invoke.MethodHandle;
+import java.util.concurrent.Callable;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.runtime.linker.InvokeByName;
/**
* Runtime interface to the global scope objects.
@@ -210,4 +212,20 @@
* @param clazz compiled Class object for the source
*/
public void cacheClass(Source source, Class<?> clazz);
+
+ /**
+ * Get cached InvokeByName object for the given key
+ * @param key key to be associated with InvokeByName object
+ * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
+ * @return InvokeByName object associated with the key.
+ */
+ public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator);
+
+ /**
+ * Get cached dynamic method handle for the given key
+ * @param key key to be associated with dynamic method handle
+ * @param creator if method handle is absent 'creator' is called to make one (lazy init)
+ * @return dynamic method handle associated with the key.
+ */
+ public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java Wed Jul 05 19:09:26 2017 +0200
@@ -27,6 +27,7 @@
import java.lang.invoke.MethodHandle;
import java.util.Iterator;
+import java.util.concurrent.Callable;
import jdk.nashorn.internal.ir.LiteralNode;
import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.ObjectNode;
@@ -42,8 +43,19 @@
*/
public final class JSONFunctions {
private JSONFunctions() {}
- private static final MethodHandle REVIVER_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
- ScriptFunction.class, ScriptObject.class, String.class, Object.class);
+
+ private static final Object REVIVER_INVOKER = new Object();
+
+ private static MethodHandle getREVIVER_INVOKER() {
+ return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(REVIVER_INVOKER,
+ new Callable<MethodHandle>() {
+ @Override
+ public MethodHandle call() {
+ return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+ ScriptFunction.class, ScriptObject.class, String.class, Object.class);
+ }
+ });
+ }
/**
* Returns JSON-compatible quoted version of the given string.
@@ -117,7 +129,7 @@
try {
// Object.class, ScriptFunction.class, ScriptObject.class, String.class, Object.class);
- return REVIVER_INVOKER.invokeExact(reviver, holder, JSType.toString(name), val);
+ return getREVIVER_INVOKER().invokeExact(reviver, holder, JSType.toString(name), val);
} catch(Error|RuntimeException t) {
throw t;
} catch(final Throwable t) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Wed Jul 05 19:09:26 2017 +0200
@@ -28,6 +28,7 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import java.lang.invoke.MethodHandles;
import java.util.Locale;
import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.beans.StaticClass;
@@ -63,47 +64,49 @@
/** Max value for an uint32 in JavaScript */
public static final long MAX_UINT = 0xFFFF_FFFFL;
+ private static final MethodHandles.Lookup myLookup = MethodHandles.lookup();
+
/** JavaScript compliant conversion function from Object to boolean */
- public static final Call TO_BOOLEAN = staticCall(JSType.class, "toBoolean", boolean.class, Object.class);
+ public static final Call TO_BOOLEAN = staticCall(myLookup, JSType.class, "toBoolean", boolean.class, Object.class);
/** JavaScript compliant conversion function from number to boolean */
- public static final Call TO_BOOLEAN_D = staticCall(JSType.class, "toBoolean", boolean.class, double.class);
+ public static final Call TO_BOOLEAN_D = staticCall(myLookup, JSType.class, "toBoolean", boolean.class, double.class);
/** JavaScript compliant conversion function from Object to integer */
- public static final Call TO_INTEGER = staticCall(JSType.class, "toInteger", int.class, Object.class);
+ public static final Call TO_INTEGER = staticCall(myLookup, JSType.class, "toInteger", int.class, Object.class);
/** JavaScript compliant conversion function from Object to long */
- public static final Call TO_LONG = staticCall(JSType.class, "toLong", long.class, Object.class);
+ public static final Call TO_LONG = staticCall(myLookup, JSType.class, "toLong", long.class, Object.class);
/** JavaScript compliant conversion function from Object to number */
- public static final Call TO_NUMBER = staticCall(JSType.class, "toNumber", double.class, Object.class);
+ public static final Call TO_NUMBER = staticCall(myLookup, JSType.class, "toNumber", double.class, Object.class);
/** JavaScript compliant conversion function from Object to int32 */
- public static final Call TO_INT32 = staticCall(JSType.class, "toInt32", int.class, Object.class);
+ public static final Call TO_INT32 = staticCall(myLookup, JSType.class, "toInt32", int.class, Object.class);
/** JavaScript compliant conversion function from double to int32 */
- public static final Call TO_INT32_D = staticCall(JSType.class, "toInt32", int.class, double.class);
+ public static final Call TO_INT32_D = staticCall(myLookup, JSType.class, "toInt32", int.class, double.class);
/** JavaScript compliant conversion function from Object to uint32 */
- public static final Call TO_UINT32 = staticCall(JSType.class, "toUint32", long.class, Object.class);
+ public static final Call TO_UINT32 = staticCall(myLookup, JSType.class, "toUint32", long.class, Object.class);
/** JavaScript compliant conversion function from number to uint32 */
- public static final Call TO_UINT32_D = staticCall(JSType.class, "toUint32", long.class, double.class);
+ public static final Call TO_UINT32_D = staticCall(myLookup, JSType.class, "toUint32", long.class, double.class);
/** JavaScript compliant conversion function from Object to int64 */
- public static final Call TO_INT64 = staticCall(JSType.class, "toInt64", long.class, Object.class);
+ public static final Call TO_INT64 = staticCall(myLookup, JSType.class, "toInt64", long.class, Object.class);
/** JavaScript compliant conversion function from number to int64 */
- public static final Call TO_INT64_D = staticCall(JSType.class, "toInt64", long.class, double.class);
+ public static final Call TO_INT64_D = staticCall(myLookup, JSType.class, "toInt64", long.class, double.class);
/** JavaScript compliant conversion function from Object to String */
- public static final Call TO_STRING = staticCall(JSType.class, "toString", String.class, Object.class);
+ public static final Call TO_STRING = staticCall(myLookup, JSType.class, "toString", String.class, Object.class);
/** JavaScript compliant conversion function from number to String */
- public static final Call TO_STRING_D = staticCall(JSType.class, "toString", String.class, double.class);
+ public static final Call TO_STRING_D = staticCall(myLookup, JSType.class, "toString", String.class, double.class);
/** JavaScript compliant conversion function from Object to primitive */
- public static final Call TO_PRIMITIVE = staticCall(JSType.class, "toPrimitive", Object.class, Object.class);
+ public static final Call TO_PRIMITIVE = staticCall(myLookup, JSType.class, "toPrimitive", Object.class, Object.class);
private static final double INT32_LIMIT = 4294967296.0;
--- a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java Wed Jul 05 19:09:26 2017 +0200
@@ -31,6 +31,7 @@
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
+import java.util.concurrent.Callable;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName;
@@ -49,16 +50,73 @@
*/
public final class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
// These add to the back and front of the list
- private static final InvokeByName PUSH = new InvokeByName("push", ScriptObject.class, void.class, Object.class);
- private static final InvokeByName UNSHIFT = new InvokeByName("unshift", ScriptObject.class, void.class, Object.class);
+ private static final Object PUSH = new Object();
+ private static InvokeByName getPUSH() {
+ return ((GlobalObject)Context.getGlobal()).getInvokeByName(PUSH,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("push", ScriptObject.class, void.class, Object.class);
+ }
+ });
+ }
+
+ private static final Object UNSHIFT = new Object();
+ private static InvokeByName getUNSHIFT() {
+ return ((GlobalObject)Context.getGlobal()).getInvokeByName(UNSHIFT,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("unshift", ScriptObject.class, void.class, Object.class);
+ }
+ });
+ }
// These remove from the back and front of the list
- private static final InvokeByName POP = new InvokeByName("pop", ScriptObject.class, Object.class);
- private static final InvokeByName SHIFT = new InvokeByName("shift", ScriptObject.class, Object.class);
+ private static final Object POP = new Object();
+ private static InvokeByName getPOP() {
+ return ((GlobalObject)Context.getGlobal()).getInvokeByName(POP,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("pop", ScriptObject.class, Object.class);
+ }
+ });
+ }
+
+ private static final Object SHIFT = new Object();
+ private static InvokeByName getSHIFT() {
+ return ((GlobalObject)Context.getGlobal()).getInvokeByName(SHIFT,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("shift", ScriptObject.class, Object.class);
+ }
+ });
+ }
// These insert and remove in the middle of the list
- private static final InvokeByName SPLICE_ADD = new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class);
- private static final InvokeByName SPLICE_REMOVE = new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class);
+ private static final Object SPLICE_ADD = new Object();
+ private static InvokeByName getSPLICE_ADD() {
+ return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_ADD,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class);
+ }
+ });
+ }
+
+ private static final Object SPLICE_REMOVE = new Object();
+ private static InvokeByName getSPLICE_REMOVE() {
+ return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_REMOVE,
+ new Callable<InvokeByName>() {
+ @Override
+ public InvokeByName call() {
+ return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class);
+ }
+ });
+ }
private final ScriptObject obj;
@@ -109,9 +167,10 @@
@Override
public void addFirst(Object e) {
try {
- final Object fn = UNSHIFT.getGetter().invokeExact(obj);
- checkFunction(fn, UNSHIFT);
- UNSHIFT.getInvoker().invokeExact(fn, obj, e);
+ final InvokeByName unshiftInvoker = getUNSHIFT();
+ final Object fn = unshiftInvoker.getGetter().invokeExact(obj);
+ checkFunction(fn, unshiftInvoker);
+ unshiftInvoker.getInvoker().invokeExact(fn, obj, e);
} catch(RuntimeException | Error ex) {
throw ex;
} catch(Throwable t) {
@@ -122,9 +181,10 @@
@Override
public void addLast(Object e) {
try {
- final Object fn = PUSH.getGetter().invokeExact(obj);
- checkFunction(fn, PUSH);
- PUSH.getInvoker().invokeExact(fn, obj, e);
+ final InvokeByName pushInvoker = getPUSH();
+ final Object fn = pushInvoker.getGetter().invokeExact(obj);
+ checkFunction(fn, pushInvoker);
+ pushInvoker.getInvoker().invokeExact(fn, obj, e);
} catch(RuntimeException | Error ex) {
throw ex;
} catch(Throwable t) {
@@ -142,9 +202,10 @@
} else {
final int size = size();
if(index < size) {
- final Object fn = SPLICE_ADD.getGetter().invokeExact(obj);
- checkFunction(fn, SPLICE_ADD);
- SPLICE_ADD.getInvoker().invokeExact(fn, obj, index, 0, e);
+ final InvokeByName spliceAddInvoker = getSPLICE_ADD();
+ final Object fn = spliceAddInvoker.getGetter().invokeExact(obj);
+ checkFunction(fn, spliceAddInvoker);
+ spliceAddInvoker.getInvoker().invokeExact(fn, obj, index, 0, e);
} else if(index == size) {
addLast(e);
} else {
@@ -234,9 +295,10 @@
private Object invokeShift() {
try {
- final Object fn = SHIFT.getGetter().invokeExact(obj);
- checkFunction(fn, SHIFT);
- return SHIFT.getInvoker().invokeExact(fn, obj);
+ final InvokeByName shiftInvoker = getSHIFT();
+ final Object fn = shiftInvoker.getGetter().invokeExact(obj);
+ checkFunction(fn, shiftInvoker);
+ return shiftInvoker.getInvoker().invokeExact(fn, obj);
} catch(RuntimeException | Error ex) {
throw ex;
} catch(Throwable t) {
@@ -246,9 +308,10 @@
private Object invokePop() {
try {
- final Object fn = POP.getGetter().invokeExact(obj);
- checkFunction(fn, POP);
- return POP.getInvoker().invokeExact(fn, obj);
+ final InvokeByName popInvoker = getPOP();
+ final Object fn = popInvoker.getGetter().invokeExact(obj);
+ checkFunction(fn, popInvoker);
+ return popInvoker.getInvoker().invokeExact(fn, obj);
} catch(RuntimeException | Error ex) {
throw ex;
} catch(Throwable t) {
@@ -263,9 +326,10 @@
private void invokeSpliceRemove(int fromIndex, int count) {
try {
- final Object fn = SPLICE_REMOVE.getGetter().invokeExact(obj);
- checkFunction(fn, SPLICE_REMOVE);
- SPLICE_REMOVE.getInvoker().invokeExact(fn, obj, fromIndex, count);
+ final InvokeByName spliceRemoveInvoker = getSPLICE_REMOVE();
+ final Object fn = spliceRemoveInvoker.getGetter().invokeExact(obj);
+ checkFunction(fn, spliceRemoveInvoker);
+ spliceRemoveInvoker.getInvoker().invokeExact(fn, obj, fromIndex, count);
} catch(RuntimeException | Error ex) {
throw ex;
} catch(Throwable t) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/Logging.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Logging.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,6 +25,11 @@
package jdk.nashorn.internal.runtime;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -35,6 +40,7 @@
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
+import java.util.logging.LoggingPermission;
/**
* Logging system for getting loggers for arbitrary subsystems as
@@ -50,12 +56,20 @@
private static final Logger disabledLogger = Logger.getLogger("disabled");
+ private static AccessControlContext createLoggerControlAccCtxt() {
+ final Permissions perms = new Permissions();
+ perms.add(new LoggingPermission("control", null));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
static {
- try {
- Logging.disabledLogger.setLevel(Level.OFF);
- } catch (final SecurityException e) {
- //ignored
- }
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ Logging.disabledLogger.setLevel(Level.OFF);
+ return null;
+ }
+ }, createLoggerControlAccCtxt());
}
/** Maps logger name to loggers. Names are typically per package */
--- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Wed Jul 05 19:09:26 2017 +0200
@@ -47,18 +47,24 @@
* This is a subclass that represents a script function that may be regenerated,
* for example with specialization based on call site types, or lazily generated.
* The common denominator is that it can get new invokers during its lifespan,
- * unlike {@link FinalScriptFunctionData}
+ * unlike {@code FinalScriptFunctionData}
*/
public final class RecompilableScriptFunctionData extends ScriptFunctionData {
/** FunctionNode with the code for this ScriptFunction */
- private FunctionNode functionNode;
+ private volatile FunctionNode functionNode;
+
+ /** Source from which FunctionNode was parsed. */
+ private final Source source;
+
+ /** Token of this function within the source. */
+ private final long token;
/** Allocator map from makeMap() */
private final PropertyMap allocatorMap;
/** Code installer used for all further recompilation/specialization of this ScriptFunction */
- private final CodeInstaller<ScriptEnvironment> installer;
+ private volatile CodeInstaller<ScriptEnvironment> installer;
/** Name of class where allocator function resides */
private final String allocatorClassName;
@@ -103,6 +109,8 @@
true);
this.functionNode = functionNode;
+ this.source = functionNode.getSource();
+ this.token = tokenFor(functionNode);
this.installer = installer;
this.allocatorClassName = allocatorClassName;
this.allocatorMap = allocatorMap;
@@ -110,9 +118,6 @@
@Override
String toSource() {
- final Source source = functionNode.getSource();
- final long token = tokenFor(functionNode);
-
if (source != null && token != 0) {
return source.getString(Token.descPosition(token), Token.descLength(token));
}
@@ -123,8 +128,6 @@
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
- final Source source = functionNode.getSource();
- final long token = tokenFor(functionNode);
if (source != null) {
sb.append(source.getName())
@@ -190,6 +193,12 @@
// code exists - look it up and add it into the automatically sorted invoker list
addCode(functionNode);
+
+ if (! functionNode.canSpecialize()) {
+ // allow GC to claim IR stuff that is not needed anymore
+ functionNode = null;
+ installer = null;
+ }
}
private MethodHandle addCode(final FunctionNode fn) {
@@ -325,7 +334,7 @@
* footprint too large to store a parse snapshot, or if it is meaningless
* to do so, such as e.g. for runScript
*/
- if (!functionNode.canSpecialize()) {
+ if (functionNode == null || !functionNode.canSpecialize()) {
return mh;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Wed Jul 05 19:09:26 2017 +0200
@@ -496,32 +496,24 @@
MethodHandle boundHandle;
MethodHandle guard = null;
+ final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
+
if (data.needsCallee()) {
final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
- if (NashornCallSiteDescriptor.isScope(desc)) {
+ if (scopeCall) {
// Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
// (callee, this, args...) => (callee, args...)
boundHandle = MH.insertArguments(callHandle, 1, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
// (callee, args...) => (callee, [this], args...)
boundHandle = MH.dropArguments(boundHandle, 1, Object.class);
+
} else {
// It's already (callee, this, args...), just what we need
boundHandle = callHandle;
-
- // For non-strict functions, check whether this-object is primitive type.
- // If so add a to-object-wrapper argument filter.
- // Else install a guard that will trigger a relink when the argument becomes primitive.
- if (needsWrappedThis()) {
- if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) {
- boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER);
- } else {
- guard = getNonStrictFunctionGuard(this);
- }
- }
}
} else {
final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1), request.getArguments());
- if (NashornCallSiteDescriptor.isScope(desc)) {
+ if (scopeCall) {
// Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
// (this, args...) => (args...)
boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
@@ -533,6 +525,17 @@
}
}
+ // For non-strict functions, check whether this-object is primitive type.
+ // If so add a to-object-wrapper argument filter.
+ // Else install a guard that will trigger a relink when the argument becomes primitive.
+ if (!scopeCall && needsWrappedThis()) {
+ if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) {
+ boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER);
+ } else {
+ guard = getNonStrictFunctionGuard(this);
+ }
+ }
+
boundHandle = pairArguments(boundHandle, type);
return new GuardedInvocation(boundHandle, guard == null ? getFunctionGuard(this) : guard);
@@ -550,19 +553,18 @@
private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) {
if (bindName == null) {
return methodHandle;
- } else {
- // if it is vararg method, we need to extend argument array with
- // a new zeroth element that is set to bindName value.
- final MethodType methodType = methodHandle.type();
- final int parameterCount = methodType.parameterCount();
- final boolean isVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
+ }
- if (isVarArg) {
- return MH.filterArguments(methodHandle, 1, MH.insertArguments(ADD_ZEROTH_ELEMENT, 1, bindName));
- } else {
- return MH.insertArguments(methodHandle, 1, bindName);
- }
+ // if it is vararg method, we need to extend argument array with
+ // a new zeroth element that is set to bindName value.
+ final MethodType methodType = methodHandle.type();
+ final int parameterCount = methodType.parameterCount();
+ final boolean isVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
+
+ if (isVarArg) {
+ return MH.filterArguments(methodHandle, 1, MH.insertArguments(ADD_ZEROTH_ELEMENT, 1, bindName));
}
+ return MH.insertArguments(methodHandle, 1, bindName);
}
/**
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Wed Jul 05 19:09:26 2017 +0200
@@ -250,9 +250,18 @@
final int length = args == null ? 0 : args.length;
CompiledFunctions boundList = new CompiledFunctions();
- for (final CompiledFunction inv : code) {
+ if (code.size() == 1) {
+ // only one variant - bind that
+ boundList.add(bind(code.first(), fn, self, allArgs));
+ } else {
+ // There are specialized versions. Get the most generic one.
+ // This is to avoid ambiguous overloaded versions of bound and
+ // specialized variants and choosing wrong overload.
+ final MethodHandle genInvoker = getGenericInvoker();
+ final CompiledFunction inv = new CompiledFunction(genInvoker.type(), genInvoker, getGenericConstructor());
boundList.add(bind(inv, fn, self, allArgs));
}
+
ScriptFunctionData boundData = new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, isStrict(), isBuiltin(), isConstructor());
return boundData;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Jul 05 19:09:26 2017 +0200
@@ -138,10 +138,10 @@
private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
/** Method handle for getting a function argument at a given index. Used from MapCreator */
- public static final Call GET_ARGUMENT = virtualCall(ScriptObject.class, "getArgument", Object.class, int.class);
+ public static final Call GET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
/** Method handle for setting a function argument at a given index. Used from MapCreator */
- public static final Call SET_ARGUMENT = virtualCall(ScriptObject.class, "setArgument", void.class, int.class, Object.class);
+ public static final Call SET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArgument", void.class, int.class, Object.class);
/** Method handle for getting the proto of a ScriptObject */
public static final Call GET_PROTO = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);
@@ -150,7 +150,7 @@
public static final Call SET_PROTO = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class);
/** Method handle for setting the user accessors of a ScriptObject */
- public static final Call SET_USER_ACCESSORS = virtualCall(ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
+ public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
/**
* Constructor
@@ -2012,9 +2012,10 @@
final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
if (find != null) {
- final Object value = getObjectValue(find);
- ScriptFunction func = null;
- MethodHandle methodHandle = null;
+ final Object value = getObjectValue(find);
+ ScriptFunction func = null;
+ MethodHandle methodHandle = null;
+
if (value instanceof ScriptFunction) {
func = (ScriptFunction)value;
methodHandle = getCallMethodHandle(func, desc.getMethodType(), name);
@@ -3219,6 +3220,11 @@
return property;
}
+ /**
+ * Write a value to a spill slot
+ * @param slot the slot index
+ * @param value the value
+ */
protected final void setSpill(final int slot, final Object value) {
if (spill == null) {
// create new spill.
@@ -3233,6 +3239,11 @@
spill[slot] = value;
}
+ /**
+ * Get a value from a spill slot
+ * @param slot the slot index
+ * @return the value in the spill slot with the given index
+ */
protected Object getSpill(final int slot) {
return spill != null && slot < spill.length ? spill[slot] : null;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Wed Jul 05 19:09:26 2017 +0200
@@ -33,6 +33,7 @@
import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.Iterator;
@@ -100,7 +101,7 @@
* call sites that are known to be megamorphic. Using an invoke dynamic here would
* lead to the JVM deoptimizing itself to death
*/
- public static final Call APPLY = staticCall(ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
+ public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
/**
* Converts a switch tag value to a simple integer. deflt value if it can't.
--- a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java Wed Jul 05 19:09:26 2017 +0200
@@ -27,6 +27,7 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
+import java.util.concurrent.Callable;
import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.lookup.Lookup;
@@ -68,12 +69,32 @@
"userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
/** Dynamic invoker for getter */
- private static final MethodHandle INVOKE_UA_GETTER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
- Object.class, Object.class);
+ private static final Object INVOKE_UA_GETTER = new Object();
+
+ private static MethodHandle getINVOKE_UA_GETTER() {
+
+ return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_GETTER,
+ new Callable<MethodHandle>() {
+ @Override
+ public MethodHandle call() {
+ return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+ Object.class, Object.class);
+ }
+ });
+ }
/** Dynamic invoker for setter */
- private static final MethodHandle INVOKE_UA_SETTER = Bootstrap.createDynamicInvoker("dyn:call", void.class,
- Object.class, Object.class, Object.class);
+ private static Object INVOKE_UA_SETTER = new Object();
+ private static MethodHandle getINVOKE_UA_SETTER() {
+ return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_SETTER,
+ new Callable<MethodHandle>() {
+ @Override
+ public MethodHandle call() {
+ return Bootstrap.createDynamicInvoker("dyn:call", void.class,
+ Object.class, Object.class, Object.class);
+ }
+ });
+ }
/**
* Constructor
@@ -191,7 +212,7 @@
if (func instanceof ScriptFunction) {
try {
- return INVOKE_UA_GETTER.invokeExact(func, self);
+ return getINVOKE_UA_GETTER().invokeExact(func, self);
} catch(final Error|RuntimeException t) {
throw t;
} catch(final Throwable t) {
@@ -208,7 +229,7 @@
if (func instanceof ScriptFunction) {
try {
- INVOKE_UA_SETTER.invokeExact(func, self, value);
+ getINVOKE_UA_SETTER().invokeExact(func, self, value);
} catch(final Error|RuntimeException t) {
throw t;
} catch(final Throwable t) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
-
-import jdk.nashorn.internal.runtime.ScriptObject;
-
-/**
- * Iterator over a NativeArray
- */
-class ArrayIterator extends ArrayLikeIterator<Object> {
-
- /** Array {@link ScriptObject} to iterate over */
- protected final ScriptObject array;
-
- /** length of array */
- protected final long length;
-
- /**
- * Constructor
- * @param array array to iterate over
- * @param includeUndefined should undefined elements be included in iteration
- */
- protected ArrayIterator(final ScriptObject array, final boolean includeUndefined) {
- super(includeUndefined);
- this.array = array;
- this.length = array.getArray().length();
- }
-
- /**
- * Is the current index still inside the array
- * @return true if inside the array
- */
- protected boolean indexInArray() {
- return index < length;
- }
-
- @Override
- public Object next() {
- return array.get(bumpIndex());
- }
-
- @Override
- public long getLength() {
- return length;
- }
-
- @Override
- public boolean hasNext() {
- if (!includeUndefined) {
- while (indexInArray()) {
- if (array.has(index)) {
- break;
- }
- bumpIndex();
- }
- }
-
- return indexInArray();
- }
-
- @Override
- public void remove() {
- array.delete(index, false);
- }
-}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.runtime.arrays;
import java.util.Iterator;
+import java.util.List;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -49,7 +50,7 @@
*
* @param includeUndefined should undefined elements be included in the iteration?
*/
- protected ArrayLikeIterator(final boolean includeUndefined) {
+ ArrayLikeIterator(final boolean includeUndefined) {
this.includeUndefined = includeUndefined;
this.index = 0;
}
@@ -118,18 +119,26 @@
Object obj = object;
if (ScriptObject.isArray(obj)) {
- return new ArrayIterator((ScriptObject) obj, includeUndefined);
+ return new ScriptArrayIterator((ScriptObject) obj, includeUndefined);
}
obj = JSType.toScriptObject(obj);
if (obj instanceof ScriptObject) {
- return new MapIterator((ScriptObject)obj, includeUndefined);
+ return new ScriptObjectIterator((ScriptObject)obj, includeUndefined);
}
if (obj instanceof ScriptObjectMirror) {
return new ScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined);
}
+ if (obj instanceof List) {
+ return new JavaListIterator((List<?>)obj, includeUndefined);
+ }
+
+ if (obj != null && obj.getClass().isArray()) {
+ return new JavaArrayIterator(obj, includeUndefined);
+ }
+
return new EmptyArrayLikeIterator();
}
@@ -143,19 +152,25 @@
Object obj = object;
if (ScriptObject.isArray(obj)) {
- return new ReverseArrayIterator((ScriptObject) obj, includeUndefined);
+ return new ReverseScriptArrayIterator((ScriptObject) obj, includeUndefined);
}
obj = JSType.toScriptObject(obj);
if (obj instanceof ScriptObject) {
- return new ReverseMapIterator((ScriptObject)obj, includeUndefined);
+ return new ReverseScriptObjectIterator((ScriptObject)obj, includeUndefined);
}
if (obj instanceof ScriptObjectMirror) {
return new ReverseScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined);
}
- assert !obj.getClass().isArray();
+ if (obj instanceof List) {
+ return new ReverseJavaListIterator((List<?>)obj, includeUndefined);
+ }
+
+ if (obj != null && obj.getClass().isArray()) {
+ return new ReverseJavaArrayIterator(obj, includeUndefined);
+ }
return new EmptyArrayLikeIterator();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JavaArrayIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import java.lang.reflect.Array;
+
+/**
+ * Iterator over a Java List.
+ */
+class JavaArrayIterator extends ArrayLikeIterator<Object> {
+
+ /** Array to iterate over */
+ protected final Object array;
+
+ /** length of array */
+ protected final long length;
+
+ /**
+ * Constructor
+ * @param array array to iterate over
+ * @param includeUndefined should undefined elements be included in iteration
+ */
+ protected JavaArrayIterator(final Object array, final boolean includeUndefined) {
+ super(includeUndefined);
+ assert array.getClass().isArray() : "expecting Java array object";
+ this.array = array;
+ this.length = Array.getLength(array);
+ }
+
+ /**
+ * Is the current index still inside the array
+ * @return true if inside the array
+ */
+ protected boolean indexInArray() {
+ return index < length;
+ }
+
+ @Override
+ public Object next() {
+ return Array.get(array, (int)bumpIndex());
+ }
+
+ @Override
+ public long getLength() {
+ return length;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return indexInArray();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("remove");
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JavaListIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import java.util.List;
+
+/**
+ * Iterator over a Java List.
+ */
+class JavaListIterator extends ArrayLikeIterator<Object> {
+
+ /** {@link java.util.List} to iterate over */
+ protected final List<?> list;
+
+ /** length of array */
+ protected final long length;
+
+ /**
+ * Constructor
+ * @param list list to iterate over
+ * @param includeUndefined should undefined elements be included in iteration
+ */
+ protected JavaListIterator(final List<?> list, final boolean includeUndefined) {
+ super(includeUndefined);
+ this.list = list;
+ this.length = list.size();
+ }
+
+ /**
+ * Is the current index still inside the array
+ * @return true if inside the array
+ */
+ protected boolean indexInArray() {
+ return index < length;
+ }
+
+ @Override
+ public Object next() {
+ return list.get((int)bumpIndex());
+ }
+
+ @Override
+ public long getLength() {
+ return length;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return indexInArray();
+ }
+
+ @Override
+ public void remove() {
+ list.remove(index);
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Wed Jul 05 19:09:26 2017 +0200
@@ -98,9 +98,8 @@
final int length = (int) length();
if (type == Double.class) {
return new NumberArrayData(LongArrayData.toDoubleArray(array, length), length);
- } else {
- return new ObjectArrayData(LongArrayData.toObjectArray(array, length), length);
}
+ return new ObjectArrayData(LongArrayData.toObjectArray(array, length), length);
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
-
-import java.util.NoSuchElementException;
-import jdk.nashorn.internal.runtime.JSType;
-import jdk.nashorn.internal.runtime.ScriptObject;
-
-/**
- * Iterator over a map
- */
-class MapIterator extends ArrayLikeIterator<Object> {
-
- protected final ScriptObject obj;
- private final long length;
-
- MapIterator(final ScriptObject obj, final boolean includeUndefined) {
- super(includeUndefined);
- this.obj = obj;
- this.length = JSType.toUint32(obj.getLength());
- this.index = 0;
- }
-
- protected boolean indexInArray() {
- return index < length;
- }
-
- @Override
- public long getLength() {
- return length;
- }
-
- @Override
- public boolean hasNext() {
- if (length == 0L) {
- return false; //return empty string if toUint32(length) == 0
- }
-
- while (indexInArray()) {
- if (obj.has(index) || includeUndefined) {
- break;
- }
- bumpIndex();
- }
-
- return indexInArray();
- }
-
- @Override
- public Object next() {
- if (indexInArray()) {
- return obj.get(bumpIndex());
- }
-
- throw new NoSuchElementException();
- }
-}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
-
-import jdk.nashorn.internal.runtime.ScriptObject;
-
-/**
- * Reverse iterator over a NativeArray
- */
-final class ReverseArrayIterator extends ArrayIterator {
-
- /**
- * Constructor
- * @param array array to iterate over
- * @param includeUndefined should undefined elements be included in iteration
- */
- public ReverseArrayIterator(final ScriptObject array, final boolean includeUndefined) {
- super(array, includeUndefined);
- this.index = array.getArray().length() - 1;
- }
-
- @Override
- public boolean isReverse() {
- return true;
- }
-
- @Override
- protected boolean indexInArray() {
- return index >= 0;
- }
-
- @Override
- protected long bumpIndex() {
- return index--;
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJavaArrayIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import java.lang.reflect.Array;
+
+/**
+ * Reverse iterator over a array
+ */
+final class ReverseJavaArrayIterator extends JavaArrayIterator {
+ /**
+ * Constructor
+ * @param array array to iterate over
+ * @param includeUndefined should undefined elements be included in iteration
+ */
+ public ReverseJavaArrayIterator(final Object array, final boolean includeUndefined) {
+ super(array, includeUndefined);
+ this.index = Array.getLength(array) - 1;
+ }
+
+ @Override
+ public boolean isReverse() {
+ return true;
+ }
+
+ @Override
+ protected boolean indexInArray() {
+ return index >= 0;
+ }
+
+ @Override
+ protected long bumpIndex() {
+ return index--;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJavaListIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import java.util.List;
+
+/**
+ * Reverse iterator over a List
+ */
+final class ReverseJavaListIterator extends JavaListIterator {
+ /**
+ * Constructor
+ * @param list list to iterate over
+ * @param includeUndefined should undefined elements be included in iteration
+ */
+ public ReverseJavaListIterator(final List<?> list, final boolean includeUndefined) {
+ super(list, includeUndefined);
+ this.index = list.size() - 1;
+ }
+
+ @Override
+ public boolean isReverse() {
+ return true;
+ }
+
+ @Override
+ protected boolean indexInArray() {
+ return index >= 0;
+ }
+
+ @Override
+ protected long bumpIndex() {
+ return index--;
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java Fri Aug 23 14:17:49 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
-
-import jdk.nashorn.internal.runtime.JSType;
-import jdk.nashorn.internal.runtime.ScriptObject;
-
-/**
- * Reverse iterator over a map
- */
-final class ReverseMapIterator extends MapIterator {
-
- ReverseMapIterator(final ScriptObject obj, final boolean includeUndefined) {
- super(obj, includeUndefined);
- this.index = JSType.toUint32(obj.getLength()) - 1;
- }
-
- @Override
- public boolean isReverse() {
- return true;
- }
-
- @Override
- protected boolean indexInArray() {
- return index >= 0;
- }
-
- @Override
- protected long bumpIndex() {
- return index--;
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptArrayIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Reverse iterator over a NativeArray
+ */
+final class ReverseScriptArrayIterator extends ScriptArrayIterator {
+
+ /**
+ * Constructor
+ * @param array array to iterate over
+ * @param includeUndefined should undefined elements be included in iteration
+ */
+ public ReverseScriptArrayIterator(final ScriptObject array, final boolean includeUndefined) {
+ super(array, includeUndefined);
+ this.index = array.getArray().length() - 1;
+ }
+
+ @Override
+ public boolean isReverse() {
+ return true;
+ }
+
+ @Override
+ protected boolean indexInArray() {
+ return index >= 0;
+ }
+
+ @Override
+ protected long bumpIndex() {
+ return index--;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Reverse iterator over a map
+ */
+final class ReverseScriptObjectIterator extends ScriptObjectIterator {
+
+ ReverseScriptObjectIterator(final ScriptObject obj, final boolean includeUndefined) {
+ super(obj, includeUndefined);
+ this.index = JSType.toUint32(obj.getLength()) - 1;
+ }
+
+ @Override
+ public boolean isReverse() {
+ return true;
+ }
+
+ @Override
+ protected boolean indexInArray() {
+ return index >= 0;
+ }
+
+ @Override
+ protected long bumpIndex() {
+ return index--;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptArrayIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Iterator over a NativeArray
+ */
+class ScriptArrayIterator extends ArrayLikeIterator<Object> {
+
+ /** Array {@link ScriptObject} to iterate over */
+ protected final ScriptObject array;
+
+ /** length of array */
+ protected final long length;
+
+ /**
+ * Constructor
+ * @param array array to iterate over
+ * @param includeUndefined should undefined elements be included in iteration
+ */
+ protected ScriptArrayIterator(final ScriptObject array, final boolean includeUndefined) {
+ super(includeUndefined);
+ this.array = array;
+ this.length = array.getArray().length();
+ }
+
+ /**
+ * Is the current index still inside the array
+ * @return true if inside the array
+ */
+ protected boolean indexInArray() {
+ return index < length;
+ }
+
+ @Override
+ public Object next() {
+ return array.get(bumpIndex());
+ }
+
+ @Override
+ public long getLength() {
+ return length;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (!includeUndefined) {
+ while (indexInArray()) {
+ if (array.has(index)) {
+ break;
+ }
+ bumpIndex();
+ }
+ }
+
+ return indexInArray();
+ }
+
+ @Override
+ public void remove() {
+ array.delete(index, false);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectIterator.java Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.arrays;
+
+import java.util.NoSuchElementException;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptObject;
+
+/**
+ * Iterator over a map
+ */
+class ScriptObjectIterator extends ArrayLikeIterator<Object> {
+
+ protected final ScriptObject obj;
+ private final long length;
+
+ ScriptObjectIterator(final ScriptObject obj, final boolean includeUndefined) {
+ super(includeUndefined);
+ this.obj = obj;
+ this.length = JSType.toUint32(obj.getLength());
+ this.index = 0;
+ }
+
+ protected boolean indexInArray() {
+ return index < length;
+ }
+
+ @Override
+ public long getLength() {
+ return length;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (length == 0L) {
+ return false; //return empty string if toUint32(length) == 0
+ }
+
+ while (indexInArray()) {
+ if (obj.has(index) || includeUndefined) {
+ break;
+ }
+ bumpIndex();
+ }
+
+ return indexInArray();
+ }
+
+ @Override
+ public Object next() {
+ if (indexInArray()) {
+ return obj.get(bumpIndex());
+ }
+
+ throw new NoSuchElementException();
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java Wed Jul 05 19:09:26 2017 +0200
@@ -60,7 +60,7 @@
@Override
public ArrayData copy() {
- return new SparseArrayData(underlying.copy(), length(), new TreeMap<Long, Object>(sparseMap));
+ return new SparseArrayData(underlying.copy(), length(), new TreeMap<>(sparseMap));
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Jul 05 19:09:26 2017 +0200
@@ -68,6 +68,10 @@
if (relinkThreshold > -1) {
factory.setUnstableRelinkThreshold(relinkThreshold);
}
+
+ // Linkers for any additional language runtimes deployed alongside Nashorn will be picked up by the factory.
+ factory.setClassLoader(Bootstrap.class.getClassLoader());
+
dynamicLinker = factory.createLinker();
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethod.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethod.java Wed Jul 05 19:09:26 2017 +0200
@@ -29,7 +29,7 @@
/**
* Represents a Dynalink dynamic method bound to a receiver. Note that objects of this class are just the tuples of
- * a method and a bound this, without any behavior. All the behavior is defined in the {@link BoundDynamicMethodLinker}.
+ * a method and a bound this, without any behavior. All the behavior is defined in the {@code BoundDynamicMethodLinker}.
*/
final class BoundDynamicMethod {
private final Object dynamicMethod;
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Wed Jul 05 19:09:26 2017 +0200
@@ -37,7 +37,7 @@
import jdk.internal.dynalink.support.Guards;
/**
- * Links {@link BoundDynamicMethod} objects. Passes through to Dynalink's BeansLinker for linking a dynamic method
+ * Links {@code BoundDynamicMethod} objects. Passes through to Dynalink's BeansLinker for linking a dynamic method
* (they only respond to "dyn:call"), and modifies the returned invocation to deal with the receiver binding.
*/
final class BoundDynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ClassAndLoader.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ClassAndLoader.java Wed Jul 05 19:09:26 2017 +0200
@@ -27,8 +27,11 @@
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -43,6 +46,16 @@
* used to determine if one loader can see the other loader's classes.
*/
final class ClassAndLoader {
+ static AccessControlContext createPermAccCtxt(final String... permNames) {
+ final Permissions perms = new Permissions();
+ for (final String permName : permNames) {
+ perms.add(new RuntimePermission(permName));
+ }
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext GET_LOADER_ACC_CTXT = createPermAccCtxt("getClassLoader");
+
private final Class<?> representativeClass;
// Don't access this directly; most of the time, use getRetrievedLoader(), or if you know what you're doing,
// getLoader().
@@ -116,7 +129,7 @@
public ClassAndLoader run() {
return getDefiningClassAndLoaderPrivileged(types);
}
- });
+ }, GET_LOADER_ACC_CTXT);
}
static ClassAndLoader getDefiningClassAndLoaderPrivileged(final Class<?>[] types) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Wed Jul 05 19:09:26 2017 +0200
@@ -49,6 +49,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
@@ -868,6 +869,8 @@
}
}
+ private static final AccessControlContext GET_DECLARED_MEMBERS_ACC_CTXT = ClassAndLoader.createPermAccCtxt("accessDeclaredMembers");
+
/**
* Creates a collection of methods that are not final, but we still never allow them to be overridden in adapters,
* as explicitly declaring them automatically is a bad idea. Currently, this means {@code Object.finalize()} and
@@ -886,7 +889,7 @@
throw new AssertionError(e);
}
}
- });
+ }, GET_DECLARED_MEMBERS_ACC_CTXT);
}
private String getCommonSuperClass(final String type1, final String type2) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Wed Jul 05 19:09:26 2017 +0200
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.runtime.linker;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.AllPermission;
import java.security.CodeSigner;
@@ -46,9 +47,10 @@
@SuppressWarnings("javadoc")
final class JavaAdapterClassLoader {
private static final ProtectionDomain GENERATED_PROTECTION_DOMAIN = createGeneratedProtectionDomain();
+ private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
private final String className;
- private final byte[] classBytes;
+ private volatile byte[] classBytes;
JavaAdapterClassLoader(String className, byte[] classBytes) {
this.className = className.replace('/', '.');
@@ -56,6 +58,13 @@
}
/**
+ * clear classBytes after loading class.
+ */
+ void clearClassBytes() {
+ this.classBytes = null;
+ }
+
+ /**
* Loads the generated adapter class into the JVM.
* @param parentLoader the parent class loader for the generated class loader
* @return the generated adapter class
@@ -70,7 +79,7 @@
throw new AssertionError(e); // cannot happen
}
}
- });
+ }, CREATE_LOADER_ACC_CTXT);
}
// Note that the adapter class is created in the protection domain of the class/interface being
@@ -103,10 +112,10 @@
@Override
protected Class<?> findClass(final String name) throws ClassNotFoundException {
if(name.equals(className)) {
+ assert classBytes != null : "what? already cleared .class bytes!!";
return defineClass(name, classBytes, 0, classBytes.length, GENERATED_PROTECTION_DOMAIN);
- } else {
- throw new ClassNotFoundException(name);
}
+ throw new ClassNotFoundException(name);
}
};
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Wed Jul 05 19:09:26 2017 +0200
@@ -31,9 +31,9 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Modifier;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -70,6 +70,11 @@
@SuppressWarnings("javadoc")
public final class JavaAdapterFactory {
+ // context with permissions needs for AdapterInfo creation
+ private static final AccessControlContext CREATE_ADAPTER_INFO_ACC_CTXT =
+ ClassAndLoader.createPermAccCtxt("createClassLoader", "getClassLoader",
+ "accessDeclaredMembers", "accessClassInPackage.jdk.nashorn.internal.runtime");
+
/**
* A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
*/
@@ -124,17 +129,10 @@
*/
public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType) throws Exception {
final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType }, null);
- return AccessController.doPrivileged(new PrivilegedExceptionAction<MethodHandle>() {
- @Override
- public MethodHandle run() throws Exception {
- // NOTE: we use publicLookup(), but none of our adapter constructors are caller sensitive, so this is
- // okay, we won't artificially limit access.
- return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
- NashornCallSiteDescriptor.get(MethodHandles.publicLookup(), "dyn:new",
- MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
- adapterClass, null)).getInvocation(), adapterClass);
- }
- });
+ return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
+ NashornCallSiteDescriptor.get(MethodHandles.publicLookup(), "dyn:new",
+ MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
+ adapterClass, null)).getInvocation(), adapterClass);
}
/**
@@ -171,7 +169,7 @@
return (List)Collections.singletonList(clazz);
}
- /**
+ /**
* For a given class, create its adapter class and associated info.
* @param type the class for which the adapter is created
* @return the adapter info for the class.
@@ -190,12 +188,19 @@
}
superClass = t;
} else {
+ if (interfaces.size() > 65535) {
+ throw new IllegalArgumentException("interface limit exceeded");
+ }
+
interfaces.add(t);
}
+
if(!Modifier.isPublic(mod)) {
return new AdapterInfo(AdaptationResult.Outcome.ERROR_NON_PUBLIC_CLASS, t.getCanonicalName());
}
}
+
+
final Class<?> effectiveSuperClass = superClass == null ? Object.class : superClass;
return AccessController.doPrivileged(new PrivilegedAction<AdapterInfo>() {
@Override
@@ -206,7 +211,7 @@
return new AdapterInfo(e.getAdaptationResult());
}
}
- });
+ }, CREATE_ADAPTER_INFO_ACC_CTXT);
}
private static class AdapterInfo {
@@ -224,7 +229,10 @@
this.commonLoader = findCommonLoader(definingLoader);
final JavaAdapterBytecodeGenerator gen = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, false);
this.autoConvertibleFromFunction = gen.isAutoConvertibleFromFunction();
- this.instanceAdapterClass = gen.createAdapterClassLoader().generateClass(commonLoader);
+ final JavaAdapterClassLoader jacl = gen.createAdapterClassLoader();
+ this.instanceAdapterClass = jacl.generateClass(commonLoader);
+ // loaded Class - no need to keep class bytes around
+ jacl.clearClassBytes();
this.adapterGenerator = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, true).createAdapterClassLoader();
this.adaptationResult = AdaptationResult.SUCCESSFUL_RESULT;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Wed Jul 05 19:09:26 2017 +0200
@@ -88,6 +88,6 @@
}
private static void checkReflectionPermission(final SecurityManager sm) {
- sm.checkPermission(new RuntimePermission("nashorn.JavaReflection"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_JAVA_REFLECTION));
}
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Wed Jul 05 19:09:26 2017 +0200
@@ -26,8 +26,11 @@
package jdk.nashorn.internal.runtime.options;
import java.io.PrintWriter;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
@@ -39,6 +42,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
+import java.util.PropertyPermission;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.TimeZone;
@@ -51,6 +55,15 @@
* Manages global runtime options.
*/
public final class Options {
+ // permission to just read nashorn.* System properties
+ private static AccessControlContext createPropertyReadAccCtxt() {
+ final Permissions perms = new Permissions();
+ perms.add(new PropertyPermission("nashorn.*", "read"));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext READ_PROPERTY_ACC_CTXT = createPropertyReadAccCtxt();
+
/** Resource tag. */
private final String resource;
@@ -144,7 +157,7 @@
return false;
}
}
- });
+ }, READ_PROPERTY_ACC_CTXT);
}
/**
@@ -171,7 +184,7 @@
return defValue;
}
}
- });
+ }, READ_PROPERTY_ACC_CTXT);
}
/**
@@ -198,7 +211,7 @@
return defValue;
}
}
- });
+ }, READ_PROPERTY_ACC_CTXT);
}
/**
@@ -395,13 +408,13 @@
final LinkedList<String> argList = new LinkedList<>();
Collections.addAll(argList, args);
- final String extra = getStringProperty(NASHORN_ARGS_PROPERTY, null);
- if (extra != null) {
- final StringTokenizer st = new StringTokenizer(extra);
- while (st.hasMoreTokens()) {
- argList.add(st.nextToken());
+ final String extra = getStringProperty(NASHORN_ARGS_PROPERTY, null);
+ if (extra != null) {
+ final StringTokenizer st = new StringTokenizer(extra);
+ while (st.hasMoreTokens()) {
+ argList.add(st.nextToken());
+ }
}
- }
while (!argList.isEmpty()) {
final String arg = argList.remove(0);
@@ -418,8 +431,9 @@
continue;
}
- // if it doesn't start with -, it's a file
- if (!arg.startsWith("-")) {
+ // If it doesn't start with -, it's a file. But, if it is just "-",
+ // then it is a file representing standard input.
+ if (!arg.startsWith("-") || arg.length() == 1) {
files.add(arg);
continue;
}
@@ -567,15 +581,7 @@
private static String definePropPrefix;
static {
- // Without do privileged, under security manager messages can not be
- // loaded.
- Options.bundle = AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(Options.MESSAGES_RESOURCE, Locale.getDefault());
- }
- });
-
+ Options.bundle = ResourceBundle.getBundle(Options.MESSAGES_RESOURCE, Locale.getDefault());
Options.validOptions = new TreeSet<>();
Options.usage = new HashMap<>();
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Jul 05 19:09:26 2017 +0200
@@ -100,7 +100,7 @@
type.error.inconsistent.property.descriptor=inconsistent property descriptor
type.error.bad.default.value=bad default value: {0}
type.error.function.apply.expects.array=Function.prototype.apply expects an Array for second argument
-type.error.instanceof.on.non.object=instanceof cannot be used on objects without [[HasInstance]]
+type.error.instanceof.on.non.object=instanceof must be called with a javascript or java object as the right-hand argument
type.error.cannot.convert.to.interface=object {0} cannot be converted to {1} due to "{2}"
type.error.array.reduce.invalid.init=invalid initialValue for Array.prototype.reduce
type.error.array.reduceright.invalid.init=invalid initialValue for Array.prototype.reduceRight
--- a/nashorn/src/jdk/nashorn/tools/Shell.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java Wed Jul 05 19:09:26 2017 +0200
@@ -34,8 +34,6 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -68,18 +66,7 @@
/**
* Shell message bundle.
*/
- private static ResourceBundle bundle;
-
- static {
- // Without do privileged, under security manager messages can not be
- // loaded.
- bundle = AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(MESSAGE_RESOURCE, Locale.getDefault());
- }
- });
- }
+ private static final ResourceBundle bundle = ResourceBundle.getBundle(MESSAGE_RESOURCE, Locale.getDefault());
/**
* Exit code for command line tool - successful
@@ -305,6 +292,14 @@
// For each file on the command line.
for (final String fileName : files) {
+ if ("-".equals(fileName)) {
+ final int res = readEvalPrint(context, global);
+ if (res != SUCCESS) {
+ return res;
+ }
+ continue;
+ }
+
final File file = new File(fileName);
final ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global);
if (script == null || errors.getNumberOfErrors() != 0) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8019985.js Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, 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.
+ */
+
+/**
+ * JDK-8019985: Date.parse("2000-01-01T00:00:00.Z") should return NaN
+ *
+ * @test
+ * @run
+ */
+
+function testFail(str) {
+ if (!isNaN(Date.parse(str))) {
+ throw new Error("Parsed invalid date string: " + str);
+ }
+}
+
+function testOk(str) {
+ if (isNaN(Date.parse(str))) {
+ throw new Error("Failed to parse valid date string: " + str);
+ }
+}
+
+testFail("2000-01-01T00:00:00.Z");
+testFail("2000-01-01T00:00:Z");
+testFail("2000-01-01T00:Z");
+testFail("2000-01-01T00Z");
+testOk("2000-01-01T00:00:00.000Z");
+testOk("2000-01-01T00:00:00.0Z");
+testOk("2000-01-01T00:00:00Z");
+testOk("2000-01-01T00:00Z");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020355.js Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010, 2013, 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.
+ */
+
+/**
+ * JDK-8020355: bind on built-in constructors don't use bound argument values
+ *
+ * @test
+ * @run
+ */
+
+if (Array.bind(null, 2)().length != 2) {
+ fail("Expected Array.bind(null, 2)().length to be 2");
+}
+
+if (RegExp.bind(null, "a")().source.length != 1) {
+ fail("Expected RegExp.bind(null, 'a')().source.length to be 1");
+}
+
+// check user defined functions as well
+
+var res = (function(x, y) { return x*y }).bind(null, 20, 30)();
+if (res != 600) {
+ fail("Expected 600, but got " + res);
+}
+
+var obj = new ((function(x, y) { this.foo = x*y }).bind({}, 20, 30))();
+if (obj.foo != 600) {
+ fail("Expected this.foo = 600, but got " + res);
+}
+
+// try variadic function as well
+
+var res = (function() { return arguments[0]*arguments[1] }).bind(null, 20, 30)();
+if (res != 600) {
+ fail("Expected 600, but got " + res);
+}
+
+var obj = new ((function(x, y) { this.foo = arguments[0]*arguments[1] }).bind({}, 20, 30))();
+if (obj.foo != 600) {
+ fail("Expected this.foo = 600, but got " + res);
+}
+
+
--- a/nashorn/test/script/basic/JDK-8020357.js Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/script/basic/JDK-8020357.js Wed Jul 05 19:09:26 2017 +0200
@@ -33,17 +33,6 @@
var limit = Math.pow(2, UNSIGNED_INT_BITS)/BYTES_PER_INT_32
-try {
- // A value at or under the limit should either succeed if we have
- // enough heap, or throw an OutOfMemoryError if we don't.
- Int32Array(limit - 1)
-} catch(e) {
- if(!(e instanceof java.lang.OutOfMemoryError)) {
- // Only print an unexpected result; OutOfMemoryError is expected
- print(e)
- }
-}
-
// A value over the limit should throw a RangeError.
try {
Int32Array(limit)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022598.js Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 2013, 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.
+ */
+
+/**
+ * JDK-8022598: Object.getPrototypeOf should return null for host objects rather than throwing TypeError
+ *
+ * @test
+ * @run
+ */
+
+// the following should not throw TypeError, just return null instead
+
+var proto = Object.getPrototypeOf(new java.lang.Object());
+if (proto !== null) {
+ fail("Expected 'null' __proto__ for host objects");
+}
+
+// on primitive should result in TypeError
+
+function checkTypeError(obj) {
+ try {
+ Object.getPrototypeOf(obj);
+ fail("Expected TypeError for Object.getPrototypeOf on " + obj);
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("Expected TypeError, but got " + e);
+ }
+ }
+}
+
+checkTypeError(undefined);
+checkTypeError(null);
+checkTypeError(3.1415);
+checkTypeError("hello");
+checkTypeError(false);
+checkTypeError(true);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022731.js Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010, 2013, 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.
+ */
+
+/**
+ * JDK-8022731: NativeArguments has wrong implementation of isMapped()
+ *
+ * @test
+ * @run
+ */
+
+Object.defineProperty(Object.prototype, "0", {value: "proto"});
+
+function test0(a, b) {
+ Object.defineProperty(arguments, "1", {get: function() { return "get" }});
+ return arguments[0];
+}
+
+function test1(a, b) {
+ Object.defineProperty(arguments, "0", {get: function() { return "get" }});
+ return a;
+}
+
+function test2(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value"});
+ delete arguments[0];
+ return a;
+}
+
+function test3(a, b) {
+ arguments[1] = "arg1";
+ return b;
+}
+
+function test4(a, b) {
+ b = "b";
+ return arguments[1];
+}
+
+function test5(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value"});
+ arguments[0] = "new";
+ return a;
+}
+
+function test6(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value"});
+ arguments[0] = "new";
+ delete arguments[0];
+ return a;
+}
+
+function test7(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value", writable: false});
+ arguments[0] = "new";
+ return a;
+}
+
+print(test0());
+print(test0("p1", "p2"));
+print(test1());
+print(test1("p1"));
+print(test2());
+print(test2("p1"));
+print(test3());
+print(test3(1, 2));
+print(test4());
+print(test4("p1", "p2"));
+print(test5());
+print(test5("p1"));
+print(test6());
+print(test6("p1"));
+print(test7());
+print(test7("p1"));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022731.js.EXPECTED Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,16 @@
+proto
+p1
+undefined
+p1
+undefined
+value
+undefined
+arg1
+undefined
+b
+undefined
+new
+undefined
+new
+undefined
+value
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023026.js Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010, 2013, 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.
+ */
+
+/**
+ * JDK-8023026: Array.prototype iterator functions like forEach, reduce should work for Java arrays, lists
+ *
+ * @test
+ * @run
+ */
+
+function checkIterations(obj) {
+ if (typeof obj.getClass == 'function') {
+ print("iterating on an object of " + obj.getClass());
+ } else {
+ print("iterating on " + String(obj));
+ }
+
+ Array.prototype.forEach.call(obj,
+ function(x) { print("forEach " + x); });
+
+ print("left sum " + Array.prototype.reduce.call(obj,
+ function(x, y) { print("reduce", x, y); return x + y; }));
+
+ print("right sum " + Array.prototype.reduceRight.call(obj,
+ function(x, y) { print("reduceRight", x, y); return x + y; }));
+
+ print("squared " + Array.prototype.map.call(obj,
+ function(x) x*x));
+}
+
+var array = new (Java.type("[I"))(4);
+for (var i in array) {
+ array[i] = i;
+}
+
+checkIterations(array);
+
+var list = new java.util.ArrayList();
+list.add(1);
+list.add(3);
+list.add(5);
+list.add(7);
+
+checkIterations(list);
+
+var mirror = loadWithNewGlobal({
+ name: "test",
+ script: "[2, 4, 6, 8]"
+});
+
+checkIterations(mirror);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023026.js.EXPECTED Wed Jul 05 19:09:26 2017 +0200
@@ -0,0 +1,42 @@
+iterating on an object of class [I
+forEach 0
+forEach 1
+forEach 2
+forEach 3
+reduce 0 1
+reduce 1 2
+reduce 3 3
+left sum 6
+reduceRight 3 2
+reduceRight 5 1
+reduceRight 6 0
+right sum 6
+squared 0,1,4,9
+iterating on an object of class java.util.ArrayList
+forEach 1
+forEach 3
+forEach 5
+forEach 7
+reduce 1 3
+reduce 4 5
+reduce 9 7
+left sum 16
+reduceRight 7 5
+reduceRight 12 3
+reduceRight 15 1
+right sum 16
+squared 1,9,25,49
+iterating on [object Array]
+forEach 2
+forEach 4
+forEach 6
+forEach 8
+reduce 2 4
+reduce 6 6
+reduce 12 8
+left sum 20
+reduceRight 8 6
+reduceRight 14 4
+reduceRight 18 2
+right sum 20
+squared 4,16,36,64
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -33,6 +33,7 @@
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -44,7 +45,7 @@
public class BooleanAccessTest {
private static ScriptEngine e = null;
- private static SharedObject o = new SharedObject();
+ private static SharedObject o = null;
public static void main(final String[] args) {
TestNG.main(args);
@@ -54,10 +55,17 @@
public static void setUpClass() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
e = m.getEngineByName("nashorn");
+ o = new SharedObject();
e.put("o", o);
e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
}
+ @AfterClass
+ public static void tearDownClass() {
+ e = null;
+ o = null;
+ }
+
@Test
public void accessFieldBoolean() throws ScriptException {
e.eval("var p_boolean = o.publicBoolean;");
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -36,6 +36,7 @@
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -47,7 +48,7 @@
public class MethodAccessTest {
private static ScriptEngine e = null;
- private static SharedObject o = new SharedObject();
+ private static SharedObject o = null;
public static void main(final String[] args) {
TestNG.main(args);
@@ -57,12 +58,19 @@
public static void setUpClass() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
e = m.getEngineByName("nashorn");
+ o = new SharedObject();
o.setEngine(e);
e.put("o", o);
e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;");
}
+ @AfterClass
+ public static void tearDownClass() {
+ e = null;
+ o = null;
+ }
+
@Test
public void accessMethodthrowsCheckedException() throws ScriptException {
e.eval("try {" +
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -33,6 +33,7 @@
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -44,7 +45,7 @@
public class NumberAccessTest {
private static ScriptEngine e = null;
- private static SharedObject o = new SharedObject();
+ private static SharedObject o = null;
public static void main(final String[] args) {
TestNG.main(args);
@@ -54,10 +55,17 @@
public static void setUpClass() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
e = m.getEngineByName("nashorn");
+ o = new SharedObject();
e.put("o", o);
e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
}
+ @AfterClass
+ public static void tearDownClass() {
+ e = null;
+ o = null;
+ }
+
// --------------------------------long
// tests------------------------------------
@Test
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -32,6 +32,7 @@
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -43,7 +44,7 @@
public class NumberBoxingTest {
private static ScriptEngine e = null;
- private static SharedObject o = new SharedObject();
+ private static SharedObject o = null;
public static void main(final String[] args) {
TestNG.main(args);
@@ -53,10 +54,17 @@
public static void setUpClass() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
e = m.getEngineByName("nashorn");
+ o = new SharedObject();
e.put("o", o);
e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
}
+ @AfterClass
+ public static void tearDownClass() {
+ e = null;
+ o = null;
+ }
+
// --------------------------------long
// tests------------------------------------
@Test
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -32,6 +32,7 @@
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -43,7 +44,7 @@
public class ObjectAccessTest {
private static ScriptEngine e = null;
- private static SharedObject o = new SharedObject();
+ private static SharedObject o = null;
public static void main(final String[] args) {
TestNG.main(args);
@@ -53,11 +54,18 @@
public static void setUpClass() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
e = m.getEngineByName("nashorn");
+ o = new SharedObject();
e.put("o", o);
e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;");
}
+ @AfterClass
+ public static void tearDownClass() {
+ e = null;
+ o = null;
+ }
+
@Test
public void accessFieldObject() throws ScriptException {
e.eval("var p_object = o.publicObject;");
--- a/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -32,6 +32,7 @@
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -43,7 +44,7 @@
public class StringAccessTest {
private static ScriptEngine e = null;
- private static SharedObject o = new SharedObject();
+ private static SharedObject o = null;
public static void main(final String[] args) {
TestNG.main(args);
@@ -53,10 +54,17 @@
public static void setUpClass() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
e = m.getEngineByName("nashorn");
+ o = new SharedObject();
e.put("o", o);
e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;");
}
+ @AfterClass
+ public static void tearDownClass() {
+ e = null;
+ o = null;
+ }
+
@Test
public void accessFieldString() throws ScriptException {
e.eval("var p_string = o.publicString;");
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -1235,7 +1235,8 @@
fail(t.getMessage());
}
- assertEquals(sw.toString(), "hello\n");
+ // dos2unix - fix line endings if running on windows
+ assertEquals(sw.toString().replaceAll("\r", ""), "hello\n");
}
@Test
@@ -1252,6 +1253,7 @@
fail(t.getMessage());
}
- assertEquals(sw.toString(), "34 true hello\n");
+ // dos2unix - fix line endings if running on windows
+ assertEquals(sw.toString().replaceAll("\r", ""), "34 true hello\n");
}
}
--- a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -35,6 +35,8 @@
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.options.Options;
import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
@@ -58,7 +60,8 @@
private Context context;
private ScriptObject global;
- public CompilerTest() {
+ @BeforeClass
+ public void setupTest() {
final Options options = new Options("nashorn");
options.set("anon.functions", true);
options.set("compile.only", true);
@@ -79,6 +82,12 @@
this.global = context.createGlobal();
}
+ @AfterClass
+ public void tearDownTest() {
+ this.context = null;
+ this.global = null;
+ }
+
@Test
public void compileAllTests() {
if (TEST262) {
--- a/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java Fri Aug 23 14:17:49 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java Wed Jul 05 19:09:26 2017 +0200
@@ -28,10 +28,11 @@
import java.io.File;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
-import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.options.Options;
import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
@@ -54,9 +55,9 @@
}
private Context context;
- private ScriptObject global;
- public ParserTest() {
+ @BeforeClass
+ public void setupTest() {
final Options options = new Options("nashorn");
options.set("anon.functions", true);
options.set("parse.only", true);
@@ -64,7 +65,11 @@
ErrorManager errors = new ErrorManager();
this.context = new Context(options, errors, Thread.currentThread().getContextClassLoader());
- this.global = context.createGlobal();
+ }
+
+ @AfterClass
+ public void tearDownTest() {
+ this.context = null;
}
@Test
@@ -125,8 +130,6 @@
log("Begin parsing " + file.getAbsolutePath());
}
- final ScriptObject oldGlobal = Context.getGlobal();
- final boolean globalChanged = (oldGlobal != global);
try {
final char[] buffer = Source.readFully(file);
boolean excluded = false;
@@ -150,9 +153,6 @@
}
};
errors.setLimit(0);
- if (globalChanged) {
- Context.setGlobal(global);
- }
final Source source = new Source(file.getAbsolutePath(), buffer);
new Parser(context.getEnv(), source, errors).parse();
if (errors.getNumberOfErrors() > 0) {
@@ -167,10 +167,6 @@
exp.printStackTrace(System.out);
}
failed++;
- } finally {
- if (globalChanged) {
- Context.setGlobal(oldGlobal);
- }
}
if (VERBOSE) {