Merge
This commit is contained in:
commit
de016af85d
@ -312,3 +312,4 @@ dc6e8336f51bb6b67b7245766179eab5ca7720b4 jdk9-b66
|
||||
f546760134eb861fcfecd4ce611b0040b0d25a6a jdk9-b67
|
||||
70e4272790b6199e9ca89df2758ff9cb58ec4125 jdk9-b68
|
||||
1bcfd6b8726582cff5a42dbfc75903e36f9dd4fe jdk9-b69
|
||||
eed77fcd77711fcdba05f18fc22f37d86efb243c jdk9-b70
|
||||
|
@ -312,3 +312,4 @@ afc1e295c4bf83f9a5dd539c29914edd4a754a3f jdk9-b65
|
||||
4418697e56f1f43597f55c7cb6573549c6117868 jdk9-b67
|
||||
8efad64f40eb8cd4df376c0a5275892eeb396bbd jdk9-b68
|
||||
de8acedcb5b5870f1dc54cba575aaa5d33897ea2 jdk9-b69
|
||||
e7cf01990ed366bd493080663259281e91ce223b jdk9-b70
|
||||
|
@ -472,3 +472,4 @@ e7ae94c4f35e940ea423fc1dd260435df34a77c0 jdk9-b65
|
||||
d47dfabd16d48eb96a451edd1b61194a39ee0eb5 jdk9-b67
|
||||
11af3990d56c97b40318bc1f20608e86f051a3f7 jdk9-b68
|
||||
ff0929a59ced0e144201aa05819ae2e47d6f2c61 jdk9-b69
|
||||
8672e9264db30c21504063932dbc374eabc287a1 jdk9-b70
|
||||
|
@ -121,6 +121,8 @@ public class VM {
|
||||
private Flag[] commandLineFlags;
|
||||
private Map flagsMap;
|
||||
|
||||
private static Type intType;
|
||||
private static Type uintType;
|
||||
private static Type intxType;
|
||||
private static Type uintxType;
|
||||
private static Type sizetType;
|
||||
@ -170,6 +172,28 @@ public class VM {
|
||||
return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned()) != 0;
|
||||
}
|
||||
|
||||
public boolean isInt() {
|
||||
return type.equals("int");
|
||||
}
|
||||
|
||||
public long getInt() {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(isInt(), "not an int flag!");
|
||||
}
|
||||
return addr.getCIntegerAt(0, intType.getSize(), false);
|
||||
}
|
||||
|
||||
public boolean isUInt() {
|
||||
return type.equals("uint");
|
||||
}
|
||||
|
||||
public long getUInt() {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(isUInt(), "not a uint flag!");
|
||||
}
|
||||
return addr.getCIntegerAt(0, uintType.getSize(), false);
|
||||
}
|
||||
|
||||
public boolean isIntx() {
|
||||
return type.equals("intx");
|
||||
}
|
||||
@ -206,6 +230,10 @@ public class VM {
|
||||
public String getValue() {
|
||||
if (isBool()) {
|
||||
return new Boolean(getBool()).toString();
|
||||
} else if (isInt()) {
|
||||
return new Long(getInt()).toString();
|
||||
} else if (isUInt()) {
|
||||
return new Long(getUInt()).toString();
|
||||
} else if (isIntx()) {
|
||||
return new Long(getIntx()).toString();
|
||||
} else if (isUIntx()) {
|
||||
@ -334,6 +362,8 @@ public class VM {
|
||||
heapWordSize = db.lookupIntConstant("HeapWordSize").intValue();
|
||||
oopSize = db.lookupIntConstant("oopSize").intValue();
|
||||
|
||||
intType = db.lookupType("int");
|
||||
uintType = db.lookupType("uint");
|
||||
intxType = db.lookupType("intx");
|
||||
uintxType = db.lookupType("uintx");
|
||||
sizetType = db.lookupType("size_t");
|
||||
|
@ -13276,7 +13276,7 @@ instruct replicate16B_imm(vecX dst, immI con)
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "movi $dst, $con\t# vector(16B)" %}
|
||||
ins_encode %{
|
||||
__ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant);
|
||||
__ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
@ -13298,7 +13298,7 @@ instruct replicate8S_imm(vecX dst, immI con)
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "movi $dst, $con\t# vector(8H)" %}
|
||||
ins_encode %{
|
||||
__ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant);
|
||||
__ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
@ -491,6 +491,11 @@ class Address VALUE_OBJ_CLASS_SPEC {
|
||||
i->rf(_index, 16);
|
||||
i->f(_ext.option(), 15, 13);
|
||||
unsigned size = i->get(31, 30);
|
||||
if (i->get(26, 26) && i->get(23, 23)) {
|
||||
// SIMD Q Type - Size = 128 bits
|
||||
assert(size == 0, "bad size");
|
||||
size = 0b100;
|
||||
}
|
||||
if (size == 0) // It's a byte
|
||||
i->f(_ext.shift() >= 0, 12);
|
||||
else {
|
||||
|
@ -1408,6 +1408,52 @@ void MacroAssembler::movptr(Register r, uintptr_t imm64) {
|
||||
movk(r, imm64 & 0xffff, 32);
|
||||
}
|
||||
|
||||
// Macro to mov replicated immediate to vector register.
|
||||
// Vd will get the following values for different arrangements in T
|
||||
// imm32 == hex 000000gh T8B: Vd = ghghghghghghghgh
|
||||
// imm32 == hex 000000gh T16B: Vd = ghghghghghghghghghghghghghghghgh
|
||||
// imm32 == hex 0000efgh T4H: Vd = efghefghefghefgh
|
||||
// imm32 == hex 0000efgh T8H: Vd = efghefghefghefghefghefghefghefgh
|
||||
// imm32 == hex abcdefgh T2S: Vd = abcdefghabcdefgh
|
||||
// imm32 == hex abcdefgh T4S: Vd = abcdefghabcdefghabcdefghabcdefgh
|
||||
// T1D/T2D: invalid
|
||||
void MacroAssembler::mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32) {
|
||||
assert(T != T1D && T != T2D, "invalid arrangement");
|
||||
if (T == T8B || T == T16B) {
|
||||
assert((imm32 & ~0xff) == 0, "extraneous bits in unsigned imm32 (T8B/T16B)");
|
||||
movi(Vd, T, imm32 & 0xff, 0);
|
||||
return;
|
||||
}
|
||||
u_int32_t nimm32 = ~imm32;
|
||||
if (T == T4H || T == T8H) {
|
||||
assert((imm32 & ~0xffff) == 0, "extraneous bits in unsigned imm32 (T4H/T8H)");
|
||||
imm32 &= 0xffff;
|
||||
nimm32 &= 0xffff;
|
||||
}
|
||||
u_int32_t x = imm32;
|
||||
int movi_cnt = 0;
|
||||
int movn_cnt = 0;
|
||||
while (x) { if (x & 0xff) movi_cnt++; x >>= 8; }
|
||||
x = nimm32;
|
||||
while (x) { if (x & 0xff) movn_cnt++; x >>= 8; }
|
||||
if (movn_cnt < movi_cnt) imm32 = nimm32;
|
||||
unsigned lsl = 0;
|
||||
while (imm32 && (imm32 & 0xff) == 0) { lsl += 8; imm32 >>= 8; }
|
||||
if (movn_cnt < movi_cnt)
|
||||
mvni(Vd, T, imm32 & 0xff, lsl);
|
||||
else
|
||||
movi(Vd, T, imm32 & 0xff, lsl);
|
||||
imm32 >>= 8; lsl += 8;
|
||||
while (imm32) {
|
||||
while ((imm32 & 0xff) == 0) { lsl += 8; imm32 >>= 8; }
|
||||
if (movn_cnt < movi_cnt)
|
||||
bici(Vd, T, imm32 & 0xff, lsl);
|
||||
else
|
||||
orri(Vd, T, imm32 & 0xff, lsl);
|
||||
lsl += 8; imm32 >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::mov_immediate64(Register dst, u_int64_t imm64)
|
||||
{
|
||||
#ifndef PRODUCT
|
||||
|
@ -465,44 +465,7 @@ public:
|
||||
|
||||
void movptr(Register r, uintptr_t imm64);
|
||||
|
||||
// Macro to mov replicated immediate to vector register.
|
||||
// Where imm32 == hex abcdefgh, Vd will get the following values
|
||||
// for different arrangements in T
|
||||
// T8B: Vd = ghghghghghghghgh
|
||||
// T16B: Vd = ghghghghghghghghghghghghghghghgh
|
||||
// T4H: Vd = efghefghefghefgh
|
||||
// T8H: Vd = efghefghefghefghefghefghefghefgh
|
||||
// T2S: Vd = abcdefghabcdefgh
|
||||
// T4S: Vd = abcdefghabcdefghabcdefghabcdefgh
|
||||
// T1D/T2D: invalid
|
||||
void mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32) {
|
||||
assert(T != T1D && T != T2D, "invalid arrangement");
|
||||
u_int32_t nimm32 = ~imm32;
|
||||
if (T == T8B || T == T16B) { imm32 &= 0xff; nimm32 &= 0xff; }
|
||||
if (T == T4H || T == T8H) { imm32 &= 0xffff; nimm32 &= 0xffff; }
|
||||
u_int32_t x = imm32;
|
||||
int movi_cnt = 0;
|
||||
int movn_cnt = 0;
|
||||
while (x) { if (x & 0xff) movi_cnt++; x >>= 8; }
|
||||
x = nimm32;
|
||||
while (x) { if (x & 0xff) movn_cnt++; x >>= 8; }
|
||||
if (movn_cnt < movi_cnt) imm32 = nimm32;
|
||||
unsigned lsl = 0;
|
||||
while (imm32 && (imm32 & 0xff) == 0) { lsl += 8; imm32 >>= 8; }
|
||||
if (movn_cnt < movi_cnt)
|
||||
mvni(Vd, T, imm32 & 0xff, lsl);
|
||||
else
|
||||
movi(Vd, T, imm32 & 0xff, lsl);
|
||||
imm32 >>= 8; lsl += 8;
|
||||
while (imm32) {
|
||||
while ((imm32 & 0xff) == 0) { lsl += 8; imm32 >>= 8; }
|
||||
if (movn_cnt < movi_cnt)
|
||||
bici(Vd, T, imm32 & 0xff, lsl);
|
||||
else
|
||||
orri(Vd, T, imm32 & 0xff, lsl);
|
||||
lsl += 8; imm32 >>= 8;
|
||||
}
|
||||
}
|
||||
void mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32);
|
||||
|
||||
// macro instructions for accessing and updating floating point
|
||||
// status register
|
||||
|
@ -228,6 +228,9 @@ void VM_Version::get_processor_features() {
|
||||
warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
|
||||
}
|
||||
if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSHA, false);
|
||||
}
|
||||
}
|
||||
|
||||
// This machine allows unaligned memory accesses
|
||||
|
@ -71,8 +71,7 @@
|
||||
// Loaded method.
|
||||
ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) :
|
||||
ciMetadata(h_m()),
|
||||
_holder(holder),
|
||||
_has_injected_profile(false)
|
||||
_holder(holder)
|
||||
{
|
||||
assert(h_m() != NULL, "no null method");
|
||||
|
||||
@ -170,8 +169,7 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
|
||||
_liveness( NULL),
|
||||
_can_be_statically_bound(false),
|
||||
_method_blocks( NULL),
|
||||
_method_data( NULL),
|
||||
_has_injected_profile( false)
|
||||
_method_data( NULL)
|
||||
#if defined(COMPILER2) || defined(SHARK)
|
||||
,
|
||||
_flow( NULL),
|
||||
|
@ -81,7 +81,6 @@ class ciMethod : public ciMetadata {
|
||||
bool _is_c1_compilable;
|
||||
bool _is_c2_compilable;
|
||||
bool _can_be_statically_bound;
|
||||
bool _has_injected_profile;
|
||||
|
||||
// Lazy fields, filled in on demand
|
||||
address _code;
|
||||
@ -179,9 +178,9 @@ class ciMethod : public ciMetadata {
|
||||
// Code size for inlining decisions.
|
||||
int code_size_for_inlining();
|
||||
|
||||
bool caller_sensitive() { return get_Method()->caller_sensitive(); }
|
||||
bool force_inline() { return get_Method()->force_inline(); }
|
||||
bool dont_inline() { return get_Method()->dont_inline(); }
|
||||
bool caller_sensitive() const { return get_Method()->caller_sensitive(); }
|
||||
bool force_inline() const { return get_Method()->force_inline(); }
|
||||
bool dont_inline() const { return get_Method()->dont_inline(); }
|
||||
|
||||
int comp_level();
|
||||
int highest_osr_comp_level();
|
||||
@ -289,9 +288,6 @@ class ciMethod : public ciMetadata {
|
||||
int instructions_size();
|
||||
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
|
||||
|
||||
bool has_injected_profile() const { return _has_injected_profile; }
|
||||
void set_injected_profile(bool x) { _has_injected_profile = x; }
|
||||
|
||||
// Stack walking support
|
||||
bool is_ignored_by_security_stack_walk() const;
|
||||
|
||||
|
@ -1742,6 +1742,10 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d
|
||||
if (_location != _in_method) break; // only allow for methods
|
||||
if (!privileged) break; // only allow in privileged code
|
||||
return _method_DontInline;
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_InjectedProfile_signature):
|
||||
if (_location != _in_method) break; // only allow for methods
|
||||
if (!privileged) break; // only allow in privileged code
|
||||
return _method_InjectedProfile;
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature):
|
||||
if (_location != _in_method) break; // only allow for methods
|
||||
if (!privileged) break; // only allow in privileged code
|
||||
@ -1783,6 +1787,8 @@ void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
|
||||
m->set_force_inline(true);
|
||||
if (has_annotation(_method_DontInline))
|
||||
m->set_dont_inline(true);
|
||||
if (has_annotation(_method_InjectedProfile))
|
||||
m->set_has_injected_profile(true);
|
||||
if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none)
|
||||
m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
|
||||
if (has_annotation(_method_LambdaForm_Hidden))
|
||||
|
@ -127,6 +127,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
_method_CallerSensitive,
|
||||
_method_ForceInline,
|
||||
_method_DontInline,
|
||||
_method_InjectedProfile,
|
||||
_method_LambdaForm_Compiled,
|
||||
_method_LambdaForm_Hidden,
|
||||
_sun_misc_Contended,
|
||||
|
@ -278,6 +278,7 @@
|
||||
template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \
|
||||
template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \
|
||||
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
|
||||
template(java_lang_invoke_InjectedProfile_signature, "Ljava/lang/invoke/InjectedProfile;") \
|
||||
template(java_lang_invoke_Stable_signature, "Ljava/lang/invoke/Stable;") \
|
||||
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
|
||||
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
|
||||
|
@ -96,7 +96,7 @@ void PSMarkSweep::invoke(bool maximum_heap_compaction) {
|
||||
heap->collector_policy()->should_clear_all_soft_refs();
|
||||
|
||||
uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
|
||||
UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
|
||||
UIntXFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
|
||||
PSMarkSweep::invoke_no_policy(clear_all_soft_refs || maximum_heap_compaction);
|
||||
}
|
||||
|
||||
|
@ -785,7 +785,7 @@ HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
|
||||
// free memory should be here, especially if they are expensive. If this
|
||||
// attempt fails, an OOM exception will be thrown.
|
||||
{
|
||||
UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
|
||||
UIntXFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
|
||||
|
||||
gch->do_collection(true /* full */,
|
||||
true /* clear_all_soft_refs */,
|
||||
|
@ -93,6 +93,7 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
|
||||
set_force_inline(false);
|
||||
set_hidden(false);
|
||||
set_dont_inline(false);
|
||||
set_has_injected_profile(false);
|
||||
set_method_data(NULL);
|
||||
clear_method_counters();
|
||||
set_vtable_index(Method::garbage_vtable_index);
|
||||
|
@ -76,12 +76,13 @@ class Method : public Metadata {
|
||||
|
||||
// Flags
|
||||
enum Flags {
|
||||
_jfr_towrite = 1 << 0,
|
||||
_caller_sensitive = 1 << 1,
|
||||
_force_inline = 1 << 2,
|
||||
_dont_inline = 1 << 3,
|
||||
_hidden = 1 << 4,
|
||||
_running_emcp = 1 << 5
|
||||
_jfr_towrite = 1 << 0,
|
||||
_caller_sensitive = 1 << 1,
|
||||
_force_inline = 1 << 2,
|
||||
_dont_inline = 1 << 3,
|
||||
_hidden = 1 << 4,
|
||||
_has_injected_profile = 1 << 5,
|
||||
_running_emcp = 1 << 6
|
||||
};
|
||||
u1 _flags;
|
||||
|
||||
@ -814,6 +815,13 @@ class Method : public Metadata {
|
||||
_flags = x ? (_flags | _hidden) : (_flags & ~_hidden);
|
||||
}
|
||||
|
||||
bool has_injected_profile() {
|
||||
return (_flags & _has_injected_profile) != 0;
|
||||
}
|
||||
void set_has_injected_profile(bool x) {
|
||||
_flags = x ? (_flags | _has_injected_profile) : (_flags & ~_has_injected_profile);
|
||||
}
|
||||
|
||||
ConstMethod::MethodType method_type() const {
|
||||
return _constMethod->method_type();
|
||||
}
|
||||
|
@ -438,11 +438,17 @@ bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
|
||||
// replace fallthrough projections of the ArrayCopyNode by the
|
||||
// new memory, control and the input IO.
|
||||
CallProjections callprojs;
|
||||
extract_projections(&callprojs, true);
|
||||
extract_projections(&callprojs, true, false);
|
||||
|
||||
igvn->replace_node(callprojs.fallthrough_ioproj, in(TypeFunc::I_O));
|
||||
igvn->replace_node(callprojs.fallthrough_memproj, mem);
|
||||
igvn->replace_node(callprojs.fallthrough_catchproj, ctl);
|
||||
if (callprojs.fallthrough_ioproj != NULL) {
|
||||
igvn->replace_node(callprojs.fallthrough_ioproj, in(TypeFunc::I_O));
|
||||
}
|
||||
if (callprojs.fallthrough_memproj != NULL) {
|
||||
igvn->replace_node(callprojs.fallthrough_memproj, mem);
|
||||
}
|
||||
if (callprojs.fallthrough_catchproj != NULL) {
|
||||
igvn->replace_node(callprojs.fallthrough_catchproj, ctl);
|
||||
}
|
||||
|
||||
// The ArrayCopyNode is not disconnected. It still has the
|
||||
// projections for the exception case. Replace current
|
||||
|
@ -724,6 +724,26 @@ uint CallNode::match_edge(uint idx) const {
|
||||
//
|
||||
bool CallNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
|
||||
assert((t_oop != NULL), "sanity");
|
||||
if (is_call_to_arraycopystub()) {
|
||||
const TypeTuple* args = _tf->domain();
|
||||
Node* dest = NULL;
|
||||
// Stubs that can be called once an ArrayCopyNode is expanded have
|
||||
// different signatures. Look for the second pointer argument,
|
||||
// that is the destination of the copy.
|
||||
for (uint i = TypeFunc::Parms, j = 0; i < args->cnt(); i++) {
|
||||
if (args->field_at(i)->isa_ptr()) {
|
||||
j++;
|
||||
if (j == 2) {
|
||||
dest = in(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dest->is_top() && may_modify_arraycopy_helper(phase->type(dest)->is_oopptr(), t_oop, phase)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (t_oop->is_known_instance()) {
|
||||
// The instance_id is set only for scalar-replaceable allocations which
|
||||
// are not passed as arguments according to Escape Analysis.
|
||||
@ -810,7 +830,7 @@ Node *CallNode::result_cast() {
|
||||
}
|
||||
|
||||
|
||||
void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj) {
|
||||
void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts) {
|
||||
projs->fallthrough_proj = NULL;
|
||||
projs->fallthrough_catchproj = NULL;
|
||||
projs->fallthrough_ioproj = NULL;
|
||||
@ -873,17 +893,18 @@ void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj
|
||||
}
|
||||
}
|
||||
|
||||
// The resproj may not exist because the result couuld be ignored
|
||||
// The resproj may not exist because the result could be ignored
|
||||
// and the exception object may not exist if an exception handler
|
||||
// swallows the exception but all the other must exist and be found.
|
||||
assert(projs->fallthrough_proj != NULL, "must be found");
|
||||
assert(Compile::current()->inlining_incrementally() || projs->fallthrough_catchproj != NULL, "must be found");
|
||||
assert(Compile::current()->inlining_incrementally() || projs->fallthrough_memproj != NULL, "must be found");
|
||||
assert(Compile::current()->inlining_incrementally() || projs->fallthrough_ioproj != NULL, "must be found");
|
||||
assert(Compile::current()->inlining_incrementally() || projs->catchall_catchproj != NULL, "must be found");
|
||||
do_asserts = do_asserts && !Compile::current()->inlining_incrementally();
|
||||
assert(!do_asserts || projs->fallthrough_catchproj != NULL, "must be found");
|
||||
assert(!do_asserts || projs->fallthrough_memproj != NULL, "must be found");
|
||||
assert(!do_asserts || projs->fallthrough_ioproj != NULL, "must be found");
|
||||
assert(!do_asserts || projs->catchall_catchproj != NULL, "must be found");
|
||||
if (separate_io_proj) {
|
||||
assert(Compile::current()->inlining_incrementally() || projs->catchall_memproj != NULL, "must be found");
|
||||
assert(Compile::current()->inlining_incrementally() || projs->catchall_ioproj != NULL, "must be found");
|
||||
assert(!do_asserts || projs->catchall_memproj != NULL, "must be found");
|
||||
assert(!do_asserts || projs->catchall_ioproj != NULL, "must be found");
|
||||
}
|
||||
}
|
||||
|
||||
@ -909,6 +930,12 @@ Node *CallNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
return SafePointNode::Ideal(phase, can_reshape);
|
||||
}
|
||||
|
||||
bool CallNode::is_call_to_arraycopystub() const {
|
||||
if (_name != NULL && strstr(_name, "arraycopy") != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
uint CallJavaNode::size_of() const { return sizeof(*this); }
|
||||
@ -1007,14 +1034,6 @@ void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_reg
|
||||
|
||||
|
||||
//=============================================================================
|
||||
bool CallLeafNode::is_call_to_arraycopystub() const {
|
||||
if (_name != NULL && strstr(_name, "arraycopy") != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
void CallLeafNode::dump_spec(outputStream *st) const {
|
||||
st->print("# ");
|
||||
@ -1930,26 +1949,3 @@ bool CallNode::may_modify_arraycopy_helper(const TypeOopPtr* dest_t, const TypeO
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallLeafNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
|
||||
if (is_call_to_arraycopystub()) {
|
||||
const TypeTuple* args = _tf->domain();
|
||||
Node* dest = NULL;
|
||||
// Stubs that can be called once an ArrayCopyNode is expanded have
|
||||
// different signatures. Look for the second pointer argument,
|
||||
// that is the destination of the copy.
|
||||
for (uint i = TypeFunc::Parms, j = 0; i < args->cnt(); i++) {
|
||||
if (args->field_at(i)->isa_ptr()) {
|
||||
j++;
|
||||
if (j == 2) {
|
||||
dest = in(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dest->is_top() && may_modify_arraycopy_helper(phase->type(dest)->is_oopptr(), t_oop, phase)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return CallNode::may_modify(t_oop, phase);
|
||||
}
|
||||
|
@ -565,13 +565,15 @@ public:
|
||||
address _entry_point; // Address of method being called
|
||||
float _cnt; // Estimate of number of times called
|
||||
CallGenerator* _generator; // corresponding CallGenerator for some late inline calls
|
||||
const char *_name; // Printable name, if _method is NULL
|
||||
|
||||
CallNode(const TypeFunc* tf, address addr, const TypePtr* adr_type)
|
||||
: SafePointNode(tf->domain()->cnt(), NULL, adr_type),
|
||||
_tf(tf),
|
||||
_entry_point(addr),
|
||||
_cnt(COUNT_UNKNOWN),
|
||||
_generator(NULL)
|
||||
_generator(NULL),
|
||||
_name(NULL)
|
||||
{
|
||||
init_class_id(Class_Call);
|
||||
}
|
||||
@ -626,10 +628,12 @@ public:
|
||||
// Collect all the interesting edges from a call for use in
|
||||
// replacing the call by something else. Used by macro expansion
|
||||
// and the late inlining support.
|
||||
void extract_projections(CallProjections* projs, bool separate_io_proj);
|
||||
void extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts = true);
|
||||
|
||||
virtual uint match_edge(uint idx) const;
|
||||
|
||||
bool is_call_to_arraycopystub() const;
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_req(outputStream *st = tty) const;
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
@ -683,7 +687,7 @@ class CallStaticJavaNode : public CallJavaNode {
|
||||
virtual uint size_of() const; // Size is bigger
|
||||
public:
|
||||
CallStaticJavaNode(Compile* C, const TypeFunc* tf, address addr, ciMethod* method, int bci)
|
||||
: CallJavaNode(tf, addr, method, bci), _name(NULL) {
|
||||
: CallJavaNode(tf, addr, method, bci) {
|
||||
init_class_id(Class_CallStaticJava);
|
||||
if (C->eliminate_boxing() && (method != NULL) && method->is_boxing_method()) {
|
||||
init_flags(Flag_is_macro);
|
||||
@ -694,14 +698,14 @@ public:
|
||||
}
|
||||
CallStaticJavaNode(const TypeFunc* tf, address addr, const char* name, int bci,
|
||||
const TypePtr* adr_type)
|
||||
: CallJavaNode(tf, addr, NULL, bci), _name(name) {
|
||||
: CallJavaNode(tf, addr, NULL, bci) {
|
||||
init_class_id(Class_CallStaticJava);
|
||||
// This node calls a runtime stub, which often has narrow memory effects.
|
||||
_adr_type = adr_type;
|
||||
_is_scalar_replaceable = false;
|
||||
_is_non_escaping = false;
|
||||
_name = name;
|
||||
}
|
||||
const char *_name; // Runtime wrapper name
|
||||
|
||||
// Result of Escape Analysis
|
||||
bool _is_scalar_replaceable;
|
||||
@ -754,13 +758,12 @@ class CallRuntimeNode : public CallNode {
|
||||
public:
|
||||
CallRuntimeNode(const TypeFunc* tf, address addr, const char* name,
|
||||
const TypePtr* adr_type)
|
||||
: CallNode(tf, addr, adr_type),
|
||||
_name(name)
|
||||
: CallNode(tf, addr, adr_type)
|
||||
{
|
||||
init_class_id(Class_CallRuntime);
|
||||
_name = name;
|
||||
}
|
||||
|
||||
const char *_name; // Printable name, if _method is NULL
|
||||
virtual int Opcode() const;
|
||||
virtual void calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const;
|
||||
|
||||
@ -785,8 +788,6 @@ public:
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
#endif
|
||||
bool is_call_to_arraycopystub() const;
|
||||
virtual bool may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase);
|
||||
};
|
||||
|
||||
//------------------------------CallLeafNoFPNode-------------------------------
|
||||
|
@ -3390,9 +3390,6 @@ bool Compile::final_graph_reshaping() {
|
||||
bool Compile::too_many_traps(ciMethod* method,
|
||||
int bci,
|
||||
Deoptimization::DeoptReason reason) {
|
||||
if (method->has_injected_profile()) {
|
||||
return false;
|
||||
}
|
||||
ciMethodData* md = method->method_data();
|
||||
if (md->is_empty()) {
|
||||
// Assume the trap has not occurred, or that it occurred only
|
||||
@ -3442,9 +3439,6 @@ bool Compile::too_many_traps(Deoptimization::DeoptReason reason,
|
||||
bool Compile::too_many_recompiles(ciMethod* method,
|
||||
int bci,
|
||||
Deoptimization::DeoptReason reason) {
|
||||
if (method->has_injected_profile()) {
|
||||
return false;
|
||||
}
|
||||
ciMethodData* md = method->method_data();
|
||||
if (md->is_empty()) {
|
||||
// Assume the trap has not occurred, or that it occurred only
|
||||
|
@ -6125,8 +6125,6 @@ bool LibraryCallKit::inline_profileBoolean() {
|
||||
jint false_cnt = aobj->element_value(0).as_int();
|
||||
jint true_cnt = aobj->element_value(1).as_int();
|
||||
|
||||
method()->set_injected_profile(true);
|
||||
|
||||
if (C->log() != NULL) {
|
||||
C->log()->elem("observe source='profileBoolean' false='%d' true='%d'",
|
||||
false_cnt, true_cnt);
|
||||
|
@ -108,11 +108,10 @@ extern void print_alias_types();
|
||||
|
||||
#endif
|
||||
|
||||
static bool membar_for_arraycopy_helper(const TypeOopPtr *t_oop, MergeMemNode* mm, PhaseTransform *phase) {
|
||||
if (mm->memory_at(Compile::AliasIdxRaw)->is_Proj()) {
|
||||
Node* n = mm->memory_at(Compile::AliasIdxRaw)->in(0);
|
||||
if ((n->is_ArrayCopy() && n->as_ArrayCopy()->may_modify(t_oop, phase)) ||
|
||||
(n->is_CallLeaf() && n->as_CallLeaf()->may_modify(t_oop, phase))) {
|
||||
static bool membar_for_arraycopy_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase) {
|
||||
if (n->is_Proj()) {
|
||||
n = n->in(0);
|
||||
if (n->is_Call() && n->as_Call()->may_modify(t_oop, phase)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -121,16 +120,22 @@ static bool membar_for_arraycopy_helper(const TypeOopPtr *t_oop, MergeMemNode* m
|
||||
|
||||
static bool membar_for_arraycopy(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase) {
|
||||
Node* mem = mb->in(TypeFunc::Memory);
|
||||
|
||||
if (mem->is_MergeMem()) {
|
||||
return membar_for_arraycopy_helper(t_oop, mem->as_MergeMem(), phase);
|
||||
} else if (mem->is_Phi()) {
|
||||
// after macro expansion of an ArrayCopyNode we may have a Phi
|
||||
for (uint i = 1; i < mem->req(); i++) {
|
||||
if (mem->in(i) != NULL && mem->in(i)->is_MergeMem() && membar_for_arraycopy_helper(t_oop, mem->in(i)->as_MergeMem(), phase)) {
|
||||
return true;
|
||||
Node* n = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
|
||||
if (membar_for_arraycopy_helper(t_oop, n, phase)) {
|
||||
return true;
|
||||
} else if (n->is_Phi()) {
|
||||
for (uint i = 1; i < n->req(); i++) {
|
||||
if (n->in(i) != NULL) {
|
||||
if (membar_for_arraycopy_helper(t_oop, n->in(i), phase)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/relocator.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
@ -174,6 +175,9 @@ void VM_RedefineClasses::doit_epilogue() {
|
||||
// Free os::malloc allocated memory.
|
||||
os::free(_scratch_classes);
|
||||
|
||||
// Reset the_class_oop to null for error printing.
|
||||
_the_class_oop = NULL;
|
||||
|
||||
if (RC_TRACE_ENABLED(0x00000004)) {
|
||||
// Used to have separate timers for "doit" and "all", but the timer
|
||||
// overhead skewed the measurements.
|
||||
@ -4105,6 +4109,13 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
|
||||
java_lang_Class::classRedefinedCount(the_class_mirror),
|
||||
os::available_memory() >> 10));
|
||||
|
||||
{
|
||||
ResourceMark rm(THREAD);
|
||||
Events::log_redefinition(THREAD, "redefined class name=%s, count=%d",
|
||||
the_class->external_name(),
|
||||
java_lang_Class::classRedefinedCount(the_class_mirror));
|
||||
|
||||
}
|
||||
RC_TIMER_STOP(_timer_rsc_phase2);
|
||||
} // end redefine_single_class()
|
||||
|
||||
@ -4249,3 +4260,11 @@ void VM_RedefineClasses::dump_methods() {
|
||||
tty->cr();
|
||||
}
|
||||
}
|
||||
|
||||
void VM_RedefineClasses::print_on_error(outputStream* st) const {
|
||||
VM_Operation::print_on_error(st);
|
||||
if (_the_class_oop != NULL) {
|
||||
ResourceMark rm;
|
||||
st->print_cr(", redefining class %s", _the_class_oop->external_name());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
@ -539,5 +539,8 @@ class VM_RedefineClasses: public VM_Operation {
|
||||
static unsigned char * get_cached_class_file_bytes(JvmtiCachedClassFileData *cache) {
|
||||
return cache == NULL ? NULL : cache->data;
|
||||
}
|
||||
|
||||
// Error printing
|
||||
void print_on_error(outputStream* st) const;
|
||||
};
|
||||
#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP
|
||||
|
@ -710,6 +710,24 @@ WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name))
|
||||
return NULL;
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jobject, WB_GetIntVMFlag(JNIEnv* env, jobject o, jstring name))
|
||||
int result;
|
||||
if (GetVMFlag <int> (thread, env, name, &result, &CommandLineFlags::intAt)) {
|
||||
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
|
||||
return longBox(thread, env, result);
|
||||
}
|
||||
return NULL;
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jobject, WB_GetUintVMFlag(JNIEnv* env, jobject o, jstring name))
|
||||
uint result;
|
||||
if (GetVMFlag <uint> (thread, env, name, &result, &CommandLineFlags::uintAt)) {
|
||||
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
|
||||
return longBox(thread, env, result);
|
||||
}
|
||||
return NULL;
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name))
|
||||
intx result;
|
||||
if (GetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAt)) {
|
||||
@ -771,6 +789,16 @@ WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolea
|
||||
SetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAtPut);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_SetIntVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
|
||||
int result = value;
|
||||
SetVMFlag <int> (thread, env, name, &result, &CommandLineFlags::intAtPut);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_SetUintVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
|
||||
uint result = value;
|
||||
SetVMFlag <uint> (thread, env, name, &result, &CommandLineFlags::uintAtPut);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
|
||||
intx result = value;
|
||||
SetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAtPut);
|
||||
@ -1336,6 +1364,8 @@ static JNINativeMethod methods[] = {
|
||||
{CC"isConstantVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag},
|
||||
{CC"isLockedVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag},
|
||||
{CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
|
||||
{CC"setIntVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntVMFlag},
|
||||
{CC"setUintVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintVMFlag},
|
||||
{CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag},
|
||||
{CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag},
|
||||
{CC"setUint64VMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag},
|
||||
@ -1345,6 +1375,10 @@ static JNINativeMethod methods[] = {
|
||||
(void*)&WB_SetStringVMFlag},
|
||||
{CC"getBooleanVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Boolean;",
|
||||
(void*)&WB_GetBooleanVMFlag},
|
||||
{CC"getIntVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
|
||||
(void*)&WB_GetIntVMFlag},
|
||||
{CC"getUintVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
|
||||
(void*)&WB_GetUintVMFlag},
|
||||
{CC"getIntxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
|
||||
(void*)&WB_GetIntxVMFlag},
|
||||
{CC"getUintxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
|
||||
|
@ -586,11 +586,12 @@ static bool set_fp_numeric_flag(char* name, char* value, Flag::Flags origin) {
|
||||
|
||||
static bool set_numeric_flag(char* name, char* value, Flag::Flags origin) {
|
||||
julong v;
|
||||
int int_v;
|
||||
intx intx_v;
|
||||
bool is_neg = false;
|
||||
// Check the sign first since atomull() parses only unsigned values.
|
||||
if (*value == '-') {
|
||||
if (!CommandLineFlags::intxAt(name, &intx_v)) {
|
||||
if (!CommandLineFlags::intxAt(name, &intx_v) && !CommandLineFlags::intAt(name, &int_v)) {
|
||||
return false;
|
||||
}
|
||||
value++;
|
||||
@ -599,6 +600,17 @@ static bool set_numeric_flag(char* name, char* value, Flag::Flags origin) {
|
||||
if (!atomull(value, &v)) {
|
||||
return false;
|
||||
}
|
||||
int_v = (int) v;
|
||||
if (is_neg) {
|
||||
int_v = -int_v;
|
||||
}
|
||||
if (CommandLineFlags::intAtPut(name, &int_v, origin)) {
|
||||
return true;
|
||||
}
|
||||
uint uint_v = (uint) v;
|
||||
if (!is_neg && CommandLineFlags::uintAtPut(name, &uint_v, origin)) {
|
||||
return true;
|
||||
}
|
||||
intx_v = (intx) v;
|
||||
if (is_neg) {
|
||||
intx_v = -intx_v;
|
||||
|
@ -1460,7 +1460,11 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
|
||||
//
|
||||
// The other actions cause immediate removal of the present code.
|
||||
|
||||
bool update_trap_state = (reason != Reason_tenured);
|
||||
// Traps caused by injected profile shouldn't pollute trap counts.
|
||||
bool injected_profile_trap = trap_method->has_injected_profile() &&
|
||||
(reason == Reason_intrinsic || reason == Reason_unreached);
|
||||
|
||||
bool update_trap_state = (reason != Reason_tenured) && !injected_profile_trap;
|
||||
bool make_not_entrant = false;
|
||||
bool make_not_compilable = false;
|
||||
bool reprofile = false;
|
||||
|
@ -93,6 +93,32 @@ void Flag::set_bool(bool value) {
|
||||
*((bool*) _addr) = value;
|
||||
}
|
||||
|
||||
bool Flag::is_int() const {
|
||||
return strcmp(_type, "int") == 0;
|
||||
}
|
||||
|
||||
int Flag::get_int() const {
|
||||
return *((int*) _addr);
|
||||
}
|
||||
|
||||
void Flag::set_int(int value) {
|
||||
check_writable();
|
||||
*((int*) _addr) = value;
|
||||
}
|
||||
|
||||
bool Flag::is_uint() const {
|
||||
return strcmp(_type, "uint") == 0;
|
||||
}
|
||||
|
||||
uint Flag::get_uint() const {
|
||||
return *((uint*) _addr);
|
||||
}
|
||||
|
||||
void Flag::set_uint(uint value) {
|
||||
check_writable();
|
||||
*((uint*) _addr) = value;
|
||||
}
|
||||
|
||||
bool Flag::is_intx() const {
|
||||
return strcmp(_type, "intx") == 0;
|
||||
}
|
||||
@ -316,6 +342,12 @@ void Flag::print_on(outputStream* st, bool withComments) {
|
||||
if (is_bool()) {
|
||||
st->print("%-16s", get_bool() ? "true" : "false");
|
||||
}
|
||||
if (is_int()) {
|
||||
st->print("%-16d", get_int());
|
||||
}
|
||||
if (is_uint()) {
|
||||
st->print("%-16u", get_uint());
|
||||
}
|
||||
if (is_intx()) {
|
||||
st->print("%-16ld", get_intx());
|
||||
}
|
||||
@ -411,6 +443,10 @@ void Flag::print_kind(outputStream* st) {
|
||||
void Flag::print_as_flag(outputStream* st) {
|
||||
if (is_bool()) {
|
||||
st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
|
||||
} else if (is_int()) {
|
||||
st->print("-XX:%s=%d", _name, get_int());
|
||||
} else if (is_uint()) {
|
||||
st->print("-XX:%s=%u", _name, get_uint());
|
||||
} else if (is_intx()) {
|
||||
st->print("-XX:%s=" INTX_FORMAT, _name, get_intx());
|
||||
} else if (is_uintx()) {
|
||||
@ -663,6 +699,62 @@ void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Fla
|
||||
faddr->set_origin(origin);
|
||||
}
|
||||
|
||||
bool CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
|
||||
Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
|
||||
if (result == NULL) return false;
|
||||
if (!result->is_int()) return false;
|
||||
*value = result->get_int();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
|
||||
Flag* result = Flag::find_flag(name, len);
|
||||
if (result == NULL) return false;
|
||||
if (!result->is_int()) return false;
|
||||
int old_value = result->get_int();
|
||||
trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
|
||||
result->set_int(*value);
|
||||
*value = old_value;
|
||||
result->set_origin(origin);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
|
||||
Flag* faddr = address_of_flag(flag);
|
||||
guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
|
||||
trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
|
||||
faddr->set_int(value);
|
||||
faddr->set_origin(origin);
|
||||
}
|
||||
|
||||
bool CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
|
||||
Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
|
||||
if (result == NULL) return false;
|
||||
if (!result->is_uint()) return false;
|
||||
*value = result->get_uint();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
|
||||
Flag* result = Flag::find_flag(name, len);
|
||||
if (result == NULL) return false;
|
||||
if (!result->is_uint()) return false;
|
||||
uint old_value = result->get_uint();
|
||||
trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
|
||||
result->set_uint(*value);
|
||||
*value = old_value;
|
||||
result->set_origin(origin);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
|
||||
Flag* faddr = address_of_flag(flag);
|
||||
guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
|
||||
trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
|
||||
faddr->set_uint(value);
|
||||
faddr->set_origin(origin);
|
||||
}
|
||||
|
||||
bool CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
|
||||
Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
|
||||
if (result == NULL) return false;
|
||||
|
@ -279,6 +279,14 @@ struct Flag {
|
||||
bool get_bool() const;
|
||||
void set_bool(bool value);
|
||||
|
||||
bool is_int() const;
|
||||
int get_int() const;
|
||||
void set_int(int value);
|
||||
|
||||
bool is_uint() const;
|
||||
uint get_uint() const;
|
||||
void set_uint(uint value);
|
||||
|
||||
bool is_intx() const;
|
||||
intx get_intx() const;
|
||||
void set_intx(intx value);
|
||||
@ -363,13 +371,28 @@ class CounterSetting {
|
||||
~CounterSetting() { (*counter)--; }
|
||||
};
|
||||
|
||||
class IntFlagSetting {
|
||||
int val;
|
||||
int* flag;
|
||||
public:
|
||||
IntFlagSetting(int& fl, int newValue) { flag = &fl; val = fl; fl = newValue; }
|
||||
~IntFlagSetting() { *flag = val; }
|
||||
};
|
||||
|
||||
class UIntFlagSetting {
|
||||
uint val;
|
||||
uint* flag;
|
||||
public:
|
||||
UIntFlagSetting(uint& fl, uint newValue) { flag = &fl; val = fl; fl = newValue; }
|
||||
~UIntFlagSetting() { *flag = val; }
|
||||
};
|
||||
|
||||
class UIntXFlagSetting {
|
||||
uintx val;
|
||||
uintx* flag;
|
||||
public:
|
||||
UIntFlagSetting(uintx& fl, uintx newValue) { flag = &fl; val = fl; fl = newValue; }
|
||||
~UIntFlagSetting() { *flag = val; }
|
||||
UIntXFlagSetting(uintx& fl, uintx newValue) { flag = &fl; val = fl; fl = newValue; }
|
||||
~UIntXFlagSetting() { *flag = val; }
|
||||
};
|
||||
|
||||
class DoubleFlagSetting {
|
||||
@ -396,6 +419,16 @@ class CommandLineFlags {
|
||||
static bool boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin);
|
||||
static bool boolAtPut(const char* name, bool* value, Flag::Flags origin) { return boolAtPut(name, strlen(name), value, origin); }
|
||||
|
||||
static bool intAt(const char* name, size_t len, int* value, bool allow_locked = false, bool return_flag = false);
|
||||
static bool intAt(const char* name, int* value, bool allow_locked = false, bool return_flag = false) { return intAt(name, strlen(name), value, allow_locked, return_flag); }
|
||||
static bool intAtPut(const char* name, size_t len, int* value, Flag::Flags origin);
|
||||
static bool intAtPut(const char* name, int* value, Flag::Flags origin) { return intAtPut(name, strlen(name), value, origin); }
|
||||
|
||||
static bool uintAt(const char* name, size_t len, uint* value, bool allow_locked = false, bool return_flag = false);
|
||||
static bool uintAt(const char* name, uint* value, bool allow_locked = false, bool return_flag = false) { return uintAt(name, strlen(name), value, allow_locked, return_flag); }
|
||||
static bool uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin);
|
||||
static bool uintAtPut(const char* name, uint* value, Flag::Flags origin) { return uintAtPut(name, strlen(name), value, origin); }
|
||||
|
||||
static bool intxAt(const char* name, size_t len, intx* value, bool allow_locked = false, bool return_flag = false);
|
||||
static bool intxAt(const char* name, intx* value, bool allow_locked = false, bool return_flag = false) { return intxAt(name, strlen(name), value, allow_locked, return_flag); }
|
||||
static bool intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin);
|
||||
|
@ -197,6 +197,8 @@ typedef enum {
|
||||
class CommandLineFlagsEx : CommandLineFlags {
|
||||
public:
|
||||
static void boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin);
|
||||
static void intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin);
|
||||
static void uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin);
|
||||
static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin);
|
||||
static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
|
||||
static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
|
||||
|
@ -192,7 +192,7 @@ class VM_Operation: public CHeapObj<mtInternal> {
|
||||
static const char* mode_to_string(Mode mode);
|
||||
|
||||
// Debugging
|
||||
void print_on_error(outputStream* st) const;
|
||||
virtual void print_on_error(outputStream* st) const;
|
||||
const char* name() const { return _names[type()]; }
|
||||
static const char* name(int type) {
|
||||
assert(type >= 0 && type < VMOp_Terminating, "invalid VM operation type");
|
||||
|
@ -1558,6 +1558,12 @@ bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag,
|
||||
if (flag->is_bool()) {
|
||||
global->value.z = flag->get_bool() ? JNI_TRUE : JNI_FALSE;
|
||||
global->type = JMM_VMGLOBAL_TYPE_JBOOLEAN;
|
||||
} else if (flag->is_int()) {
|
||||
global->value.j = (jlong)flag->get_int();
|
||||
global->type = JMM_VMGLOBAL_TYPE_JLONG;
|
||||
} else if (flag->is_uint()) {
|
||||
global->value.j = (jlong)flag->get_uint();
|
||||
global->type = JMM_VMGLOBAL_TYPE_JLONG;
|
||||
} else if (flag->is_intx()) {
|
||||
global->value.j = (jlong)flag->get_intx();
|
||||
global->type = JMM_VMGLOBAL_TYPE_JLONG;
|
||||
|
@ -44,6 +44,36 @@ int WriteableFlags::set_bool_flag(const char* name, bool value, Flag::Flags orig
|
||||
return CommandLineFlags::boolAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
|
||||
}
|
||||
|
||||
// set a int global flag
|
||||
int WriteableFlags::set_int_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
|
||||
int value;
|
||||
|
||||
if (sscanf(arg, "%d", &value)) {
|
||||
return set_int_flag(name, value, origin, err_msg);
|
||||
}
|
||||
err_msg.print("flag value must be an integer");
|
||||
return WRONG_FORMAT;
|
||||
}
|
||||
|
||||
int WriteableFlags::set_int_flag(const char* name, int value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
|
||||
return CommandLineFlags::intAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
|
||||
}
|
||||
|
||||
// set a uint global flag
|
||||
int WriteableFlags::set_uint_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
|
||||
uint value;
|
||||
|
||||
if (sscanf(arg, "%u", &value)) {
|
||||
return set_uint_flag(name, value, origin, err_msg);
|
||||
}
|
||||
err_msg.print("flag value must be an unsigned integer");
|
||||
return WRONG_FORMAT;
|
||||
}
|
||||
|
||||
int WriteableFlags::set_uint_flag(const char* name, uint value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
|
||||
return CommandLineFlags::uintAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
|
||||
}
|
||||
|
||||
// set a intx global flag
|
||||
int WriteableFlags::set_intx_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
|
||||
intx value;
|
||||
@ -173,6 +203,10 @@ int WriteableFlags::set_flag_from_char(Flag* f, const void* value, Flag::Flags o
|
||||
}
|
||||
if (f->is_bool()) {
|
||||
return set_bool_flag(f->_name, flag_value, origin, err_msg);
|
||||
} else if (f->is_int()) {
|
||||
return set_int_flag(f->_name, flag_value, origin, err_msg);
|
||||
} else if (f->is_uint()) {
|
||||
return set_uint_flag(f->_name, flag_value, origin, err_msg);
|
||||
} else if (f->is_intx()) {
|
||||
return set_intx_flag(f->_name, flag_value, origin, err_msg);
|
||||
} else if (f->is_uintx()) {
|
||||
@ -195,6 +229,12 @@ int WriteableFlags::set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags
|
||||
if (f->is_bool()) {
|
||||
bool bvalue = (new_value.z == JNI_TRUE ? true : false);
|
||||
return set_bool_flag(f->_name, bvalue, origin, err_msg);
|
||||
} else if (f->is_int()) {
|
||||
int ivalue = (int)new_value.j;
|
||||
return set_int_flag(f->_name, ivalue, origin, err_msg);
|
||||
} else if (f->is_uint()) {
|
||||
uint uvalue = (uint)new_value.j;
|
||||
return set_uint_flag(f->_name, uvalue, origin, err_msg);
|
||||
} else if (f->is_intx()) {
|
||||
intx ivalue = (intx)new_value.j;
|
||||
return set_intx_flag(f->_name, ivalue, origin, err_msg);
|
||||
|
@ -56,6 +56,10 @@ private:
|
||||
|
||||
// set a boolean global flag
|
||||
static int set_bool_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a int global flag
|
||||
static int set_int_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a uint global flag
|
||||
static int set_uint_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a intx global flag
|
||||
static int set_intx_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a uintx global flag
|
||||
@ -66,6 +70,10 @@ private:
|
||||
static int set_size_t_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a boolean global flag
|
||||
static int set_bool_flag(const char* name, bool value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a int global flag
|
||||
static int set_int_flag(const char* name, int value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a uint global flag
|
||||
static int set_uint_flag(const char* name, uint value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a intx global flag
|
||||
static int set_intx_flag(const char* name, intx value, Flag::Flags origin, FormatBuffer<80>& err_msg);
|
||||
// set a uintx global flag
|
||||
|
@ -122,6 +122,22 @@ Declares a structure type that can be used in other events.
|
||||
<value type="CLASS" field="definingClassLoader" label="Defining Class Loader"/>
|
||||
</event>
|
||||
|
||||
<event id="IntFlagChanged" path="vm/flag/int_changed" label="Int Flag Changed"
|
||||
is_instant="true">
|
||||
<value type="UTF8" field="name" label="Name" />
|
||||
<value type="INTEGER" field="old_value" label="Old Value" />
|
||||
<value type="INTEGER" field="new_value" label="New Value" />
|
||||
<value type="FLAGVALUEORIGIN" field="origin" label="Origin" />
|
||||
</event>
|
||||
|
||||
<event id="UnsignedIntFlagChanged" path="vm/flag/uint_changed" label="Unsigned Int Flag Changed"
|
||||
is_instant="true">
|
||||
<value type="UTF8" field="name" label="Name" />
|
||||
<value type="UINT" field="old_value" label="Old Value" />
|
||||
<value type="UINT" field="new_value" label="New Value" />
|
||||
<value type="FLAGVALUEORIGIN" field="origin" label="Origin" />
|
||||
</event>
|
||||
|
||||
<event id="LongFlagChanged" path="vm/flag/long_changed" label="Long Flag Changed"
|
||||
is_instant="true">
|
||||
<value type="UTF8" field="name" label="Name" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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 @@
|
||||
EventLog* Events::_logs = NULL;
|
||||
StringEventLog* Events::_messages = NULL;
|
||||
StringEventLog* Events::_exceptions = NULL;
|
||||
StringEventLog* Events::_redefinitions = NULL;
|
||||
StringEventLog* Events::_deopt_messages = NULL;
|
||||
|
||||
EventLog::EventLog() {
|
||||
@ -66,6 +67,7 @@ void Events::init() {
|
||||
if (LogEvents) {
|
||||
_messages = new StringEventLog("Events");
|
||||
_exceptions = new StringEventLog("Internal exceptions");
|
||||
_redefinitions = new StringEventLog("Classes redefined");
|
||||
_deopt_messages = new StringEventLog("Deoptimization events");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -186,6 +186,9 @@ class Events : AllStatic {
|
||||
// Deoptization related messages
|
||||
static StringEventLog* _deopt_messages;
|
||||
|
||||
// Redefinition related messages
|
||||
static StringEventLog* _redefinitions;
|
||||
|
||||
public:
|
||||
static void print_all(outputStream* out);
|
||||
|
||||
@ -198,6 +201,8 @@ class Events : AllStatic {
|
||||
// Log exception related message
|
||||
static void log_exception(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
|
||||
|
||||
static void log_redefinition(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
|
||||
|
||||
static void log_deopt_message(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
|
||||
|
||||
// Register default loggers
|
||||
@ -222,6 +227,15 @@ inline void Events::log_exception(Thread* thread, const char* format, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void Events::log_redefinition(Thread* thread, const char* format, ...) {
|
||||
if (LogEvents) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
_redefinitions->logv(thread, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Events::log_deopt_message(Thread* thread, const char* format, ...) {
|
||||
if (LogEvents) {
|
||||
va_list ap;
|
||||
|
71
hotspot/test/compiler/arraycopy/TestLoadBypassArrayCopy.java
Normal file
71
hotspot/test/compiler/arraycopy/TestLoadBypassArrayCopy.java
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 8086046
|
||||
* @summary load bypasses arraycopy that sets the value after the ArrayCopyNode is expanded
|
||||
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestLoadBypassArrayCopy::test_helper -XX:-TieredCompilation TestLoadBypassArrayCopy
|
||||
*
|
||||
*/
|
||||
|
||||
public class TestLoadBypassArrayCopy {
|
||||
|
||||
static long i;
|
||||
static boolean test_helper() {
|
||||
i++;
|
||||
if ((i%10) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test(int[] src, int len, boolean flag) {
|
||||
int[] dest = new int[10];
|
||||
int res = 0;
|
||||
while (test_helper()) {
|
||||
System.arraycopy(src, 0, dest, 0, len);
|
||||
// predicate moved out of loop so control of following
|
||||
// load is not the ArrayCopyNode. Otherwise, if the memory
|
||||
// of the load is changed and the control is set to the
|
||||
// ArrayCopyNode the graph is unschedulable and the test
|
||||
// doesn't fail.
|
||||
if (flag) {
|
||||
}
|
||||
// The memory of this load shouldn't bypass the arraycopy
|
||||
res = dest[0];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static public void main(String[] args) {
|
||||
int[] src = new int[10];
|
||||
src[0] = 0x42;
|
||||
for (int i = 0; i < 20000; i++) {
|
||||
int res = test(src, 10, false);
|
||||
if (res != src[0]) {
|
||||
throw new RuntimeException("test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -71,7 +71,7 @@ public class SHAOptionsBase extends CommandLineOptionTest {
|
||||
* instructions required by the option are not supported.
|
||||
*/
|
||||
protected static String getWarningForUnsupportedCPU(String optionName) {
|
||||
if (Platform.isSparc()) {
|
||||
if (Platform.isSparc() || Platform.isAArch64()) {
|
||||
switch (optionName) {
|
||||
case SHAOptionsBase.USE_SHA_OPTION:
|
||||
return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
|
||||
|
@ -36,7 +36,7 @@
|
||||
*/
|
||||
public class TestUseSHA1IntrinsicsOptionOnSupportedCPU {
|
||||
public static void main(String args[]) throws Throwable {
|
||||
new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
|
||||
new SHAOptionsBase(new GenericTestCaseForSupportedCPU(
|
||||
SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,12 @@ public class TestUseSHA1IntrinsicsOptionOnUnsupportedCPU {
|
||||
new SHAOptionsBase(
|
||||
new GenericTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
|
||||
new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForUnsupportedX86CPU(
|
||||
SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForUnsupportedAArch64CPU(
|
||||
SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
|
||||
new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU(
|
||||
SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForOtherCPU(
|
||||
SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
*/
|
||||
public class TestUseSHA256IntrinsicsOptionOnSupportedCPU {
|
||||
public static void main(String args[]) throws Throwable {
|
||||
new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
|
||||
new SHAOptionsBase(new GenericTestCaseForSupportedCPU(
|
||||
SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,12 @@ public class TestUseSHA256IntrinsicsOptionOnUnsupportedCPU {
|
||||
new SHAOptionsBase(
|
||||
new GenericTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
|
||||
new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForUnsupportedX86CPU(
|
||||
SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForUnsupportedAArch64CPU(
|
||||
SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
|
||||
new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU(
|
||||
SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForOtherCPU(
|
||||
SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
*/
|
||||
public class TestUseSHA512IntrinsicsOptionOnSupportedCPU {
|
||||
public static void main(String args[]) throws Throwable {
|
||||
new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
|
||||
new SHAOptionsBase(new GenericTestCaseForSupportedCPU(
|
||||
SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,12 @@ public class TestUseSHA512IntrinsicsOptionOnUnsupportedCPU {
|
||||
new SHAOptionsBase(
|
||||
new GenericTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
|
||||
new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForUnsupportedX86CPU(
|
||||
SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForUnsupportedAArch64CPU(
|
||||
SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
|
||||
new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU(
|
||||
SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
|
||||
new GenericTestCaseForOtherCPU(
|
||||
SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
|
||||
}
|
||||
|
@ -37,9 +37,9 @@
|
||||
public class TestUseSHAOptionOnSupportedCPU {
|
||||
public static void main(String args[]) throws Throwable {
|
||||
new SHAOptionsBase(
|
||||
new GenericTestCaseForSupportedSparcCPU(
|
||||
new GenericTestCaseForSupportedCPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION),
|
||||
new UseSHASpecificTestCaseForSupportedSparcCPU(
|
||||
new UseSHASpecificTestCaseForSupportedCPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION)).test();
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,12 @@ public class TestUseSHAOptionOnUnsupportedCPU {
|
||||
new SHAOptionsBase(
|
||||
new GenericTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION),
|
||||
new UseSHASpecificTestCaseForUnsupportedSparcCPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION),
|
||||
new GenericTestCaseForUnsupportedX86CPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION),
|
||||
new GenericTestCaseForUnsupportedAArch64CPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION),
|
||||
new UseSHASpecificTestCaseForUnsupportedCPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION),
|
||||
new GenericTestCaseForOtherCPU(
|
||||
SHAOptionsBase.USE_SHA_OPTION)).test();
|
||||
}
|
||||
|
@ -35,16 +35,18 @@ public class GenericTestCaseForOtherCPU extends
|
||||
SHAOptionsBase.TestCase {
|
||||
public GenericTestCaseForOtherCPU(String optionName) {
|
||||
// Execute the test case on any CPU except SPARC and X86
|
||||
super(optionName, new NotPredicate(new OrPredicate(Platform::isSparc,
|
||||
new OrPredicate(Platform::isX64, Platform::isX86))));
|
||||
super(optionName, new NotPredicate(
|
||||
new OrPredicate(
|
||||
new OrPredicate(Platform::isSparc, Platform::isAArch64),
|
||||
new OrPredicate(Platform::isX64, Platform::isX86))));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifyWarnings() throws Throwable {
|
||||
String shouldPassMessage = String.format("JVM should start with "
|
||||
+ "option '%s' without any warnings", optionName);
|
||||
// Verify that on non-x86 and non-SPARC CPU usage of SHA-related
|
||||
// options will not cause any warnings.
|
||||
// Verify that on non-x86, non-SPARC and non-AArch64 CPU usage of
|
||||
// SHA-related options will not cause any warnings.
|
||||
CommandLineOptionTest.verifySameJVMStartup(null,
|
||||
new String[] { ".*" + optionName + ".*" }, shouldPassMessage,
|
||||
shouldPassMessage, ExitCode.OK,
|
||||
|
@ -25,16 +25,19 @@ import jdk.test.lib.ExitCode;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.cli.CommandLineOptionTest;
|
||||
import jdk.test.lib.cli.predicate.AndPredicate;
|
||||
import jdk.test.lib.cli.predicate.OrPredicate;
|
||||
|
||||
/**
|
||||
* Generic test case for SHA-related options targeted to SPARC CPUs which
|
||||
* Generic test case for SHA-related options targeted to CPUs which
|
||||
* support instructions required by the tested option.
|
||||
*/
|
||||
public class GenericTestCaseForSupportedSparcCPU extends
|
||||
public class GenericTestCaseForSupportedCPU extends
|
||||
SHAOptionsBase.TestCase {
|
||||
public GenericTestCaseForSupportedSparcCPU(String optionName) {
|
||||
super(optionName, new AndPredicate(Platform::isSparc,
|
||||
SHAOptionsBase.getPredicateForOption(optionName)));
|
||||
public GenericTestCaseForSupportedCPU(String optionName) {
|
||||
super(optionName,
|
||||
new AndPredicate(
|
||||
new OrPredicate(Platform::isSparc, Platform::isAArch64),
|
||||
SHAOptionsBase.getPredicateForOption(optionName)));
|
||||
}
|
||||
|
||||
@Override
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, 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 jdk.test.lib.ExitCode;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.cli.CommandLineOptionTest;
|
||||
import jdk.test.lib.cli.predicate.AndPredicate;
|
||||
import jdk.test.lib.cli.predicate.NotPredicate;
|
||||
|
||||
/**
|
||||
* Generic test case for SHA-related options targeted to AArch64 CPUs
|
||||
* which don't support instruction required by the tested option.
|
||||
*/
|
||||
public class GenericTestCaseForUnsupportedAArch64CPU extends
|
||||
SHAOptionsBase.TestCase {
|
||||
public GenericTestCaseForUnsupportedAArch64CPU(String optionName) {
|
||||
super(optionName, new AndPredicate(Platform::isAArch64,
|
||||
new NotPredicate(SHAOptionsBase.getPredicateForOption(
|
||||
optionName))));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifyWarnings() throws Throwable {
|
||||
String shouldPassMessage = String.format("JVM startup should pass with"
|
||||
+ "option '-XX:-%s' without any warnings", optionName);
|
||||
//Verify that option could be disabled without any warnings.
|
||||
CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
|
||||
SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
|
||||
}, shouldPassMessage, shouldPassMessage, ExitCode.OK,
|
||||
CommandLineOptionTest.prepareBooleanFlag(optionName, false));
|
||||
|
||||
shouldPassMessage = String.format("JVM should start with '-XX:+"
|
||||
+ "%s' flag, but output should contain warning.", optionName);
|
||||
// Verify that when the tested option is explicitly enabled, then
|
||||
// a warning will occur in VM output.
|
||||
CommandLineOptionTest.verifySameJVMStartup(new String[] {
|
||||
SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
|
||||
}, null, shouldPassMessage, shouldPassMessage, ExitCode.OK,
|
||||
CommandLineOptionTest.prepareBooleanFlag(optionName, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifyOptionValues() throws Throwable {
|
||||
// Verify that option is disabled by default.
|
||||
CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
|
||||
String.format("Option '%s' should be disabled by default",
|
||||
optionName));
|
||||
|
||||
// Verify that option is disabled even if it was explicitly enabled
|
||||
// using CLI options.
|
||||
CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
|
||||
String.format("Option '%s' should be off on unsupported "
|
||||
+ "AArch64CPU even if set to true directly", optionName),
|
||||
CommandLineOptionTest.prepareBooleanFlag(optionName, true));
|
||||
|
||||
// Verify that option is disabled when +UseSHA was passed to JVM.
|
||||
CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
|
||||
String.format("Option '%s' should be off on unsupported "
|
||||
+ "AArch64CPU even if %s flag set to JVM",
|
||||
optionName, CommandLineOptionTest.prepareBooleanFlag(
|
||||
SHAOptionsBase.USE_SHA_OPTION, true)),
|
||||
CommandLineOptionTest.prepareBooleanFlag(
|
||||
SHAOptionsBase.USE_SHA_OPTION, true));
|
||||
}
|
||||
}
|
@ -25,24 +25,26 @@ import jdk.test.lib.ExitCode;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.cli.CommandLineOptionTest;
|
||||
import jdk.test.lib.cli.predicate.AndPredicate;
|
||||
import jdk.test.lib.cli.predicate.OrPredicate;
|
||||
import jdk.test.lib.cli.predicate.NotPredicate;
|
||||
import sha.predicate.IntrinsicPredicates;
|
||||
|
||||
/**
|
||||
* Test case specific to UseSHA*Intrinsics options targeted to SPARC CPUs which
|
||||
* don't support required instruction, but support other SHA-related
|
||||
* Test case specific to UseSHA*Intrinsics options targeted to SPARC and AArch64
|
||||
* CPUs which don't support required instruction, but support other SHA-related
|
||||
* instructions.
|
||||
*
|
||||
* For example, CPU support sha1 instruction, but don't support sha256 or
|
||||
* sha512.
|
||||
*/
|
||||
public class UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU
|
||||
public class UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU
|
||||
extends SHAOptionsBase.TestCase {
|
||||
public UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
|
||||
public UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU(
|
||||
String optionName) {
|
||||
// execute test case on SPARC CPU that support any sha* instructions,
|
||||
// but does not support sha* instruction required by the tested option.
|
||||
super(optionName, new AndPredicate(Platform::isSparc,
|
||||
super(optionName, new AndPredicate(
|
||||
new OrPredicate(Platform::isSparc, Platform::isAArch64),
|
||||
new AndPredicate(
|
||||
IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE,
|
||||
new NotPredicate(SHAOptionsBase.getPredicateForOption(
|
@ -26,16 +26,18 @@ import jdk.test.lib.ExitCode;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.cli.CommandLineOptionTest;
|
||||
import jdk.test.lib.cli.predicate.AndPredicate;
|
||||
import jdk.test.lib.cli.predicate.OrPredicate;
|
||||
import sha.predicate.IntrinsicPredicates;
|
||||
|
||||
/**
|
||||
* UseSHA specific test case targeted to SPARC CPUs which support any sha*
|
||||
* instruction.
|
||||
* UseSHA specific test case targeted to SPARC and AArch64 CPUs which
|
||||
* support any sha* instruction.
|
||||
*/
|
||||
public class UseSHASpecificTestCaseForSupportedSparcCPU
|
||||
public class UseSHASpecificTestCaseForSupportedCPU
|
||||
extends SHAOptionsBase.TestCase {
|
||||
public UseSHASpecificTestCaseForSupportedSparcCPU(String optionName) {
|
||||
super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
|
||||
public UseSHASpecificTestCaseForSupportedCPU(String optionName) {
|
||||
super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(
|
||||
new OrPredicate(Platform::isSparc, Platform::isAArch64),
|
||||
IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE));
|
||||
|
||||
Asserts.assertEQ(optionName, SHAOptionsBase.USE_SHA_OPTION,
|
@ -26,17 +26,19 @@ import jdk.test.lib.ExitCode;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.cli.CommandLineOptionTest;
|
||||
import jdk.test.lib.cli.predicate.AndPredicate;
|
||||
import jdk.test.lib.cli.predicate.OrPredicate;
|
||||
import jdk.test.lib.cli.predicate.NotPredicate;
|
||||
import sha.predicate.IntrinsicPredicates;
|
||||
|
||||
/**
|
||||
* UseSHA specific test case targeted to SPARC CPUs which don't support all sha*
|
||||
* instructions.
|
||||
* UseSHA specific test case targeted to SPARC and AArch64 CPUs which don't
|
||||
* support all sha* instructions./
|
||||
*/
|
||||
public class UseSHASpecificTestCaseForUnsupportedSparcCPU
|
||||
public class UseSHASpecificTestCaseForUnsupportedCPU
|
||||
extends SHAOptionsBase.TestCase {
|
||||
public UseSHASpecificTestCaseForUnsupportedSparcCPU(String optionName) {
|
||||
super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
|
||||
public UseSHASpecificTestCaseForUnsupportedCPU(String optionName) {
|
||||
super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(
|
||||
new OrPredicate(Platform::isSparc, Platform::isAArch64),
|
||||
new NotPredicate(
|
||||
IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE)));
|
||||
|
||||
@ -49,7 +51,7 @@ public class UseSHASpecificTestCaseForUnsupportedSparcCPU
|
||||
protected void verifyWarnings() throws Throwable {
|
||||
// Verify that attempt to use UseSHA option will cause a warning.
|
||||
String shouldPassMessage = String.format("JVM startup should pass with"
|
||||
+ " '%s' option on unsupported SparcCPU, but there should be"
|
||||
+ " '%s' option on unsupported CPU, but there should be"
|
||||
+ "the message shown.", optionName);
|
||||
CommandLineOptionTest.verifySameJVMStartup(new String[] {
|
||||
SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
|
||||
@ -63,7 +65,7 @@ public class UseSHASpecificTestCaseForUnsupportedSparcCPU
|
||||
// UseSHA*Intrinsics were enabled.
|
||||
CommandLineOptionTest.verifyOptionValueForSameVM(
|
||||
SHAOptionsBase.USE_SHA_OPTION, "false", String.format(
|
||||
"%s option should be disabled on unsupported SparcCPU"
|
||||
"%s option should be disabled on unsupported CPU"
|
||||
+ " even if all UseSHA*Intrinsics options were enabled.",
|
||||
SHAOptionsBase.USE_SHA_OPTION),
|
||||
CommandLineOptionTest.prepareBooleanFlag(
|
||||
@ -77,7 +79,7 @@ public class UseSHASpecificTestCaseForUnsupportedSparcCPU
|
||||
// UseSHA*Intrinsics options were enabled and UseSHA was enabled as well.
|
||||
CommandLineOptionTest.verifyOptionValueForSameVM(
|
||||
SHAOptionsBase.USE_SHA_OPTION, "false", String.format(
|
||||
"%s option should be disabled on unsupported SparcCPU"
|
||||
"%s option should be disabled on unsupported CPU"
|
||||
+ " even if all UseSHA*Intrinsics options were enabled"
|
||||
+ " and %s was enabled as well",
|
||||
SHAOptionsBase.USE_SHA_OPTION,
|
109
hotspot/test/compiler/jsr292/PollutedTrapCounts.java
Normal file
109
hotspot/test/compiler/jsr292/PollutedTrapCounts.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 8074551
|
||||
* @library /testlibrary
|
||||
* @run main PollutedTrapCounts
|
||||
*/
|
||||
import java.lang.invoke.*;
|
||||
import jdk.test.lib.*;
|
||||
|
||||
public class PollutedTrapCounts {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-XX:+IgnoreUnrecognizedVMOptions",
|
||||
"-XX:-TieredCompilation", "-Xbatch",
|
||||
"-XX:PerBytecodeRecompilationCutoff=10", "-XX:PerMethodRecompilationCutoff=10",
|
||||
"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining",
|
||||
"PollutedTrapCounts$Test");
|
||||
|
||||
OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
|
||||
|
||||
analyzer.shouldHaveExitValue(0);
|
||||
|
||||
analyzer.shouldNotContain("not compilable (disabled)");
|
||||
}
|
||||
|
||||
static class Test {
|
||||
public static final MethodHandle test1;
|
||||
public static final MethodHandle test2;
|
||||
public static final MethodHandle empty;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> THIS_CLASS = Test.class;
|
||||
MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
test1 = LOOKUP.findStatic(THIS_CLASS, "test1", MethodType.methodType(boolean.class, boolean.class));
|
||||
test2 = LOOKUP.findStatic(THIS_CLASS, "test2", MethodType.methodType(boolean.class, boolean.class));
|
||||
empty = LOOKUP.findStatic(THIS_CLASS, "empty", MethodType.methodType(void.class, boolean.class));
|
||||
} catch(Throwable e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean test1(boolean b) {
|
||||
return b;
|
||||
}
|
||||
static boolean test2(boolean b) {
|
||||
return true;
|
||||
}
|
||||
static void empty(boolean b) {}
|
||||
|
||||
static void test(boolean freqValue, boolean removeInlineBlocker) throws Throwable {
|
||||
MethodHandle innerGWT = MethodHandles.guardWithTest(test1, empty, empty);
|
||||
MethodHandle outerGWT = MethodHandles.guardWithTest(test2, innerGWT, innerGWT);
|
||||
|
||||
// Trigger compilation
|
||||
for (int i = 0; i < 20_000; i++) {
|
||||
outerGWT.invokeExact(freqValue);
|
||||
}
|
||||
|
||||
// Trigger deopt & nmethod invalidation
|
||||
outerGWT.invokeExact(!freqValue);
|
||||
|
||||
// Force inline blocker removal on rare-taken path
|
||||
if (removeInlineBlocker) {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
outerGWT.invokeExact(!freqValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger recompilation
|
||||
for (int i = 0; i < 20_000; i++) {
|
||||
outerGWT.invokeExact(freqValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
boolean freqValue = true;
|
||||
boolean removeInlineBlocker = false;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
test(freqValue, removeInlineBlocker);
|
||||
freqValue = !freqValue;
|
||||
removeInlineBlocker = !removeInlineBlocker;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -59,16 +59,19 @@ public class IntrinsicPredicates {
|
||||
};
|
||||
|
||||
public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE
|
||||
= new CPUSpecificPredicate("sparc.*", new String[] { "sha1" },
|
||||
null);
|
||||
= new OrPredicate(
|
||||
new CPUSpecificPredicate("sparc.*", new String[] { "sha1" },null),
|
||||
new CPUSpecificPredicate("aarch64.*", new String[] { "sha1" },null));
|
||||
|
||||
public static final BooleanSupplier SHA256_INSTRUCTION_AVAILABLE
|
||||
= new CPUSpecificPredicate("sparc.*", new String[] { "sha256" },
|
||||
null);
|
||||
= new OrPredicate(
|
||||
new CPUSpecificPredicate("sparc.*", new String[] { "sha256" },null),
|
||||
new CPUSpecificPredicate("aarch64.*", new String[] { "sha256" },null));
|
||||
|
||||
public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE
|
||||
= new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },
|
||||
null);
|
||||
= new OrPredicate(
|
||||
new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },null),
|
||||
new CPUSpecificPredicate("aarch64.*", new String[] { "sha512" },null));
|
||||
|
||||
public static final BooleanSupplier ANY_SHA_INSTRUCTION_AVAILABLE
|
||||
= new OrPredicate(IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE,
|
||||
|
@ -32,11 +32,15 @@
|
||||
* @run driver RandomGeneratorTest DIFFERENT_SEED
|
||||
*/
|
||||
|
||||
import jdk.test.lib.ProcessTools;
|
||||
import jdk.test.lib.Utils;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.OutputAnalyzer;
|
||||
import jdk.test.lib.ProcessTools;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
/**
|
||||
* The test verifies correctness of work {@link jdk.test.lib.Utils#getRandomInstance()}.
|
||||
@ -59,8 +63,13 @@ public class RandomGeneratorTest {
|
||||
jvmArgs.add(optStr);
|
||||
}
|
||||
jvmArgs.add(RandomRunner.class.getName());
|
||||
String origFileName = seedOpt.name() + "_orig";
|
||||
jvmArgs.add(origFileName);
|
||||
int fileNameIndex = jvmArgs.size() - 1;
|
||||
String[] cmdLineArgs = jvmArgs.toArray(new String[jvmArgs.size()]);
|
||||
String etalon = ProcessTools.executeTestJvm(cmdLineArgs).getStdout().trim();
|
||||
ProcessTools.executeTestJvm(cmdLineArgs).shouldHaveExitValue(0);
|
||||
String etalon = Utils.fileAsString(origFileName).trim();
|
||||
cmdLineArgs[fileNameIndex] = seedOpt.name();
|
||||
seedOpt.verify(etalon, cmdLineArgs);
|
||||
}
|
||||
|
||||
@ -121,26 +130,31 @@ public class RandomGeneratorTest {
|
||||
* @throws Throwable - Throws an exception in case test failure.
|
||||
*/
|
||||
public void verify(String orig, String[] cmdLine) {
|
||||
String lastLineOrig = getLastLine(orig);
|
||||
String lastLine;
|
||||
String output;
|
||||
OutputAnalyzer oa;
|
||||
try {
|
||||
lastLine = getLastLine(ProcessTools.executeTestJvm(cmdLine).getStdout().trim());
|
||||
oa = ProcessTools.executeTestJvm(cmdLine);
|
||||
} catch (Throwable t) {
|
||||
throw new Error("TESTBUG: Unexpedted exception during jvm execution.", t);
|
||||
}
|
||||
if (!isOutputExpected(lastLineOrig, lastLine)) {
|
||||
throw new AssertionError("Unexpected random number sequence for mode: " + this.name());
|
||||
oa.shouldHaveExitValue(0);
|
||||
try {
|
||||
output = Utils.fileAsString(name()).trim();
|
||||
} catch (IOException ioe) {
|
||||
throw new Error("TESTBUG: Problem during IO operation with file: " + name(), ioe);
|
||||
}
|
||||
if (!isOutputExpected(orig, output)) {
|
||||
System.err.println("Initial output: " + orig);
|
||||
System.err.println("Second run output: " + output);
|
||||
throw new AssertionError("Unexpected random number sequence for mode: " + this.name());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getLastLine(String output) {
|
||||
return output.substring(output.lastIndexOf(Utils.NEW_LINE)).trim();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The helper class generates several random numbers
|
||||
* and prints them out.
|
||||
* and put results to a file. The file name came as first
|
||||
* command line argument.
|
||||
*/
|
||||
public static class RandomRunner {
|
||||
private static final int COUNT = 10;
|
||||
@ -150,7 +164,11 @@ public class RandomGeneratorTest {
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
sb.append(rng.nextLong()).append(' ');
|
||||
}
|
||||
System.out.println(sb.toString());
|
||||
try (PrintWriter pw = new PrintWriter(new FileWriter(args[0]))) {
|
||||
pw.write(sb.toString());
|
||||
} catch (IOException ioe) {
|
||||
throw new Error("TESTBUG: Problem during IO operation with file: " + args[0], ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -312,3 +312,4 @@ ed94f3e7ba6bbfec0772de6d24e39543e13f6d88 jdk9-b65
|
||||
1abd45df5480a04bff98fba1851d66a5230e67d4 jdk9-b67
|
||||
046fd17bb9a0cdf6681124866df9626d17b0516a jdk9-b68
|
||||
551323004d0ce2f1d4b0e99552f7e0cdcebc6fca jdk9-b69
|
||||
a7f731125b7fb0e4b0186172f85a21e2d5139f7e jdk9-b70
|
||||
|
@ -26,6 +26,7 @@
|
||||
include GensrcCommon.gmk
|
||||
|
||||
include GensrcLocaleData.gmk
|
||||
include GensrcCLDR.gmk
|
||||
include GensrcCharacterData.gmk
|
||||
include GensrcMisc.gmk
|
||||
include GensrcCharsetMapping.gmk
|
||||
|
@ -23,19 +23,30 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
CLDRVERSION := 21.0.1
|
||||
CLDRVERSION := 27.0.0
|
||||
CLDRSRCDIR := $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/cldr/resources/$(subst .,_,$(CLDRVERSION))
|
||||
|
||||
GENSRC_BASEDIR := $(SUPPORT_OUTPUTDIR)/gensrc/java.base
|
||||
GENSRC_DIR := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata
|
||||
|
||||
CLDR_METAINFO_FILE := $(GENSRC_DIR)/sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo.java
|
||||
CLDR_BASEMETAINFO_FILE := $(GENSRC_DIR)/sun/util/cldr/CLDRBaseLocaleDataMetaInfo.java
|
||||
CLDR_METAINFO_FILE := $(GENSRC_DIR)/sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo_jdk_localedata.java
|
||||
|
||||
CLDR_BASE_LOCALES := "en-US"
|
||||
|
||||
$(CLDR_BASEMETAINFO_FILE): $(wildcard $(CLDRSRCDIR)/common/dtd/*.dtd) \
|
||||
$(wildcard $(CLDRSRCDIR)/common/main/en*.xml) \
|
||||
$(wildcard $(CLDRSRCDIR)/common/supplemental/*.xml) \
|
||||
$(BUILD_TOOLS_JDK)
|
||||
$(MKDIR) -p $(GENSRC_BASEDIR)
|
||||
$(TOOL_CLDRCONVERTER) -base $(CLDRSRCDIR) -baselocales $(CLDR_BASE_LOCALES) -basemodule -o $(GENSRC_BASEDIR)
|
||||
|
||||
$(CLDR_METAINFO_FILE): $(wildcard $(CLDRSRCDIR)/common/dtd/*.dtd) \
|
||||
$(wildcard $(CLDRSRCDIR)/common/main/*.xml) \
|
||||
$(wildcard $(CLDRSRCDIR)/common/supplemental/*.xml) \
|
||||
$(BUILD_TOOLS_JDK)
|
||||
$(MKDIR) -p $(GENSRC_DIR)
|
||||
$(TOOL_CLDRCONVERTER) -base $(CLDRSRCDIR) -o $(GENSRC_DIR)
|
||||
$(TOOL_CLDRCONVERTER) -base $(CLDRSRCDIR) -baselocales $(CLDR_BASE_LOCALES) -o $(GENSRC_DIR)
|
||||
|
||||
GENSRC_CLDR := $(CLDR_METAINFO_FILE)
|
||||
GENSRC_JDK_LOCALEDATA += $(GENSRC_CLDR)
|
||||
GENSRC_JAVA_BASE += $(CLDR_BASEMETAINFO_FILE)
|
||||
GENSRC_JDK_LOCALEDATA += $(CLDR_METAINFO_FILE)
|
||||
|
@ -42,51 +42,54 @@ LOCALE_FILES := $(shell $(FIND) $(JDK_TOPDIR)/src/java.base/share/classes \
|
||||
LOCALE_RESOURCES := $(sort $(subst .properties,,$(subst .java,,$(notdir $(LOCALE_FILES)))))
|
||||
|
||||
# Include the list of resources found during the previous compile.
|
||||
-include $(SUPPORT_OUTPUTDIR)/gensrc/java.base/_the.locale_resources
|
||||
-include $(SUPPORT_OUTPUTDIR)/gensrc/_the.locale_resources
|
||||
|
||||
MISSING_RESOURCES := $(filter-out $(LOCALE_RESOURCES), $(PREV_LOCALE_RESOURCES))
|
||||
NEW_RESOURCES := $(filter-out $(PREV_LOCALE_RESOURCES), $(LOCALE_RESOURCES))
|
||||
|
||||
ifneq (, $(MISSING_RESOURCES)$(NEW_RESOURCES))
|
||||
# There is a difference in the number of supported resources. Trigger a regeneration.
|
||||
$(shell $(RM) $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/LocaleDataMetaInfo.java)
|
||||
$(shell $(RM) $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/BaseLocaleDataMetaInfo.java \
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonBaseLocaleDataMetaInfo.java \
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/util/cldr/CLDRBaseLocaleDataMetaInfo.java \
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo_jdk_localedata.java)
|
||||
endif
|
||||
|
||||
# The EN locales
|
||||
EN_LOCALES := en%
|
||||
# The base locales
|
||||
BASE_LOCALES := en en-US
|
||||
|
||||
# Locales that don't have any resource files should be included here.
|
||||
ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
|
||||
ALL_NON_BASE_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
|
||||
|
||||
SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
|
||||
SED_NONENARGS := $(SED_ENARGS)
|
||||
SED_BASEARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
|
||||
SED_NONBASEARGS := $(SED_BASEARGS)
|
||||
|
||||
# Fill in the languages and package names
|
||||
SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \
|
||||
SED_BASEARGS += -e 's/$(HASH)Lang$(HASH)/Base/' \
|
||||
-e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/'
|
||||
SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \
|
||||
SED_NONBASEARGS += -e 's/$(HASH)Lang$(HASH)/NonBase/' \
|
||||
-e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/'
|
||||
|
||||
# This macro creates a sed expression that substitues for example:
|
||||
# #FormatData_ENLocales# with: en% locales.
|
||||
# #FormatData_Locales# with: en-US locales.
|
||||
define CaptureLocale
|
||||
$1_LOCALES := $$(subst _,-,$$(filter-out $1, $$(subst $1_,,$$(filter $1_%, $(LOCALE_RESOURCES)))))
|
||||
$1_EN_LOCALES := $$(filter $(EN_LOCALES), $$($1_LOCALES))
|
||||
$1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES), $$($1_LOCALES))
|
||||
$1_BASE_LOCALES := $$(filter $(BASE_LOCALES), $$($1_LOCALES))
|
||||
$1_NON_BASE_LOCALES := $$(filter-out $(BASE_LOCALES), $$($1_LOCALES))
|
||||
|
||||
# Special handling for Chinese locales to include implicit scripts
|
||||
$1_NON_EN_LOCALES := $$(subst zh-CN,zh-CN$$(SPACE)zh-Hans-CN, $$($1_NON_EN_LOCALES))
|
||||
$1_NON_EN_LOCALES := $$(subst zh-SG,zh-SG$$(SPACE)zh-Hans-SG, $$($1_NON_EN_LOCALES))
|
||||
$1_NON_EN_LOCALES := $$(subst zh-HK,zh-HK$$(SPACE)zh-Hant-HK, $$($1_NON_EN_LOCALES))
|
||||
$1_NON_EN_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_EN_LOCALES))
|
||||
$1_NON_EN_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_EN_LOCALES))
|
||||
$1_NON_BASE_LOCALES := $$(subst zh-CN,zh-CN$$(SPACE)zh-Hans-CN, $$($1_NON_BASE_LOCALES))
|
||||
$1_NON_BASE_LOCALES := $$(subst zh-SG,zh-SG$$(SPACE)zh-Hans-SG, $$($1_NON_BASE_LOCALES))
|
||||
$1_NON_BASE_LOCALES := $$(subst zh-HK,zh-HK$$(SPACE)zh-Hant-HK, $$($1_NON_BASE_LOCALES))
|
||||
$1_NON_BASE_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_BASE_LOCALES))
|
||||
$1_NON_BASE_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_BASE_LOCALES))
|
||||
|
||||
ALL_EN_LOCALES += $$($1_EN_LOCALES)
|
||||
ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES)
|
||||
ALL_BASE_LOCALES += $$($1_BASE_LOCALES)
|
||||
ALL_NON_BASE_LOCALES += $$($1_NON_BASE_LOCALES)
|
||||
|
||||
# Don't sed in a space if there are no locales.
|
||||
SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
|
||||
SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
|
||||
SED_BASEARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_BASE_LOCALES),$$(SPACE)$$($1_BASE_LOCALES),)/g'
|
||||
SED_NONBASEARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_BASE_LOCALES),$$(SPACE)$$($1_NON_BASE_LOCALES),)/g'
|
||||
endef
|
||||
|
||||
#sun.text.resources.FormatData
|
||||
@ -113,27 +116,27 @@ $(eval $(call CaptureLocale,CurrencyNames))
|
||||
#sun.util.resources.CalendarData
|
||||
$(eval $(call CaptureLocale,CalendarData))
|
||||
|
||||
SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
|
||||
SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
|
||||
SED_BASEARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_BASE_LOCALES))/g'
|
||||
SED_NONBASEARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_BASE_LOCALES))/g'
|
||||
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/BaseLocaleDataMetaInfo.java: \
|
||||
$(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
|
||||
$(MKDIR) -p $(@D)
|
||||
$(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
|
||||
$(ECHO) Creating sun/util/locale/provider/BaseLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
|
||||
$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" \
|
||||
> $(SUPPORT_OUTPUTDIR)/gensrc/_the.locale_resources
|
||||
$(SED) $(SED_ENARGS) $< > $@
|
||||
$(SED) $(SED_BASEARGS) $< > $@
|
||||
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonBaseLocaleDataMetaInfo.java: \
|
||||
$(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
|
||||
$(MKDIR) -p $(@D)
|
||||
$(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
|
||||
$(ECHO) Creating sun/util/resources/provider/NonBaseLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
|
||||
$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" \
|
||||
> $(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata/_the.locale_resources
|
||||
$(SED) $(SED_NONENARGS) $< > $@
|
||||
> $(SUPPORT_OUTPUTDIR)/gensrc/_the.locale_resources
|
||||
$(SED) $(SED_NONBASEARGS) $< > $@
|
||||
|
||||
GENSRC_BASELOCALEDATA := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java
|
||||
GENSRC_LOCALEDATA := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java
|
||||
GENSRC_BASELOCALEDATA := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/BaseLocaleDataMetaInfo.java
|
||||
GENSRC_LOCALEDATA := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonBaseLocaleDataMetaInfo.java
|
||||
|
||||
################################################################################
|
||||
|
||||
|
@ -161,7 +161,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
|
||||
-export:getLastErrorString \
|
||||
jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \
|
||||
shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \
|
||||
advapi32.lib, \
|
||||
advapi32.lib version.lib, \
|
||||
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
|
||||
RC_FLAGS := $(RC_FLAGS) \
|
||||
-D "JDK_FNAME=java.dll" \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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
|
||||
@ -121,6 +121,15 @@ abstract class AbstractLDMLHandler<V> extends DefaultHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* start an element that defines an alias entry, with the value provided by the element's alias.
|
||||
*/
|
||||
void pushAliasEntry(String qName, Attributes attributes, String key) {
|
||||
if (!pushIfIgnored(qName, attributes)) {
|
||||
currentContainer = new AliasEntry(qName, currentContainer, key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* start an element that defines a string entry, with the value provided by an attribute value.
|
||||
*/
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 build.tools.cldrconverter;
|
||||
|
||||
class AliasEntry extends StringEntry {
|
||||
AliasEntry(String qName, Container parent, String key) {
|
||||
super(qName, parent, key);
|
||||
}
|
||||
|
||||
AliasEntry(String qName, Container parent, String key, String value) {
|
||||
super(qName, parent, key, value);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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
|
||||
@ -32,6 +32,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
class Bundle {
|
||||
static enum Type {
|
||||
@ -81,7 +82,10 @@ class Bundle {
|
||||
};
|
||||
|
||||
private final static String[] DATETIME_PATTERN_KEYS = {
|
||||
"DateTimePatterns/date-time"
|
||||
"DateTimePatterns/full-dateTime",
|
||||
"DateTimePatterns/long-dateTime",
|
||||
"DateTimePatterns/medium-dateTime",
|
||||
"DateTimePatterns/short-dateTime",
|
||||
};
|
||||
|
||||
private final static String[] ERA_KEYS = {
|
||||
@ -170,6 +174,7 @@ class Bundle {
|
||||
for (index = 0; index < cldrBundles.length; index++) {
|
||||
if (cldrBundles[index].equals(id)) {
|
||||
myMap.putAll(CLDRConverter.getCLDRBundle(cldrBundles[index]));
|
||||
CLDRConverter.handleAliases(myMap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -179,10 +184,11 @@ class Bundle {
|
||||
for (int i = cldrBundles.length - 1; i > index; i--) {
|
||||
if (!("no".equals(cldrBundles[i]) || cldrBundles[i].startsWith("no_"))) {
|
||||
parentsMap.putAll(CLDRConverter.getCLDRBundle(cldrBundles[i]));
|
||||
CLDRConverter.handleAliases(parentsMap);
|
||||
}
|
||||
}
|
||||
// Duplicate myMap as parentsMap for "root" so that the
|
||||
// fallback works. This is a huck, though.
|
||||
// fallback works. This is a hack, though.
|
||||
if ("root".equals(cldrBundles[0])) {
|
||||
assert parentsMap.isEmpty();
|
||||
parentsMap.putAll(myMap);
|
||||
@ -370,6 +376,17 @@ class Bundle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all duplicates
|
||||
if (Objects.nonNull(parentsMap)) {
|
||||
for (Iterator<String> it = myMap.keySet().iterator(); it.hasNext();) {
|
||||
String key = it.next();
|
||||
if (Objects.deepEquals(parentsMap.get(key), myMap.get(key))) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return myMap;
|
||||
}
|
||||
|
||||
@ -506,11 +523,6 @@ class Bundle {
|
||||
if (patterns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (String p : patterns) {
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String key = calendarPrefix + name;
|
||||
if (!rawPatterns.equals(patterns)) {
|
||||
myMap.put("java.time." + key, rawPatterns.toArray(new String[len]));
|
||||
@ -630,7 +642,9 @@ class Bundle {
|
||||
if (name.contains("Standard Time")) {
|
||||
name = name.replace("Standard Time", "Daylight Time");
|
||||
} else if (name.endsWith("Mean Time")) {
|
||||
if (!name.startsWith("Greenwich ")) {
|
||||
name = name.replace("Mean Time", "Summer Time");
|
||||
}
|
||||
} else if (name.endsWith(" Time")) {
|
||||
name = name.replace(" Time", " Summer Time");
|
||||
}
|
||||
@ -644,8 +658,10 @@ class Bundle {
|
||||
if (name.endsWith("Standard Time")) {
|
||||
name = name.replace("Standard Time", "Time");
|
||||
} else if (name.endsWith("Mean Time")) {
|
||||
if (!name.startsWith("Greenwich ")) {
|
||||
name = name.replace("Mean Time", "Time");
|
||||
}
|
||||
}
|
||||
map.put(TZ_GEN_LONG_KEY, name);
|
||||
fillInAbbrs(TZ_GEN_LONG_KEY, TZ_GEN_SHORT_KEY, map);
|
||||
}
|
||||
@ -712,6 +728,15 @@ class Bundle {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
// 'l' is deprecated as a pattern character. Should be ignored.
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
// Use 'y' for now.
|
||||
appendN('y', count, sb);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
appendN('z', count, sb);
|
||||
@ -723,16 +748,14 @@ class Bundle {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
case 'q':
|
||||
case 'Q':
|
||||
case 'l':
|
||||
case 'g':
|
||||
case 'j':
|
||||
case 'A':
|
||||
throw new InternalError(String.format("Unsupported letter: '%c', count=%d%n",
|
||||
cldrLetter, count));
|
||||
throw new InternalError(String.format("Unsupported letter: '%c', count=%d, id=%s%n",
|
||||
cldrLetter, count, id));
|
||||
default:
|
||||
appendN(cldrLetter, count, sb);
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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
|
||||
@ -32,6 +32,9 @@ import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.ResourceBundle.Control;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
@ -64,12 +67,22 @@ public class CLDRConverter {
|
||||
static final String TIMEZONE_ID_PREFIX = "timezone.id.";
|
||||
static final String ZONE_NAME_PREFIX = "timezone.displayname.";
|
||||
static final String METAZONE_ID_PREFIX = "metazone.id.";
|
||||
static final String PARENT_LOCALE_PREFIX = "parentLocale.";
|
||||
|
||||
private static SupplementDataParseHandler handlerSuppl;
|
||||
static NumberingSystemsParseHandler handlerNumbering;
|
||||
static MetaZonesParseHandler handlerMetaZones;
|
||||
private static BundleGenerator bundleGenerator;
|
||||
|
||||
// java.base module related
|
||||
static boolean isBaseModule = false;
|
||||
static final Set<Locale> BASE_LOCALES = new HashSet<>();
|
||||
|
||||
// "parentLocales" map
|
||||
private static final Map<String, SortedSet<String>> parentLocalesMap = new HashMap<>();
|
||||
private static final ResourceBundle.Control defCon =
|
||||
ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
|
||||
|
||||
static enum DraftType {
|
||||
UNCONFIRMED,
|
||||
PROVISIONAL,
|
||||
@ -142,6 +155,16 @@ public class CLDRConverter {
|
||||
}
|
||||
break;
|
||||
|
||||
case "-baselocales":
|
||||
// base locales
|
||||
setupBaseLocales(args[++i]);
|
||||
break;
|
||||
|
||||
case "-basemodule":
|
||||
// indicates java.base module resource generation
|
||||
isBaseModule = true;
|
||||
break;
|
||||
|
||||
case "-o":
|
||||
// output directory
|
||||
DESTINATION_DIR = args[++i];
|
||||
@ -179,8 +202,15 @@ public class CLDRConverter {
|
||||
NUMBERING_SOURCE_FILE = CLDR_BASE + "common/supplemental/numberingSystems.xml";
|
||||
METAZONES_SOURCE_FILE = CLDR_BASE + "common/supplemental/metaZones.xml";
|
||||
|
||||
if (BASE_LOCALES.isEmpty()) {
|
||||
setupBaseLocales("en-US");
|
||||
}
|
||||
|
||||
bundleGenerator = new ResourceBundleGenerator();
|
||||
|
||||
// Parse data independent of locales
|
||||
parseSupplemental();
|
||||
|
||||
List<Bundle> bundles = readBundleList();
|
||||
convertBundles(bundles);
|
||||
}
|
||||
@ -192,6 +222,9 @@ public class CLDRConverter {
|
||||
+ "\t-draft [approved | provisional | unconfirmed]%n"
|
||||
+ "\t\t draft level for using data (default: approved)%n"
|
||||
+ "\t-base dir base directory for CLDR input files%n"
|
||||
+ "\t-basemodule generates bundles that go into java.base module%n"
|
||||
+ "\t-baselocales loc(,loc)* locales that go into the base module%n"
|
||||
+ "\t-o dir output directory (default: ./build/gensrc)%n"
|
||||
+ "\t-o dir output directory (defaut: ./build/gensrc)%n"
|
||||
+ "\t-utf8 use UTF-8 rather than \\uxxxx (for debug)%n");
|
||||
}
|
||||
@ -248,7 +281,6 @@ public class CLDRConverter {
|
||||
}
|
||||
|
||||
private static List<Bundle> readBundleList() throws Exception {
|
||||
ResourceBundle.Control defCon = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
|
||||
List<Bundle> retList = new ArrayList<>();
|
||||
Path path = FileSystems.getDefault().getPath(SOURCE_FILE_DIR);
|
||||
try (DirectoryStream<Path> dirStr = Files.newDirectoryStream(path)) {
|
||||
@ -257,7 +289,7 @@ public class CLDRConverter {
|
||||
if (fileName.endsWith(".xml")) {
|
||||
String id = fileName.substring(0, fileName.indexOf('.'));
|
||||
Locale cldrLoc = Locale.forLanguageTag(toLanguageTag(id));
|
||||
List<Locale> candList = defCon.getCandidateLocales("", cldrLoc);
|
||||
List<Locale> candList = applyParentLocales("", defCon.getCandidateLocales("", cldrLoc));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Locale loc : candList) {
|
||||
if (!loc.equals(Locale.ROOT)) {
|
||||
@ -269,9 +301,9 @@ public class CLDRConverter {
|
||||
sb.append("root");
|
||||
}
|
||||
Bundle b = new Bundle(id, sb.toString(), null, null);
|
||||
// Insert the bundle for en at the top so that it will get
|
||||
// Insert the bundle for root at the top so that it will get
|
||||
// processed first.
|
||||
if ("en".equals(id)) {
|
||||
if ("root".equals(id)) {
|
||||
retList.add(0, b);
|
||||
} else {
|
||||
retList.add(b);
|
||||
@ -282,7 +314,7 @@ public class CLDRConverter {
|
||||
return retList;
|
||||
}
|
||||
|
||||
private static Map<String, Map<String, Object>> cldrBundles = new HashMap<>();
|
||||
private static final Map<String, Map<String, Object>> cldrBundles = new HashMap<>();
|
||||
|
||||
static Map<String, Object> getCLDRBundle(String id) throws Exception {
|
||||
Map<String, Object> bundle = cldrBundles.get(id);
|
||||
@ -319,12 +351,19 @@ public class CLDRConverter {
|
||||
return bundle;
|
||||
}
|
||||
|
||||
private static void convertBundles(List<Bundle> bundles) throws Exception {
|
||||
// Parsers for data in "supplemental" directory
|
||||
//
|
||||
private static void parseSupplemental() throws Exception {
|
||||
// Parse SupplementalData file and store the information in the HashMap
|
||||
// Calendar information such as firstDay and minDay are stored in
|
||||
// supplementalData.xml as of CLDR1.4. Individual territory is listed
|
||||
// with its ISO 3166 country code while default is listed using UNM49
|
||||
// region and composition numerical code (001 for World.)
|
||||
//
|
||||
// SupplementalData file also provides the "parent" locales which
|
||||
// are othrwise not to be fallen back. Process them here as well.
|
||||
//
|
||||
info("..... Parsing supplementalData.xml .....");
|
||||
SAXParserFactory factorySuppl = SAXParserFactory.newInstance();
|
||||
factorySuppl.setValidating(true);
|
||||
SAXParser parserSuppl = factorySuppl.newSAXParser();
|
||||
@ -332,8 +371,14 @@ public class CLDRConverter {
|
||||
handlerSuppl = new SupplementDataParseHandler();
|
||||
File fileSupply = new File(SPPL_SOURCE_FILE);
|
||||
parserSuppl.parse(fileSupply, handlerSuppl);
|
||||
Map<String, Object> parentData = handlerSuppl.getData("root");
|
||||
parentData.keySet().forEach(key -> {
|
||||
parentLocalesMap.put(key, new TreeSet(
|
||||
Arrays.asList(((String)parentData.get(key)).split(" "))));
|
||||
});
|
||||
|
||||
// Parse numberingSystems to get digit zero character information.
|
||||
info("..... Parsing numberingSystem.xml .....");
|
||||
SAXParserFactory numberingParser = SAXParserFactory.newInstance();
|
||||
numberingParser.setValidating(true);
|
||||
SAXParser parserNumbering = numberingParser.newSAXParser();
|
||||
@ -343,6 +388,7 @@ public class CLDRConverter {
|
||||
parserNumbering.parse(fileNumbering, handlerNumbering);
|
||||
|
||||
// Parse metaZones to create mappings between Olson tzids and CLDR meta zone names
|
||||
info("..... Parsing metaZones.xml .....");
|
||||
SAXParserFactory metazonesParser = SAXParserFactory.newInstance();
|
||||
metazonesParser.setValidating(true);
|
||||
SAXParser parserMetaZones = metazonesParser.newSAXParser();
|
||||
@ -350,14 +396,23 @@ public class CLDRConverter {
|
||||
handlerMetaZones = new MetaZonesParseHandler();
|
||||
File fileMetaZones = new File(METAZONES_SOURCE_FILE);
|
||||
parserNumbering.parse(fileMetaZones, handlerMetaZones);
|
||||
}
|
||||
|
||||
private static void convertBundles(List<Bundle> bundles) throws Exception {
|
||||
// For generating information on supported locales.
|
||||
Map<String, SortedSet<String>> metaInfo = new HashMap<>();
|
||||
metaInfo.put("LocaleNames", new TreeSet<String>());
|
||||
metaInfo.put("CurrencyNames", new TreeSet<String>());
|
||||
metaInfo.put("TimeZoneNames", new TreeSet<String>());
|
||||
metaInfo.put("CalendarData", new TreeSet<String>());
|
||||
metaInfo.put("FormatData", new TreeSet<String>());
|
||||
metaInfo.put("LocaleNames", new TreeSet<>());
|
||||
metaInfo.put("CurrencyNames", new TreeSet<>());
|
||||
metaInfo.put("TimeZoneNames", new TreeSet<>());
|
||||
metaInfo.put("CalendarData", new TreeSet<>());
|
||||
metaInfo.put("FormatData", new TreeSet<>());
|
||||
metaInfo.put("AvailableLocales", new TreeSet<>());
|
||||
|
||||
// parent locales map. The mappings are put in base metaInfo file
|
||||
// for now.
|
||||
if (isBaseModule) {
|
||||
metaInfo.putAll(parentLocalesMap);
|
||||
}
|
||||
|
||||
for (Bundle bundle : bundles) {
|
||||
// Get the target map, which contains all the data that should be
|
||||
@ -367,21 +422,7 @@ public class CLDRConverter {
|
||||
|
||||
EnumSet<Bundle.Type> bundleTypes = bundle.getBundleTypes();
|
||||
|
||||
// Fill in any missing resources in the base bundle from en and en-US data.
|
||||
// This is because CLDR root.xml is supposed to be language neutral and doesn't
|
||||
// provide some resource data. Currently, the runtime assumes that there are all
|
||||
// resources though the parent resource bundle chain.
|
||||
if (bundle.isRoot()) {
|
||||
Map<String, Object> enData = new HashMap<>();
|
||||
// Create a superset of en-US and en bundles data in order to
|
||||
// fill in any missing resources in the base bundle.
|
||||
enData.putAll(Bundle.getBundle("en").getTargetMap());
|
||||
enData.putAll(Bundle.getBundle("en_US").getTargetMap());
|
||||
for (String key : enData.keySet()) {
|
||||
if (!targetMap.containsKey(key)) {
|
||||
targetMap.put(key, enData.get(key));
|
||||
}
|
||||
}
|
||||
// Add DateTimePatternChars because CLDR no longer supports localized patterns.
|
||||
targetMap.put("DateTimePatternChars", "GyMdkHmsSEDFwWahKzZ");
|
||||
}
|
||||
@ -418,60 +459,56 @@ public class CLDRConverter {
|
||||
}
|
||||
if (bundleTypes.contains(Bundle.Type.FORMATDATA)) {
|
||||
Map<String, Object> formatDataMap = extractFormatData(targetMap, bundle.getID());
|
||||
// LocaleData.getAvailableLocales depends on having FormatData bundles around
|
||||
if (!formatDataMap.isEmpty() || bundle.isRoot()) {
|
||||
metaInfo.get("FormatData").add(toLanguageTag(bundle.getID()));
|
||||
bundleGenerator.generateBundle("text", "FormatData", bundle.getID(), true, formatDataMap, BundleType.PLAIN);
|
||||
}
|
||||
}
|
||||
|
||||
// For testing
|
||||
SortedSet<String> allLocales = new TreeSet<>();
|
||||
allLocales.addAll(metaInfo.get("CurrencyNames"));
|
||||
allLocales.addAll(metaInfo.get("LocaleNames"));
|
||||
allLocales.addAll(metaInfo.get("CalendarData"));
|
||||
allLocales.addAll(metaInfo.get("FormatData"));
|
||||
metaInfo.put("AvailableLocales", allLocales);
|
||||
// For AvailableLocales
|
||||
metaInfo.get("AvailableLocales").add(toLanguageTag(bundle.getID()));
|
||||
}
|
||||
|
||||
bundleGenerator.generateMetaInfo(metaInfo);
|
||||
}
|
||||
|
||||
static final Map<String, String> aliases = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Translate the aliases into the real entries in the bundle map.
|
||||
*/
|
||||
static void handleAliases(Map<String, Object> bundleMap) {
|
||||
Set bundleKeys = bundleMap.keySet();
|
||||
try {
|
||||
for (String key : aliases.keySet()) {
|
||||
String targetKey = aliases.get(key);
|
||||
if (bundleKeys.contains(targetKey)) {
|
||||
bundleMap.putIfAbsent(key, bundleMap.get(targetKey));
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(CLDRConverter.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the language portion of the given id.
|
||||
* If id is "root", "" is returned.
|
||||
*/
|
||||
static String getLanguageCode(String id) {
|
||||
int index = id.indexOf('_');
|
||||
String lang = null;
|
||||
if (index != -1) {
|
||||
lang = id.substring(0, index);
|
||||
} else {
|
||||
lang = "root".equals(id) ? "" : id;
|
||||
}
|
||||
return lang;
|
||||
return "root".equals(id) ? "" : Locale.forLanguageTag(id.replaceAll("_", "-")).getLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine if the id includes the country (territory) code. If it does, it returns
|
||||
* the country code.
|
||||
* Otherwise, it returns null. eg. when the id is "zh_Hans_SG", it return "SG".
|
||||
* For now, it does not return US M.49 code, e.g., '001', as those three digit numbers cannot
|
||||
* be translated into package names.
|
||||
*/
|
||||
private static String getCountryCode(String id) {
|
||||
//Truncate a variant code with '@' if there is any
|
||||
//(eg. de_DE@collation=phonebook,currency=DOM)
|
||||
if (id.indexOf('@') != -1) {
|
||||
id = id.substring(0, id.indexOf('@'));
|
||||
}
|
||||
String[] tokens = id.split("_");
|
||||
for (int index = 1; index < tokens.length; ++index) {
|
||||
if (tokens[index].length() == 2
|
||||
&& Character.isLetter(tokens[index].charAt(0))
|
||||
&& Character.isLetter(tokens[index].charAt(1))) {
|
||||
return tokens[index];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
static String getCountryCode(String id) {
|
||||
String ctry = Locale.forLanguageTag(id.replaceAll("_", "-")).getCountry();
|
||||
return ctry.length() == 2 ? ctry : null;
|
||||
}
|
||||
|
||||
private static class KeyComparator implements Comparator<String> {
|
||||
@ -598,6 +635,9 @@ public class CLDRConverter {
|
||||
private static Map<String, Object> extractFormatData(Map<String, Object> map, String id) {
|
||||
Map<String, Object> formatData = new LinkedHashMap<>();
|
||||
for (CalendarType calendarType : CalendarType.values()) {
|
||||
if (calendarType == CalendarType.GENERIC) {
|
||||
continue;
|
||||
}
|
||||
String prefix = calendarType.keyElementName();
|
||||
for (String element : FORMAT_DATA_ELEMENTS) {
|
||||
String key = prefix + element;
|
||||
@ -605,28 +645,15 @@ public class CLDRConverter {
|
||||
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()) {
|
||||
// Copy available calendar names
|
||||
if (key.startsWith(CLDRConverter.CALENDAR_NAME_PREFIX)) {
|
||||
String type = key.substring(CLDRConverter.CALENDAR_NAME_PREFIX.length());
|
||||
for (CalendarType calendarType : CalendarType.values()) {
|
||||
if (calendarType == CalendarType.GENERIC) {
|
||||
continue;
|
||||
}
|
||||
if (type.equals(calendarType.lname())) {
|
||||
Object value = map.get(key);
|
||||
formatData.put(key, value);
|
||||
@ -745,4 +772,43 @@ public class CLDRConverter {
|
||||
}
|
||||
return tag.replaceAll("-", "_");
|
||||
}
|
||||
|
||||
private static void setupBaseLocales(String localeList) {
|
||||
Arrays.stream(localeList.split(","))
|
||||
.map(Locale::forLanguageTag)
|
||||
.map(l -> Control.getControl(Control.FORMAT_DEFAULT)
|
||||
.getCandidateLocales("", l))
|
||||
.forEach(BASE_LOCALES::addAll);
|
||||
}
|
||||
|
||||
// applying parent locale rules to the passed candidates list
|
||||
// This has to match with the one in sun.util.cldr.CLDRLocaleProviderAdapter
|
||||
private static Map<Locale, Locale> childToParentLocaleMap = null;
|
||||
private static List<Locale> applyParentLocales(String baseName, List<Locale> candidates) {
|
||||
if (Objects.isNull(childToParentLocaleMap)) {
|
||||
childToParentLocaleMap = new HashMap<>();
|
||||
parentLocalesMap.keySet().forEach(key -> {
|
||||
String parent = key.substring(PARENT_LOCALE_PREFIX.length()).replaceAll("_", "-");
|
||||
parentLocalesMap.get(key).stream().forEach(child -> {
|
||||
childToParentLocaleMap.put(Locale.forLanguageTag(child),
|
||||
"root".equals(parent) ? Locale.ROOT : Locale.forLanguageTag(parent));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// check irregular parents
|
||||
for (int i = 0; i < candidates.size(); i++) {
|
||||
Locale l = candidates.get(i);
|
||||
Locale p = childToParentLocaleMap.get(l);
|
||||
if (!l.equals(Locale.ROOT) &&
|
||||
Objects.nonNull(p) &&
|
||||
!candidates.get(i+1).equals(p)) {
|
||||
List<Locale> applied = candidates.subList(0, i+1);
|
||||
applied.addAll(applyParentLocales(baseName, defCon.getCandidateLocales(baseName, p)));
|
||||
return applied;
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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,19 +29,21 @@ import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Constants for the Calendars supported by JRE.
|
||||
* Note that "GENERIC" calendar data will NOT be extracted to JDK's ResourceBundles.
|
||||
*/
|
||||
enum CalendarType {
|
||||
GREGORIAN("gregory"), BUDDHIST, JAPANESE, ROC,
|
||||
ISLAMIC, ISLAMIC_CIVIL("islamicc"), ISLAMIC_UMALQURA("islamic-umalqura");
|
||||
GENERIC, GREGORIAN("gregory"), BUDDHIST, JAPANESE, ROC,
|
||||
ISLAMIC, ISLAMIC_CIVIL("islamic-civil"), ISLAMIC_UMALQURA("islamic-umalqura");
|
||||
|
||||
private static final int[][] ERA_DATA = {
|
||||
// start index, array length
|
||||
{0, 2}, // generic
|
||||
{0, 2}, // gregorian
|
||||
{0, 1}, // buddhist
|
||||
{232, 4}, // japanese (eras from Meiji)
|
||||
{0, 2}, // roc (Minguo)
|
||||
{0, 1}, // islamic (Hijrah)
|
||||
{0, 1}, // islamicc (same as islamic)
|
||||
{0, 1}, // islamic-civil (same as islamic)
|
||||
{0, 1}, // islamic-umalqura
|
||||
};
|
||||
|
||||
@ -87,7 +89,7 @@ enum CalendarType {
|
||||
|
||||
static CalendarType forName(String name) {
|
||||
for (CalendarType type : values()) {
|
||||
if (type.lname.equals(name)) {
|
||||
if (type.lname.equals(name) || type.uname.equals(name)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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
|
||||
@ -41,41 +41,46 @@ class CopyrightHeaders {
|
||||
" * Copyright (c) 2012, %d, Oracle and/or its affiliates. All rights reserved.\n" +
|
||||
" */\n";
|
||||
|
||||
// Last updated: - 1/16/2015, 1:42:31 PM
|
||||
private static final String UNICODE =
|
||||
"/*\n" +
|
||||
" * COPYRIGHT AND PERMISSION NOTICE\n" +
|
||||
" *\n" +
|
||||
" * Copyright (C) 1991-2012 Unicode, Inc. All rights reserved. Distributed under\n" +
|
||||
" * the Terms of Use in http://www.unicode.org/copyright.html.\n" +
|
||||
" * Copyright (C) 1991-2015 Unicode, Inc. All rights reserved.\n" +
|
||||
" * Distributed under the Terms of Use in \n" +
|
||||
" * http://www.unicode.org/copyright.html.\n" +
|
||||
" *\n" +
|
||||
" * Permission is hereby granted, free of charge, to any person obtaining a copy\n" +
|
||||
" * of the Unicode data files and any associated documentation (the \"Data\n" +
|
||||
" * Files\") or Unicode software and any associated documentation (the\n" +
|
||||
" * \"Software\") to deal in the Data Files or Software without restriction,\n" +
|
||||
" * including without limitation the rights to use, copy, modify, merge,\n" +
|
||||
" * publish, distribute, and/or sell copies of the Data Files or Software, and\n" +
|
||||
" * to permit persons to whom the Data Files or Software are furnished to do so,\n" +
|
||||
" * provided that (a) the above copyright notice(s) and this permission notice\n" +
|
||||
" * appear with all copies of the Data Files or Software, (b) both the above\n" +
|
||||
" * copyright notice(s) and this permission notice appear in associated\n" +
|
||||
" * documentation, and (c) there is clear notice in each modified Data File or\n" +
|
||||
" * in the Software as well as in the documentation associated with the Data\n" +
|
||||
" * File(s) or Software that the data or software has been modified.\n" +
|
||||
" * Permission is hereby granted, free of charge, to any person obtaining\n" +
|
||||
" * a copy of the Unicode data files and any associated documentation\n" +
|
||||
" * (the \"Data Files\") or Unicode software and any associated documentation\n" +
|
||||
" * (the \"Software\") to deal in the Data Files or Software\n" +
|
||||
" * without restriction, including without limitation the rights to use,\n" +
|
||||
" * copy, modify, merge, publish, distribute, and/or sell copies of\n" +
|
||||
" * the Data Files or Software, and to permit persons to whom the Data Files\n" +
|
||||
" * or Software are furnished to do so, provided that\n" +
|
||||
" * (a) this copyright and permission notice appear with all copies \n" +
|
||||
" * of the Data Files or Software,\n" +
|
||||
" * (b) this copyright and permission notice appear in associated \n" +
|
||||
" * documentation, and\n" +
|
||||
" * (c) there is clear notice in each modified Data File or in the Software\n" +
|
||||
" * as well as in the documentation associated with the Data File(s) or\n" +
|
||||
" * Software that the data or software has been modified.\n" +
|
||||
" *\n" +
|
||||
" * THE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n" +
|
||||
" * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n" +
|
||||
" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF\n" +
|
||||
" * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS\n" +
|
||||
" * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR\n" +
|
||||
" * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\n" +
|
||||
" * THE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF\n" +
|
||||
" * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n" +
|
||||
" * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n" +
|
||||
" * NONINFRINGEMENT OF THIRD PARTY RIGHTS.\n" +
|
||||
" * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS\n" +
|
||||
" * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL\n" +
|
||||
" * DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\n" +
|
||||
" * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n" +
|
||||
" * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\n" +
|
||||
" * OF THE DATA FILES OR SOFTWARE.\n" +
|
||||
" * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n" +
|
||||
" * PERFORMANCE OF THE DATA FILES OR SOFTWARE.\n" +
|
||||
" *\n" +
|
||||
" * Except as contained in this notice, the name of a copyright holder shall not\n" +
|
||||
" * be used in advertising or otherwise to promote the sale, use or other\n" +
|
||||
" * dealings in these Data Files or Software without prior written authorization\n" +
|
||||
" * of the copyright holder.\n" +
|
||||
" * Except as contained in this notice, the name of a copyright holder\n" +
|
||||
" * shall not be used in advertising or otherwise to promote the sale,\n" +
|
||||
" * use or other dealings in these Data Files or Software without prior\n" +
|
||||
" * written authorization of the copyright holder.\n" +
|
||||
" */\n";
|
||||
|
||||
private static String OPENJDK2012 =
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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,9 +29,11 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
@ -47,6 +49,8 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
private String zoneNameStyle; // "long" or "short" for time zone names
|
||||
private String zonePrefix;
|
||||
private final String id;
|
||||
private String currentContext = ""; // "format"/"stand-alone"
|
||||
private String currentWidth = ""; // "wide"/"narrow"/"abbreviated"
|
||||
|
||||
LDMLParseHandler(String id) {
|
||||
this.id = id;
|
||||
@ -78,20 +82,17 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
pushIgnoredContainer(qName);
|
||||
}
|
||||
break;
|
||||
|
||||
case "language":
|
||||
// for LocaleNames
|
||||
// copy string
|
||||
pushStringEntry(qName, attributes, CLDRConverter.LOCALE_NAME_PREFIX + attributes.getValue("type"));
|
||||
break;
|
||||
case "script":
|
||||
// for LocaleNames
|
||||
// copy string
|
||||
pushStringEntry(qName, attributes, CLDRConverter.LOCALE_NAME_PREFIX + attributes.getValue("type"));
|
||||
break;
|
||||
case "territory":
|
||||
case "variant":
|
||||
// for LocaleNames
|
||||
// copy string
|
||||
pushStringEntry(qName, attributes, CLDRConverter.LOCALE_NAME_PREFIX + attributes.getValue("type"));
|
||||
pushStringEntry(qName, attributes,
|
||||
CLDRConverter.LOCALE_NAME_PREFIX +
|
||||
(qName.equals("variant") ? "%%" : "") +
|
||||
attributes.getValue("type"));
|
||||
break;
|
||||
|
||||
//
|
||||
@ -112,9 +113,10 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// Calendar or currency
|
||||
case "displayName":
|
||||
{
|
||||
if (currentCalendarType != null) {
|
||||
if (currentContainer.getqName().equals("field")) {
|
||||
pushStringEntry(qName, attributes,
|
||||
currentCalendarType.keyElementName() + "field." + getContainerKey());
|
||||
(currentCalendarType != null ? currentCalendarType.keyElementName() : "")
|
||||
+ "field." + getContainerKey());
|
||||
} else {
|
||||
// for CurrencyNames
|
||||
// need to get the key from the containing <currency> element
|
||||
@ -149,10 +151,8 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
}
|
||||
break;
|
||||
case "fields":
|
||||
if (currentCalendarType != null) {
|
||||
{
|
||||
pushContainer(qName, attributes);
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
}
|
||||
break;
|
||||
case "field":
|
||||
@ -183,6 +183,7 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// need to keep stand-alone and format, to allow for inheritance in CLDR
|
||||
String type = attributes.getValue("type");
|
||||
if ("stand-alone".equals(type) || "format".equals(type)) {
|
||||
currentContext = type;
|
||||
pushKeyContainer(qName, attributes, type);
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
@ -194,8 +195,13 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// for FormatData
|
||||
// create string array for the two types that the JRE knows
|
||||
// keep info about the context type so we can sort out inheritance later
|
||||
if (currentCalendarType == null) {
|
||||
pushIgnoredContainer(qName);
|
||||
break;
|
||||
}
|
||||
String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName();
|
||||
switch (attributes.getValue("type")) {
|
||||
currentWidth = attributes.getValue("type");
|
||||
switch (currentWidth) {
|
||||
case "wide":
|
||||
pushStringArrayEntry(qName, attributes, prefix + "MonthNames/" + getContainerKey(), 13);
|
||||
break;
|
||||
@ -222,6 +228,7 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// need to keep stand-alone and format, to allow for multiple inheritance in CLDR
|
||||
String type = attributes.getValue("type");
|
||||
if ("stand-alone".equals(type) || "format".equals(type)) {
|
||||
currentContext = type;
|
||||
pushKeyContainer(qName, attributes, type);
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
@ -234,7 +241,8 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// create string array for the two types that the JRE knows
|
||||
// keep info about the context type so we can sort out inheritance later
|
||||
String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName();
|
||||
switch (attributes.getValue("type")) {
|
||||
currentWidth = attributes.getValue("type");
|
||||
switch (currentWidth) {
|
||||
case "wide":
|
||||
pushStringArrayEntry(qName, attributes, prefix + "DayNames/" + getContainerKey(), 7);
|
||||
break;
|
||||
@ -263,6 +271,7 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
{
|
||||
String type = attributes.getValue("type");
|
||||
if ("stand-alone".equals(type) || "format".equals(type)) {
|
||||
currentContext = type;
|
||||
pushKeyContainer(qName, attributes, type);
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
@ -272,7 +281,8 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
case "dayPeriodWidth":
|
||||
// for FormatData
|
||||
// create string array entry for am/pm. only keeping wide
|
||||
switch (attributes.getValue("type")) {
|
||||
currentWidth = attributes.getValue("type");
|
||||
switch (currentWidth) {
|
||||
case "wide":
|
||||
pushStringArrayEntry(qName, attributes, "AmPmMarkers/" + getContainerKey(), 2);
|
||||
break;
|
||||
@ -362,6 +372,7 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// need to keep stand-alone and format, to allow for inheritance in CLDR
|
||||
String type = attributes.getValue("type");
|
||||
if ("stand-alone".equals(type) || "format".equals(type)) {
|
||||
currentContext = type;
|
||||
pushKeyContainer(qName, attributes, type);
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
@ -373,7 +384,8 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// for FormatData
|
||||
// keep info about the context type so we can sort out inheritance later
|
||||
String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName();
|
||||
switch (attributes.getValue("type")) {
|
||||
currentWidth = attributes.getValue("type");
|
||||
switch (currentWidth) {
|
||||
case "wide":
|
||||
pushStringArrayEntry(qName, attributes, prefix + "QuarterNames/" + getContainerKey(), 4);
|
||||
break;
|
||||
@ -450,12 +462,20 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
case "currencyFormat":
|
||||
// for FormatData
|
||||
// copy string for later assembly into NumberPatterns
|
||||
if (attributes.getValue("type").equals("standard")) {
|
||||
pushStringEntry(qName, attributes, "NumberPatterns/currency");
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
}
|
||||
break;
|
||||
case "percentFormat":
|
||||
// for FormatData
|
||||
// copy string for later assembly into NumberPatterns
|
||||
if (attributes.getValue("type").equals("standard")) {
|
||||
pushStringEntry(qName, attributes, "NumberPatterns/percent");
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
}
|
||||
break;
|
||||
case "defaultNumberingSystem":
|
||||
// default numbering system if multiple numbering systems are used.
|
||||
@ -582,12 +602,12 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
pushStringEntry(qName, attributes, prefix + "DateTimePatterns/" + attributes.getValue("type") + "-date");
|
||||
}
|
||||
break;
|
||||
case "dateTimeFormat":
|
||||
case "dateTimeFormatLength":
|
||||
{
|
||||
// for FormatData
|
||||
// copy string for later assembly into DateTimePatterns
|
||||
String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName();
|
||||
pushStringEntry(qName, attributes, prefix + "DateTimePatterns/date-time");
|
||||
pushStringEntry(qName, attributes, prefix + "DateTimePatterns/" + attributes.getValue("type") + "-dateTime");
|
||||
}
|
||||
break;
|
||||
case "localizedPatternChars":
|
||||
@ -599,6 +619,20 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
}
|
||||
break;
|
||||
|
||||
// "alias" for root
|
||||
case "alias":
|
||||
{
|
||||
if (id.equals("root") &&
|
||||
!isIgnored(attributes) &&
|
||||
currentCalendarType != null &&
|
||||
!currentCalendarType.lname().startsWith("islamic-")) { // ignore Islamic variants
|
||||
pushAliasEntry(qName, attributes, attributes.getValue("path"));
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// treat anything else as a container
|
||||
pushContainer(qName, attributes);
|
||||
@ -606,6 +640,184 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] CONTEXTS = {"stand-alone", "format"};
|
||||
private static final String[] WIDTHS = {"wide", "narrow", "abbreviated"};
|
||||
private static final String[] LENGTHS = {"full", "long", "medium", "short"};
|
||||
|
||||
private void populateWidthAlias(String type, Set<String> keys) {
|
||||
for (String context : CONTEXTS) {
|
||||
for (String width : WIDTHS) {
|
||||
String keyName = toJDKKey(type+"Width", context, width);
|
||||
if (keyName.length() > 0) {
|
||||
keys.add(keyName + "," + context + "," + width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void populateFormatLengthAlias(String type, Set<String> keys) {
|
||||
for (String length: LENGTHS) {
|
||||
String keyName = toJDKKey(type+"FormatLength", currentContext, length);
|
||||
if (keyName.length() > 0) {
|
||||
keys.add(keyName + "," + currentContext + "," + length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> populateAliasKeys(String qName, String context, String width) {
|
||||
HashSet<String> ret = new HashSet<>();
|
||||
String keyName = qName;
|
||||
|
||||
switch (qName) {
|
||||
case "monthWidth":
|
||||
case "dayWidth":
|
||||
case "quarterWidth":
|
||||
case "dayPeriodWidth":
|
||||
case "dateFormatLength":
|
||||
case "timeFormatLength":
|
||||
case "dateTimeFormatLength":
|
||||
case "eraNames":
|
||||
case "eraAbbr":
|
||||
case "eraNarrow":
|
||||
ret.add(toJDKKey(qName, context, width) + "," + context + "," + width);
|
||||
break;
|
||||
case "days":
|
||||
populateWidthAlias("day", ret);
|
||||
break;
|
||||
case "months":
|
||||
populateWidthAlias("month", ret);
|
||||
break;
|
||||
case "quarters":
|
||||
populateWidthAlias("quarter", ret);
|
||||
break;
|
||||
case "dayPeriods":
|
||||
populateWidthAlias("dayPeriod", ret);
|
||||
break;
|
||||
case "eras":
|
||||
ret.add(toJDKKey("eraNames", context, width) + "," + context + "," + width);
|
||||
ret.add(toJDKKey("eraAbbr", context, width) + "," + context + "," + width);
|
||||
ret.add(toJDKKey("eraNarrow", context, width) + "," + context + "," + width);
|
||||
break;
|
||||
case "dateFormats":
|
||||
populateFormatLengthAlias("date", ret);
|
||||
break;
|
||||
case "timeFormats":
|
||||
populateFormatLengthAlias("time", ret);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private String translateWidthAlias(String qName, String context, String width) {
|
||||
String keyName = qName;
|
||||
String type = Character.toUpperCase(qName.charAt(0)) + qName.substring(1, qName.indexOf("Width"));
|
||||
|
||||
switch (width) {
|
||||
case "wide":
|
||||
keyName = type + "Names/" + context;
|
||||
break;
|
||||
case "abbreviated":
|
||||
keyName = type + "Abbreviations/" + context;
|
||||
break;
|
||||
case "narrow":
|
||||
keyName = type + "Narrows/" + context;
|
||||
break;
|
||||
default:
|
||||
assert false;
|
||||
}
|
||||
|
||||
return keyName;
|
||||
}
|
||||
|
||||
private String toJDKKey(String containerqName, String context, String type) {
|
||||
String keyName = containerqName;
|
||||
|
||||
switch (containerqName) {
|
||||
case "monthWidth":
|
||||
case "dayWidth":
|
||||
case "quarterWidth":
|
||||
keyName = translateWidthAlias(keyName, context, type);
|
||||
break;
|
||||
case "dayPeriodWidth":
|
||||
switch (type) {
|
||||
case "wide":
|
||||
keyName = "AmPmMarkers/" + context;
|
||||
break;
|
||||
case "narrow":
|
||||
keyName = "narrow.AmPmMarkers/" + context;
|
||||
break;
|
||||
case "abbreviated":
|
||||
keyName = "";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "dateFormatLength":
|
||||
case "timeFormatLength":
|
||||
case "dateTimeFormatLength":
|
||||
keyName = "DateTimePatterns/" +
|
||||
type + "-" +
|
||||
keyName.substring(0, keyName.indexOf("FormatLength"));
|
||||
break;
|
||||
case "eraNames":
|
||||
keyName = "long.Eras";
|
||||
break;
|
||||
case "eraAbbr":
|
||||
keyName = "Eras";
|
||||
break;
|
||||
case "eraNarrow":
|
||||
keyName = "narrow.Eras";
|
||||
break;
|
||||
case "dateFormats":
|
||||
case "timeFormats":
|
||||
case "days":
|
||||
case "months":
|
||||
case "quarters":
|
||||
case "dayPeriods":
|
||||
case "eras":
|
||||
break;
|
||||
default:
|
||||
keyName = "";
|
||||
break;
|
||||
}
|
||||
|
||||
return keyName;
|
||||
}
|
||||
|
||||
private String getTarget(String qName, String path, String calType, String context, String width) {
|
||||
// qName
|
||||
int lastSlash = path.lastIndexOf('/');
|
||||
qName = path.substring(lastSlash+1);
|
||||
int bracket = qName.indexOf('[');
|
||||
if (bracket != -1) {
|
||||
qName = qName.substring(0, bracket);
|
||||
}
|
||||
|
||||
// calType
|
||||
String typeKey = "/calendar[@type='";
|
||||
int start = path.indexOf(typeKey);
|
||||
if (start != -1) {
|
||||
calType = path.substring(start+typeKey.length(), path.indexOf("']", start));
|
||||
}
|
||||
|
||||
// context
|
||||
typeKey = "Context[@type='";
|
||||
start = path.indexOf(typeKey);
|
||||
if (start != -1) {
|
||||
context = (path.substring(start+typeKey.length(), path.indexOf("']", start)));
|
||||
}
|
||||
|
||||
// width
|
||||
typeKey = "Width[@type='";
|
||||
start = path.indexOf(typeKey);
|
||||
if (start != -1) {
|
||||
width = path.substring(start+typeKey.length(), path.indexOf("']", start));
|
||||
}
|
||||
|
||||
return calType + "." + toJDKKey(qName, context, width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
assert qName.equals(currentContainer.getqName()) : "current=" + currentContainer.getqName() + ", param=" + qName;
|
||||
@ -628,6 +840,7 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
case "timeZoneNames":
|
||||
zonePrefix = null;
|
||||
break;
|
||||
|
||||
case "generic":
|
||||
case "standard":
|
||||
case "daylight":
|
||||
@ -638,8 +851,52 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
valmap.put(entry.getKey(), (String) entry.getValue());
|
||||
}
|
||||
break;
|
||||
|
||||
case "monthWidth":
|
||||
case "dayWidth":
|
||||
case "dayPeriodWidth":
|
||||
case "quarterWidth":
|
||||
currentWidth = "";
|
||||
putIfEntry();
|
||||
break;
|
||||
|
||||
case "monthContext":
|
||||
case "dayContext":
|
||||
case "dayPeriodContext":
|
||||
case "quarterContext":
|
||||
currentContext = "";
|
||||
putIfEntry();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (currentContainer instanceof Entry) {
|
||||
putIfEntry();
|
||||
}
|
||||
currentContainer = currentContainer.getParent();
|
||||
}
|
||||
|
||||
private void putIfEntry() {
|
||||
if (currentContainer instanceof AliasEntry) {
|
||||
Entry<?> entry = (Entry<?>) currentContainer;
|
||||
String containerqName = entry.getParent().getqName();
|
||||
Set<String> keyNames = populateAliasKeys(containerqName, currentContext, currentWidth);
|
||||
if (!keyNames.isEmpty()) {
|
||||
for (String keyName : keyNames) {
|
||||
String[] tmp = keyName.split(",", 3);
|
||||
String calType = currentCalendarType.lname();
|
||||
String src = calType+"."+tmp[0];
|
||||
String target = getTarget(containerqName,
|
||||
entry.getKey(),
|
||||
calType,
|
||||
tmp[1].length()>0 ? tmp[1] : currentContext,
|
||||
tmp[2].length()>0 ? tmp[2] : currentWidth);
|
||||
if (target.substring(target.lastIndexOf('.')+1).equals(containerqName)) {
|
||||
target = target.substring(0, target.indexOf('.'))+"."+tmp[0];
|
||||
}
|
||||
CLDRConverter.aliases.put(src.replaceFirst("^gregorian.", ""),
|
||||
target.replaceFirst("^gregorian.", ""));
|
||||
}
|
||||
}
|
||||
} else if (currentContainer instanceof Entry) {
|
||||
Entry<?> entry = (Entry<?>) currentContainer;
|
||||
Object value = entry.getValue();
|
||||
if (value != null) {
|
||||
@ -647,6 +904,4 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
}
|
||||
}
|
||||
}
|
||||
currentContainer = currentContainer.getParent();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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,22 +30,62 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
class ResourceBundleGenerator implements BundleGenerator {
|
||||
// preferred timezones - keeping compatibility with JDK1.1 3 letter abbreviations
|
||||
private static final String[] preferredTZIDs = {
|
||||
"America/Los_Angeles",
|
||||
"America/Denver",
|
||||
"America/Phoenix",
|
||||
"America/Chicago",
|
||||
"America/New_York",
|
||||
"America/Indianapolis",
|
||||
"Pacific/Honolulu",
|
||||
"America/Anchorage",
|
||||
"America/Halifax",
|
||||
"America/Sitka",
|
||||
"America/St_Johns",
|
||||
"Europe/Paris",
|
||||
// Although CLDR does not support abbreviated zones, handle "GMT" as a
|
||||
// special case here, as it is specified in the javadoc.
|
||||
"GMT",
|
||||
"Africa/Casablanca",
|
||||
"Asia/Jerusalem",
|
||||
"Asia/Tokyo",
|
||||
"Europe/Bucharest",
|
||||
"Asia/Shanghai",
|
||||
};
|
||||
|
||||
// For duplicated values
|
||||
private static final String META_VALUE_PREFIX = "metaValue_";
|
||||
|
||||
@Override
|
||||
public void generateBundle(String packageName, String baseName, String localeID, boolean useJava,
|
||||
Map<String, ?> map, BundleType type) throws IOException {
|
||||
String suffix = useJava ? ".java" : ".properties";
|
||||
String lang = CLDRConverter.getLanguageCode(localeID);
|
||||
String ctry = CLDRConverter.getCountryCode(localeID);
|
||||
String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator
|
||||
+ packageName + File.separator + "resources" + File.separator + "cldr";
|
||||
if (lang.length() > 0) {
|
||||
dirName = dirName + File.separator + lang;
|
||||
packageName = packageName + ".resources.cldr." + lang;
|
||||
if (CLDRConverter.isBaseModule ^ isBaseLocale(localeID)) {
|
||||
return;
|
||||
}
|
||||
dirName = dirName + File.separator + lang +
|
||||
(ctry != null && ctry.length() > 0 ? File.separator + ctry : "");
|
||||
packageName = packageName + ".resources.cldr." + lang +
|
||||
(ctry != null && ctry.length() > 0 ? "." + ctry : "");
|
||||
} else {
|
||||
if (!CLDRConverter.isBaseModule) {
|
||||
return;
|
||||
}
|
||||
packageName = packageName + ".resources.cldr";
|
||||
}
|
||||
File dir = new File(dirName);
|
||||
@ -89,6 +129,65 @@ class ResourceBundleGenerator implements BundleGenerator {
|
||||
for (String key : metaKeys) {
|
||||
map.remove(key);
|
||||
}
|
||||
|
||||
// Make it preferred ordered
|
||||
LinkedHashMap<String, Object> newMap = new LinkedHashMap<>();
|
||||
for (String preferred : preferredTZIDs) {
|
||||
if (map.containsKey(preferred)) {
|
||||
newMap.put(preferred, map.remove(preferred));
|
||||
} else if ("GMT".equals(preferred) &&
|
||||
metaKeys.contains(CLDRConverter.METAZONE_ID_PREFIX+preferred)) {
|
||||
newMap.put(preferred, preferred);
|
||||
}
|
||||
}
|
||||
newMap.putAll(map);
|
||||
map = newMap;
|
||||
} else {
|
||||
// generic reduction of duplicated values
|
||||
Map<String, Object> newMap = null;
|
||||
for (String key : map.keySet()) {
|
||||
Object val = map.get(key);
|
||||
String metaVal = null;
|
||||
|
||||
for (Map.Entry<String, ?> entry : map.entrySet()) {
|
||||
String k = entry.getKey();
|
||||
if (!k.equals(key) &&
|
||||
Objects.deepEquals(val, entry.getValue()) &&
|
||||
!(Objects.nonNull(newMap) && newMap.containsKey(k))) {
|
||||
if (Objects.isNull(newMap)) {
|
||||
newMap = new HashMap<>();
|
||||
fmt = new Formatter();
|
||||
}
|
||||
|
||||
if (Objects.isNull(metaVal)) {
|
||||
metaVal = META_VALUE_PREFIX + key.replaceAll("\\.", "_");
|
||||
|
||||
if (val instanceof String[]) {
|
||||
fmt.format(" final String[] %s = new String[] {\n", metaVal);
|
||||
for (String s : (String[])val) {
|
||||
fmt.format(" \"%s\",\n", CLDRConverter.saveConvert(s, useJava));
|
||||
}
|
||||
fmt.format(" };\n");
|
||||
} else {
|
||||
fmt.format(" final String %s = \"%s\";\n", metaVal, CLDRConverter.saveConvert((String)val, useJava));
|
||||
}
|
||||
}
|
||||
|
||||
newMap.put(k, metaVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.nonNull(metaVal)) {
|
||||
newMap.put(key, metaVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.nonNull(newMap)) {
|
||||
for (String key : map.keySet()) {
|
||||
newMap.putIfAbsent(key, map.get(key));
|
||||
}
|
||||
map = newMap;
|
||||
}
|
||||
}
|
||||
|
||||
try (PrintWriter out = new PrintWriter(file, encoding)) {
|
||||
@ -114,7 +213,8 @@ class ResourceBundleGenerator implements BundleGenerator {
|
||||
if (value == null) {
|
||||
CLDRConverter.warning("null value for " + key);
|
||||
} else if (value instanceof String) {
|
||||
if (type == BundleType.TIMEZONE) {
|
||||
if (type == BundleType.TIMEZONE ||
|
||||
((String)value).startsWith(META_VALUE_PREFIX)) {
|
||||
out.printf(" { \"%s\", %s },\n", key, CLDRConverter.saveConvert((String) value, useJava));
|
||||
} else {
|
||||
out.printf(" { \"%s\", \"%s\" },\n", key, CLDRConverter.saveConvert((String) value, useJava));
|
||||
@ -139,18 +239,22 @@ class ResourceBundleGenerator implements BundleGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String METAINFO_CLASS = "CLDRLocaleDataMetaInfo";
|
||||
|
||||
@Override
|
||||
public void generateMetaInfo(Map<String, SortedSet<String>> metaInfo) throws IOException {
|
||||
String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" +
|
||||
File.separator + "resources" + File.separator + "cldr" + File.separator +
|
||||
"provider" + File.separator ;
|
||||
File.separator +
|
||||
(CLDRConverter.isBaseModule ? "cldr" + File.separator + File.separator :
|
||||
"resources" + File.separator + "cldr" + File.separator + "provider" + File.separator);
|
||||
File dir = new File(dirName);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
File file = new File(dir, METAINFO_CLASS + ".java");
|
||||
String className =
|
||||
(CLDRConverter.isBaseModule ? "CLDRBaseLocaleDataMetaInfo" :
|
||||
"CLDRLocaleDataMetaInfo_" +
|
||||
CLDRConverter.DESTINATION_DIR.substring(CLDRConverter.DESTINATION_DIR.lastIndexOf('/')+1)
|
||||
.replaceAll("\\.", "_"));
|
||||
File file = new File(dir, className + ".java");
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
@ -159,34 +263,71 @@ class ResourceBundleGenerator implements BundleGenerator {
|
||||
try (PrintWriter out = new PrintWriter(file, "us-ascii")) {
|
||||
out.println(CopyrightHeaders.getOpenJDKCopyright());
|
||||
|
||||
out.println("package sun.util.resources.cldr.provider;\n\n"
|
||||
out.println((CLDRConverter.isBaseModule ? "package sun.util.cldr;\n\n" :
|
||||
"package sun.util.resources.cldr.provider;\n\n")
|
||||
+ "import java.util.HashMap;\n"
|
||||
+ "import java.util.Map;\n"
|
||||
+ "import java.util.ListResourceBundle;\n"
|
||||
+ "import sun.util.locale.provider.LocaleProviderAdapter;\n"
|
||||
+ "import sun.util.locale.provider.LocaleDataMetaInfo;\n");
|
||||
out.printf("public class %s extends ListResourceBundle implements LocaleDataMetaInfo {\n", METAINFO_CLASS);
|
||||
out.printf("public class %s extends ListResourceBundle implements LocaleDataMetaInfo {\n", className);
|
||||
out.println(" @Override\n" +
|
||||
" protected final Object[][] getContents() {\n" +
|
||||
" final Object[][] data = new Object[][] {");
|
||||
for (String key : metaInfo.keySet()) {
|
||||
out.printf(" { \"%s\",\n", key);
|
||||
out.printf(" \"%s\" },\n", toLocaleList(metaInfo.get(key)));
|
||||
out.printf(" \"%s\" },\n",
|
||||
toLocaleList(key.equals("FormatData") ? metaInfo.get("AvailableLocales") :
|
||||
metaInfo.get(key),
|
||||
key.startsWith(CLDRConverter.PARENT_LOCALE_PREFIX)));
|
||||
}
|
||||
out.println(" };\n return data;\n }\n\n");
|
||||
|
||||
out.println(" public LocaleProviderAdapter.Type getType() {\n" +
|
||||
out.println(" @Override\n" +
|
||||
" public LocaleProviderAdapter.Type getType() {\n" +
|
||||
" return LocaleProviderAdapter.Type.CLDR;\n" +
|
||||
" }\n\n");
|
||||
|
||||
out.println(" public String availableLanguageTags(String category) {\n" +
|
||||
out.println(" @Override\n" +
|
||||
" public String availableLanguageTags(String category) {\n" +
|
||||
" return getString(category);\n" +
|
||||
" };\n}");
|
||||
" };\n\n");
|
||||
|
||||
if (CLDRConverter.isBaseModule) {
|
||||
out.printf(" public Map<String, String> parentLocales() {\n" +
|
||||
" Map<String, String> ret = new HashMap<>();\n" +
|
||||
" keySet().stream()\n" +
|
||||
" .filter(key -> key.startsWith(\"%s\"))\n" +
|
||||
" .forEach(key -> ret.put(key.substring(%d), getString(key)));\n" +
|
||||
" return ret.isEmpty() ? null : ret;\n" +
|
||||
" };\n}",
|
||||
CLDRConverter.PARENT_LOCALE_PREFIX,
|
||||
CLDRConverter.PARENT_LOCALE_PREFIX.length());
|
||||
} else {
|
||||
out.println("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String toLocaleList(SortedSet<String> set) {
|
||||
private static final Locale.Builder LOCALE_BUILDER = new Locale.Builder();
|
||||
private static boolean isBaseLocale(String localeID) {
|
||||
localeID = localeID.replaceAll("-", "_");
|
||||
// ignore script here
|
||||
Locale locale = LOCALE_BUILDER
|
||||
.clear()
|
||||
.setLanguage(CLDRConverter.getLanguageCode(localeID))
|
||||
.setRegion(CLDRConverter.getCountryCode(localeID))
|
||||
.build();
|
||||
return CLDRConverter.BASE_LOCALES.contains(locale);
|
||||
}
|
||||
|
||||
private static String toLocaleList(SortedSet<String> set, boolean all) {
|
||||
StringBuilder sb = new StringBuilder(set.size() * 6);
|
||||
for (String id : set) {
|
||||
if (!"root".equals(id)) {
|
||||
if (!all && CLDRConverter.isBaseModule ^ isBaseLocale(id)) {
|
||||
continue;
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
sb.append(' ');
|
||||
}
|
||||
|
@ -51,12 +51,21 @@ class SupplementDataParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// When parsing the locale neutral file (supplementalData.xml),
|
||||
// we need to rely on the country code because
|
||||
// the weekData is listed using country code.
|
||||
//
|
||||
// weekData are generated per each country
|
||||
private final Map<String, Object> firstDayMap;
|
||||
private final Map<String, Object> minDaysMap;
|
||||
|
||||
// Parent locales. These information will only be
|
||||
// generated towards the base meta info, with the format of
|
||||
//
|
||||
// parentLocale.<parent_locale_id>=<child_locale_id>(" "<child_locale_id>)+
|
||||
private final Map<String, String> parentLocalesMap;
|
||||
|
||||
SupplementDataParseHandler() {
|
||||
firstDayMap = new HashMap<>();
|
||||
minDaysMap = new HashMap<>();
|
||||
parentLocalesMap = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,16 +77,23 @@ class SupplementDataParseHandler extends AbstractLDMLHandler<Object> {
|
||||
* although this should not happen because supplementalData.xml includes
|
||||
* default value for the world ("001") for firstDay and minDays.
|
||||
*/
|
||||
Map<String, Object> getData(String country) {
|
||||
Map<String, Object> getData(String id) {
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
String countryData = getWeekData(country, JAVA_FIRSTDAY, firstDayMap);
|
||||
if ("root".equals(id)) {
|
||||
parentLocalesMap.keySet().forEach(key -> {
|
||||
values.put(CLDRConverter.PARENT_LOCALE_PREFIX+key,
|
||||
parentLocalesMap.get(key));
|
||||
});
|
||||
} else {
|
||||
String countryData = getWeekData(id, JAVA_FIRSTDAY, firstDayMap);
|
||||
if (countryData != null) {
|
||||
values.put(JAVA_FIRSTDAY, countryData);
|
||||
}
|
||||
String minDaysData = getWeekData(country, JAVA_MINDAY, minDaysMap);
|
||||
String minDaysData = getWeekData(id, JAVA_MINDAY, minDaysMap);
|
||||
if (minDaysData != null) {
|
||||
values.put(JAVA_MINDAY, minDaysData);
|
||||
}
|
||||
}
|
||||
return values.isEmpty() ? null : values;
|
||||
}
|
||||
|
||||
@ -144,6 +160,13 @@ class SupplementDataParseHandler extends AbstractLDMLHandler<Object> {
|
||||
minDaysMap.put(attributes.getValue("territories"), attributes.getValue("count"));
|
||||
}
|
||||
break;
|
||||
case "parentLocale":
|
||||
if (!isIgnored(attributes)) {
|
||||
parentLocalesMap.put(
|
||||
attributes.getValue("parent").replaceAll("_", "-"),
|
||||
attributes.getValue("locales").replaceAll("_", "-"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// treat anything else as a container
|
||||
pushContainer(qName, attributes);
|
||||
|
@ -1,10 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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.
|
||||
* 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
|
||||
@ -21,23 +23,15 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a not a test.
|
||||
*
|
||||
* This is supporting code for other tests.
|
||||
* It is compiled and placed into loader.jar
|
||||
*/
|
||||
import java.security.*;
|
||||
import sun.security.pkcs11.SunPKCS11;
|
||||
package java.lang.invoke;
|
||||
|
||||
public class ProviderLoader {
|
||||
public static void go(final String config) throws Exception {
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
SunPKCS11 provider = new SunPKCS11(config);
|
||||
Security.addProvider(provider);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Internal marker for some methods in the JSR 292 implementation.
|
||||
*/
|
||||
/*non-public*/
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface InjectedProfile {
|
||||
}
|
@ -669,6 +669,11 @@ class InvokerBytecodeGenerator {
|
||||
switch (intr) {
|
||||
case SELECT_ALTERNATIVE:
|
||||
assert isSelectAlternative(i);
|
||||
if (PROFILE_GWT) {
|
||||
assert(name.arguments[0] instanceof Name &&
|
||||
nameRefersTo((Name)name.arguments[0], MethodHandleImpl.class, "profileBoolean"));
|
||||
mv.visitAnnotation("Ljava/lang/invoke/InjectedProfile;", true);
|
||||
}
|
||||
onStack = emitSelectAlternative(name, lambdaForm.names[i+1]);
|
||||
i++; // skip MH.invokeBasic of the selectAlternative result
|
||||
continue;
|
||||
|
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.nio.file;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A file-based lines spliterator, leveraging a shared mapped byte buffer and
|
||||
* associated file channel, covering lines of a file for character encodings
|
||||
* where line feed characters can be easily identified from character encoded
|
||||
* bytes.
|
||||
*
|
||||
* <p>
|
||||
* When the root spliterator is first split a mapped byte buffer will be created
|
||||
* over the file for it's size that was observed when the stream was created.
|
||||
* Thus a mapped byte buffer is only required for parallel stream execution.
|
||||
* Sub-spliterators will share that mapped byte buffer. Splitting will use the
|
||||
* mapped byte buffer to find the closest line feed characters(s) to the left or
|
||||
* right of the mid-point of covered range of bytes of the file. If a line feed
|
||||
* is found then the spliterator is split with returned spliterator containing
|
||||
* the identified line feed characters(s) at the end of it's covered range of
|
||||
* bytes.
|
||||
*
|
||||
* <p>
|
||||
* Traversing will create a buffered reader, derived from the file channel, for
|
||||
* the range of bytes of the file. The lines are then read from that buffered
|
||||
* reader. Once traversing commences no further splitting can be performed and
|
||||
* the reference to the mapped byte buffer will be set to null.
|
||||
*/
|
||||
final class FileChannelLinesSpliterator implements Spliterator<String> {
|
||||
|
||||
static final Set<String> SUPPORTED_CHARSET_NAMES;
|
||||
static {
|
||||
SUPPORTED_CHARSET_NAMES = new HashSet<>();
|
||||
SUPPORTED_CHARSET_NAMES.add(StandardCharsets.UTF_8.name());
|
||||
SUPPORTED_CHARSET_NAMES.add(StandardCharsets.ISO_8859_1.name());
|
||||
SUPPORTED_CHARSET_NAMES.add(StandardCharsets.US_ASCII.name());
|
||||
}
|
||||
|
||||
private final FileChannel fc;
|
||||
private final Charset cs;
|
||||
private int index;
|
||||
private final int fence;
|
||||
|
||||
// Null before first split, non-null when splitting, null when traversing
|
||||
private ByteBuffer buffer;
|
||||
// Non-null when traversing
|
||||
private BufferedReader reader;
|
||||
|
||||
FileChannelLinesSpliterator(FileChannel fc, Charset cs, int index, int fence) {
|
||||
this.fc = fc;
|
||||
this.cs = cs;
|
||||
this.index = index;
|
||||
this.fence = fence;
|
||||
}
|
||||
|
||||
private FileChannelLinesSpliterator(FileChannel fc, Charset cs, int index, int fence, ByteBuffer buffer) {
|
||||
this.fc = fc;
|
||||
this.buffer = buffer;
|
||||
this.cs = cs;
|
||||
this.index = index;
|
||||
this.fence = fence;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super String> action) {
|
||||
String line = readLine();
|
||||
if (line != null) {
|
||||
action.accept(line);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(Consumer<? super String> action) {
|
||||
String line;
|
||||
while ((line = readLine()) != null) {
|
||||
action.accept(line);
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedReader getBufferedReader() {
|
||||
/**
|
||||
* A readable byte channel that reads bytes from an underlying
|
||||
* file channel over a specified range.
|
||||
*/
|
||||
ReadableByteChannel rrbc = new ReadableByteChannel() {
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
int bytesToRead = fence - index;
|
||||
if (bytesToRead == 0)
|
||||
return -1;
|
||||
|
||||
int bytesRead;
|
||||
if (bytesToRead < dst.remaining()) {
|
||||
// The number of bytes to read is less than remaining
|
||||
// bytes in the buffer
|
||||
// Snapshot the limit, reduce it, read, then restore
|
||||
int oldLimit = dst.limit();
|
||||
dst.limit(dst.position() + bytesToRead);
|
||||
bytesRead = fc.read(dst, index);
|
||||
dst.limit(oldLimit);
|
||||
} else {
|
||||
bytesRead = fc.read(dst, index);
|
||||
}
|
||||
if (bytesRead == -1) {
|
||||
index = fence;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
index += bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return fc.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
fc.close();
|
||||
}
|
||||
};
|
||||
return new BufferedReader(Channels.newReader(rrbc, cs.newDecoder(), -1));
|
||||
}
|
||||
|
||||
private String readLine() {
|
||||
if (reader == null) {
|
||||
reader = getBufferedReader();
|
||||
buffer = null;
|
||||
}
|
||||
|
||||
try {
|
||||
return reader.readLine();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ByteBuffer getMappedByteBuffer() {
|
||||
// TODO can the mapped byte buffer be explicitly unmapped?
|
||||
// It's possible, via a shared-secret mechanism, when either
|
||||
// 1) the spliterator starts traversing, although traversal can
|
||||
// happen concurrently for mulitple spliterators, so care is
|
||||
// needed in this case; or
|
||||
// 2) when the stream is closed using some shared holder to pass
|
||||
// the mapped byte buffer when it is created.
|
||||
try {
|
||||
return fc.map(FileChannel.MapMode.READ_ONLY, 0, fence);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<String> trySplit() {
|
||||
// Cannot split after partial traverse
|
||||
if (reader != null)
|
||||
return null;
|
||||
|
||||
ByteBuffer b;
|
||||
if ((b = buffer) == null) {
|
||||
b = buffer = getMappedByteBuffer();
|
||||
}
|
||||
|
||||
final int hi = fence, lo = index;
|
||||
|
||||
// Check if line separator hits the mid point
|
||||
int mid = (lo + hi) >>> 1;
|
||||
int c = b.get(mid);
|
||||
if (c == '\n') {
|
||||
mid++;
|
||||
} else if (c == '\r') {
|
||||
// Check if a line separator of "\r\n"
|
||||
if (++mid < hi && b.get(mid) == '\n') {
|
||||
mid++;
|
||||
}
|
||||
} else {
|
||||
// TODO give up after a certain distance from the mid point?
|
||||
// Scan to the left and right of the mid point
|
||||
int midL = mid - 1;
|
||||
int midR = mid + 1;
|
||||
mid = 0;
|
||||
while (midL > lo && midR < hi) {
|
||||
// Sample to the left
|
||||
c = b.get(midL--);
|
||||
if (c == '\n' || c == '\r') {
|
||||
// If c is "\r" then no need to check for "\r\n"
|
||||
// since the subsequent value was previously checked
|
||||
mid = midL + 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Sample to the right
|
||||
c = b.get(midR++);
|
||||
if (c == '\n' || c == '\r') {
|
||||
mid = midR;
|
||||
// Check if line-separator is "\r\n"
|
||||
if (c == '\r' && mid < hi && b.get(mid) == '\n') {
|
||||
mid++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The left spliterator will have the line-separator at the end
|
||||
return (mid > lo && mid < hi)
|
||||
? new FileChannelLinesSpliterator(fc, cs, lo, index = mid, b)
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
// Use the number of bytes as an estimate.
|
||||
// We could divide by a constant that is the average number of
|
||||
// characters per-line, but that constant will be factored out.
|
||||
return fence - index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getExactSizeIfKnown() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return Spliterator.ORDERED | Spliterator.NONNULL;
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.Writer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
@ -3735,6 +3736,7 @@ public final class Files {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read all lines from a file as a {@code Stream}. Unlike {@link
|
||||
* #readAllLines(Path, Charset) readAllLines}, this method does not read
|
||||
@ -3748,6 +3750,10 @@ public final class Files {
|
||||
* <p> The returned stream contains a reference to an open file. The file
|
||||
* is closed by closing the stream.
|
||||
*
|
||||
* <p> The file contents should not be modified during the execution of the
|
||||
* terminal stream operation. Otherwise, the result of the terminal stream
|
||||
* operation is undefined.
|
||||
*
|
||||
* <p> After this method returns, then any subsequent I/O exception that
|
||||
* occurs while reading from the file or when a malformed or unmappable byte
|
||||
* sequence is read, is wrapped in an {@link UncheckedIOException} that will
|
||||
@ -3761,6 +3767,30 @@ public final class Files {
|
||||
* control structure to ensure that the stream's open file is closed promptly
|
||||
* after the stream's operations have completed.
|
||||
*
|
||||
* @implNote
|
||||
* This implementation supports good parallel stream performance for the
|
||||
* standard charsets {@link StandardCharsets#UTF_8 UTF-8},
|
||||
* {@link StandardCharsets#US_ASCII US-ASCII} and
|
||||
* {@link StandardCharsets#ISO_8859_1 ISO-8859-1}. Such
|
||||
* <em>line-optimal</em> charsets have the property that the encoded bytes
|
||||
* of a line feed ('\n') or a carriage return ('\r') are efficiently
|
||||
* identifiable from other encoded characters when randomly accessing the
|
||||
* bytes of the file.
|
||||
*
|
||||
* <p> For non-<em>line-optimal</em> charsets the stream source's
|
||||
* spliterator has poor splitting properties, similar to that of a
|
||||
* spliterator associated with an iterator or that associated with a stream
|
||||
* returned from {@link BufferedReader#lines()}. Poor splitting properties
|
||||
* can result in poor parallel stream performance.
|
||||
*
|
||||
* <p> For <em>line-optimal</em> charsets the stream source's spliterator
|
||||
* has good splitting properties, assuming the file contains a regular
|
||||
* sequence of lines. Good splitting properties can result in good parallel
|
||||
* stream performance. The spliterator for a <em>line-optimal</em> charset
|
||||
* takes advantage of the charset properties (a line feed or a carriage
|
||||
* return being efficient identifiable) such that when splitting it can
|
||||
* approximately divide the number of covered lines in half.
|
||||
*
|
||||
* @param path
|
||||
* the path to the file
|
||||
* @param cs
|
||||
@ -3781,7 +3811,50 @@ public final class Files {
|
||||
* @since 1.8
|
||||
*/
|
||||
public static Stream<String> lines(Path path, Charset cs) throws IOException {
|
||||
BufferedReader br = Files.newBufferedReader(path, cs);
|
||||
// Use the good splitting spliterator if:
|
||||
// 1) the path is associated with the default file system;
|
||||
// 2) the character set is supported; and
|
||||
// 3) the file size is such that all bytes can be indexed by int values
|
||||
// (this limitation is imposed by ByteBuffer)
|
||||
if (path.getFileSystem() == FileSystems.getDefault() &&
|
||||
FileChannelLinesSpliterator.SUPPORTED_CHARSET_NAMES.contains(cs.name())) {
|
||||
FileChannel fc = FileChannel.open(path, StandardOpenOption.READ);
|
||||
|
||||
Stream<String> fcls = createFileChannelLinesStream(fc, cs);
|
||||
if (fcls != null) {
|
||||
return fcls;
|
||||
}
|
||||
fc.close();
|
||||
}
|
||||
|
||||
return createBufferedReaderLinesStream(Files.newBufferedReader(path, cs));
|
||||
}
|
||||
|
||||
private static Stream<String> createFileChannelLinesStream(FileChannel fc, Charset cs) throws IOException {
|
||||
try {
|
||||
// Obtaining the size from the FileChannel is much faster
|
||||
// than obtaining using path.toFile().length()
|
||||
long length = fc.size();
|
||||
if (length <= Integer.MAX_VALUE) {
|
||||
Spliterator<String> s = new FileChannelLinesSpliterator(fc, cs, 0, (int) length);
|
||||
return StreamSupport.stream(s, false)
|
||||
.onClose(Files.asUncheckedRunnable(fc));
|
||||
}
|
||||
} catch (Error|RuntimeException|IOException e) {
|
||||
try {
|
||||
fc.close();
|
||||
} catch (IOException ex) {
|
||||
try {
|
||||
e.addSuppressed(ex);
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Stream<String> createBufferedReaderLinesStream(BufferedReader br) {
|
||||
try {
|
||||
return br.lines().onClose(asUncheckedRunnable(br));
|
||||
} catch (Error|RuntimeException e) {
|
||||
@ -3790,7 +3863,8 @@ public final class Files {
|
||||
} catch (IOException ex) {
|
||||
try {
|
||||
e.addSuppressed(ex);
|
||||
} catch (Throwable ignore) {}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
@ -3804,6 +3878,10 @@ public final class Files {
|
||||
* <p> The returned stream contains a reference to an open file. The file
|
||||
* is closed by closing the stream.
|
||||
*
|
||||
* <p> The file contents should not be modified during the execution of the
|
||||
* terminal stream operation. Otherwise, the result of the terminal stream
|
||||
* operation is undefined.
|
||||
*
|
||||
* <p> This method works as if invoking it were equivalent to evaluating the
|
||||
* expression:
|
||||
* <pre>{@code
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2015, 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
|
||||
@ -41,30 +41,22 @@ import java.util.function.Function;
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>Algorithms (such as DSA, RSA, MD5 or SHA-1).
|
||||
* <li>Algorithms (such as DSA, RSA, or SHA-256).
|
||||
*
|
||||
* <li>Key generation, conversion, and management facilities (such as for
|
||||
* algorithm-specific keys).
|
||||
*
|
||||
*</ul>
|
||||
*
|
||||
* <p>Each provider has a name and a version number, and is configured
|
||||
* in each runtime it is installed in.
|
||||
*
|
||||
* <p>See <a href =
|
||||
* "../../../technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
|
||||
* in the "Java Cryptography Architecture API Specification & Reference"
|
||||
* for information about how a particular type of provider, the
|
||||
* cryptographic service provider, works and is installed. However,
|
||||
* please note that a provider can be used to implement any security
|
||||
* service in Java that uses a pluggable architecture with a choice
|
||||
* of implementations that fit underneath.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Some provider implementations may encounter unrecoverable internal
|
||||
* errors during their operation, for example a failure to communicate with a
|
||||
* security token. A {@link ProviderException} should be used to indicate
|
||||
* such errors.
|
||||
*
|
||||
* <p>Please note that a provider can be used to implement any security
|
||||
* service in Java that uses a pluggable architecture with a choice
|
||||
* of implementations that fit underneath.
|
||||
*
|
||||
* <p>The service type {@code Provider} is reserved for use by the
|
||||
* security framework. Services of this type cannot be added, removed,
|
||||
* or modified by applications.
|
||||
@ -82,6 +74,28 @@ import java.util.function.Function;
|
||||
* <td>{@code provider.getClass().getName()}</td>
|
||||
* </table>
|
||||
*
|
||||
* <p>Each provider has a name and a version number. A provider normally
|
||||
* identifies itself with a file named {@code java.security.Provider}
|
||||
* in the resource directory {@code META-INF/services}.
|
||||
* Security providers are looked up via the {@link ServiceLoader} mechanism
|
||||
* using the {@link ClassLoader#getSystemClassLoader application class loader}.
|
||||
*
|
||||
* <p>Providers may be configured such that they are automatically
|
||||
* installed and made available at runtime via the
|
||||
* {@link Security#getProviders() Security.getProviders()} method.
|
||||
* The mechanism for configuring and installing security providers is
|
||||
* implementation-specific.
|
||||
*
|
||||
* @implNote
|
||||
* The JDK implementation supports static registration of the security
|
||||
* providers via the {@code conf/security/java.security} file in the Java
|
||||
* installation directory. These providers are automatically installed by
|
||||
* the JDK runtime, see <a href =
|
||||
* "../../../technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
|
||||
* in the "Java Cryptography Architecture API Specification & Reference"
|
||||
* for information about how a particular type of provider, the cryptographic
|
||||
* service provider, works and is installed.
|
||||
*
|
||||
* @author Benjamin Renaud
|
||||
* @author Andreas Sterbenz
|
||||
*/
|
||||
@ -121,6 +135,18 @@ public abstract class Provider extends Properties {
|
||||
|
||||
private transient boolean initialized;
|
||||
|
||||
private static Object newInstanceUtil(final Class<?> clazz,
|
||||
final Class<?> ctrParamClz, final Object ctorParamObj)
|
||||
throws Exception {
|
||||
if (ctrParamClz == null) {
|
||||
Constructor<?> con = clazz.getConstructor();
|
||||
return con.newInstance();
|
||||
} else {
|
||||
Constructor<?> con = clazz.getConstructor(ctrParamClz);
|
||||
return con.newInstance(ctorParamObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a provider with the specified name, version number,
|
||||
* and information.
|
||||
@ -139,6 +165,34 @@ public abstract class Provider extends Properties {
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the supplied configuration argument to this provider instance
|
||||
* and return the configured provider. Note that if this provider cannot
|
||||
* be configured in-place, a new provider will be created and returned.
|
||||
* Therefore, callers should always use the returned provider.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation throws {@code UnsupportedOperationException}.
|
||||
* Subclasses should override this method only if a configuration argument
|
||||
* is supported.
|
||||
*
|
||||
* @param configArg the configuration information for configuring this
|
||||
* provider.
|
||||
*
|
||||
* @throws UnsupportedOperationException if a configuration argument is
|
||||
* not supported.
|
||||
* @throws NullPointerException if the supplied configuration argument is
|
||||
null.
|
||||
* @throws InvalidParameterException if the supplied configuration argument
|
||||
* is invalid.
|
||||
* @return a provider configured with the supplied configuration argument.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
public Provider configure(String configArg) {
|
||||
throw new UnsupportedOperationException("configure is not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this provider.
|
||||
*
|
||||
@ -212,8 +266,8 @@ public abstract class Provider extends Properties {
|
||||
/**
|
||||
* Reads a property list (key and element pairs) from the input stream.
|
||||
*
|
||||
* @param inStream the input stream.
|
||||
* @exception IOException if an error occurred when reading from the
|
||||
* @param inStream the input stream.
|
||||
* @exception IOException if an error occurred when reading from the
|
||||
* input stream.
|
||||
* @see java.util.Properties#load
|
||||
*/
|
||||
@ -1579,39 +1633,35 @@ public abstract class Provider extends Properties {
|
||||
}
|
||||
registered = true;
|
||||
}
|
||||
Class<?> ctrParamClz;
|
||||
try {
|
||||
EngineDescription cap = knownEngines.get(type);
|
||||
if (cap == null) {
|
||||
// unknown engine type, use generic code
|
||||
// this is the code path future for non-core
|
||||
// optional packages
|
||||
return newInstanceGeneric(constructorParameter);
|
||||
}
|
||||
if (cap.constructorParameterClassName == null) {
|
||||
if (constructorParameter != null) {
|
||||
throw new InvalidParameterException
|
||||
("constructorParameter not used with " + type
|
||||
+ " engines");
|
||||
}
|
||||
Class<?> clazz = getImplClass();
|
||||
Class<?>[] empty = {};
|
||||
Constructor<?> con = clazz.getConstructor(empty);
|
||||
return con.newInstance();
|
||||
ctrParamClz = constructorParameter == null?
|
||||
null : constructorParameter.getClass();
|
||||
} else {
|
||||
Class<?> paramClass = cap.getConstructorParameterClass();
|
||||
ctrParamClz = cap.constructorParameterClassName == null?
|
||||
null : Class.forName(cap.constructorParameterClassName);
|
||||
if (constructorParameter != null) {
|
||||
Class<?> argClass = constructorParameter.getClass();
|
||||
if (paramClass.isAssignableFrom(argClass) == false) {
|
||||
if (ctrParamClz == null) {
|
||||
throw new InvalidParameterException
|
||||
("constructorParameter must be instanceof "
|
||||
+ cap.constructorParameterClassName.replace('$', '.')
|
||||
+ " for engine type " + type);
|
||||
("constructorParameter not used with " + type
|
||||
+ " engines");
|
||||
} else {
|
||||
Class<?> argClass = constructorParameter.getClass();
|
||||
if (ctrParamClz.isAssignableFrom(argClass) == false) {
|
||||
throw new InvalidParameterException
|
||||
("constructorParameter must be instanceof "
|
||||
+ cap.constructorParameterClassName.replace('$', '.')
|
||||
+ " for engine type " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
Class<?> clazz = getImplClass();
|
||||
Constructor<?> cons = clazz.getConstructor(paramClass);
|
||||
return cons.newInstance(constructorParameter);
|
||||
}
|
||||
return newInstanceUtil(getImplClass(), ctrParamClz, constructorParameter);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw e;
|
||||
} catch (InvocationTargetException e) {
|
||||
@ -1654,43 +1704,6 @@ public abstract class Provider extends Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic code path for unknown engine types. Call the
|
||||
* no-args constructor if constructorParameter is null, otherwise
|
||||
* use the first matching constructor.
|
||||
*/
|
||||
private Object newInstanceGeneric(Object constructorParameter)
|
||||
throws Exception {
|
||||
Class<?> clazz = getImplClass();
|
||||
if (constructorParameter == null) {
|
||||
// create instance with public no-arg constructor if it exists
|
||||
try {
|
||||
Class<?>[] empty = {};
|
||||
Constructor<?> con = clazz.getConstructor(empty);
|
||||
return con.newInstance();
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new NoSuchAlgorithmException("No public no-arg "
|
||||
+ "constructor found in class " + className);
|
||||
}
|
||||
}
|
||||
Class<?> argClass = constructorParameter.getClass();
|
||||
Constructor<?>[] cons = clazz.getConstructors();
|
||||
// find first public constructor that can take the
|
||||
// argument as parameter
|
||||
for (Constructor<?> con : cons) {
|
||||
Class<?>[] paramTypes = con.getParameterTypes();
|
||||
if (paramTypes.length != 1) {
|
||||
continue;
|
||||
}
|
||||
if (paramTypes[0].isAssignableFrom(argClass) == false) {
|
||||
continue;
|
||||
}
|
||||
return con.newInstance(constructorParameter);
|
||||
}
|
||||
throw new NoSuchAlgorithmException("No public constructor matching "
|
||||
+ argClass.getName() + " found in class " + className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether this Service can use the specified parameter.
|
||||
* Returns false if this service cannot use the parameter. Returns
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2015, 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
|
||||
@ -41,7 +41,7 @@ import sun.security.jca.*;
|
||||
*
|
||||
* <p>The default values of security properties are read from an
|
||||
* implementation-specific location, which is typically the properties file
|
||||
* {@code lib/security/java.security} in the Java installation directory.
|
||||
* {@code conf/security/java.security} in the Java installation directory.
|
||||
*
|
||||
* @author Benjamin Renaud
|
||||
*/
|
||||
|
@ -737,7 +737,7 @@ public class Base64 {
|
||||
// anything left is invalid, if is not MIME.
|
||||
// if MIME, ignore all non-base64 character
|
||||
while (sp < sl) {
|
||||
if (isMIME && base64[src[sp++]] < 0)
|
||||
if (isMIME && base64[src[sp++] & 0xff] < 0)
|
||||
continue;
|
||||
throw new IllegalArgumentException(
|
||||
"Input byte array has incorrect ending byte at " + sp);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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
|
||||
@ -242,8 +242,6 @@ public class DoubleSummaryStatistics implements DoubleConsumer {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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,14 +150,12 @@ public class IntSummaryStatistics implements IntConsumer {
|
||||
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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
|
||||
@ -162,14 +162,12 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer {
|
||||
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
|
||||
|
@ -112,29 +112,36 @@ import java.util.Locale;
|
||||
* provider returns null instead of a name, the lookup will proceed as
|
||||
* described above as if the locale was not supported.
|
||||
* <p>
|
||||
* Starting from JDK8, the search order of locale sensitive services can
|
||||
* The search order of locale sensitive services can
|
||||
* be configured by using the "java.locale.providers" system property.
|
||||
* This system property declares the user's preferred order for looking up
|
||||
* the locale sensitive services separated by a comma. It is only read at
|
||||
* the Java runtime startup, so the later call to System.setProperty() won't
|
||||
* affect the order.
|
||||
* <p>
|
||||
* Java Runtime Environment provides the following four locale providers:
|
||||
* <ul>
|
||||
* <li> "CLDR": A provider based on Unicode Consortium's
|
||||
* <a href="http://cldr.unicode.org/">CLDR Project</a>.
|
||||
* <li> "JRE": represents the locale sensitive services that is compatible
|
||||
* with the prior JDK releases (same with JDK8's "JRE").
|
||||
* <li> "SPI": represents the locale sensitive services implementing the subclasses of
|
||||
* this {@code LocaleServiceProvider} class.
|
||||
* <li> "HOST": A provider that reflects the user's custom settings in the
|
||||
* underlying operating system. This provider may not be available, depending
|
||||
* on the Java Runtime Environment implementation.
|
||||
* </ul>
|
||||
* <p>
|
||||
* For example, if the following is specified in the property:
|
||||
* <pre>
|
||||
* java.locale.providers=SPI,JRE
|
||||
* java.locale.providers=SPI,CLDR,JRE
|
||||
* </pre>
|
||||
* where "SPI" represents the locale sensitive services implemented in the
|
||||
* installed SPI providers, and "JRE" represents the locale sensitive services
|
||||
* in the Java Runtime Environment, the locale sensitive services in the SPI
|
||||
* providers are looked up first.
|
||||
* the locale sensitive services in the SPI providers are looked up first. If the
|
||||
* desired locale sensitive service is not available, then the runtime looks for CLDR,
|
||||
* JRE in that order.
|
||||
* <p>
|
||||
* There are two other possible locale sensitive service providers, i.e., "CLDR"
|
||||
* which is a provider based on Unicode Consortium's
|
||||
* <a href="http://cldr.unicode.org/">CLDR Project</a>, and "HOST" which is a
|
||||
* provider that reflects the user's custom settings in the underlying operating
|
||||
* system. These two providers may not be available, depending on the Java Runtime
|
||||
* Environment implementation. Specifying "JRE,SPI" is identical to the default
|
||||
* behavior, which is compatibile with the prior releases.
|
||||
* The default order for looking up the preferred locale providers is "CLDR,JRE,SPI",
|
||||
* so specifying "CLDR,JRE,SPI" is identical to the default behavior.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
@ -249,6 +249,11 @@ abstract class AbstractPipeline<E_IN, E_OUT, S extends BaseStream<E_OUT, S>>
|
||||
// If the last intermediate operation is stateful then
|
||||
// evaluate directly to avoid an extra collection step
|
||||
if (isParallel() && previousStage != null && opIsStateful()) {
|
||||
// Set the depth of this, last, pipeline stage to zero to slice the
|
||||
// pipeline such that this operation will not be included in the
|
||||
// upstream slice and upstream operations will not be included
|
||||
// in this slice
|
||||
depth = 0;
|
||||
return opEvaluateParallel(previousStage, previousStage.sourceSpliterator(0), generator);
|
||||
}
|
||||
else {
|
||||
@ -402,47 +407,19 @@ abstract class AbstractPipeline<E_IN, E_OUT, S extends BaseStream<E_OUT, S>>
|
||||
throw new IllegalStateException(MSG_CONSUMED);
|
||||
}
|
||||
|
||||
boolean hasTerminalFlags = terminalFlags != 0;
|
||||
if (isParallel() && sourceStage.sourceAnyStateful) {
|
||||
// Adjust pipeline stages if there are stateful ops,
|
||||
// and find the last short circuiting op, if any, that
|
||||
// defines the head stage for back-propagation of terminal flags
|
||||
@SuppressWarnings("rawtypes")
|
||||
AbstractPipeline backPropagationHead = sourceStage;
|
||||
int depth = 1;
|
||||
for (@SuppressWarnings("rawtypes") AbstractPipeline p = sourceStage.nextStage;
|
||||
p != null;
|
||||
p = p.nextStage) {
|
||||
if (p.opIsStateful()) {
|
||||
if (StreamOpFlag.SHORT_CIRCUIT.isKnown(p.sourceOrOpFlags)) {
|
||||
// If the stateful operation is a short-circuit operation
|
||||
// then move the back propagation head forwards
|
||||
// NOTE: there are no size-injecting ops
|
||||
backPropagationHead = p;
|
||||
}
|
||||
|
||||
depth = 0;
|
||||
}
|
||||
p.depth = depth++;
|
||||
}
|
||||
|
||||
// Adapt the source spliterator, evaluating each stateful op
|
||||
// in the pipeline up to and including this pipeline stage
|
||||
// Flags for each pipeline stage are adjusted accordingly
|
||||
boolean backPropagate = false;
|
||||
int upstreamTerminalFlags = terminalFlags & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK;
|
||||
// in the pipeline up to and including this pipeline stage.
|
||||
// The depth and flags of each pipeline stage are adjusted accordingly.
|
||||
int depth = 1;
|
||||
for (@SuppressWarnings("rawtypes") AbstractPipeline u = sourceStage, p = sourceStage.nextStage, e = this;
|
||||
u != e;
|
||||
u = p, p = p.nextStage) {
|
||||
|
||||
if (hasTerminalFlags &&
|
||||
(backPropagate || (backPropagate = (u == backPropagationHead)))) {
|
||||
// Back-propagate flags from the terminal operation
|
||||
u.combinedFlags = StreamOpFlag.combineOpFlags(upstreamTerminalFlags, u.combinedFlags);
|
||||
}
|
||||
|
||||
int thisOpFlags = p.sourceOrOpFlags;
|
||||
if (p.opIsStateful()) {
|
||||
depth = 0;
|
||||
|
||||
if (StreamOpFlag.SHORT_CIRCUIT.isKnown(thisOpFlags)) {
|
||||
// Clear the short circuit flag for next pipeline stage
|
||||
// This stage encapsulates short-circuiting, the next
|
||||
@ -460,11 +437,12 @@ abstract class AbstractPipeline<E_IN, E_OUT, S extends BaseStream<E_OUT, S>>
|
||||
? (thisOpFlags & ~StreamOpFlag.NOT_SIZED) | StreamOpFlag.IS_SIZED
|
||||
: (thisOpFlags & ~StreamOpFlag.IS_SIZED) | StreamOpFlag.NOT_SIZED;
|
||||
}
|
||||
p.depth = depth++;
|
||||
p.combinedFlags = StreamOpFlag.combineOpFlags(thisOpFlags, u.combinedFlags);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasTerminalFlags) {
|
||||
if (terminalFlags != 0) {
|
||||
// Apply flags from the terminal operation to last pipeline stage
|
||||
combinedFlags = StreamOpFlag.combineOpFlags(terminalFlags, combinedFlags);
|
||||
}
|
||||
@ -472,7 +450,6 @@ abstract class AbstractPipeline<E_IN, E_OUT, S extends BaseStream<E_OUT, S>>
|
||||
return spliterator;
|
||||
}
|
||||
|
||||
|
||||
// PipelineHelper
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
@ -27,14 +27,15 @@ package sun.security.jca;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
import java.security.*;
|
||||
|
||||
import sun.security.util.PropertyExpander;
|
||||
|
||||
/**
|
||||
* Class representing a configured provider. Encapsulates configuration
|
||||
* (className plus optional argument), the provider loading logic, and
|
||||
* Class representing a configured provider which encapsulates configuration
|
||||
* (provider name + optional argument), the provider loading logic, and
|
||||
* the loaded Provider object itself.
|
||||
*
|
||||
* @author Andreas Sterbenz
|
||||
@ -45,9 +46,8 @@ final class ProviderConfig {
|
||||
private final static sun.security.util.Debug debug =
|
||||
sun.security.util.Debug.getInstance("jca", "ProviderConfig");
|
||||
|
||||
// classname of the SunPKCS11-Solaris provider
|
||||
private static final String P11_SOL_NAME =
|
||||
"sun.security.pkcs11.SunPKCS11";
|
||||
// suffix for identifying the SunPKCS11-Solaris provider
|
||||
private static final String P11_SOL_NAME = "SunPKCS11";
|
||||
|
||||
// config file argument of the SunPKCS11-Solaris provider
|
||||
private static final String P11_SOL_ARG =
|
||||
@ -56,15 +56,10 @@ final class ProviderConfig {
|
||||
// maximum number of times to try loading a provider before giving up
|
||||
private final static int MAX_LOAD_TRIES = 30;
|
||||
|
||||
// parameters for the Provider(String) constructor,
|
||||
// use by doLoadProvider()
|
||||
private final static Class<?>[] CL_STRING = { String.class };
|
||||
// could be provider name (module) or provider class name (legacy)
|
||||
private final String provName;
|
||||
|
||||
// name of the provider class
|
||||
private final String className;
|
||||
|
||||
// argument to the provider constructor,
|
||||
// empty string indicates no-arg constructor
|
||||
// argument to the Provider.configure() call, never null
|
||||
private final String argument;
|
||||
|
||||
// number of times we have already tried to load this provider
|
||||
@ -77,20 +72,20 @@ final class ProviderConfig {
|
||||
// used to detect recursion
|
||||
private boolean isLoading;
|
||||
|
||||
ProviderConfig(String className, String argument) {
|
||||
if (className.equals(P11_SOL_NAME) && argument.equals(P11_SOL_ARG)) {
|
||||
ProviderConfig(String provName, String argument) {
|
||||
if (provName.endsWith(P11_SOL_NAME) && argument.equals(P11_SOL_ARG)) {
|
||||
checkSunPKCS11Solaris();
|
||||
}
|
||||
this.className = className;
|
||||
this.provName = provName;
|
||||
this.argument = expand(argument);
|
||||
}
|
||||
|
||||
ProviderConfig(String className) {
|
||||
this(className, "");
|
||||
ProviderConfig(String provName) {
|
||||
this(provName, "");
|
||||
}
|
||||
|
||||
ProviderConfig(Provider provider) {
|
||||
this.className = provider.getClass().getName();
|
||||
this.provName = provider.getName();
|
||||
this.argument = "";
|
||||
this.provider = provider;
|
||||
}
|
||||
@ -144,19 +139,20 @@ final class ProviderConfig {
|
||||
return false;
|
||||
}
|
||||
ProviderConfig other = (ProviderConfig)obj;
|
||||
return this.className.equals(other.className)
|
||||
return this.provName.equals(other.provName)
|
||||
&& this.argument.equals(other.argument);
|
||||
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return className.hashCode() + argument.hashCode();
|
||||
return provName.hashCode() + argument.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (hasArgument()) {
|
||||
return className + "('" + argument + "')";
|
||||
return provName + "('" + argument + "')";
|
||||
} else {
|
||||
return className;
|
||||
return provName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,21 +168,33 @@ final class ProviderConfig {
|
||||
if (shouldLoad() == false) {
|
||||
return null;
|
||||
}
|
||||
if (isLoading) {
|
||||
// because this method is synchronized, this can only
|
||||
// happen if there is recursion.
|
||||
if (debug != null) {
|
||||
debug.println("Recursion loading provider: " + this);
|
||||
new Exception("Call trace").printStackTrace();
|
||||
|
||||
// Create providers which are in java.base directly
|
||||
if (provName.equals("SUN") || provName.equals("sun.security.provider.Sun")) {
|
||||
p = new sun.security.provider.Sun();
|
||||
} else if (provName.equals("SunRsaSign") || provName.equals("sun.security.rsa.SunRsaSign")) {
|
||||
p = new sun.security.rsa.SunRsaSign();
|
||||
} else if (provName.equals("SunJCE") || provName.equals("com.sun.crypto.provider.SunJCE")) {
|
||||
p = new com.sun.crypto.provider.SunJCE();
|
||||
} else if (provName.equals("SunJSSE") || provName.equals("com.sun.net.ssl.internal.ssl.Provider")) {
|
||||
p = new com.sun.net.ssl.internal.ssl.Provider();
|
||||
} else {
|
||||
if (isLoading) {
|
||||
// because this method is synchronized, this can only
|
||||
// happen if there is recursion.
|
||||
if (debug != null) {
|
||||
debug.println("Recursion loading provider: " + this);
|
||||
new Exception("Call trace").printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
isLoading = true;
|
||||
tries++;
|
||||
p = doLoadProvider();
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
isLoading = true;
|
||||
tries++;
|
||||
p = doLoadProvider();
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
provider = p;
|
||||
return p;
|
||||
@ -206,55 +214,39 @@ final class ProviderConfig {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Provider>() {
|
||||
public Provider run() {
|
||||
if (debug != null) {
|
||||
debug.println("Loading provider: " + ProviderConfig.this);
|
||||
debug.println("Loading provider " + ProviderConfig.this);
|
||||
}
|
||||
ProviderLoader pl = new ProviderLoader();
|
||||
try {
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
Class<?> provClass;
|
||||
if (cl != null) {
|
||||
provClass = cl.loadClass(className);
|
||||
} else {
|
||||
provClass = Class.forName(className);
|
||||
}
|
||||
Object obj;
|
||||
if (hasArgument() == false) {
|
||||
obj = provClass.newInstance();
|
||||
} else {
|
||||
Constructor<?> cons = provClass.getConstructor(CL_STRING);
|
||||
obj = cons.newInstance(argument);
|
||||
}
|
||||
if (obj instanceof Provider) {
|
||||
if (debug != null) {
|
||||
debug.println("Loaded provider " + obj);
|
||||
Provider p = pl.load(provName);
|
||||
if (p != null) {
|
||||
if (hasArgument()) {
|
||||
p = p.configure(argument);
|
||||
}
|
||||
if (debug != null) {
|
||||
debug.println("Loaded provider " + p.getName());
|
||||
}
|
||||
return (Provider)obj;
|
||||
} else {
|
||||
if (debug != null) {
|
||||
debug.println(className + " is not a provider");
|
||||
debug.println("Error loading provider " +
|
||||
ProviderConfig.this);
|
||||
}
|
||||
disableLoad();
|
||||
}
|
||||
return p;
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ProviderException) {
|
||||
// pass up
|
||||
throw e;
|
||||
} else {
|
||||
if (debug != null) {
|
||||
debug.println("Error loading provider " +
|
||||
ProviderConfig.this);
|
||||
e.printStackTrace();
|
||||
}
|
||||
disableLoad();
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwable t;
|
||||
if (e instanceof InvocationTargetException) {
|
||||
t = ((InvocationTargetException)e).getCause();
|
||||
} else {
|
||||
t = e;
|
||||
}
|
||||
if (debug != null) {
|
||||
debug.println("Error loading provider " + ProviderConfig.this);
|
||||
t.printStackTrace();
|
||||
}
|
||||
// provider indicates fatal error, pass through exception
|
||||
if (t instanceof ProviderException) {
|
||||
throw (ProviderException)t;
|
||||
}
|
||||
// provider indicates that loading should not be retried
|
||||
if (t instanceof UnsupportedOperationException) {
|
||||
disableLoad();
|
||||
}
|
||||
return null;
|
||||
} catch (ExceptionInInitializerError err) {
|
||||
// no sufficient permission to initialize provider class
|
||||
if (debug != null) {
|
||||
@ -289,4 +281,119 @@ final class ProviderConfig {
|
||||
});
|
||||
}
|
||||
|
||||
// Inner class for loading security providers listed in java.security file
|
||||
private static final class ProviderLoader {
|
||||
private final ServiceLoader<Provider> services;
|
||||
|
||||
ProviderLoader() {
|
||||
// VM should already been booted at this point, if not
|
||||
// - Only providers in java.base should be loaded, don't use
|
||||
// ServiceLoader
|
||||
// - ClassLoader.getSystemClassLoader() will throw InternalError
|
||||
services = ServiceLoader.load(java.security.Provider.class,
|
||||
ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the provider with the specified class name.
|
||||
*
|
||||
* @param name the name of the provider
|
||||
* @return the Provider, or null if it cannot be found or loaded
|
||||
* @throws ProviderException all other exceptions are ignored
|
||||
*/
|
||||
public Provider load(String pn) {
|
||||
if (debug != null) {
|
||||
debug.println("Attempt to load " + pn + " using SL");
|
||||
}
|
||||
Iterator<Provider> iter = services.iterator();
|
||||
while (iter.hasNext()) {
|
||||
try {
|
||||
Provider p = iter.next();
|
||||
String pName = p.getName();
|
||||
if (debug != null) {
|
||||
debug.println("Found SL Provider named " + pName);
|
||||
}
|
||||
if (pName.equals(pn)) {
|
||||
return p;
|
||||
}
|
||||
} catch (SecurityException | ServiceConfigurationError |
|
||||
InvalidParameterException ex) {
|
||||
// if provider loading fail due to security permission,
|
||||
// log it and move on to next provider
|
||||
if (debug != null) {
|
||||
debug.println("Encountered " + ex +
|
||||
" while iterating through SL, ignore and move on");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
// No success with ServiceLoader. Try loading provider the legacy,
|
||||
// i.e. pre-module, way via reflection
|
||||
try {
|
||||
return legacyLoad(pn);
|
||||
} catch (ProviderException pe) {
|
||||
// pass through
|
||||
throw pe;
|
||||
} catch (Exception ex) {
|
||||
// logged and ignored
|
||||
if (debug != null) {
|
||||
debug.println("Encountered " + ex +
|
||||
" during legacy load of " + pn);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Provider legacyLoad(String classname) {
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Loading legacy provider: " + classname);
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> provClass =
|
||||
ClassLoader.getSystemClassLoader().loadClass(classname);
|
||||
|
||||
// only continue if the specified class extends Provider
|
||||
if (!Provider.class.isAssignableFrom(provClass)) {
|
||||
if (debug != null) {
|
||||
debug.println(classname + " is not a provider");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Provider p = AccessController.doPrivileged
|
||||
(new PrivilegedExceptionAction<Provider>() {
|
||||
public Provider run() throws Exception {
|
||||
return (Provider) provClass.newInstance();
|
||||
}
|
||||
});
|
||||
return p;
|
||||
} catch (Exception e) {
|
||||
Throwable t;
|
||||
if (e instanceof InvocationTargetException) {
|
||||
t = ((InvocationTargetException)e).getCause();
|
||||
} else {
|
||||
t = e;
|
||||
}
|
||||
if (debug != null) {
|
||||
debug.println("Error loading legacy provider " + classname);
|
||||
t.printStackTrace();
|
||||
}
|
||||
// provider indicates fatal error, pass through exception
|
||||
if (t instanceof ProviderException) {
|
||||
throw (ProviderException) t;
|
||||
}
|
||||
return null;
|
||||
} catch (ExceptionInInitializerError | NoClassDefFoundError err) {
|
||||
// no sufficient permission to access/initialize provider class
|
||||
if (debug != null) {
|
||||
debug.println("Error loading legacy provider " + classname);
|
||||
err.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
@ -178,9 +178,9 @@ public final class ProviderList {
|
||||
if (k == -1) {
|
||||
config = new ProviderConfig(entry);
|
||||
} else {
|
||||
String className = entry.substring(0, k);
|
||||
String provName = entry.substring(0, k);
|
||||
String argument = entry.substring(k + 1).trim();
|
||||
config = new ProviderConfig(className, argument);
|
||||
config = new ProviderConfig(provName, argument);
|
||||
}
|
||||
|
||||
// Get rid of duplicate providers.
|
||||
@ -200,10 +200,10 @@ public final class ProviderList {
|
||||
* bootclasspath and cannot be in signed JAR files. This is to avoid
|
||||
* possible recursion and deadlock during verification.
|
||||
*/
|
||||
ProviderList getJarList(String[] jarClassNames) {
|
||||
ProviderList getJarList(String[] jarProvNames) {
|
||||
List<ProviderConfig> newConfigs = new ArrayList<>();
|
||||
for (String className : jarClassNames) {
|
||||
ProviderConfig newConfig = new ProviderConfig(className);
|
||||
for (String provName : jarProvNames) {
|
||||
ProviderConfig newConfig = new ProviderConfig(provName);
|
||||
for (ProviderConfig config : configs) {
|
||||
// if the equivalent object is present in this provider list,
|
||||
// use the old object rather than the new object.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
@ -58,9 +58,13 @@ public class Providers {
|
||||
// empty
|
||||
}
|
||||
|
||||
// we need special handling to resolve circularities when loading
|
||||
// signed JAR files during startup. The code below is part of that.
|
||||
|
||||
// After the switch to modules, JDK providers are all in modules and JDK
|
||||
// no longer needs to load signed jars during start up.
|
||||
//
|
||||
// However, for earlier releases, it need special handling to resolve
|
||||
// circularities when loading signed JAR files during startup. The code
|
||||
// below is part of that.
|
||||
//
|
||||
// Basically, before we load data from a signed JAR file, we parse
|
||||
// the PKCS#7 file and verify the signature. We need a
|
||||
// CertificateFactory, Signatures, etc. to do that. We have to make
|
||||
@ -75,35 +79,24 @@ public class Providers {
|
||||
// The code here is used by sun.security.util.SignatureFileVerifier.
|
||||
// See there for details.
|
||||
|
||||
private static final String BACKUP_PROVIDER_CLASSNAME =
|
||||
"sun.security.provider.VerificationProvider";
|
||||
|
||||
// Hardcoded classnames of providers to use for JAR verification.
|
||||
// Hardcoded names of providers to use for JAR verification.
|
||||
// MUST NOT be on the bootclasspath and not in signed JAR files.
|
||||
private static final String[] jarVerificationProviders = {
|
||||
"sun.security.provider.Sun",
|
||||
"sun.security.rsa.SunRsaSign",
|
||||
// Note: SunEC *is* in a signed JAR file, but it's not signed
|
||||
// by EC itself. So it's still safe to be listed here.
|
||||
"SUN",
|
||||
"SunRsaSign",
|
||||
// Note: when SunEC is in a signed JAR file, it's not signed
|
||||
// by EC algorithms. So it's still safe to be listed here.
|
||||
// Need to use class name here, otherwise it cannot be loaded for
|
||||
// jar verification. Only those providers in java.base are created
|
||||
// directly by ProviderConfig class.
|
||||
"sun.security.ec.SunEC",
|
||||
BACKUP_PROVIDER_CLASSNAME,
|
||||
};
|
||||
|
||||
// Return to Sun provider or its backup.
|
||||
// Return Sun provider.
|
||||
// This method should only be called by
|
||||
// sun.security.util.ManifestEntryVerifier and java.security.SecureRandom.
|
||||
public static Provider getSunProvider() {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(jarVerificationProviders[0]);
|
||||
return (Provider)clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(BACKUP_PROVIDER_CLASSNAME);
|
||||
return (Provider)clazz.newInstance();
|
||||
} catch (Exception ee) {
|
||||
throw new RuntimeException("Sun provider not found", e);
|
||||
}
|
||||
}
|
||||
return new sun.security.provider.Sun();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,6 +108,16 @@ public class Providers {
|
||||
public static Object startJarVerification() {
|
||||
ProviderList currentList = getProviderList();
|
||||
ProviderList jarList = currentList.getJarList(jarVerificationProviders);
|
||||
if (jarList.getProvider("SUN") == null) {
|
||||
// add backup provider
|
||||
Provider p;
|
||||
try {
|
||||
p = new sun.security.provider.VerificationProvider();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Missing provider for jar verification", e);
|
||||
}
|
||||
ProviderList.add(jarList, p);
|
||||
}
|
||||
// return the old thread-local provider list, usually null
|
||||
return beginThreadProviderList(jarList);
|
||||
}
|
||||
|
@ -728,21 +728,19 @@ public final class Main {
|
||||
provClass = Class.forName(provName);
|
||||
}
|
||||
|
||||
String provArg = provider.snd;
|
||||
Object obj;
|
||||
if (provArg == null) {
|
||||
obj = provClass.newInstance();
|
||||
} else {
|
||||
Constructor<?> c = provClass.getConstructor(PARAM_STRING);
|
||||
obj = c.newInstance(provArg);
|
||||
}
|
||||
Object obj = provClass.newInstance();
|
||||
if (!(obj instanceof Provider)) {
|
||||
MessageFormat form = new MessageFormat
|
||||
(rb.getString("provName.not.a.provider"));
|
||||
Object[] source = {provName};
|
||||
throw new Exception(form.format(source));
|
||||
}
|
||||
Security.addProvider((Provider)obj);
|
||||
Provider p = (Provider) obj;
|
||||
String provArg = provider.snd;
|
||||
if (provArg != null) {
|
||||
p = p.configure(provArg);
|
||||
}
|
||||
Security.addProvider(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -858,9 +858,6 @@ public class FormatData extends ParallelListResourceBundle {
|
||||
}
|
||||
},
|
||||
{ "DateTimePatternChars", "GyMdkHmsSEDFwWahKzZ" },
|
||||
|
||||
// Workaround for islamic-umalqura name support (JDK-8015986)
|
||||
{ "calendarname.islamic-umalqura", "Islamic Umm al-Qura Calendar" },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,37 +26,41 @@
|
||||
/*
|
||||
* COPYRIGHT AND PERMISSION NOTICE
|
||||
*
|
||||
* Copyright (C) 1991-2012 Unicode, Inc. All rights reserved. Distributed under
|
||||
* the Terms of Use in http://www.unicode.org/copyright.html.
|
||||
* Copyright (C) 1991-2015 Unicode, Inc. All rights reserved.
|
||||
* Distributed under the Terms of Use in
|
||||
* http://www.unicode.org/copyright.html.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of the Unicode data files and any associated documentation (the "Data
|
||||
* Files") or Unicode software and any associated documentation (the
|
||||
* "Software") to deal in the Data Files or Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, and/or sell copies of the Data Files or Software, and
|
||||
* to permit persons to whom the Data Files or Software are furnished to do so,
|
||||
* provided that (a) the above copyright notice(s) and this permission notice
|
||||
* appear with all copies of the Data Files or Software, (b) both the above
|
||||
* copyright notice(s) and this permission notice appear in associated
|
||||
* documentation, and (c) there is clear notice in each modified Data File or
|
||||
* in the Software as well as in the documentation associated with the Data
|
||||
* File(s) or Software that the data or software has been modified.
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of the Unicode data files and any associated documentation
|
||||
* (the "Data Files") or Unicode software and any associated documentation
|
||||
* (the "Software") to deal in the Data Files or Software
|
||||
* without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, and/or sell copies of
|
||||
* the Data Files or Software, and to permit persons to whom the Data Files
|
||||
* or Software are furnished to do so, provided that
|
||||
* (a) this copyright and permission notice appear with all copies
|
||||
* of the Data Files or Software,
|
||||
* (b) this copyright and permission notice appear in associated
|
||||
* documentation, and
|
||||
* (c) there is clear notice in each modified Data File or in the Software
|
||||
* as well as in the documentation associated with the Data File(s) or
|
||||
* Software that the data or software has been modified.
|
||||
*
|
||||
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
|
||||
* NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THE DATA FILES OR SOFTWARE.
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of a copyright holder shall not
|
||||
* be used in advertising or otherwise to promote the sale, use or other
|
||||
* dealings in these Data Files or Software without prior written authorization
|
||||
* of the copyright holder.
|
||||
* Except as contained in this notice, the name of a copyright holder
|
||||
* shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in these Data Files or Software without prior
|
||||
* written authorization of the copyright holder.
|
||||
*/
|
||||
|
||||
// Note: this file has been generated by a tool.
|
||||
@ -68,6 +72,21 @@ import sun.util.resources.OpenListResourceBundle;
|
||||
public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
@Override
|
||||
protected final Object[][] getContents() {
|
||||
final String[] rocMonthNarrows = {
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"",
|
||||
};
|
||||
return new Object[][] {
|
||||
{ "QuarterAbbreviations",
|
||||
new String[] {
|
||||
@ -93,22 +112,6 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
"4",
|
||||
}
|
||||
},
|
||||
{ "calendarname.buddhist",
|
||||
"Buddhist Calendar" },
|
||||
{ "calendarname.gregorian",
|
||||
"Gregorian Calendar" },
|
||||
{ "calendarname.gregory",
|
||||
"Gregorian Calendar" },
|
||||
{ "calendarname.islamic",
|
||||
"Islamic Calendar" },
|
||||
{ "calendarname.islamic-civil",
|
||||
"Islamic-Civil Calendar" },
|
||||
{ "calendarname.islamicc",
|
||||
"Islamic-Civil Calendar" },
|
||||
{ "calendarname.japanese",
|
||||
"Japanese Calendar" },
|
||||
{ "calendarname.roc",
|
||||
"Minguo Calendar" },
|
||||
{ "field.dayperiod",
|
||||
"Dayperiod" },
|
||||
{ "field.era",
|
||||
@ -129,12 +132,51 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
"Year" },
|
||||
{ "field.zone",
|
||||
"Zone" },
|
||||
{ "islamic.AmPmMarkers",
|
||||
new String[] {
|
||||
"AM",
|
||||
"PM",
|
||||
}
|
||||
},
|
||||
{ "islamic.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, MMMM d, y GGGG",
|
||||
"MMMM d, y GGGG",
|
||||
"MMM d, y GGGG",
|
||||
"M/d/yy GGGG",
|
||||
"GGGG y MMMM d, EEEE",
|
||||
"GGGG y MMMM d",
|
||||
"GGGG y MMM d",
|
||||
"G y-MM-dd",
|
||||
}
|
||||
},
|
||||
{ "islamic.DayAbbreviations",
|
||||
new String[] {
|
||||
"Sun",
|
||||
"Mon",
|
||||
"Tue",
|
||||
"Wed",
|
||||
"Thu",
|
||||
"Fri",
|
||||
"Sat",
|
||||
}
|
||||
},
|
||||
{ "islamic.DayNames",
|
||||
new String[] {
|
||||
"Sun",
|
||||
"Mon",
|
||||
"Tue",
|
||||
"Wed",
|
||||
"Thu",
|
||||
"Fri",
|
||||
"Sat",
|
||||
}
|
||||
},
|
||||
{ "islamic.DayNarrows",
|
||||
new String[] {
|
||||
"S",
|
||||
"M",
|
||||
"T",
|
||||
"W",
|
||||
"T",
|
||||
"F",
|
||||
"S",
|
||||
}
|
||||
},
|
||||
{ "islamic.Eras",
|
||||
@ -178,20 +220,47 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
}
|
||||
},
|
||||
{ "islamic.MonthNarrows",
|
||||
rocMonthNarrows },
|
||||
{ "islamic.QuarterNames",
|
||||
new String[] {
|
||||
"Q1",
|
||||
"Q2",
|
||||
"Q3",
|
||||
"Q4",
|
||||
}
|
||||
},
|
||||
{ "islamic.QuarterNarrows",
|
||||
new String[] {
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
}
|
||||
},
|
||||
{ "islamic.TimePatterns",
|
||||
new String[] {
|
||||
"HH:mm:ss zzzz",
|
||||
"HH:mm:ss z",
|
||||
"HH:mm:ss",
|
||||
"HH:mm",
|
||||
}
|
||||
},
|
||||
{ "islamic.long.Eras",
|
||||
new String[] {
|
||||
"",
|
||||
"AH",
|
||||
}
|
||||
},
|
||||
{ "islamic.narrow.AmPmMarkers",
|
||||
new String[] {
|
||||
"a",
|
||||
"p",
|
||||
}
|
||||
},
|
||||
{ "islamic.narrow.Eras",
|
||||
new String[] {
|
||||
"",
|
||||
"AH",
|
||||
}
|
||||
},
|
||||
{ "islamic.short.Eras",
|
||||
@ -202,10 +271,16 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
},
|
||||
{ "java.time.buddhist.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, G y MMMM dd",
|
||||
"G y MMMM d, EEEE",
|
||||
"G y MMMM d",
|
||||
"G y MMM d",
|
||||
"GGGGG yyyy-MM-dd",
|
||||
"GGGGG y-MM-dd",
|
||||
}
|
||||
},
|
||||
{ "java.time.buddhist.long.Eras",
|
||||
new String[] {
|
||||
"BC",
|
||||
"BE",
|
||||
}
|
||||
},
|
||||
{ "java.time.buddhist.short.Eras",
|
||||
@ -216,10 +291,10 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
},
|
||||
{ "java.time.islamic.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, MMMM d, y G",
|
||||
"MMMM d, y G",
|
||||
"MMM d, y G",
|
||||
"M/d/yy G",
|
||||
"G y MMMM d, EEEE",
|
||||
"G y MMMM d",
|
||||
"G y MMM d",
|
||||
"GGGGG y-MM-dd",
|
||||
}
|
||||
},
|
||||
{ "java.time.japanese.DatePatterns",
|
||||
@ -248,12 +323,18 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
"Heisei",
|
||||
}
|
||||
},
|
||||
{ "java.time.long.Eras",
|
||||
new String[] {
|
||||
"BCE",
|
||||
"CE",
|
||||
}
|
||||
},
|
||||
{ "java.time.roc.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, G y MMMM dd",
|
||||
"G y MMMM d, EEEE",
|
||||
"G y MMMM d",
|
||||
"G y MMM d",
|
||||
"GGGGG yyy-MM-dd",
|
||||
"GGGGG y-MM-dd",
|
||||
}
|
||||
},
|
||||
{ "java.time.short.Eras",
|
||||
@ -262,12 +343,40 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
"AD",
|
||||
}
|
||||
},
|
||||
{ "roc.AmPmMarkers",
|
||||
new String[] {
|
||||
"AM",
|
||||
"PM",
|
||||
}
|
||||
},
|
||||
{ "roc.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, GGGG y MMMM dd",
|
||||
"GGGG y MMMM d, EEEE",
|
||||
"GGGG y MMMM d",
|
||||
"GGGG y MMM d",
|
||||
"G yyy-MM-dd",
|
||||
"G y-MM-dd",
|
||||
}
|
||||
},
|
||||
{ "roc.DayNames",
|
||||
new String[] {
|
||||
"Sun",
|
||||
"Mon",
|
||||
"Tue",
|
||||
"Wed",
|
||||
"Thu",
|
||||
"Fri",
|
||||
"Sat",
|
||||
}
|
||||
},
|
||||
{ "roc.DayNarrows",
|
||||
new String[] {
|
||||
"S",
|
||||
"M",
|
||||
"T",
|
||||
"W",
|
||||
"T",
|
||||
"F",
|
||||
"S",
|
||||
}
|
||||
},
|
||||
{ "roc.Eras",
|
||||
@ -276,6 +385,84 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
||||
"R.O.C.",
|
||||
}
|
||||
},
|
||||
{ "roc.MonthAbbreviations",
|
||||
new String[] {
|
||||
"M01",
|
||||
"M02",
|
||||
"M03",
|
||||
"M04",
|
||||
"M05",
|
||||
"M06",
|
||||
"M07",
|
||||
"M08",
|
||||
"M09",
|
||||
"M10",
|
||||
"M11",
|
||||
"M12",
|
||||
"",
|
||||
}
|
||||
},
|
||||
{ "roc.MonthNames",
|
||||
new String[] {
|
||||
"M01",
|
||||
"M02",
|
||||
"M03",
|
||||
"M04",
|
||||
"M05",
|
||||
"M06",
|
||||
"M07",
|
||||
"M08",
|
||||
"M09",
|
||||
"M10",
|
||||
"M11",
|
||||
"M12",
|
||||
"",
|
||||
}
|
||||
},
|
||||
{ "roc.MonthNarrows",
|
||||
rocMonthNarrows },
|
||||
{ "roc.QuarterNames",
|
||||
new String[] {
|
||||
"Q1",
|
||||
"Q2",
|
||||
"Q3",
|
||||
"Q4",
|
||||
}
|
||||
},
|
||||
{ "roc.QuarterNarrows",
|
||||
new String[] {
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
}
|
||||
},
|
||||
{ "roc.TimePatterns",
|
||||
new String[] {
|
||||
"HH:mm:ss zzzz",
|
||||
"HH:mm:ss z",
|
||||
"HH:mm:ss",
|
||||
"HH:mm",
|
||||
}
|
||||
},
|
||||
{ "roc.long.Eras",
|
||||
new String[] {
|
||||
"Before R.O.C.",
|
||||
"R.O.C.",
|
||||
}
|
||||
},
|
||||
{ "roc.narrow.AmPmMarkers",
|
||||
new String[] {
|
||||
"a",
|
||||
"p",
|
||||
}
|
||||
},
|
||||
{ "roc.narrow.Eras",
|
||||
new String[] {
|
||||
"Before R.O.C.",
|
||||
"R.O.C.",
|
||||
}
|
||||
},
|
||||
{ "roc.short.Eras",
|
||||
new String[] {
|
||||
"Before R.O.C.",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,37 +26,41 @@
|
||||
/*
|
||||
* COPYRIGHT AND PERMISSION NOTICE
|
||||
*
|
||||
* Copyright (C) 1991-2012 Unicode, Inc. All rights reserved. Distributed under
|
||||
* the Terms of Use in http://www.unicode.org/copyright.html.
|
||||
* Copyright (C) 1991-2015 Unicode, Inc. All rights reserved.
|
||||
* Distributed under the Terms of Use in
|
||||
* http://www.unicode.org/copyright.html.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of the Unicode data files and any associated documentation (the "Data
|
||||
* Files") or Unicode software and any associated documentation (the
|
||||
* "Software") to deal in the Data Files or Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, and/or sell copies of the Data Files or Software, and
|
||||
* to permit persons to whom the Data Files or Software are furnished to do so,
|
||||
* provided that (a) the above copyright notice(s) and this permission notice
|
||||
* appear with all copies of the Data Files or Software, (b) both the above
|
||||
* copyright notice(s) and this permission notice appear in associated
|
||||
* documentation, and (c) there is clear notice in each modified Data File or
|
||||
* in the Software as well as in the documentation associated with the Data
|
||||
* File(s) or Software that the data or software has been modified.
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of the Unicode data files and any associated documentation
|
||||
* (the "Data Files") or Unicode software and any associated documentation
|
||||
* (the "Software") to deal in the Data Files or Software
|
||||
* without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, and/or sell copies of
|
||||
* the Data Files or Software, and to permit persons to whom the Data Files
|
||||
* or Software are furnished to do so, provided that
|
||||
* (a) this copyright and permission notice appear with all copies
|
||||
* of the Data Files or Software,
|
||||
* (b) this copyright and permission notice appear in associated
|
||||
* documentation, and
|
||||
* (c) there is clear notice in each modified Data File or in the Software
|
||||
* as well as in the documentation associated with the Data File(s) or
|
||||
* Software that the data or software has been modified.
|
||||
*
|
||||
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
|
||||
* NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THE DATA FILES OR SOFTWARE.
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of a copyright holder shall not
|
||||
* be used in advertising or otherwise to promote the sale, use or other
|
||||
* dealings in these Data Files or Software without prior written authorization
|
||||
* of the copyright holder.
|
||||
* Except as contained in this notice, the name of a copyright holder
|
||||
* shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in these Data Files or Software without prior
|
||||
* written authorization of the copyright holder.
|
||||
*/
|
||||
|
||||
// Note: this file has been generated by a tool.
|
||||
@ -69,14 +73,6 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
@Override
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "QuarterAbbreviations",
|
||||
new String[] {
|
||||
"Q1",
|
||||
"Q2",
|
||||
"Q3",
|
||||
"Q4",
|
||||
}
|
||||
},
|
||||
{ "QuarterNames",
|
||||
new String[] {
|
||||
"1st quarter",
|
||||
@ -94,31 +90,15 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
{ "calendarname.islamic",
|
||||
"Islamic Calendar" },
|
||||
{ "calendarname.islamic-civil",
|
||||
"Islamic-Civil Calendar" },
|
||||
{ "calendarname.islamicc",
|
||||
"Islamic-Civil Calendar" },
|
||||
"Islamic Calendar (tabular, civil epoch)" },
|
||||
{ "calendarname.islamic-umalqura",
|
||||
"Islamic Calendar (Umm al-Qura)" },
|
||||
{ "calendarname.japanese",
|
||||
"Japanese Calendar" },
|
||||
{ "calendarname.roc",
|
||||
"Minguo Calendar" },
|
||||
{ "field.dayperiod",
|
||||
"AM/PM" },
|
||||
{ "field.era",
|
||||
"Era" },
|
||||
{ "field.hour",
|
||||
"Hour" },
|
||||
{ "field.minute",
|
||||
"Minute" },
|
||||
{ "field.month",
|
||||
"Month" },
|
||||
{ "field.second",
|
||||
"Second" },
|
||||
{ "field.week",
|
||||
"Week" },
|
||||
{ "field.weekday",
|
||||
"Day of the Week" },
|
||||
{ "field.year",
|
||||
"Year" },
|
||||
{ "field.zone",
|
||||
"Time Zone" },
|
||||
{ "islamic.DatePatterns",
|
||||
@ -126,7 +106,42 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
"EEEE, MMMM d, y GGGG",
|
||||
"MMMM d, y GGGG",
|
||||
"MMM d, y GGGG",
|
||||
"M/d/yy GGGG",
|
||||
"M/d/y G",
|
||||
}
|
||||
},
|
||||
{ "islamic.DayNames",
|
||||
new String[] {
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
}
|
||||
},
|
||||
{ "islamic.QuarterAbbreviations",
|
||||
new String[] {
|
||||
"Q1",
|
||||
"Q2",
|
||||
"Q3",
|
||||
"Q4",
|
||||
}
|
||||
},
|
||||
{ "islamic.QuarterNames",
|
||||
new String[] {
|
||||
"1st quarter",
|
||||
"2nd quarter",
|
||||
"3rd quarter",
|
||||
"4th quarter",
|
||||
}
|
||||
},
|
||||
{ "islamic.TimePatterns",
|
||||
new String[] {
|
||||
"h:mm:ss a zzzz",
|
||||
"h:mm:ss a z",
|
||||
"h:mm:ss a",
|
||||
"h:mm a",
|
||||
}
|
||||
},
|
||||
{ "java.time.buddhist.DatePatterns",
|
||||
@ -134,7 +149,13 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
"EEEE, MMMM d, y G",
|
||||
"MMMM d, y G",
|
||||
"MMM d, y G",
|
||||
"M/d/yy GGGGG",
|
||||
"M/d/y GGGGG",
|
||||
}
|
||||
},
|
||||
{ "java.time.buddhist.short.Eras",
|
||||
new String[] {
|
||||
"BC",
|
||||
"BE",
|
||||
}
|
||||
},
|
||||
{ "java.time.islamic.DatePatterns",
|
||||
@ -142,7 +163,7 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
"EEEE, MMMM d, y G",
|
||||
"MMMM d, y G",
|
||||
"MMM d, y G",
|
||||
"M/d/yy G",
|
||||
"M/d/y GGGGG",
|
||||
}
|
||||
},
|
||||
{ "java.time.japanese.DatePatterns",
|
||||
@ -150,7 +171,7 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
"EEEE, MMMM d, y G",
|
||||
"MMMM d, y G",
|
||||
"MMM d, y G",
|
||||
"M/d/yy GGGGG",
|
||||
"M/d/y GGGGG",
|
||||
}
|
||||
},
|
||||
{ "java.time.long.Eras",
|
||||
@ -164,13 +185,7 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
"EEEE, MMMM d, y G",
|
||||
"MMMM d, y G",
|
||||
"MMM d, y G",
|
||||
"M/d/yy GGGGG",
|
||||
}
|
||||
},
|
||||
{ "java.time.short.Eras",
|
||||
new String[] {
|
||||
"BC",
|
||||
"AD",
|
||||
"M/d/y GGGGG",
|
||||
}
|
||||
},
|
||||
{ "roc.DatePatterns",
|
||||
@ -178,7 +193,128 @@ public class JavaTimeSupplementary_en extends OpenListResourceBundle {
|
||||
"EEEE, MMMM d, y GGGG",
|
||||
"MMMM d, y GGGG",
|
||||
"MMM d, y GGGG",
|
||||
"M/d/yy G",
|
||||
"M/d/y G",
|
||||
}
|
||||
},
|
||||
{ "roc.DayAbbreviations",
|
||||
new String[] {
|
||||
"Sun",
|
||||
"Mon",
|
||||
"Tue",
|
||||
"Wed",
|
||||
"Thu",
|
||||
"Fri",
|
||||
"Sat",
|
||||
}
|
||||
},
|
||||
{ "roc.DayNames",
|
||||
new String[] {
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
}
|
||||
},
|
||||
{ "roc.Eras",
|
||||
new String[] {
|
||||
"Before R.O.C.",
|
||||
"Minguo",
|
||||
}
|
||||
},
|
||||
{ "roc.MonthAbbreviations",
|
||||
new String[] {
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec",
|
||||
"",
|
||||
}
|
||||
},
|
||||
{ "roc.MonthNames",
|
||||
new String[] {
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
"",
|
||||
}
|
||||
},
|
||||
{ "roc.MonthNarrows",
|
||||
new String[] {
|
||||
"J",
|
||||
"F",
|
||||
"M",
|
||||
"A",
|
||||
"M",
|
||||
"J",
|
||||
"J",
|
||||
"A",
|
||||
"S",
|
||||
"O",
|
||||
"N",
|
||||
"D",
|
||||
"",
|
||||
}
|
||||
},
|
||||
{ "roc.QuarterAbbreviations",
|
||||
new String[] {
|
||||
"Q1",
|
||||
"Q2",
|
||||
"Q3",
|
||||
"Q4",
|
||||
}
|
||||
},
|
||||
{ "roc.QuarterNames",
|
||||
new String[] {
|
||||
"1st quarter",
|
||||
"2nd quarter",
|
||||
"3rd quarter",
|
||||
"4th quarter",
|
||||
}
|
||||
},
|
||||
{ "roc.TimePatterns",
|
||||
new String[] {
|
||||
"h:mm:ss a zzzz",
|
||||
"h:mm:ss a z",
|
||||
"h:mm:ss a",
|
||||
"h:mm a",
|
||||
}
|
||||
},
|
||||
{ "roc.long.Eras",
|
||||
new String[] {
|
||||
"Before R.O.C.",
|
||||
"Minguo",
|
||||
}
|
||||
},
|
||||
{ "roc.narrow.Eras",
|
||||
new String[] {
|
||||
"Before R.O.C.",
|
||||
"Minguo",
|
||||
}
|
||||
},
|
||||
{ "roc.short.Eras",
|
||||
new String[] {
|
||||
"Before R.O.C.",
|
||||
"Minguo",
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT AND PERMISSION NOTICE
|
||||
*
|
||||
* Copyright (C) 1991-2012 Unicode, Inc. All rights reserved. Distributed under
|
||||
* the Terms of Use in http://www.unicode.org/copyright.html.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of the Unicode data files and any associated documentation (the "Data
|
||||
* Files") or Unicode software and any associated documentation (the
|
||||
* "Software") to deal in the Data Files or Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, and/or sell copies of the Data Files or Software, and
|
||||
* to permit persons to whom the Data Files or Software are furnished to do so,
|
||||
* provided that (a) the above copyright notice(s) and this permission notice
|
||||
* appear with all copies of the Data Files or Software, (b) both the above
|
||||
* copyright notice(s) and this permission notice appear in associated
|
||||
* documentation, and (c) there is clear notice in each modified Data File or
|
||||
* in the Software as well as in the documentation associated with the Data
|
||||
* File(s) or Software that the data or software has been modified.
|
||||
*
|
||||
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THE DATA FILES OR SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of a copyright holder shall not
|
||||
* be used in advertising or otherwise to promote the sale, use or other
|
||||
* dealings in these Data Files or Software without prior written authorization
|
||||
* of the copyright holder.
|
||||
*/
|
||||
|
||||
// Note: this file has been generated by a tool.
|
||||
|
||||
package sun.text.resources.en;
|
||||
|
||||
import sun.util.resources.OpenListResourceBundle;
|
||||
|
||||
public class JavaTimeSupplementary_en_SG extends OpenListResourceBundle {
|
||||
@Override
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "java.time.buddhist.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, d MMMM, y G",
|
||||
"d MMMM, y G",
|
||||
"d MMM, y G",
|
||||
"d/M/yy GGGGG",
|
||||
}
|
||||
},
|
||||
{ "java.time.japanese.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, d MMMM, y G",
|
||||
"d MMMM, y G",
|
||||
"d MMM, y G",
|
||||
"d/M/yy GGGGG",
|
||||
}
|
||||
},
|
||||
{ "java.time.roc.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, d MMMM, y G",
|
||||
"d MMMM, y G",
|
||||
"d MMM, y G",
|
||||
"d/M/yy GGGGG",
|
||||
}
|
||||
},
|
||||
{ "roc.DatePatterns",
|
||||
new String[] {
|
||||
"EEEE, d MMMM, y GGGG",
|
||||
"d MMMM, y GGGG",
|
||||
"d MMM, y GGGG",
|
||||
"d/M/yy G",
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.text.resources.en;
|
||||
package sun.text.resources.en.US;
|
||||
|
||||
import sun.util.resources.ParallelListResourceBundle;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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,14 @@ import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.text.spi.BreakIteratorProvider;
|
||||
import java.text.spi.CollatorProvider;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
@ -48,11 +53,16 @@ import sun.util.locale.provider.LocaleDataMetaInfo;
|
||||
*/
|
||||
public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
|
||||
private final LocaleDataMetaInfo metaInfo;
|
||||
private static final CLDRBaseLocaleDataMetaInfo baseMetaInfo = new CLDRBaseLocaleDataMetaInfo();
|
||||
// Assumption: CLDR has only one non-Base module.
|
||||
private final LocaleDataMetaInfo nonBaseMetaInfo;
|
||||
|
||||
// parent locales map
|
||||
private static volatile Map<Locale, Locale> parentLocalesMap = null;
|
||||
|
||||
public CLDRLocaleProviderAdapter() {
|
||||
try {
|
||||
metaInfo = AccessController.doPrivileged(new PrivilegedExceptionAction<LocaleDataMetaInfo>() {
|
||||
nonBaseMetaInfo = AccessController.doPrivileged(new PrivilegedExceptionAction<LocaleDataMetaInfo>() {
|
||||
@Override
|
||||
public LocaleDataMetaInfo run() {
|
||||
for (LocaleDataMetaInfo ldmi : ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) {
|
||||
@ -70,7 +80,7 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
|
||||
if (metaInfo == null) {
|
||||
if (nonBaseMetaInfo == null) {
|
||||
throw new UnsupportedOperationException("CLDR locale data could not be found.");
|
||||
}
|
||||
}
|
||||
@ -107,7 +117,16 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
|
||||
@Override
|
||||
protected Set<String> createLanguageTagSet(String category) {
|
||||
String supportedLocaleString = metaInfo.availableLanguageTags(category);
|
||||
// Directly call Base tags, as we know it's in the base module.
|
||||
String supportedLocaleString = baseMetaInfo.availableLanguageTags(category);
|
||||
String nonBaseTags = nonBaseMetaInfo.availableLanguageTags(category);
|
||||
if (nonBaseTags != null) {
|
||||
if (supportedLocaleString != null) {
|
||||
supportedLocaleString += " " + nonBaseTags;
|
||||
} else {
|
||||
supportedLocaleString = nonBaseTags;
|
||||
}
|
||||
}
|
||||
if (supportedLocaleString == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
@ -118,4 +137,46 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
}
|
||||
return tagset;
|
||||
}
|
||||
|
||||
// Implementation of ResourceBundleBasedAdapter
|
||||
@Override
|
||||
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
|
||||
List<Locale> candidates = super.getCandidateLocales(baseName, locale);
|
||||
return applyParentLocales(baseName, candidates);
|
||||
}
|
||||
|
||||
private List<Locale> applyParentLocales(String baseName, List<Locale> candidates) {
|
||||
if (Objects.isNull(parentLocalesMap)) {
|
||||
Map<Locale, Locale> map = new HashMap<>();
|
||||
Map<String, String> parentLocales = baseMetaInfo.parentLocales();
|
||||
parentLocales.keySet().forEach(parent -> {
|
||||
Arrays.asList(parentLocales.get(parent).split(" ")).stream().forEach(child -> {
|
||||
map.put(Locale.forLanguageTag(child),
|
||||
"root".equals(parent) ? Locale.ROOT : Locale.forLanguageTag(parent));
|
||||
});
|
||||
});
|
||||
parentLocalesMap = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
// check irregular parents
|
||||
for (int i = 0; i < candidates.size(); i++) {
|
||||
Locale l = candidates.get(i);
|
||||
Locale p = parentLocalesMap.get(l);
|
||||
if (!l.equals(Locale.ROOT) &&
|
||||
Objects.nonNull(p) &&
|
||||
!candidates.get(i+1).equals(p)) {
|
||||
List<Locale> applied = candidates.subList(0, i+1);
|
||||
applied.addAll(applyParentLocales(baseName, super.getCandidateLocales(baseName, p)));
|
||||
return applied;
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedProviderLocale(Locale locale, Set<String> langtags) {
|
||||
return Locale.ROOT.equals(locale) ||
|
||||
langtags.contains(locale.stripExtensions().toLanguageTag());
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +186,6 @@ public class BreakIteratorProviderImpl extends BreakIteratorProvider
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
return LocaleProviderAdapter.isSupportedLocale(locale, type, langtags);
|
||||
return LocaleProviderAdapter.forType(type).isSupportedProviderLocale(locale, langtags);
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,14 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
||||
if (key != null) {
|
||||
LocaleResources lr = LocaleProviderAdapter.forType(type).getLocaleResources(locale);
|
||||
String[] strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
|
||||
|
||||
// If standalone names are requested and no "standalone." resources are found,
|
||||
// try the default ones instead.
|
||||
if (strings == null && key.indexOf("standalone.") != -1) {
|
||||
key = key.replaceFirst("standalone.", "");
|
||||
strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
|
||||
}
|
||||
|
||||
if (strings != null && strings.length > 0) {
|
||||
if (field == DAY_OF_WEEK || field == YEAR) {
|
||||
--value;
|
||||
@ -118,6 +126,14 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
||||
if (key != null) {
|
||||
LocaleResources lr = LocaleProviderAdapter.forType(type).getLocaleResources(locale);
|
||||
String[] strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
|
||||
|
||||
// If standalone names are requested and no "standalone." resources are found,
|
||||
// try the default ones instead.
|
||||
if (strings == null && key.indexOf("standalone.") != -1) {
|
||||
key = key.replaceFirst("standalone.", "");
|
||||
strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
|
||||
}
|
||||
|
||||
if (strings != null) {
|
||||
if (!hasDuplicates(strings)) {
|
||||
if (field == YEAR) {
|
||||
@ -281,8 +297,8 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
||||
break;
|
||||
|
||||
case DAY_OF_WEEK:
|
||||
// support standalone narrow day names
|
||||
if (isStandalone && isNarrow) {
|
||||
// support standalone day names
|
||||
if (isStandalone) {
|
||||
key.append("standalone.");
|
||||
}
|
||||
key.append("Day").append(toStyleName(baseStyle));
|
||||
|
@ -75,7 +75,7 @@ public class CollatorProviderImpl extends CollatorProvider implements AvailableL
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
return LocaleProviderAdapter.isSupportedLocale(locale, type, langtags);
|
||||
return LocaleProviderAdapter.forType(type).isSupportedProviderLocale(locale, langtags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,7 +63,7 @@ public class DateFormatProviderImpl extends DateFormatProvider implements Availa
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
return LocaleProviderAdapter.isSupportedLocale(locale, type, langtags);
|
||||
return LocaleProviderAdapter.forType(type).isSupportedProviderLocale(locale, langtags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,7 +60,7 @@ public class DateFormatSymbolsProviderImpl extends DateFormatSymbolsProvider imp
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
return LocaleProviderAdapter.isSupportedLocale(locale, type, langtags);
|
||||
return LocaleProviderAdapter.forType(type).isSupportedProviderLocale(locale, langtags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,7 +60,7 @@ public class DecimalFormatSymbolsProviderImpl extends DecimalFormatSymbolsProvid
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
return LocaleProviderAdapter.isSupportedLocale(locale, type, langtags);
|
||||
return LocaleProviderAdapter.forType(type).isSupportedProviderLocale(locale, langtags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user