Merge
This commit is contained in:
commit
09f196a078
3
.hgtags
3
.hgtags
@ -1,3 +1,5 @@
|
|||||||
|
e2b70be325bd10dae4c06f74c46d70d480854916 jdk-9+179
|
||||||
|
5b16a1c3ccffff2a82c88bb7ea894c4ff1c9ebde jdk-9+180
|
||||||
43bf6f30fcba031ecf0cc7e511efe3a8179d0f77 jdk-9+176
|
43bf6f30fcba031ecf0cc7e511efe3a8179d0f77 jdk-9+176
|
||||||
d9f6bc6ba599d0487dc18b2fbdb6c34eedf6f958 jdk-9+177
|
d9f6bc6ba599d0487dc18b2fbdb6c34eedf6f958 jdk-9+177
|
||||||
bc9df7dd63ec76f50fafeb4acc44465044662f0a jdk-9+178
|
bc9df7dd63ec76f50fafeb4acc44465044662f0a jdk-9+178
|
||||||
@ -438,3 +440,4 @@ e6d70017f5b9adbb2ec82d826973d0251800a3c3 jdk-10+12
|
|||||||
9ef5029b247b4d940080417a287440bbdbab995b jdk-10+14
|
9ef5029b247b4d940080417a287440bbdbab995b jdk-10+14
|
||||||
878e216039322cb3f0ecbd0944642a2b4e2593f3 jdk-10+15
|
878e216039322cb3f0ecbd0944642a2b4e2593f3 jdk-10+15
|
||||||
4bbea012e5676e8025ade2bcfab4d6581e6e9f4b jdk-10+16
|
4bbea012e5676e8025ade2bcfab4d6581e6e9f4b jdk-10+16
|
||||||
|
7db699468b4f84abbcc01647e5a964409737411a jdk-10+17
|
||||||
|
@ -437,3 +437,6 @@ d67a3f1f057f7e31e12f33ebe3667cb73d252268 jdk-10+13
|
|||||||
a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177
|
a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177
|
||||||
a6c830ee8a6798b186730475e700027cdf4598aa jdk-10+15
|
a6c830ee8a6798b186730475e700027cdf4598aa jdk-10+15
|
||||||
2fe66ca1e2b3c361f949de9cb2894661dc0a3fa2 jdk-10+16
|
2fe66ca1e2b3c361f949de9cb2894661dc0a3fa2 jdk-10+16
|
||||||
|
ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178
|
||||||
|
252475ccfd84cc249f8d6faf4b7806b5e2c384ce jdk-9+179
|
||||||
|
a133a7d1007b1456bc62824382fd8ac93b45d329 jdk-10+17
|
||||||
|
@ -437,3 +437,6 @@ dc78a3dd6b3a4f11cdae8a3e3d160e6a78bc7838 jdk-9+175
|
|||||||
c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177
|
c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177
|
||||||
15f59cfc6fbe9387423fb173e962265c7b5d357e jdk-10+15
|
15f59cfc6fbe9387423fb173e962265c7b5d357e jdk-10+15
|
||||||
b82b62ed5debda2d98dda597506ef29cf947fbae jdk-10+16
|
b82b62ed5debda2d98dda597506ef29cf947fbae jdk-10+16
|
||||||
|
9c1e9712648921ae389d623042d22561fad82d75 jdk-9+178
|
||||||
|
24390da83c5ee9e23ceafbcaff4460a01e37bb3a jdk-9+179
|
||||||
|
50ff1fd66362f212a8db6de76089d9d0ffa4df0f jdk-10+17
|
||||||
|
@ -597,3 +597,6 @@ e920b4d008d914f3414bd4630b58837cf0b7f08d jdk-10+14
|
|||||||
1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177
|
1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177
|
||||||
c1f3649a3a42f124b418a5a916dbad13d059b757 jdk-10+15
|
c1f3649a3a42f124b418a5a916dbad13d059b757 jdk-10+15
|
||||||
2fe2a593e8ebf3a9e4dcd9ba3333a7b43126589d jdk-10+16
|
2fe2a593e8ebf3a9e4dcd9ba3333a7b43126589d jdk-10+16
|
||||||
|
9d032191f82fca5ba0aac98682f69c4ff0f1283d jdk-9+178
|
||||||
|
d2661aa42bff322badbe6c1337fc638d2e0f5730 jdk-9+179
|
||||||
|
73e2cb8700bfa51304bd4b02f224620859a3f600 jdk-10+17
|
||||||
|
@ -14394,7 +14394,7 @@ instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
|
|||||||
ins_pipe(icmp_reg_reg);
|
ins_pipe(icmp_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero)
|
instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpL op1 zero));
|
match(Set cr (CmpL op1 zero));
|
||||||
|
|
||||||
@ -14436,6 +14436,62 @@ instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2)
|
|||||||
ins_pipe(icmp_reg_imm);
|
ins_pipe(icmp_reg_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL op1 op2));
|
||||||
|
|
||||||
|
effect(DEF cr, USE op1, USE op2);
|
||||||
|
|
||||||
|
ins_cost(INSN_COST);
|
||||||
|
format %{ "cmp $op1, $op2" %}
|
||||||
|
|
||||||
|
ins_encode(aarch64_enc_cmp(op1, op2));
|
||||||
|
|
||||||
|
ins_pipe(icmp_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL op1 zero));
|
||||||
|
|
||||||
|
effect(DEF cr, USE op1);
|
||||||
|
|
||||||
|
ins_cost(INSN_COST);
|
||||||
|
format %{ "tst $op1" %}
|
||||||
|
|
||||||
|
ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
|
||||||
|
|
||||||
|
ins_pipe(icmp_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL op1 op2));
|
||||||
|
|
||||||
|
effect(DEF cr, USE op1);
|
||||||
|
|
||||||
|
ins_cost(INSN_COST);
|
||||||
|
format %{ "cmp $op1, $op2" %}
|
||||||
|
|
||||||
|
ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
|
||||||
|
|
||||||
|
ins_pipe(icmp_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL op1 op2));
|
||||||
|
|
||||||
|
effect(DEF cr, USE op1);
|
||||||
|
|
||||||
|
ins_cost(INSN_COST * 2);
|
||||||
|
format %{ "cmp $op1, $op2" %}
|
||||||
|
|
||||||
|
ins_encode(aarch64_enc_cmp_imm(op1, op2));
|
||||||
|
|
||||||
|
ins_pipe(icmp_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
|
instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpP op1 op2));
|
match(Set cr (CmpP op1 op2));
|
||||||
@ -14920,7 +14976,7 @@ instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{
|
instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{
|
||||||
match(If cmp (CmpU op1 op2));
|
match(If cmp (CmpUL op1 op2));
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
ins_cost(BRANCH_COST);
|
ins_cost(BRANCH_COST);
|
||||||
|
@ -49,12 +49,11 @@ define_pd_global(intx, ConditionalMoveLimit, 3);
|
|||||||
define_pd_global(intx, FLOATPRESSURE, 64);
|
define_pd_global(intx, FLOATPRESSURE, 64);
|
||||||
define_pd_global(intx, FreqInlineSize, 325);
|
define_pd_global(intx, FreqInlineSize, 325);
|
||||||
define_pd_global(intx, MinJumpTableSize, 10);
|
define_pd_global(intx, MinJumpTableSize, 10);
|
||||||
define_pd_global(intx, INTPRESSURE, 25);
|
define_pd_global(intx, INTPRESSURE, 24);
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||||
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||||
define_pd_global(intx, PostLoopMultiversioning, false);
|
|
||||||
// InitialCodeCacheSize derived from specjbb2000 run.
|
// InitialCodeCacheSize derived from specjbb2000 run.
|
||||||
define_pd_global(intx, InitialCodeCacheSize, 2496*K); // Integral multiple of CodeCacheExpansionSize
|
define_pd_global(intx, InitialCodeCacheSize, 2496*K); // Integral multiple of CodeCacheExpansionSize
|
||||||
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
|
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
|
||||||
|
@ -2695,6 +2695,30 @@ operand flagsRegL_LEGT() %{
|
|||||||
format %{ "apsr_L_LEGT" %}
|
format %{ "apsr_L_LEGT" %}
|
||||||
interface(REG_INTER);
|
interface(REG_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
operand flagsRegUL_LTGE() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
|
||||||
|
format %{ "apsr_UL_LTGE" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
|
operand flagsRegUL_EQNE() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
|
||||||
|
format %{ "apsr_UL_EQNE" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
|
operand flagsRegUL_LEGT() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
|
||||||
|
format %{ "apsr_UL_LEGT" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Condition Code Register, floating comparisons, unordered same as "less".
|
// Condition Code Register, floating comparisons, unordered same as "less".
|
||||||
@ -3249,6 +3273,39 @@ operand cmpOpL_commute() %{
|
|||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
operand cmpOpUL() %{
|
||||||
|
match(Bool);
|
||||||
|
|
||||||
|
format %{ "UL" %}
|
||||||
|
interface(COND_INTER) %{
|
||||||
|
equal(0x0);
|
||||||
|
not_equal(0x1);
|
||||||
|
less(0x3);
|
||||||
|
greater_equal(0x2);
|
||||||
|
less_equal(0x9);
|
||||||
|
greater(0x8);
|
||||||
|
overflow(0x0); // unsupported/unimplemented
|
||||||
|
no_overflow(0x0); // unsupported/unimplemented
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
|
operand cmpOpUL_commute() %{
|
||||||
|
match(Bool);
|
||||||
|
|
||||||
|
format %{ "UL" %}
|
||||||
|
interface(COND_INTER) %{
|
||||||
|
equal(0x0);
|
||||||
|
not_equal(0x1);
|
||||||
|
less(0x8);
|
||||||
|
greater_equal(0x9);
|
||||||
|
less_equal(0x2);
|
||||||
|
greater(0x3);
|
||||||
|
overflow(0x0); // unsupported/unimplemented
|
||||||
|
no_overflow(0x0); // unsupported/unimplemented
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
//----------OPERAND CLASSES----------------------------------------------------
|
//----------OPERAND CLASSES----------------------------------------------------
|
||||||
// Operand Classes are groups of operands that are used to simplify
|
// Operand Classes are groups of operands that are used to simplify
|
||||||
// instruction definitions by not requiring the AD writer to specify separate
|
// instruction definitions by not requiring the AD writer to specify separate
|
||||||
@ -10467,6 +10524,17 @@ instruct compL_reg_reg(flagsReg xcc, iRegL op1, iRegL op2)
|
|||||||
%}
|
%}
|
||||||
ins_pipe(ialu_cconly_reg_reg);
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct compUL_iReg(flagsRegU xcc, iRegL op1, iRegL op2) %{
|
||||||
|
match(Set xcc (CmpUL op1 op2));
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "CMP $op1,$op2\t! unsigned long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmp($op1$$Register, $op2$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
#else
|
#else
|
||||||
instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
|
instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
|
||||||
match(Set xcc (CmpL op1 op2));
|
match(Set xcc (CmpL op1 op2));
|
||||||
@ -10481,6 +10549,20 @@ instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp)
|
|||||||
%}
|
%}
|
||||||
ins_pipe(ialu_cconly_reg_reg);
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
|
||||||
|
match(Set xcc (CmpUL op1 op2));
|
||||||
|
effect(DEF xcc, USE op1, USE op2, TEMP tmp);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
format %{ "SUBS $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
|
||||||
|
"SBCS $tmp,$op1.hi,$op2.hi" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subs($tmp$$Register, $op1$$Register, $op2$$Register);
|
||||||
|
__ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AARCH64
|
#ifdef AARCH64
|
||||||
@ -10496,6 +10578,19 @@ instruct compL_reg_con(flagsReg xcc, iRegL op1, aimmL con) %{
|
|||||||
|
|
||||||
ins_pipe(ialu_cconly_reg_imm);
|
ins_pipe(ialu_cconly_reg_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_con(flagsRegU xcc, iRegL op1, aimmL con) %{
|
||||||
|
match(Set xcc (CmpUL op1 con));
|
||||||
|
effect(DEF xcc, USE op1, USE con);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
format %{ "CMP $op1,$con\t\t! unsigned long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmp($op1$$Register, $con$$constant);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_cconly_reg_imm);
|
||||||
|
%}
|
||||||
#else
|
#else
|
||||||
instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
|
instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
|
||||||
match(Set xcc (CmpL op1 op2));
|
match(Set xcc (CmpL op1 op2));
|
||||||
@ -10575,6 +10670,85 @@ instruct compL_reg_con_LEGT(flagsRegL_LEGT xcc, iRegL op1, immLlowRot con, iRegL
|
|||||||
|
|
||||||
ins_pipe(ialu_cconly_reg_reg);
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
|
||||||
|
match(Set xcc (CmpUL op1 op2));
|
||||||
|
effect(DEF xcc, USE op1, USE op2);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
format %{ "TEQ $op1.hi,$op2.hi\t\t! unsigned long\n\t"
|
||||||
|
"TEQ.eq $op1.lo,$op2.lo" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ teq($op1$$Register->successor(), $op2$$Register->successor());
|
||||||
|
__ teq($op1$$Register, $op2$$Register, eq);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
|
||||||
|
match(Set xcc (CmpUL op1 op2));
|
||||||
|
effect(DEF xcc, USE op1, USE op2, TEMP tmp);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
format %{ "SUBS $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
|
||||||
|
"SBCS $tmp,$op2.hi,$op1.hi" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subs($tmp$$Register, $op2$$Register, $op1$$Register);
|
||||||
|
__ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
|
||||||
|
// (hi($con$$constant), lo($con$$constant)) becomes
|
||||||
|
instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
|
||||||
|
match(Set xcc (CmpUL op1 con));
|
||||||
|
effect(DEF xcc, USE op1, USE con, TEMP tmp);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
format %{ "SUBS $tmp,$op1.low,$con\t\t! unsigned long\n\t"
|
||||||
|
"SBCS $tmp,$op1.hi,0" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subs($tmp$$Register, $op1$$Register, $con$$constant);
|
||||||
|
__ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
|
||||||
|
// (hi($con$$constant), lo($con$$constant)) becomes
|
||||||
|
instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
|
||||||
|
match(Set xcc (CmpUL op1 con));
|
||||||
|
effect(DEF xcc, USE op1, USE con);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
format %{ "TEQ $op1.hi,0\t\t! unsigned long\n\t"
|
||||||
|
"TEQ.eq $op1.lo,$con" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ teq($op1$$Register->successor(), 0);
|
||||||
|
__ teq($op1$$Register, $con$$constant, eq);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
|
||||||
|
// (hi($con$$constant), lo($con$$constant)) becomes
|
||||||
|
instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
|
||||||
|
match(Set xcc (CmpUL op1 con));
|
||||||
|
effect(DEF xcc, USE op1, USE con, TEMP tmp);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
format %{ "RSBS $tmp,$op1.low,$con\t\t! unsigned long\n\t"
|
||||||
|
"RSCS $tmp,$op1.hi,0" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
|
||||||
|
__ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
|
/* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
|
||||||
@ -11126,6 +11300,48 @@ instruct branchConL_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, label labl) %{
|
|||||||
%}
|
%}
|
||||||
ins_pipe(br_cc);
|
ins_pipe(br_cc);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
|
||||||
|
match(If cmp xcc);
|
||||||
|
effect(USE labl);
|
||||||
|
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "B$cmp $xcc,$labl" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
|
||||||
|
%}
|
||||||
|
ins_pipe(br_cc);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
|
||||||
|
match(If cmp xcc);
|
||||||
|
effect(USE labl);
|
||||||
|
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "B$cmp $xcc,$labl" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
|
||||||
|
%}
|
||||||
|
ins_pipe(br_cc);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
|
||||||
|
match(If cmp xcc);
|
||||||
|
effect(USE labl);
|
||||||
|
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "B$cmp $xcc,$labl" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
|
||||||
|
%}
|
||||||
|
ins_pipe(br_cc);
|
||||||
|
%}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
|
instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
|
||||||
|
@ -70,7 +70,6 @@ define_pd_global(bool, UseTLAB, true);
|
|||||||
define_pd_global(bool, ResizeTLAB, true);
|
define_pd_global(bool, ResizeTLAB, true);
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1
|
define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1
|
||||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||||
define_pd_global(intx, PostLoopMultiversioning, false);
|
|
||||||
define_pd_global(intx, MinJumpTableSize, 16);
|
define_pd_global(intx, MinJumpTableSize, 16);
|
||||||
|
|
||||||
// Peephole and CISC spilling both break the graph, and so makes the
|
// Peephole and CISC spilling both break the graph, and so makes the
|
||||||
|
@ -55,7 +55,6 @@ define_pd_global(bool, UseTLAB, true);
|
|||||||
define_pd_global(bool, ResizeTLAB, true);
|
define_pd_global(bool, ResizeTLAB, true);
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||||
define_pd_global(intx, PostLoopMultiversioning, false);
|
|
||||||
|
|
||||||
// Peephole and CISC spilling both break the graph, and so make the
|
// Peephole and CISC spilling both break the graph, and so make the
|
||||||
// scheduler sick.
|
// scheduler sick.
|
||||||
|
@ -11048,6 +11048,29 @@ instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
|
|||||||
ins_pipe(pipe_class_compare);
|
ins_pipe(pipe_class_compare);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Added CmpUL for LoopPredicate.
|
||||||
|
instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
|
||||||
|
match(Set crx (CmpUL src1 src2));
|
||||||
|
format %{ "CMPLD $crx, $src1, $src2" %}
|
||||||
|
size(4);
|
||||||
|
ins_encode %{
|
||||||
|
// TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
|
||||||
|
__ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
|
||||||
|
match(Set crx (CmpUL src1 src2));
|
||||||
|
format %{ "CMPLDI $crx, $src1, $src2" %}
|
||||||
|
size(4);
|
||||||
|
ins_encode %{
|
||||||
|
// TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
|
||||||
|
__ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
|
instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
|
||||||
match(Set cr0 (CmpL (AndL src1 src2) zero));
|
match(Set cr0 (CmpL (AndL src1 src2) zero));
|
||||||
// r0 is killed
|
// r0 is killed
|
||||||
|
@ -56,7 +56,6 @@ define_pd_global(bool, UseTLAB, true);
|
|||||||
define_pd_global(bool, ResizeTLAB, true);
|
define_pd_global(bool, ResizeTLAB, true);
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||||
define_pd_global(intx, PostLoopMultiversioning, false);
|
|
||||||
define_pd_global(intx, MinJumpTableSize, 18);
|
define_pd_global(intx, MinJumpTableSize, 18);
|
||||||
|
|
||||||
// Peephole and CISC spilling both break the graph, and so makes the
|
// Peephole and CISC spilling both break the graph, and so makes the
|
||||||
|
@ -8475,6 +8475,24 @@ instruct compL_reg_memI(iRegL dst, memory src, flagsReg cr)%{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// LONG unsigned
|
// LONG unsigned
|
||||||
|
// Added CmpUL for LoopPredicate.
|
||||||
|
instruct compUL_reg_reg(flagsReg cr, iRegL op1, iRegL op2) %{
|
||||||
|
match(Set cr (CmpUL op1 op2));
|
||||||
|
size(4);
|
||||||
|
format %{ "CLGR $op1,$op2\t # long" %}
|
||||||
|
opcode(CLGR_ZOPC);
|
||||||
|
ins_encode(z_rreform(op1, op2));
|
||||||
|
ins_pipe(pipe_class_dummy);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compUL_reg_imm32(flagsReg cr, iRegL op1, uimmL32 con) %{
|
||||||
|
match(Set cr (CmpUL op1 con));
|
||||||
|
size(6);
|
||||||
|
format %{ "CLGFI $op1,$con" %}
|
||||||
|
opcode(CLGFI_ZOPC);
|
||||||
|
ins_encode(z_rilform_unsigned(op1, con));
|
||||||
|
ins_pipe(pipe_class_dummy);
|
||||||
|
%}
|
||||||
|
|
||||||
// PTR unsigned
|
// PTR unsigned
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@ define_pd_global(bool, UseTLAB, true);
|
|||||||
define_pd_global(bool, ResizeTLAB, true);
|
define_pd_global(bool, ResizeTLAB, true);
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1
|
define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1
|
||||||
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
define_pd_global(intx, LoopPercentProfileLimit, 10);
|
||||||
define_pd_global(intx, PostLoopMultiversioning, false);
|
|
||||||
define_pd_global(intx, MinJumpTableSize, 5);
|
define_pd_global(intx, MinJumpTableSize, 5);
|
||||||
|
|
||||||
// Peephole and CISC spilling both break the graph, and so makes the
|
// Peephole and CISC spilling both break the graph, and so makes the
|
||||||
|
@ -3403,6 +3403,16 @@ operand immU12() %{
|
|||||||
interface(CONST_INTER);
|
interface(CONST_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Unsigned Long Immediate: 12-bit (non-negative that fits in simm13)
|
||||||
|
operand immUL12() %{
|
||||||
|
predicate((0 <= n->get_long()) && (n->get_long() == (int)n->get_long()) && Assembler::is_simm13((int)n->get_long()));
|
||||||
|
match(ConL);
|
||||||
|
op_cost(0);
|
||||||
|
|
||||||
|
format %{ %}
|
||||||
|
interface(CONST_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
// Integer Immediate non-negative
|
// Integer Immediate non-negative
|
||||||
operand immU31()
|
operand immU31()
|
||||||
%{
|
%{
|
||||||
@ -3936,6 +3946,15 @@ operand flagsRegL() %{
|
|||||||
interface(REG_INTER);
|
interface(REG_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Condition Code Register, unsigned long comparisons.
|
||||||
|
operand flagsRegUL() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
|
||||||
|
format %{ "xcc_UL" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
// Condition Code Register, floating comparisons, unordered same as "less".
|
// Condition Code Register, floating comparisons, unordered same as "less".
|
||||||
operand flagsRegF() %{
|
operand flagsRegF() %{
|
||||||
constraint(ALLOC_IN_RC(float_flags));
|
constraint(ALLOC_IN_RC(float_flags));
|
||||||
@ -8797,6 +8816,17 @@ instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{
|
|||||||
ins_pipe(ialu_cconly_reg_reg);
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct compUL_iReg(flagsRegUL xcc, iRegL op1, iRegL op2) %{
|
||||||
|
match(Set xcc (CmpUL op1 op2));
|
||||||
|
effect(DEF xcc, USE op1, USE op2);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "CMP $op1,$op2\t! unsigned long" %}
|
||||||
|
opcode(Assembler::subcc_op3, Assembler::arith_op);
|
||||||
|
ins_encode(form3_rs1_rs2_rd(op1, op2, R_G0));
|
||||||
|
ins_pipe(ialu_cconly_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct compI_iReg_imm13(flagsReg icc, iRegI op1, immI13 op2) %{
|
instruct compI_iReg_imm13(flagsReg icc, iRegI op1, immI13 op2) %{
|
||||||
match(Set icc (CmpI op1 op2));
|
match(Set icc (CmpI op1 op2));
|
||||||
effect( DEF icc, USE op1 );
|
effect( DEF icc, USE op1 );
|
||||||
@ -8883,6 +8913,17 @@ instruct compU_iReg_imm13(flagsRegU icc, iRegI op1, immU12 op2 ) %{
|
|||||||
ins_pipe(ialu_cconly_reg_imm);
|
ins_pipe(ialu_cconly_reg_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct compUL_iReg_imm13(flagsRegUL xcc, iRegL op1, immUL12 op2) %{
|
||||||
|
match(Set xcc (CmpUL op1 op2));
|
||||||
|
effect(DEF xcc, USE op1, USE op2);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "CMP $op1,$op2\t! unsigned long" %}
|
||||||
|
opcode(Assembler::subcc_op3, Assembler::arith_op);
|
||||||
|
ins_encode(form3_rs1_simm13_rd(op1, op2, R_G0));
|
||||||
|
ins_pipe(ialu_cconly_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare Pointers
|
// Compare Pointers
|
||||||
instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
|
instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
|
||||||
match(Set pcc (CmpP op1 op2));
|
match(Set pcc (CmpP op1 op2));
|
||||||
@ -9256,6 +9297,44 @@ instruct cmpU_imm_branch(cmpOpU cmp, iRegI op1, immI5 op2, label labl, flagsRegU
|
|||||||
ins_pipe(cmp_br_reg_imm);
|
ins_pipe(cmp_br_reg_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpUL_reg_branch(cmpOpU cmp, iRegL op1, iRegL op2, label labl, flagsRegUL xcc) %{
|
||||||
|
match(If cmp (CmpUL op1 op2));
|
||||||
|
effect(USE labl, KILL xcc);
|
||||||
|
|
||||||
|
size(12);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "CMP $op1,$op2\t! unsigned long\n\t"
|
||||||
|
"BP$cmp $labl" %}
|
||||||
|
ins_encode %{
|
||||||
|
Label* L = $labl$$label;
|
||||||
|
Assembler::Predict predict_taken =
|
||||||
|
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
|
||||||
|
__ cmp($op1$$Register, $op2$$Register);
|
||||||
|
__ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
|
||||||
|
__ delayed()->nop();
|
||||||
|
%}
|
||||||
|
ins_pipe(cmp_br_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmpUL_imm_branch(cmpOpU cmp, iRegL op1, immL5 op2, label labl, flagsRegUL xcc) %{
|
||||||
|
match(If cmp (CmpUL op1 op2));
|
||||||
|
effect(USE labl, KILL xcc);
|
||||||
|
|
||||||
|
size(12);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "CMP $op1,$op2\t! unsigned long\n\t"
|
||||||
|
"BP$cmp $labl" %}
|
||||||
|
ins_encode %{
|
||||||
|
Label* L = $labl$$label;
|
||||||
|
Assembler::Predict predict_taken =
|
||||||
|
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
|
||||||
|
__ cmp($op1$$Register, $op2$$constant);
|
||||||
|
__ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
|
||||||
|
__ delayed()->nop();
|
||||||
|
%}
|
||||||
|
ins_pipe(cmp_br_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmpL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{
|
instruct cmpL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{
|
||||||
match(If cmp (CmpL op1 op2));
|
match(If cmp (CmpL op1 op2));
|
||||||
effect(USE labl, KILL xcc);
|
effect(USE labl, KILL xcc);
|
||||||
@ -9484,6 +9563,42 @@ instruct cmpU_imm_branch_short(cmpOpU cmp, iRegI op1, immI5 op2, label labl, fla
|
|||||||
ins_pipe(cbcond_reg_imm);
|
ins_pipe(cbcond_reg_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpUL_reg_branch_short(cmpOpU cmp, iRegL op1, iRegL op2, label labl, flagsRegUL xcc) %{
|
||||||
|
match(If cmp (CmpUL op1 op2));
|
||||||
|
predicate(UseCBCond);
|
||||||
|
effect(USE labl, KILL xcc);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "CXB$cmp $op1,$op2,$labl\t! unsigned long" %}
|
||||||
|
ins_encode %{
|
||||||
|
Label* L = $labl$$label;
|
||||||
|
assert(__ use_cbcond(*L), "back to back cbcond");
|
||||||
|
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L);
|
||||||
|
%}
|
||||||
|
ins_short_branch(1);
|
||||||
|
ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
|
||||||
|
ins_pipe(cbcond_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmpUL_imm_branch_short(cmpOpU cmp, iRegL op1, immL5 op2, label labl, flagsRegUL xcc) %{
|
||||||
|
match(If cmp (CmpUL op1 op2));
|
||||||
|
predicate(UseCBCond);
|
||||||
|
effect(USE labl, KILL xcc);
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "CXB$cmp $op1,$op2,$labl\t! unsigned long" %}
|
||||||
|
ins_encode %{
|
||||||
|
Label* L = $labl$$label;
|
||||||
|
assert(__ use_cbcond(*L), "back to back cbcond");
|
||||||
|
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L);
|
||||||
|
%}
|
||||||
|
ins_short_branch(1);
|
||||||
|
ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
|
||||||
|
ins_pipe(cbcond_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{
|
instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{
|
||||||
match(If cmp (CmpL op1 op2));
|
match(If cmp (CmpL op1 op2));
|
||||||
predicate(UseCBCond);
|
predicate(UseCBCond);
|
||||||
@ -9722,6 +9837,25 @@ instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
|
|||||||
ins_pipe(br_cc);
|
ins_pipe(br_cc);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct branchConU_long(cmpOpU cmp, flagsRegUL xcc, label labl) %{
|
||||||
|
match(If cmp xcc);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
size(8);
|
||||||
|
ins_cost(BRANCH_COST);
|
||||||
|
format %{ "BP$cmp $xcc,$labl" %}
|
||||||
|
ins_encode %{
|
||||||
|
Label* L = $labl$$label;
|
||||||
|
Assembler::Predict predict_taken =
|
||||||
|
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
|
||||||
|
|
||||||
|
__ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
|
||||||
|
__ delayed()->nop();
|
||||||
|
%}
|
||||||
|
ins_avoid_back_to_back(AVOID_BEFORE);
|
||||||
|
ins_pipe(br_cc);
|
||||||
|
%}
|
||||||
|
|
||||||
// Manifest a CmpL3 result in an integer register. Very painful.
|
// Manifest a CmpL3 result in an integer register. Very painful.
|
||||||
// This is the test to avoid.
|
// This is the test to avoid.
|
||||||
instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
|
instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
|
||||||
|
@ -47,7 +47,6 @@ define_pd_global(intx, ConditionalMoveLimit, 3);
|
|||||||
define_pd_global(intx, FreqInlineSize, 325);
|
define_pd_global(intx, FreqInlineSize, 325);
|
||||||
define_pd_global(intx, MinJumpTableSize, 10);
|
define_pd_global(intx, MinJumpTableSize, 10);
|
||||||
define_pd_global(intx, LoopPercentProfileLimit, 30);
|
define_pd_global(intx, LoopPercentProfileLimit, 30);
|
||||||
define_pd_global(intx, PostLoopMultiversioning, true);
|
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
define_pd_global(intx, INTPRESSURE, 13);
|
define_pd_global(intx, INTPRESSURE, 13);
|
||||||
define_pd_global(intx, FLOATPRESSURE, 14);
|
define_pd_global(intx, FLOATPRESSURE, 14);
|
||||||
|
@ -116,7 +116,7 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
|
|||||||
product(bool, UseStoreImmI16, true, \
|
product(bool, UseStoreImmI16, true, \
|
||||||
"Use store immediate 16-bits value instruction on x86") \
|
"Use store immediate 16-bits value instruction on x86") \
|
||||||
\
|
\
|
||||||
product(intx, UseAVX, 99, \
|
product(intx, UseAVX, 2, \
|
||||||
"Highest supported AVX instructions set on x86/x64") \
|
"Highest supported AVX instructions set on x86/x64") \
|
||||||
range(0, 99) \
|
range(0, 99) \
|
||||||
\
|
\
|
||||||
|
@ -4030,6 +4030,26 @@ operand flagsReg_long_LEGT() %{
|
|||||||
interface(REG_INTER);
|
interface(REG_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Condition Code Register used by unsigned long compare
|
||||||
|
operand flagsReg_ulong_LTGE() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
format %{ "FLAGS_U_LTGE" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
operand flagsReg_ulong_EQNE() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
format %{ "FLAGS_U_EQNE" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
operand flagsReg_ulong_LEGT() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
format %{ "FLAGS_U_LEGT" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
// Float register operands
|
// Float register operands
|
||||||
operand regDPR() %{
|
operand regDPR() %{
|
||||||
predicate( UseSSE < 2 );
|
predicate( UseSSE < 2 );
|
||||||
@ -4588,7 +4608,7 @@ operand cmpOp_fcmov() %{
|
|||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Comparision Code used in long compares
|
// Comparison Code used in long compares
|
||||||
operand cmpOp_commute() %{
|
operand cmpOp_commute() %{
|
||||||
match(Bool);
|
match(Bool);
|
||||||
|
|
||||||
@ -4605,6 +4625,23 @@ operand cmpOp_commute() %{
|
|||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Comparison Code used in unsigned long compares
|
||||||
|
operand cmpOpU_commute() %{
|
||||||
|
match(Bool);
|
||||||
|
|
||||||
|
format %{ "" %}
|
||||||
|
interface(COND_INTER) %{
|
||||||
|
equal(0x4, "e");
|
||||||
|
not_equal(0x5, "ne");
|
||||||
|
less(0x7, "nbe");
|
||||||
|
greater_equal(0x6, "be");
|
||||||
|
less_equal(0x3, "nb");
|
||||||
|
greater(0x2, "b");
|
||||||
|
overflow(0x0, "o");
|
||||||
|
no_overflow(0x1, "no");
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
//----------OPERAND CLASSES----------------------------------------------------
|
//----------OPERAND CLASSES----------------------------------------------------
|
||||||
// Operand Classes are groups of operands that are used as to simplify
|
// Operand Classes are groups of operands that are used as to simplify
|
||||||
// instruction definitions by not requiring the AD writer to specify separate
|
// instruction definitions by not requiring the AD writer to specify separate
|
||||||
@ -12639,6 +12676,44 @@ instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{
|
|||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
//======
|
||||||
|
// Manifest a CmpUL result in the normal flags. Only good for LT or GE
|
||||||
|
// compares. Can be used for LE or GT compares by reversing arguments.
|
||||||
|
// NOT GOOD FOR EQ/NE tests.
|
||||||
|
instruct cmpUL_zero_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src, immL0 zero) %{
|
||||||
|
match(Set flags (CmpUL src zero));
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "TEST $src.hi,$src.hi" %}
|
||||||
|
opcode(0x85);
|
||||||
|
ins_encode(OpcP, RegReg_Hi2(src, src));
|
||||||
|
ins_pipe(ialu_cr_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Manifest a CmpUL result in the normal flags. Only good for LT or GE
|
||||||
|
// compares. Can be used for LE or GT compares by reversing arguments.
|
||||||
|
// NOT GOOD FOR EQ/NE tests.
|
||||||
|
instruct cmpUL_reg_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src1, eRegL src2, rRegI tmp) %{
|
||||||
|
match(Set flags (CmpUL src1 src2));
|
||||||
|
effect(TEMP tmp);
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t"
|
||||||
|
"MOV $tmp,$src1.hi\n\t"
|
||||||
|
"SBB $tmp,$src2.hi\t! Compute flags for unsigned long compare" %}
|
||||||
|
ins_encode(long_cmp_flags2(src1, src2, tmp));
|
||||||
|
ins_pipe(ialu_cr_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Unsigned long compares reg < zero/req OR reg >= zero/req.
|
||||||
|
// Just a wrapper for a normal branch, plus the predicate test.
|
||||||
|
instruct cmpUL_LTGE(cmpOpU cmp, flagsReg_ulong_LTGE flags, label labl) %{
|
||||||
|
match(If cmp flags);
|
||||||
|
effect(USE labl);
|
||||||
|
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
|
||||||
|
expand %{
|
||||||
|
jmpCon(cmp, flags, labl); // JLT or JGE...
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare 2 longs and CMOVE longs.
|
// Compare 2 longs and CMOVE longs.
|
||||||
instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{
|
instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{
|
||||||
match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
|
match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
|
||||||
@ -12767,6 +12842,41 @@ instruct cmpL_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, label labl) %{
|
|||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
//======
|
||||||
|
// Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares.
|
||||||
|
instruct cmpUL_zero_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src, immL0 zero, rRegI tmp) %{
|
||||||
|
match(Set flags (CmpUL src zero));
|
||||||
|
effect(TEMP tmp);
|
||||||
|
ins_cost(200);
|
||||||
|
format %{ "MOV $tmp,$src.lo\n\t"
|
||||||
|
"OR $tmp,$src.hi\t! Unsigned long is EQ/NE 0?" %}
|
||||||
|
ins_encode(long_cmp_flags0(src, tmp));
|
||||||
|
ins_pipe(ialu_reg_reg_long);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Manifest a CmpUL result in the normal flags. Only good for EQ/NE compares.
|
||||||
|
instruct cmpUL_reg_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src1, eRegL src2) %{
|
||||||
|
match(Set flags (CmpUL src1 src2));
|
||||||
|
ins_cost(200+300);
|
||||||
|
format %{ "CMP $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t"
|
||||||
|
"JNE,s skip\n\t"
|
||||||
|
"CMP $src1.hi,$src2.hi\n\t"
|
||||||
|
"skip:\t" %}
|
||||||
|
ins_encode(long_cmp_flags1(src1, src2));
|
||||||
|
ins_pipe(ialu_cr_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Unsigned long compare reg == zero/reg OR reg != zero/reg
|
||||||
|
// Just a wrapper for a normal branch, plus the predicate test.
|
||||||
|
instruct cmpUL_EQNE(cmpOpU cmp, flagsReg_ulong_EQNE flags, label labl) %{
|
||||||
|
match(If cmp flags);
|
||||||
|
effect(USE labl);
|
||||||
|
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
|
||||||
|
expand %{
|
||||||
|
jmpCon(cmp, flags, labl); // JEQ or JNE...
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare 2 longs and CMOVE longs.
|
// Compare 2 longs and CMOVE longs.
|
||||||
instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{
|
instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{
|
||||||
match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
|
match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
|
||||||
@ -12900,6 +13010,46 @@ instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{
|
|||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
//======
|
||||||
|
// Manifest a CmpUL result in the normal flags. Only good for LE or GT compares.
|
||||||
|
// Same as cmpUL_reg_flags_LEGT except must negate src
|
||||||
|
instruct cmpUL_zero_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src, immL0 zero, rRegI tmp) %{
|
||||||
|
match(Set flags (CmpUL src zero));
|
||||||
|
effect(TEMP tmp);
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "XOR $tmp,$tmp\t# Unsigned long compare for -$src < 0, use commuted test\n\t"
|
||||||
|
"CMP $tmp,$src.lo\n\t"
|
||||||
|
"SBB $tmp,$src.hi\n\t" %}
|
||||||
|
ins_encode(long_cmp_flags3(src, tmp));
|
||||||
|
ins_pipe(ialu_reg_reg_long);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Manifest a CmpUL result in the normal flags. Only good for LE or GT compares.
|
||||||
|
// Same as cmpUL_reg_flags_LTGE except operands swapped. Swapping operands
|
||||||
|
// requires a commuted test to get the same result.
|
||||||
|
instruct cmpUL_reg_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src1, eRegL src2, rRegI tmp) %{
|
||||||
|
match(Set flags (CmpUL src1 src2));
|
||||||
|
effect(TEMP tmp);
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "CMP $src2.lo,$src1.lo\t! Unsigned long compare, swapped operands, use with commuted test\n\t"
|
||||||
|
"MOV $tmp,$src2.hi\n\t"
|
||||||
|
"SBB $tmp,$src1.hi\t! Compute flags for unsigned long compare" %}
|
||||||
|
ins_encode(long_cmp_flags2( src2, src1, tmp));
|
||||||
|
ins_pipe(ialu_cr_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Unsigned long compares reg < zero/req OR reg >= zero/req.
|
||||||
|
// Just a wrapper for a normal branch, plus the predicate test
|
||||||
|
instruct cmpUL_LEGT(cmpOpU_commute cmp, flagsReg_ulong_LEGT flags, label labl) %{
|
||||||
|
match(If cmp flags);
|
||||||
|
effect(USE labl);
|
||||||
|
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
|
||||||
|
ins_cost(300);
|
||||||
|
expand %{
|
||||||
|
jmpCon(cmp, flags, labl); // JGT or JLE...
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare 2 longs and CMOVE longs.
|
// Compare 2 longs and CMOVE longs.
|
||||||
instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{
|
instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{
|
||||||
match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
|
match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
|
||||||
|
@ -11518,6 +11518,48 @@ instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Unsigned long compare Instructions; really, same as signed long except they
|
||||||
|
// produce an rFlagsRegU instead of rFlagsReg.
|
||||||
|
instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL op1 op2));
|
||||||
|
|
||||||
|
format %{ "cmpq $op1, $op2\t# unsigned" %}
|
||||||
|
opcode(0x3B); /* Opcode 3B /r */
|
||||||
|
ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
|
||||||
|
ins_pipe(ialu_cr_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL op1 op2));
|
||||||
|
|
||||||
|
format %{ "cmpq $op1, $op2\t# unsigned" %}
|
||||||
|
opcode(0x81, 0x07); /* Opcode 81 /7 */
|
||||||
|
ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
|
||||||
|
ins_pipe(ialu_cr_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL op1 (LoadL op2)));
|
||||||
|
|
||||||
|
format %{ "cmpq $op1, $op2\t# unsigned" %}
|
||||||
|
opcode(0x3B); /* Opcode 3B /r */
|
||||||
|
ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
|
||||||
|
ins_pipe(ialu_cr_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero)
|
||||||
|
%{
|
||||||
|
match(Set cr (CmpUL src zero));
|
||||||
|
|
||||||
|
format %{ "testq $src, $src\t# unsigned" %}
|
||||||
|
opcode(0x85);
|
||||||
|
ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
|
||||||
|
ins_pipe(ialu_cr_reg_imm);
|
||||||
|
%}
|
||||||
|
|
||||||
//----------Max and Min--------------------------------------------------------
|
//----------Max and Min--------------------------------------------------------
|
||||||
// Min Instructions
|
// Min Instructions
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
package org.graalvm.compiler.hotspot;
|
package org.graalvm.compiler.hotspot;
|
||||||
|
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mechanism for checking that the current Java runtime environment supports the minimum JVMCI API
|
* Mechanism for checking that the current Java runtime environment supports the minimum JVMCI API
|
||||||
@ -37,10 +38,11 @@ import java.util.Formatter;
|
|||||||
class JVMCIVersionCheck {
|
class JVMCIVersionCheck {
|
||||||
|
|
||||||
private static final int JVMCI8_MIN_MAJOR_VERSION = 0;
|
private static final int JVMCI8_MIN_MAJOR_VERSION = 0;
|
||||||
private static final int JVMCI8_MIN_MINOR_VERSION = 23;
|
private static final int JVMCI8_MIN_MINOR_VERSION = 26;
|
||||||
|
|
||||||
// Will be updated once an ea build with the required JVMCI API is available.
|
// MAX_VALUE indicates that no current EA version is compatible with Graal.
|
||||||
private static final int JVMCI9_MIN_EA_BUILD = 143;
|
// Note: Keep README.md in sync with the EA version support checked here.
|
||||||
|
private static final int JVMCI9_MIN_EA_BUILD = 176;
|
||||||
|
|
||||||
private static void failVersionCheck(boolean exit, String reason, Object... args) {
|
private static void failVersionCheck(boolean exit, String reason, Object... args) {
|
||||||
Formatter errorMessage = new Formatter().format(reason, args);
|
Formatter errorMessage = new Formatter().format(reason, args);
|
||||||
@ -77,13 +79,27 @@ class JVMCIVersionCheck {
|
|||||||
start += "-jvmci-".length();
|
start += "-jvmci-".length();
|
||||||
int end = vmVersion.indexOf('.', start);
|
int end = vmVersion.indexOf('.', start);
|
||||||
if (end > 0) {
|
if (end > 0) {
|
||||||
int major = Integer.parseInt(vmVersion.substring(start, end));
|
int major;
|
||||||
|
try {
|
||||||
|
major = Integer.parseInt(vmVersion.substring(start, end));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
|
||||||
|
"Cannot read JVMCI major version from java.vm.version property: %s.%n", vmVersion);
|
||||||
|
return;
|
||||||
|
}
|
||||||
start = end + 1;
|
start = end + 1;
|
||||||
end = start;
|
end = start;
|
||||||
while (end < vmVersion.length() && Character.isDigit(vmVersion.charAt(end))) {
|
while (end < vmVersion.length() && Character.isDigit(vmVersion.charAt(end))) {
|
||||||
end++;
|
end++;
|
||||||
}
|
}
|
||||||
int minor = Integer.parseInt(vmVersion.substring(start, end));
|
int minor;
|
||||||
|
try {
|
||||||
|
minor = Integer.parseInt(vmVersion.substring(start, end));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
|
||||||
|
"Cannot read JVMCI minor version from java.vm.version property: %s.%n", vmVersion);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (major >= JVMCI8_MIN_MAJOR_VERSION && minor >= JVMCI8_MIN_MINOR_VERSION) {
|
if (major >= JVMCI8_MIN_MAJOR_VERSION && minor >= JVMCI8_MIN_MINOR_VERSION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -96,7 +112,7 @@ class JVMCIVersionCheck {
|
|||||||
"Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
|
"Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
|
||||||
} else {
|
} else {
|
||||||
if (vmVersion.contains("SNAPSHOT")) {
|
if (vmVersion.contains("SNAPSHOT")) {
|
||||||
// The snapshot of http://hg.openjdk.java.net/jdk9/hs tip is expected to work
|
// The snapshot of http://hg.openjdk.java.net/jdk9/dev tip is expected to work
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vmVersion.contains("internal")) {
|
if (vmVersion.contains("internal")) {
|
||||||
@ -104,23 +120,36 @@ class JVMCIVersionCheck {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// http://openjdk.java.net/jeps/223
|
// http://openjdk.java.net/jeps/223
|
||||||
// Only support EA builds until GA is available
|
if (vmVersion.startsWith("9+")) {
|
||||||
if (vmVersion.startsWith("9-ea+")) {
|
int start = "9+".length();
|
||||||
int start = "9-ea+".length();
|
|
||||||
int end = start;
|
int end = start;
|
||||||
end = start;
|
end = start;
|
||||||
while (end < vmVersion.length() && Character.isDigit(vmVersion.charAt(end))) {
|
while (end < vmVersion.length() && Character.isDigit(vmVersion.charAt(end))) {
|
||||||
end++;
|
end++;
|
||||||
}
|
}
|
||||||
int build = Integer.parseInt(vmVersion.substring(start, end));
|
int build;
|
||||||
|
try {
|
||||||
|
build = Integer.parseInt(vmVersion.substring(start, end));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
|
||||||
|
"Cannot read JDK9 EA build number from java.vm.version property: %s.%n", vmVersion);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (build >= JVMCI9_MIN_EA_BUILD) {
|
if (build >= JVMCI9_MIN_EA_BUILD) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
failVersionCheck(exitOnFailure, "The VM is an insufficiently recent EA JDK9 build for Graal: %d < %d.%n", build, JVMCI9_MIN_EA_BUILD);
|
// Using Object.equals suppresses Eclipse's "Dead code" warning.
|
||||||
|
// Unfortunately @SuppressWarnings("unused") can only be applied at method level.
|
||||||
|
if (Objects.equals(JVMCI9_MIN_EA_BUILD, Integer.MAX_VALUE)) {
|
||||||
|
failVersionCheck(exitOnFailure, "This version of Graal is not compatible with any JDK 9 Early Access build.%n");
|
||||||
|
} else {
|
||||||
|
failVersionCheck(exitOnFailure, "The VM is an insufficiently recent EA JDK9 build for Graal: %d < %d.%n", build, JVMCI9_MIN_EA_BUILD);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
// Graal will be compatible with all JDK versions as of 9 GA
|
||||||
|
// until a JVMCI API change is made in a 9u or later release.
|
||||||
}
|
}
|
||||||
failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
|
|
||||||
"Cannot read JDK9 EA build number from java.vm.version property: %s.%n", vmVersion);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1166,6 +1166,7 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
|
|||||||
|| strcmp(idealName,"CmpP") == 0
|
|| strcmp(idealName,"CmpP") == 0
|
||||||
|| strcmp(idealName,"CmpN") == 0
|
|| strcmp(idealName,"CmpN") == 0
|
||||||
|| strcmp(idealName,"CmpL") == 0
|
|| strcmp(idealName,"CmpL") == 0
|
||||||
|
|| strcmp(idealName,"CmpUL") == 0
|
||||||
|| strcmp(idealName,"CmpD") == 0
|
|| strcmp(idealName,"CmpD") == 0
|
||||||
|| strcmp(idealName,"CmpF") == 0
|
|| strcmp(idealName,"CmpF") == 0
|
||||||
|| strcmp(idealName,"FastLock") == 0
|
|| strcmp(idealName,"FastLock") == 0
|
||||||
|
@ -181,7 +181,7 @@
|
|||||||
"Map number of unrolls for main loop via " \
|
"Map number of unrolls for main loop via " \
|
||||||
"Superword Level Parallelism analysis") \
|
"Superword Level Parallelism analysis") \
|
||||||
\
|
\
|
||||||
diagnostic_pd(bool, PostLoopMultiversioning, \
|
experimental(bool, PostLoopMultiversioning, false, \
|
||||||
"Multi versioned post loops to eliminate range checks") \
|
"Multi versioned post loops to eliminate range checks") \
|
||||||
\
|
\
|
||||||
notproduct(bool, TraceSuperWordLoopUnrollAnalysis, false, \
|
notproduct(bool, TraceSuperWordLoopUnrollAnalysis, false, \
|
||||||
|
@ -81,6 +81,7 @@ macro(CmpL3)
|
|||||||
macro(CmpLTMask)
|
macro(CmpLTMask)
|
||||||
macro(CmpP)
|
macro(CmpP)
|
||||||
macro(CmpU)
|
macro(CmpU)
|
||||||
|
macro(CmpUL)
|
||||||
macro(CompareAndSwapB)
|
macro(CompareAndSwapB)
|
||||||
macro(CompareAndSwapS)
|
macro(CompareAndSwapS)
|
||||||
macro(CompareAndSwapI)
|
macro(CompareAndSwapI)
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "opto/connode.hpp"
|
#include "opto/connode.hpp"
|
||||||
#include "opto/convertnode.hpp"
|
#include "opto/convertnode.hpp"
|
||||||
#include "opto/loopnode.hpp"
|
#include "opto/loopnode.hpp"
|
||||||
|
#include "opto/matcher.hpp"
|
||||||
#include "opto/mulnode.hpp"
|
#include "opto/mulnode.hpp"
|
||||||
#include "opto/opaquenode.hpp"
|
#include "opto/opaquenode.hpp"
|
||||||
#include "opto/rootnode.hpp"
|
#include "opto/rootnode.hpp"
|
||||||
@ -629,45 +630,138 @@ bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invari
|
|||||||
// max(scale*i + offset) = scale*init + offset
|
// max(scale*i + offset) = scale*init + offset
|
||||||
BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
|
BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
|
||||||
int scale, Node* offset,
|
int scale, Node* offset,
|
||||||
Node* init, Node* limit, Node* stride,
|
Node* init, Node* limit, jint stride,
|
||||||
Node* range, bool upper) {
|
Node* range, bool upper, bool &overflow) {
|
||||||
|
jint con_limit = limit->is_Con() ? limit->get_int() : 0;
|
||||||
|
jint con_init = init->is_Con() ? init->get_int() : 0;
|
||||||
|
jint con_offset = offset->is_Con() ? offset->get_int() : 0;
|
||||||
|
|
||||||
stringStream* predString = NULL;
|
stringStream* predString = NULL;
|
||||||
if (TraceLoopPredicate) {
|
if (TraceLoopPredicate) {
|
||||||
predString = new stringStream();
|
predString = new stringStream();
|
||||||
predString->print("rc_predicate ");
|
predString->print("rc_predicate ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* max_idx_expr = init;
|
overflow = false;
|
||||||
int stride_con = stride->get_int();
|
Node* max_idx_expr = NULL;
|
||||||
if ((stride_con > 0) == (scale > 0) == upper) {
|
const TypeInt* idx_type = TypeInt::INT;
|
||||||
// Limit is not exact.
|
if ((stride > 0) == (scale > 0) == upper) {
|
||||||
// Calculate exact limit here.
|
if (TraceLoopPredicate) {
|
||||||
// Note, counted loop's test is '<' or '>'.
|
predString->print(limit->is_Con() ? "(%d " : "(limit ", con_limit);
|
||||||
limit = exact_limit(loop);
|
predString->print("- %d) ", stride);
|
||||||
max_idx_expr = new SubINode(limit, stride);
|
}
|
||||||
|
// Check if (limit - stride) may overflow
|
||||||
|
const TypeInt* limit_type = _igvn.type(limit)->isa_int();
|
||||||
|
jint limit_lo = limit_type->_lo;
|
||||||
|
jint limit_hi = limit_type->_hi;
|
||||||
|
if ((stride > 0 && (java_subtract(limit_lo, stride) < limit_lo)) ||
|
||||||
|
(stride < 0 && (java_subtract(limit_hi, stride) > limit_hi))) {
|
||||||
|
// No overflow possible
|
||||||
|
ConINode* con_stride = _igvn.intcon(stride);
|
||||||
|
set_ctrl(con_stride, C->root());
|
||||||
|
max_idx_expr = new SubINode(limit, con_stride);
|
||||||
|
idx_type = TypeInt::make(limit_lo - stride, limit_hi - stride, limit_type->_widen);
|
||||||
|
} else {
|
||||||
|
// May overflow
|
||||||
|
overflow = true;
|
||||||
|
limit = new ConvI2LNode(limit);
|
||||||
|
register_new_node(limit, ctrl);
|
||||||
|
ConLNode* con_stride = _igvn.longcon(stride);
|
||||||
|
set_ctrl(con_stride, C->root());
|
||||||
|
max_idx_expr = new SubLNode(limit, con_stride);
|
||||||
|
}
|
||||||
register_new_node(max_idx_expr, ctrl);
|
register_new_node(max_idx_expr, ctrl);
|
||||||
if (TraceLoopPredicate) predString->print("(limit - stride) ");
|
|
||||||
} else {
|
} else {
|
||||||
if (TraceLoopPredicate) predString->print("init ");
|
if (TraceLoopPredicate) {
|
||||||
|
predString->print(init->is_Con() ? "%d " : "init ", con_init);
|
||||||
|
}
|
||||||
|
idx_type = _igvn.type(init)->isa_int();
|
||||||
|
max_idx_expr = init;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scale != 1) {
|
if (scale != 1) {
|
||||||
ConNode* con_scale = _igvn.intcon(scale);
|
ConNode* con_scale = _igvn.intcon(scale);
|
||||||
set_ctrl(con_scale, C->root());
|
set_ctrl(con_scale, C->root());
|
||||||
max_idx_expr = new MulINode(max_idx_expr, con_scale);
|
if (TraceLoopPredicate) {
|
||||||
|
predString->print("* %d ", scale);
|
||||||
|
}
|
||||||
|
// Check if (scale * max_idx_expr) may overflow
|
||||||
|
const TypeInt* scale_type = TypeInt::make(scale);
|
||||||
|
MulINode* mul = new MulINode(max_idx_expr, con_scale);
|
||||||
|
idx_type = (TypeInt*)mul->mul_ring(idx_type, scale_type);
|
||||||
|
if (overflow || TypeInt::INT->higher_equal(idx_type)) {
|
||||||
|
// May overflow
|
||||||
|
mul->destruct();
|
||||||
|
if (!overflow) {
|
||||||
|
max_idx_expr = new ConvI2LNode(max_idx_expr);
|
||||||
|
register_new_node(max_idx_expr, ctrl);
|
||||||
|
}
|
||||||
|
overflow = true;
|
||||||
|
con_scale = _igvn.longcon(scale);
|
||||||
|
set_ctrl(con_scale, C->root());
|
||||||
|
max_idx_expr = new MulLNode(max_idx_expr, con_scale);
|
||||||
|
} else {
|
||||||
|
// No overflow possible
|
||||||
|
max_idx_expr = mul;
|
||||||
|
}
|
||||||
register_new_node(max_idx_expr, ctrl);
|
register_new_node(max_idx_expr, ctrl);
|
||||||
if (TraceLoopPredicate) predString->print("* %d ", scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset && (!offset->is_Con() || offset->get_int() != 0)){
|
if (offset && (!offset->is_Con() || con_offset != 0)){
|
||||||
max_idx_expr = new AddINode(max_idx_expr, offset);
|
if (TraceLoopPredicate) {
|
||||||
|
predString->print(offset->is_Con() ? "+ %d " : "+ offset", con_offset);
|
||||||
|
}
|
||||||
|
// Check if (max_idx_expr + offset) may overflow
|
||||||
|
const TypeInt* offset_type = _igvn.type(offset)->isa_int();
|
||||||
|
jint lo = java_add(idx_type->_lo, offset_type->_lo);
|
||||||
|
jint hi = java_add(idx_type->_hi, offset_type->_hi);
|
||||||
|
if (overflow || (lo > hi) ||
|
||||||
|
((idx_type->_lo & offset_type->_lo) < 0 && lo >= 0) ||
|
||||||
|
((~(idx_type->_hi | offset_type->_hi)) < 0 && hi < 0)) {
|
||||||
|
// May overflow
|
||||||
|
if (!overflow) {
|
||||||
|
max_idx_expr = new ConvI2LNode(max_idx_expr);
|
||||||
|
register_new_node(max_idx_expr, ctrl);
|
||||||
|
}
|
||||||
|
overflow = true;
|
||||||
|
offset = new ConvI2LNode(offset);
|
||||||
|
register_new_node(offset, ctrl);
|
||||||
|
max_idx_expr = new AddLNode(max_idx_expr, offset);
|
||||||
|
} else {
|
||||||
|
// No overflow possible
|
||||||
|
max_idx_expr = new AddINode(max_idx_expr, offset);
|
||||||
|
}
|
||||||
register_new_node(max_idx_expr, ctrl);
|
register_new_node(max_idx_expr, ctrl);
|
||||||
if (TraceLoopPredicate)
|
|
||||||
if (offset->is_Con()) predString->print("+ %d ", offset->get_int());
|
|
||||||
else predString->print("+ offset ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CmpUNode* cmp = new CmpUNode(max_idx_expr, range);
|
CmpNode* cmp = NULL;
|
||||||
|
if (overflow) {
|
||||||
|
// Integer expressions may overflow, do long comparison
|
||||||
|
range = new ConvI2LNode(range);
|
||||||
|
register_new_node(range, ctrl);
|
||||||
|
if (!Matcher::has_match_rule(Op_CmpUL)) {
|
||||||
|
// We don't support unsigned long comparisons. Set 'max_idx_expr'
|
||||||
|
// to max_julong if < 0 to make the signed comparison fail.
|
||||||
|
ConINode* sign_pos = _igvn.intcon(BitsPerLong - 1);
|
||||||
|
set_ctrl(sign_pos, C->root());
|
||||||
|
Node* sign_bit_mask = new RShiftLNode(max_idx_expr, sign_pos);
|
||||||
|
register_new_node(sign_bit_mask, ctrl);
|
||||||
|
// OR with sign bit to set all bits to 1 if negative (otherwise no change)
|
||||||
|
max_idx_expr = new OrLNode(max_idx_expr, sign_bit_mask);
|
||||||
|
register_new_node(max_idx_expr, ctrl);
|
||||||
|
// AND with 0x7ff... to unset the sign bit
|
||||||
|
ConLNode* remove_sign_mask = _igvn.longcon(max_jlong);
|
||||||
|
set_ctrl(remove_sign_mask, C->root());
|
||||||
|
max_idx_expr = new AndLNode(max_idx_expr, remove_sign_mask);
|
||||||
|
register_new_node(max_idx_expr, ctrl);
|
||||||
|
|
||||||
|
cmp = new CmpLNode(max_idx_expr, range);
|
||||||
|
} else {
|
||||||
|
cmp = new CmpULNode(max_idx_expr, range);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cmp = new CmpUNode(max_idx_expr, range);
|
||||||
|
}
|
||||||
register_new_node(cmp, ctrl);
|
register_new_node(cmp, ctrl);
|
||||||
BoolNode* bol = new BoolNode(cmp, BoolTest::lt);
|
BoolNode* bol = new BoolNode(cmp, BoolTest::lt);
|
||||||
register_new_node(bol, ctrl);
|
register_new_node(bol, ctrl);
|
||||||
@ -814,28 +908,30 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
|
|||||||
assert(ok, "must be index expression");
|
assert(ok, "must be index expression");
|
||||||
|
|
||||||
Node* init = cl->init_trip();
|
Node* init = cl->init_trip();
|
||||||
Node* limit = cl->limit();
|
// Limit is not exact.
|
||||||
Node* stride = cl->stride();
|
// Calculate exact limit here.
|
||||||
|
// Note, counted loop's test is '<' or '>'.
|
||||||
|
Node* limit = exact_limit(loop);
|
||||||
|
int stride = cl->stride()->get_int();
|
||||||
|
|
||||||
// Build if's for the upper and lower bound tests. The
|
// Build if's for the upper and lower bound tests. The
|
||||||
// lower_bound test will dominate the upper bound test and all
|
// lower_bound test will dominate the upper bound test and all
|
||||||
// cloned or created nodes will use the lower bound test as
|
// cloned or created nodes will use the lower bound test as
|
||||||
// their declared control.
|
// their declared control.
|
||||||
ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode());
|
|
||||||
ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode());
|
|
||||||
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
|
|
||||||
Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
|
|
||||||
|
|
||||||
// Perform cloning to keep Invariance state correct since the
|
// Perform cloning to keep Invariance state correct since the
|
||||||
// late schedule will place invariant things in the loop.
|
// late schedule will place invariant things in the loop.
|
||||||
|
Node *ctrl = predicate_proj->in(0)->as_If()->in(0);
|
||||||
rng = invar.clone(rng, ctrl);
|
rng = invar.clone(rng, ctrl);
|
||||||
if (offset && offset != zero) {
|
if (offset && offset != zero) {
|
||||||
assert(invar.is_invariant(offset), "offset must be loop invariant");
|
assert(invar.is_invariant(offset), "offset must be loop invariant");
|
||||||
offset = invar.clone(offset, ctrl);
|
offset = invar.clone(offset, ctrl);
|
||||||
}
|
}
|
||||||
|
// If predicate expressions may overflow in the integer range, longs are used.
|
||||||
|
bool overflow = false;
|
||||||
|
|
||||||
// Test the lower bound
|
// Test the lower bound
|
||||||
BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false);
|
BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow);
|
||||||
// Negate test if necessary
|
// Negate test if necessary
|
||||||
bool negated = false;
|
bool negated = false;
|
||||||
if (proj->_con != predicate_proj->_con) {
|
if (proj->_con != predicate_proj->_con) {
|
||||||
@ -843,19 +939,22 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
|
|||||||
register_new_node(lower_bound_bol, ctrl);
|
register_new_node(lower_bound_bol, ctrl);
|
||||||
negated = true;
|
negated = true;
|
||||||
}
|
}
|
||||||
|
ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode());
|
||||||
IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
|
IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
|
||||||
_igvn.hash_delete(lower_bound_iff);
|
_igvn.hash_delete(lower_bound_iff);
|
||||||
lower_bound_iff->set_req(1, lower_bound_bol);
|
lower_bound_iff->set_req(1, lower_bound_bol);
|
||||||
if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx);
|
if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx);
|
||||||
|
|
||||||
// Test the upper bound
|
// Test the upper bound
|
||||||
BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true);
|
BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow);
|
||||||
negated = false;
|
negated = false;
|
||||||
if (proj->_con != predicate_proj->_con) {
|
if (proj->_con != predicate_proj->_con) {
|
||||||
upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate());
|
upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate());
|
||||||
register_new_node(upper_bound_bol, ctrl);
|
register_new_node(upper_bound_bol, ctrl);
|
||||||
negated = true;
|
negated = true;
|
||||||
}
|
}
|
||||||
|
ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode());
|
||||||
|
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
|
||||||
IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
|
IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
|
||||||
_igvn.hash_delete(upper_bound_iff);
|
_igvn.hash_delete(upper_bound_iff);
|
||||||
upper_bound_iff->set_req(1, upper_bound_bol);
|
upper_bound_iff->set_req(1, upper_bound_bol);
|
||||||
|
@ -983,8 +983,8 @@ public:
|
|||||||
// Construct a range check for a predicate if
|
// Construct a range check for a predicate if
|
||||||
BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl,
|
BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl,
|
||||||
int scale, Node* offset,
|
int scale, Node* offset,
|
||||||
Node* init, Node* limit, Node* stride,
|
Node* init, Node* limit, jint stride,
|
||||||
Node* range, bool upper);
|
Node* range, bool upper, bool &overflow);
|
||||||
|
|
||||||
// Implementation of the loop predication to promote checks outside the loop
|
// Implementation of the loop predication to promote checks outside the loop
|
||||||
bool loop_predication_impl(IdealLoopTree *loop);
|
bool loop_predication_impl(IdealLoopTree *loop);
|
||||||
|
@ -1982,6 +1982,7 @@ void Scheduling::AddNodeToAvailableList(Node *n) {
|
|||||||
if( last->is_MachIf() && last->in(1) == n &&
|
if( last->is_MachIf() && last->in(1) == n &&
|
||||||
( op == Op_CmpI ||
|
( op == Op_CmpI ||
|
||||||
op == Op_CmpU ||
|
op == Op_CmpU ||
|
||||||
|
op == Op_CmpUL ||
|
||||||
op == Op_CmpP ||
|
op == Op_CmpP ||
|
||||||
op == Op_CmpF ||
|
op == Op_CmpF ||
|
||||||
op == Op_CmpD ||
|
op == Op_CmpD ||
|
||||||
|
@ -738,6 +738,60 @@ const Type *CmpLNode::sub( const Type *t1, const Type *t2 ) const {
|
|||||||
return TypeInt::CC; // else use worst case results
|
return TypeInt::CC; // else use worst case results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Simplify a CmpUL (compare 2 unsigned longs) node, based on local information.
|
||||||
|
// If both inputs are constants, compare them.
|
||||||
|
const Type* CmpULNode::sub(const Type* t1, const Type* t2) const {
|
||||||
|
assert(!t1->isa_ptr(), "obsolete usage of CmpUL");
|
||||||
|
|
||||||
|
// comparing two unsigned longs
|
||||||
|
const TypeLong* r0 = t1->is_long(); // Handy access
|
||||||
|
const TypeLong* r1 = t2->is_long();
|
||||||
|
|
||||||
|
// Current installed version
|
||||||
|
// Compare ranges for non-overlap
|
||||||
|
julong lo0 = r0->_lo;
|
||||||
|
julong hi0 = r0->_hi;
|
||||||
|
julong lo1 = r1->_lo;
|
||||||
|
julong hi1 = r1->_hi;
|
||||||
|
|
||||||
|
// If either one has both negative and positive values,
|
||||||
|
// it therefore contains both 0 and -1, and since [0..-1] is the
|
||||||
|
// full unsigned range, the type must act as an unsigned bottom.
|
||||||
|
bool bot0 = ((jlong)(lo0 ^ hi0) < 0);
|
||||||
|
bool bot1 = ((jlong)(lo1 ^ hi1) < 0);
|
||||||
|
|
||||||
|
if (bot0 || bot1) {
|
||||||
|
// All unsigned values are LE -1 and GE 0.
|
||||||
|
if (lo0 == 0 && hi0 == 0) {
|
||||||
|
return TypeInt::CC_LE; // 0 <= bot
|
||||||
|
} else if ((jlong)lo0 == -1 && (jlong)hi0 == -1) {
|
||||||
|
return TypeInt::CC_GE; // -1 >= bot
|
||||||
|
} else if (lo1 == 0 && hi1 == 0) {
|
||||||
|
return TypeInt::CC_GE; // bot >= 0
|
||||||
|
} else if ((jlong)lo1 == -1 && (jlong)hi1 == -1) {
|
||||||
|
return TypeInt::CC_LE; // bot <= -1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We can use ranges of the form [lo..hi] if signs are the same.
|
||||||
|
assert(lo0 <= hi0 && lo1 <= hi1, "unsigned ranges are valid");
|
||||||
|
// results are reversed, '-' > '+' for unsigned compare
|
||||||
|
if (hi0 < lo1) {
|
||||||
|
return TypeInt::CC_LT; // smaller
|
||||||
|
} else if (lo0 > hi1) {
|
||||||
|
return TypeInt::CC_GT; // greater
|
||||||
|
} else if (hi0 == lo1 && lo0 == hi1) {
|
||||||
|
return TypeInt::CC_EQ; // Equal results
|
||||||
|
} else if (lo0 >= hi1) {
|
||||||
|
return TypeInt::CC_GE;
|
||||||
|
} else if (hi0 <= lo1) {
|
||||||
|
return TypeInt::CC_LE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypeInt::CC; // else use worst case results
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//------------------------------sub--------------------------------------------
|
//------------------------------sub--------------------------------------------
|
||||||
// Simplify an CmpP (compare 2 pointers) node, based on local information.
|
// Simplify an CmpP (compare 2 pointers) node, based on local information.
|
||||||
|
@ -198,6 +198,15 @@ public:
|
|||||||
virtual const Type *sub( const Type *, const Type * ) const;
|
virtual const Type *sub( const Type *, const Type * ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//------------------------------CmpULNode---------------------------------------
|
||||||
|
// Compare 2 unsigned long values, returning condition codes (-1, 0 or 1).
|
||||||
|
class CmpULNode : public CmpNode {
|
||||||
|
public:
|
||||||
|
CmpULNode(Node* in1, Node* in2) : CmpNode(in1, in2) { }
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual const Type* sub(const Type*, const Type*) const;
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------CmpL3Node--------------------------------------
|
//------------------------------CmpL3Node--------------------------------------
|
||||||
// Compare 2 long values, returning integer value (-1, 0 or 1).
|
// Compare 2 long values, returning integer value (-1, 0 or 1).
|
||||||
class CmpL3Node : public CmpLNode {
|
class CmpL3Node : public CmpLNode {
|
||||||
|
@ -2013,6 +2013,7 @@ typedef RehashableHashtable<Symbol*, mtSymbol> RehashableSymbolHashtable;
|
|||||||
declare_c2_type(CmpPNode, CmpNode) \
|
declare_c2_type(CmpPNode, CmpNode) \
|
||||||
declare_c2_type(CmpNNode, CmpNode) \
|
declare_c2_type(CmpNNode, CmpNode) \
|
||||||
declare_c2_type(CmpLNode, CmpNode) \
|
declare_c2_type(CmpLNode, CmpNode) \
|
||||||
|
declare_c2_type(CmpULNode, CmpNode) \
|
||||||
declare_c2_type(CmpL3Node, CmpLNode) \
|
declare_c2_type(CmpL3Node, CmpLNode) \
|
||||||
declare_c2_type(CmpFNode, CmpNode) \
|
declare_c2_type(CmpFNode, CmpNode) \
|
||||||
declare_c2_type(CmpF3Node, CmpFNode) \
|
declare_c2_type(CmpF3Node, CmpFNode) \
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* @bug 8154763
|
* @bug 8154763
|
||||||
* @summary Tests PostLoopMultiversioning with RangeCheckElimination disabled.
|
* @summary Tests PostLoopMultiversioning with RangeCheckElimination disabled.
|
||||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
|
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
|
||||||
* -XX:+PostLoopMultiversioning -XX:-RangeCheckElimination
|
* -XX:+UnlockExperimentalVMOptions -XX:+PostLoopMultiversioning -XX:-RangeCheckElimination
|
||||||
* compiler.rangechecks.TestRangeCheckEliminationDisabled
|
* compiler.rangechecks.TestRangeCheckEliminationDisabled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -437,3 +437,6 @@ ff293e39e83366c40a5687dacd1ccb2305ed2c1e jdk-10+12
|
|||||||
332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177
|
332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177
|
||||||
02a876781a3a6193140591d92db7b95ca743eac2 jdk-10+15
|
02a876781a3a6193140591d92db7b95ca743eac2 jdk-10+15
|
||||||
d109d55cf642bf2b438624e81f94c18c168f9178 jdk-10+16
|
d109d55cf642bf2b438624e81f94c18c168f9178 jdk-10+16
|
||||||
|
0983b2dbe17ba4fed3af34e0512ca77a9845fe8a jdk-9+178
|
||||||
|
87243a3131f79e8b3903eaca6b629abc48f08ace jdk-9+179
|
||||||
|
97d6f14334cfd766f57c296a5a707c8a709aeff0 jdk-10+17
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* reserved comment block
|
|
||||||
* DO NOT REMOVE OR ALTER!
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sun.org.apache.xml.internal.dtm;
|
|
||||||
|
|
||||||
import javax.xml.transform.SourceLocator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates a serious configuration error.
|
|
||||||
*/
|
|
||||||
public class DTMConfigurationException extends DTMException {
|
|
||||||
static final long serialVersionUID = -4607874078818418046L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new <code>DTMConfigurationException</code> with no
|
|
||||||
* detail message.
|
|
||||||
*/
|
|
||||||
public DTMConfigurationException() {
|
|
||||||
super("Configuration Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new <code>DTMConfigurationException</code> with
|
|
||||||
* the <code>String </code> specified as an error message.
|
|
||||||
*
|
|
||||||
* @param msg The error message for the exception.
|
|
||||||
*/
|
|
||||||
public DTMConfigurationException(String msg) {
|
|
||||||
super(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new <code>DTMConfigurationException</code> with a
|
|
||||||
* given <code>Exception</code> base cause of the error.
|
|
||||||
*
|
|
||||||
* @param e The exception to be encapsulated in a
|
|
||||||
* DTMConfigurationException.
|
|
||||||
*/
|
|
||||||
public DTMConfigurationException(Throwable e) {
|
|
||||||
super(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new <code>DTMConfigurationException</code> with the
|
|
||||||
* given <code>Exception</code> base cause and detail message.
|
|
||||||
*
|
|
||||||
* @param msg The detail message.
|
|
||||||
* @param e The exception to be wrapped in a DTMConfigurationException
|
|
||||||
*/
|
|
||||||
public DTMConfigurationException(String msg, Throwable e) {
|
|
||||||
super(msg, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new DTMConfigurationException from a message and a Locator.
|
|
||||||
*
|
|
||||||
* <p>This constructor is especially useful when an application is
|
|
||||||
* creating its own exception from within a DocumentHandler
|
|
||||||
* callback.</p>
|
|
||||||
*
|
|
||||||
* @param message The error or warning message.
|
|
||||||
* @param locator The locator object for the error or warning.
|
|
||||||
*/
|
|
||||||
public DTMConfigurationException(String message,
|
|
||||||
SourceLocator locator) {
|
|
||||||
super(message, locator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap an existing exception in a DTMConfigurationException.
|
|
||||||
*
|
|
||||||
* @param message The error or warning message, or null to
|
|
||||||
* use the message from the embedded exception.
|
|
||||||
* @param locator The locator object for the error or warning.
|
|
||||||
* @param e Any exception.
|
|
||||||
*/
|
|
||||||
public DTMConfigurationException(String message,
|
|
||||||
SourceLocator locator,
|
|
||||||
Throwable e) {
|
|
||||||
super(message, locator, e);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* reserved comment block
|
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT REMOVE OR ALTER!
|
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
@ -21,124 +20,20 @@
|
|||||||
|
|
||||||
package com.sun.org.apache.xml.internal.dtm;
|
package com.sun.org.apache.xml.internal.dtm;
|
||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
import javax.xml.transform.SourceLocator;
|
|
||||||
|
|
||||||
import com.sun.org.apache.xml.internal.res.XMLErrorResources;
|
|
||||||
import com.sun.org.apache.xml.internal.res.XMLMessages;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class specifies an exceptional condition that occured
|
* This class specifies an exceptional condition that occurred
|
||||||
* in the DTM module.
|
* in the DTM module.
|
||||||
*/
|
*/
|
||||||
public class DTMException extends RuntimeException {
|
public class DTMException extends RuntimeException {
|
||||||
static final long serialVersionUID = -775576419181334734L;
|
static final long serialVersionUID = -775576419181334734L;
|
||||||
|
|
||||||
/** Field locator specifies where the error occured.
|
|
||||||
* @serial */
|
|
||||||
SourceLocator locator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method getLocator retrieves an instance of a SourceLocator
|
|
||||||
* object that specifies where an error occured.
|
|
||||||
*
|
|
||||||
* @return A SourceLocator object, or null if none was specified.
|
|
||||||
*/
|
|
||||||
public SourceLocator getLocator() {
|
|
||||||
return locator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method setLocator sets an instance of a SourceLocator
|
|
||||||
* object that specifies where an error occured.
|
|
||||||
*
|
|
||||||
* @param location A SourceLocator object, or null to clear the location.
|
|
||||||
*/
|
|
||||||
public void setLocator(SourceLocator location) {
|
|
||||||
locator = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Field containedException specifies a wrapped exception. May be null.
|
|
||||||
* @serial */
|
|
||||||
Throwable containedException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method retrieves an exception that this exception wraps.
|
|
||||||
*
|
|
||||||
* @return An Throwable object, or null.
|
|
||||||
* @see #getCause
|
|
||||||
*/
|
|
||||||
public Throwable getException() {
|
|
||||||
return containedException;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the cause of this throwable or <code>null</code> if the
|
|
||||||
* cause is nonexistent or unknown. (The cause is the throwable that
|
|
||||||
* caused this throwable to get thrown.)
|
|
||||||
*/
|
|
||||||
public Throwable getCause() {
|
|
||||||
|
|
||||||
return ((containedException == this)
|
|
||||||
? null
|
|
||||||
: containedException);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the <i>cause</i> of this throwable to the specified value.
|
|
||||||
* (The cause is the throwable that caused this throwable to get thrown.)
|
|
||||||
*
|
|
||||||
* <p>This method can be called at most once. It is generally called from
|
|
||||||
* within the constructor, or immediately after creating the
|
|
||||||
* throwable. If this throwable was created
|
|
||||||
* with {@link #DTMException(Throwable)} or
|
|
||||||
* {@link #DTMException(String,Throwable)}, this method cannot be called
|
|
||||||
* even once.
|
|
||||||
*
|
|
||||||
* @param cause the cause (which is saved for later retrieval by the
|
|
||||||
* {@link #getCause()} method). (A <tt>null</tt> value is
|
|
||||||
* permitted, and indicates that the cause is nonexistent or
|
|
||||||
* unknown.)
|
|
||||||
* @return a reference to this <code>Throwable</code> instance.
|
|
||||||
* @throws IllegalArgumentException if <code>cause</code> is this
|
|
||||||
* throwable. (A throwable cannot
|
|
||||||
* be its own cause.)
|
|
||||||
* @throws IllegalStateException if this throwable was
|
|
||||||
* created with {@link #DTMException(Throwable)} or
|
|
||||||
* {@link #DTMException(String,Throwable)}, or this method has already
|
|
||||||
* been called on this throwable.
|
|
||||||
*/
|
|
||||||
public synchronized Throwable initCause(Throwable cause) {
|
|
||||||
|
|
||||||
if ((this.containedException == null) && (cause != null)) {
|
|
||||||
throw new IllegalStateException(XMLMessages.createXMLMessage(XMLErrorResources.ER_CANNOT_OVERWRITE_CAUSE, null)); //"Can't overwrite cause");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cause == this) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
XMLMessages.createXMLMessage(XMLErrorResources.ER_SELF_CAUSATION_NOT_PERMITTED, null)); //"Self-causation not permitted");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.containedException = cause;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new DTMException.
|
* Create a new DTMException.
|
||||||
*
|
*
|
||||||
* @param message The error or warning message.
|
* @param message The error or warning message.
|
||||||
*/
|
*/
|
||||||
public DTMException(String message) {
|
public DTMException(String message) {
|
||||||
|
|
||||||
super(message);
|
super(message);
|
||||||
|
|
||||||
this.containedException = null;
|
|
||||||
this.locator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,11 +42,7 @@ public class DTMException extends RuntimeException {
|
|||||||
* @param e The exception to be wrapped.
|
* @param e The exception to be wrapped.
|
||||||
*/
|
*/
|
||||||
public DTMException(Throwable e) {
|
public DTMException(Throwable e) {
|
||||||
|
super(e);
|
||||||
super(e.getMessage());
|
|
||||||
|
|
||||||
this.containedException = e;
|
|
||||||
this.locator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,162 +56,6 @@ public class DTMException extends RuntimeException {
|
|||||||
* @param e Any exception
|
* @param e Any exception
|
||||||
*/
|
*/
|
||||||
public DTMException(String message, Throwable e) {
|
public DTMException(String message, Throwable e) {
|
||||||
|
super(message, e);
|
||||||
super(((message == null) || (message.length() == 0))
|
|
||||||
? e.getMessage()
|
|
||||||
: message);
|
|
||||||
|
|
||||||
this.containedException = e;
|
|
||||||
this.locator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new DTMException from a message and a Locator.
|
|
||||||
*
|
|
||||||
* <p>This constructor is especially useful when an application is
|
|
||||||
* creating its own exception from within a DocumentHandler
|
|
||||||
* callback.</p>
|
|
||||||
*
|
|
||||||
* @param message The error or warning message.
|
|
||||||
* @param locator The locator object for the error or warning.
|
|
||||||
*/
|
|
||||||
public DTMException(String message, SourceLocator locator) {
|
|
||||||
|
|
||||||
super(message);
|
|
||||||
|
|
||||||
this.containedException = null;
|
|
||||||
this.locator = locator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap an existing exception in a DTMException.
|
|
||||||
*
|
|
||||||
* @param message The error or warning message, or null to
|
|
||||||
* use the message from the embedded exception.
|
|
||||||
* @param locator The locator object for the error or warning.
|
|
||||||
* @param e Any exception
|
|
||||||
*/
|
|
||||||
public DTMException(String message, SourceLocator locator,
|
|
||||||
Throwable e) {
|
|
||||||
|
|
||||||
super(message);
|
|
||||||
|
|
||||||
this.containedException = e;
|
|
||||||
this.locator = locator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the error message with location information
|
|
||||||
* appended.
|
|
||||||
*/
|
|
||||||
public String getMessageAndLocation() {
|
|
||||||
|
|
||||||
StringBuffer sbuffer = new StringBuffer();
|
|
||||||
String message = super.getMessage();
|
|
||||||
|
|
||||||
if (null != message) {
|
|
||||||
sbuffer.append(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null != locator) {
|
|
||||||
String systemID = locator.getSystemId();
|
|
||||||
int line = locator.getLineNumber();
|
|
||||||
int column = locator.getColumnNumber();
|
|
||||||
|
|
||||||
if (null != systemID) {
|
|
||||||
sbuffer.append("; SystemID: ");
|
|
||||||
sbuffer.append(systemID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != line) {
|
|
||||||
sbuffer.append("; Line#: ");
|
|
||||||
sbuffer.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != column) {
|
|
||||||
sbuffer.append("; Column#: ");
|
|
||||||
sbuffer.append(column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sbuffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the location information as a string.
|
|
||||||
*
|
|
||||||
* @return A string with location info, or null
|
|
||||||
* if there is no location information.
|
|
||||||
*/
|
|
||||||
public String getLocationAsString() {
|
|
||||||
|
|
||||||
if (null != locator) {
|
|
||||||
StringBuffer sbuffer = new StringBuffer();
|
|
||||||
String systemID = locator.getSystemId();
|
|
||||||
int line = locator.getLineNumber();
|
|
||||||
int column = locator.getColumnNumber();
|
|
||||||
|
|
||||||
if (null != systemID) {
|
|
||||||
sbuffer.append("; SystemID: ");
|
|
||||||
sbuffer.append(systemID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != line) {
|
|
||||||
sbuffer.append("; Line#: ");
|
|
||||||
sbuffer.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != column) {
|
|
||||||
sbuffer.append("; Column#: ");
|
|
||||||
sbuffer.append(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sbuffer.toString();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the the trace of methods from where the error
|
|
||||||
* originated. This will trace all nested exception
|
|
||||||
* objects, as well as this object.
|
|
||||||
*/
|
|
||||||
public void printStackTrace() {
|
|
||||||
printStackTrace(new java.io.PrintWriter(System.err, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the the trace of methods from where the error
|
|
||||||
* originated. This will trace all nested exception
|
|
||||||
* objects, as well as this object.
|
|
||||||
* @param s The stream where the dump will be sent to.
|
|
||||||
*/
|
|
||||||
public void printStackTrace(java.io.PrintStream s) {
|
|
||||||
printStackTrace(new java.io.PrintWriter(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the the trace of methods from where the error
|
|
||||||
* originated. This will trace all nested exception
|
|
||||||
* objects, as well as this object.
|
|
||||||
* @param s The writer where the dump will be sent to.
|
|
||||||
*/
|
|
||||||
public void printStackTrace(java.io.PrintWriter s) {
|
|
||||||
|
|
||||||
if (s == null) {
|
|
||||||
s = new java.io.PrintWriter(System.err, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
String locInfo = getLocationAsString();
|
|
||||||
|
|
||||||
if (null != locInfo) {
|
|
||||||
s.println(locInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.printStackTrace(s);
|
|
||||||
} catch (Throwable e) {}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* reserved comment block
|
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT REMOVE OR ALTER!
|
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
@ -21,12 +20,8 @@
|
|||||||
|
|
||||||
package com.sun.org.apache.xml.internal.dtm;
|
package com.sun.org.apache.xml.internal.dtm;
|
||||||
|
|
||||||
import com.sun.org.apache.xml.internal.res.XMLErrorResources;
|
|
||||||
import com.sun.org.apache.xml.internal.res.XMLMessages;
|
|
||||||
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
|
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
|
||||||
import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
|
import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
|
||||||
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
|
|
||||||
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A DTMManager instance can be used to create DTM and
|
* A DTMManager instance can be used to create DTM and
|
||||||
@ -99,11 +94,11 @@ public abstract class DTMManager
|
|||||||
*
|
*
|
||||||
* @return new DTMManager instance, never null.
|
* @return new DTMManager instance, never null.
|
||||||
*
|
*
|
||||||
* @throws DTMConfigurationException
|
* @throws DTMException
|
||||||
* if the implementation is not available or cannot be instantiated.
|
* if the implementation is not available or cannot be instantiated.
|
||||||
*/
|
*/
|
||||||
public static DTMManager newInstance(XMLStringFactory xsf)
|
public static DTMManager newInstance(XMLStringFactory xsf)
|
||||||
throws DTMConfigurationException
|
throws DTMException
|
||||||
{
|
{
|
||||||
final DTMManager factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault();
|
final DTMManager factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault();
|
||||||
factoryImpl.setXMLStringFactory(xsf);
|
factoryImpl.setXMLStringFactory(xsf);
|
||||||
@ -315,20 +310,6 @@ public abstract class DTMManager
|
|||||||
|
|
||||||
// -------------------- private methods --------------------
|
// -------------------- private methods --------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Temp debug code - this will be removed after we test everything
|
|
||||||
*/
|
|
||||||
private static boolean debug;
|
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
debug = SecuritySupport.getSystemProperty("dtm.debug") != null;
|
|
||||||
}
|
|
||||||
catch (SecurityException ex){}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This value, set at compile time, controls how many bits of the
|
/** This value, set at compile time, controls how many bits of the
|
||||||
* DTM node identifier numbers are used to identify a node within a
|
* DTM node identifier numbers are used to identify a node within a
|
||||||
* document, and thus sets the maximum number of nodes per
|
* document, and thus sets the maximum number of nodes per
|
||||||
@ -394,47 +375,4 @@ public abstract class DTMManager
|
|||||||
{
|
{
|
||||||
return IDENT_NODE_DEFAULT;
|
return IDENT_NODE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Classes
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A configuration error.
|
|
||||||
* Originally in ObjectFactory. This is the only portion used in this package
|
|
||||||
*/
|
|
||||||
static class ConfigurationError
|
|
||||||
extends Error {
|
|
||||||
static final long serialVersionUID = 5122054096615067992L;
|
|
||||||
//
|
|
||||||
// Data
|
|
||||||
//
|
|
||||||
|
|
||||||
/** Exception. */
|
|
||||||
private Exception exception;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Constructors
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new instance with the specified detail string and
|
|
||||||
* exception.
|
|
||||||
*/
|
|
||||||
ConfigurationError(String msg, Exception x) {
|
|
||||||
super(msg);
|
|
||||||
this.exception = x;
|
|
||||||
} // <init>(String,Exception)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Public methods
|
|
||||||
//
|
|
||||||
|
|
||||||
/** Returns the exception associated to this error. */
|
|
||||||
Exception getException() {
|
|
||||||
return exception;
|
|
||||||
} // getException():Exception
|
|
||||||
|
|
||||||
} // class ConfigurationError
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ import jdk.xml.internal.SecuritySupport;
|
|||||||
* The CatalogFeatures holds a collection of features and properties.
|
* The CatalogFeatures holds a collection of features and properties.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* <table class="plain">
|
* <table class="plain" id="CatalogFeatures">
|
||||||
* <caption>Catalog Features</caption>
|
* <caption>Catalog Features</caption>
|
||||||
* <thead>
|
* <thead>
|
||||||
* <tr>
|
* <tr>
|
||||||
@ -55,7 +55,7 @@ import jdk.xml.internal.SecuritySupport;
|
|||||||
* <tbody>
|
* <tbody>
|
||||||
*
|
*
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th scope="row" style="font-weight:normal">FILES</th>
|
* <th scope="row" style="font-weight:normal" id="FILES">FILES</th>
|
||||||
* <td>A semicolon-delimited list of URIs to locate the catalog files.
|
* <td>A semicolon-delimited list of URIs to locate the catalog files.
|
||||||
* The URIs must be absolute and have a URL protocol handler for the URI scheme.
|
* The URIs must be absolute and have a URL protocol handler for the URI scheme.
|
||||||
* </td>
|
* </td>
|
||||||
@ -71,7 +71,7 @@ import jdk.xml.internal.SecuritySupport;
|
|||||||
* </tr>
|
* </tr>
|
||||||
*
|
*
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th rowspan="2" scope="row" style="font-weight:normal">PREFER</th>
|
* <th rowspan="2" scope="row" style="font-weight:normal" id="PREFER">PREFER</th>
|
||||||
* <td rowspan="2">Indicates the preference between the public and system
|
* <td rowspan="2">Indicates the preference between the public and system
|
||||||
* identifiers. The default value is public [3].</td>
|
* identifiers. The default value is public [3].</td>
|
||||||
* <td rowspan="2">javax.xml.catalog.prefer</td>
|
* <td rowspan="2">javax.xml.catalog.prefer</td>
|
||||||
@ -91,7 +91,7 @@ import jdk.xml.internal.SecuritySupport;
|
|||||||
* </tr>
|
* </tr>
|
||||||
*
|
*
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th rowspan="2" scope="row" style="font-weight:normal">DEFER</th>
|
* <th rowspan="2" scope="row" style="font-weight:normal" id="DEFER">DEFER</th>
|
||||||
* <td rowspan="2">Indicates that the alternative catalogs including those
|
* <td rowspan="2">Indicates that the alternative catalogs including those
|
||||||
* specified in delegate entries or nextCatalog are not read until they are
|
* specified in delegate entries or nextCatalog are not read until they are
|
||||||
* needed. The default value is true.</td>
|
* needed. The default value is true.</td>
|
||||||
@ -111,7 +111,7 @@ import jdk.xml.internal.SecuritySupport;
|
|||||||
* </tr>
|
* </tr>
|
||||||
*
|
*
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th rowspan="3" scope="row" style="font-weight:normal">RESOLVE</th>
|
* <th rowspan="3" scope="row" style="font-weight:normal" id="RESOLVE">RESOLVE</th>
|
||||||
* <td rowspan="3">Determines the action if there is no matching entry found after
|
* <td rowspan="3">Determines the action if there is no matching entry found after
|
||||||
* all of the specified catalogs are exhausted. The default is strict.</td>
|
* all of the specified catalogs are exhausted. The default is strict.</td>
|
||||||
* <td rowspan="3">javax.xml.catalog.resolve [4]</td>
|
* <td rowspan="3">javax.xml.catalog.resolve [4]</td>
|
||||||
|
@ -34,7 +34,7 @@ import com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory that creates new {@code javax.xml.datatype} {@code Object}s that map XML to/from Java {@code Object}s.
|
* Factory that creates new {@code javax.xml.datatype} {@code Object}s that map XML to/from Java {@code Object}s.
|
||||||
* <p>
|
* <p id="DatatypeFactory.newInstance">
|
||||||
* A new instance of the {@code DatatypeFactory} is created through the {@link #newInstance()} method
|
* A new instance of the {@code DatatypeFactory} is created through the {@link #newInstance()} method
|
||||||
* that uses the following implementation resolution mechanisms to determine an implementation:
|
* that uses the following implementation resolution mechanisms to determine an implementation:
|
||||||
* <ol>
|
* <ol>
|
||||||
|
@ -149,23 +149,13 @@
|
|||||||
* <li>xs:unsignedShort</li>
|
* <li>xs:unsignedShort</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <hr>
|
* @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
|
||||||
*
|
* @see <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">
|
||||||
* <ul>
|
|
||||||
* <li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li>
|
|
||||||
* <li>See <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">
|
|
||||||
* W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a>
|
* W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a>
|
||||||
* </li>
|
* @see <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
|
||||||
* <li>See <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
|
|
||||||
* XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>
|
* XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>
|
||||||
* </li>
|
* @see <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
|
||||||
* <li>See <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
|
|
||||||
* XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>
|
* XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>
|
||||||
* </li>
|
|
||||||
* <li>Since 1.5</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <hr>
|
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@ package javax.xml.transform;
|
|||||||
*/
|
*/
|
||||||
public class TransformerConfigurationException extends TransformerException {
|
public class TransformerConfigurationException extends TransformerException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1285547467942875745L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new <code>TransformerConfigurationException</code> with no
|
* Create a new <code>TransformerConfigurationException</code> with no
|
||||||
* detail message.
|
* detail message.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,36 +27,47 @@ package javax.xml.transform;
|
|||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.security.AccessControlContext;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.CodeSigner;
|
||||||
|
import java.security.CodeSource;
|
||||||
|
import java.security.PermissionCollection;
|
||||||
|
import java.security.Permissions;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class specifies an exceptional condition that occured
|
* This class specifies an exceptional condition that occurred
|
||||||
* during the transformation process.
|
* during the transformation process.
|
||||||
*
|
*
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public class TransformerException extends Exception {
|
public class TransformerException extends Exception {
|
||||||
|
|
||||||
/** Field locator specifies where the error occured */
|
private static final long serialVersionUID = 975798773772956428L;
|
||||||
|
|
||||||
|
/** Field locator specifies where the error occurred */
|
||||||
SourceLocator locator;
|
SourceLocator locator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method getLocator retrieves an instance of a SourceLocator
|
* Method getLocator retrieves an instance of a SourceLocator
|
||||||
* object that specifies where an error occured.
|
* object that specifies where an error occurred.
|
||||||
*
|
*
|
||||||
* @return A SourceLocator object, or null if none was specified.
|
* @return A SourceLocator object, or null if none was specified.
|
||||||
*/
|
*/
|
||||||
public SourceLocator getLocator() {
|
public SourceLocator getLocator() {
|
||||||
return locator;
|
return this.locator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method setLocator sets an instance of a SourceLocator
|
* Method setLocator sets an instance of a SourceLocator
|
||||||
* object that specifies where an error occured.
|
* object that specifies where an error occurred.
|
||||||
*
|
*
|
||||||
* @param location A SourceLocator object, or null to clear the location.
|
* @param location A SourceLocator object, or null to clear the location.
|
||||||
*/
|
*/
|
||||||
public void setLocator(SourceLocator location) {
|
public void setLocator(SourceLocator location) {
|
||||||
locator = location;
|
this.locator = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Field containedException specifies a wrapped exception. May be null. */
|
/** Field containedException specifies a wrapped exception. May be null. */
|
||||||
@ -76,7 +87,9 @@ public class TransformerException extends Exception {
|
|||||||
* Returns the cause of this throwable or <code>null</code> if the
|
* Returns the cause of this throwable or <code>null</code> if the
|
||||||
* cause is nonexistent or unknown. (The cause is the throwable that
|
* cause is nonexistent or unknown. (The cause is the throwable that
|
||||||
* caused this throwable to get thrown.)
|
* caused this throwable to get thrown.)
|
||||||
|
* @return the cause, or null if unknown
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Throwable getCause() {
|
public Throwable getCause() {
|
||||||
|
|
||||||
return ((containedException == this)
|
return ((containedException == this)
|
||||||
@ -108,6 +121,7 @@ public class TransformerException extends Exception {
|
|||||||
* {@link #TransformerException(String,Throwable)}, or this method has already
|
* {@link #TransformerException(String,Throwable)}, or this method has already
|
||||||
* been called on this throwable.
|
* been called on this throwable.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public synchronized Throwable initCause(Throwable cause) {
|
public synchronized Throwable initCause(Throwable cause) {
|
||||||
|
|
||||||
// TransformerException doesn't set its cause (probably
|
// TransformerException doesn't set its cause (probably
|
||||||
@ -136,11 +150,7 @@ public class TransformerException extends Exception {
|
|||||||
* @param message The error or warning message.
|
* @param message The error or warning message.
|
||||||
*/
|
*/
|
||||||
public TransformerException(String message) {
|
public TransformerException(String message) {
|
||||||
|
this(message, null, null);
|
||||||
super(message);
|
|
||||||
|
|
||||||
this.containedException = null;
|
|
||||||
this.locator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,11 +159,7 @@ public class TransformerException extends Exception {
|
|||||||
* @param e The exception to be wrapped.
|
* @param e The exception to be wrapped.
|
||||||
*/
|
*/
|
||||||
public TransformerException(Throwable e) {
|
public TransformerException(Throwable e) {
|
||||||
|
this(null, null, e);
|
||||||
super(e.toString());
|
|
||||||
|
|
||||||
this.containedException = e;
|
|
||||||
this.locator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,13 +173,7 @@ public class TransformerException extends Exception {
|
|||||||
* @param e Any exception
|
* @param e Any exception
|
||||||
*/
|
*/
|
||||||
public TransformerException(String message, Throwable e) {
|
public TransformerException(String message, Throwable e) {
|
||||||
|
this(message, null, e);
|
||||||
super(((message == null) || (message.length() == 0))
|
|
||||||
? e.toString()
|
|
||||||
: message);
|
|
||||||
|
|
||||||
this.containedException = e;
|
|
||||||
this.locator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,11 +187,7 @@ public class TransformerException extends Exception {
|
|||||||
* @param locator The locator object for the error or warning.
|
* @param locator The locator object for the error or warning.
|
||||||
*/
|
*/
|
||||||
public TransformerException(String message, SourceLocator locator) {
|
public TransformerException(String message, SourceLocator locator) {
|
||||||
|
this(message, locator, null);
|
||||||
super(message);
|
|
||||||
|
|
||||||
this.containedException = null;
|
|
||||||
this.locator = locator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,8 +200,9 @@ public class TransformerException extends Exception {
|
|||||||
*/
|
*/
|
||||||
public TransformerException(String message, SourceLocator locator,
|
public TransformerException(String message, SourceLocator locator,
|
||||||
Throwable e) {
|
Throwable e) {
|
||||||
|
super(((message == null) || (message.length() == 0))
|
||||||
super(message);
|
? ((e == null) ? "" : e.toString())
|
||||||
|
: message);
|
||||||
|
|
||||||
this.containedException = e;
|
this.containedException = e;
|
||||||
this.locator = locator;
|
this.locator = locator;
|
||||||
@ -219,34 +216,9 @@ public class TransformerException extends Exception {
|
|||||||
* location information appended.
|
* location information appended.
|
||||||
*/
|
*/
|
||||||
public String getMessageAndLocation() {
|
public String getMessageAndLocation() {
|
||||||
|
StringBuilder sbuffer = new StringBuilder();
|
||||||
StringBuffer sbuffer = new StringBuffer();
|
sbuffer.append(Objects.toString(super.getMessage(), ""));
|
||||||
String message = super.getMessage();
|
sbuffer.append(Objects.toString(getLocationAsString(), ""));
|
||||||
|
|
||||||
if (null != message) {
|
|
||||||
sbuffer.append(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null != locator) {
|
|
||||||
String systemID = locator.getSystemId();
|
|
||||||
int line = locator.getLineNumber();
|
|
||||||
int column = locator.getColumnNumber();
|
|
||||||
|
|
||||||
if (null != systemID) {
|
|
||||||
sbuffer.append("; SystemID: ");
|
|
||||||
sbuffer.append(systemID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != line) {
|
|
||||||
sbuffer.append("; Line#: ");
|
|
||||||
sbuffer.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != column) {
|
|
||||||
sbuffer.append("; Column#: ");
|
|
||||||
sbuffer.append(column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sbuffer.toString();
|
return sbuffer.toString();
|
||||||
}
|
}
|
||||||
@ -258,9 +230,29 @@ public class TransformerException extends Exception {
|
|||||||
* if there is no location information.
|
* if there is no location information.
|
||||||
*/
|
*/
|
||||||
public String getLocationAsString() {
|
public String getLocationAsString() {
|
||||||
|
if (locator == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (null != locator) {
|
if (System.getSecurityManager() == null) {
|
||||||
StringBuffer sbuffer = new StringBuffer();
|
return getLocationString();
|
||||||
|
} else {
|
||||||
|
return AccessController.doPrivileged((PrivilegedAction<String>) () ->
|
||||||
|
getLocationString(),
|
||||||
|
new AccessControlContext(new ProtectionDomain[] {getNonPrivDomain()}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the location string.
|
||||||
|
* @return the location string
|
||||||
|
*/
|
||||||
|
private String getLocationString() {
|
||||||
|
if (locator == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sbuffer = new StringBuilder();
|
||||||
String systemID = locator.getSystemId();
|
String systemID = locator.getSystemId();
|
||||||
int line = locator.getLineNumber();
|
int line = locator.getLineNumber();
|
||||||
int column = locator.getColumnNumber();
|
int column = locator.getColumnNumber();
|
||||||
@ -281,9 +273,6 @@ public class TransformerException extends Exception {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return sbuffer.toString();
|
return sbuffer.toString();
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -291,6 +280,7 @@ public class TransformerException extends Exception {
|
|||||||
* originated. This will trace all nested exception
|
* originated. This will trace all nested exception
|
||||||
* objects, as well as this object.
|
* objects, as well as this object.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void printStackTrace() {
|
public void printStackTrace() {
|
||||||
printStackTrace(new java.io.PrintWriter(System.err, true));
|
printStackTrace(new java.io.PrintWriter(System.err, true));
|
||||||
}
|
}
|
||||||
@ -301,6 +291,7 @@ public class TransformerException extends Exception {
|
|||||||
* objects, as well as this object.
|
* objects, as well as this object.
|
||||||
* @param s The stream where the dump will be sent to.
|
* @param s The stream where the dump will be sent to.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void printStackTrace(java.io.PrintStream s) {
|
public void printStackTrace(java.io.PrintStream s) {
|
||||||
printStackTrace(new java.io.PrintWriter(s));
|
printStackTrace(new java.io.PrintWriter(s));
|
||||||
}
|
}
|
||||||
@ -311,6 +302,7 @@ public class TransformerException extends Exception {
|
|||||||
* objects, as well as this object.
|
* objects, as well as this object.
|
||||||
* @param s The writer where the dump will be sent to.
|
* @param s The writer where the dump will be sent to.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void printStackTrace(java.io.PrintWriter s) {
|
public void printStackTrace(java.io.PrintWriter s) {
|
||||||
|
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
@ -358,11 +350,8 @@ public class TransformerException extends Exception {
|
|||||||
} else {
|
} else {
|
||||||
exception = null;
|
exception = null;
|
||||||
}
|
}
|
||||||
} catch (InvocationTargetException ite) {
|
} catch (InvocationTargetException | IllegalAccessException
|
||||||
exception = null;
|
| NoSuchMethodException e) {
|
||||||
} catch (IllegalAccessException iae) {
|
|
||||||
exception = null;
|
|
||||||
} catch (NoSuchMethodException nsme) {
|
|
||||||
exception = null;
|
exception = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,4 +360,14 @@ public class TransformerException extends Exception {
|
|||||||
s.flush();
|
s.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a ProtectionDomain that has no permission.
|
||||||
|
* @return a ProtectionDomain
|
||||||
|
*/
|
||||||
|
private ProtectionDomain getNonPrivDomain() {
|
||||||
|
CodeSource nullSource = new CodeSource(null, (CodeSigner[]) null);
|
||||||
|
PermissionCollection noPermission = new Permissions();
|
||||||
|
return new ProtectionDomain(nullSource, noPermission);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -440,3 +440,6 @@ ea819b6009d33a72e6672bab6c101d51db0cfb4c jdk-9+176
|
|||||||
b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177
|
b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177
|
||||||
6d17fd0a5133a0dd916c77a9a24ae7f0ca402876 jdk-10+15
|
6d17fd0a5133a0dd916c77a9a24ae7f0ca402876 jdk-10+15
|
||||||
bc8289ce1ed3ed5fff62152ed46da3be0b60b7c3 jdk-10+16
|
bc8289ce1ed3ed5fff62152ed46da3be0b60b7c3 jdk-10+16
|
||||||
|
d0190aaf1816081d9b2e0577b65b793804896d1e jdk-9+178
|
||||||
|
56ac1831ac5924b5092a53a85d6fc68749501fb8 jdk-9+179
|
||||||
|
4c07d366c2e177edba7aa54c4b015e4dbf12bc83 jdk-10+17
|
||||||
|
@ -84,6 +84,14 @@ public class XmlUtil {
|
|||||||
private final static String LEXICAL_HANDLER_PROPERTY =
|
private final static String LEXICAL_HANDLER_PROPERTY =
|
||||||
"http://xml.org/sax/properties/lexical-handler";
|
"http://xml.org/sax/properties/lexical-handler";
|
||||||
|
|
||||||
|
private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
|
||||||
|
|
||||||
|
private static final String EXTERNAL_GE = "http://xml.org/sax/features/external-general-entities";
|
||||||
|
|
||||||
|
private static final String EXTERNAL_PE = "http://xml.org/sax/features/external-parameter-entities";
|
||||||
|
|
||||||
|
private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName());
|
||||||
|
|
||||||
private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity";
|
private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity";
|
||||||
@ -327,10 +335,24 @@ public class XmlUtil {
|
|||||||
|
|
||||||
public static DocumentBuilderFactory newDocumentBuilderFactory(boolean disableSecurity) {
|
public static DocumentBuilderFactory newDocumentBuilderFactory(boolean disableSecurity) {
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
|
||||||
try {
|
try {
|
||||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, !xmlSecurityDisabled(disableSecurity));
|
boolean securityOn = !xmlSecurityDisabled(disableSecurity);
|
||||||
|
factory.setFeature(featureToSet, securityOn);
|
||||||
|
factory.setNamespaceAware(true);
|
||||||
|
if (securityOn) {
|
||||||
|
factory.setExpandEntityReferences(false);
|
||||||
|
featureToSet = DISALLOW_DOCTYPE_DECL;
|
||||||
|
factory.setFeature(featureToSet, true);
|
||||||
|
featureToSet = EXTERNAL_GE;
|
||||||
|
factory.setFeature(featureToSet, false);
|
||||||
|
featureToSet = EXTERNAL_PE;
|
||||||
|
factory.setFeature(featureToSet, false);
|
||||||
|
featureToSet = LOAD_EXTERNAL_DTD;
|
||||||
|
factory.setFeature(featureToSet, false);
|
||||||
|
}
|
||||||
} catch (ParserConfigurationException e) {
|
} catch (ParserConfigurationException e) {
|
||||||
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } );
|
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[] {factory.getClass().getName()} );
|
||||||
}
|
}
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
@ -347,10 +369,23 @@ public class XmlUtil {
|
|||||||
|
|
||||||
public static SAXParserFactory newSAXParserFactory(boolean disableSecurity) {
|
public static SAXParserFactory newSAXParserFactory(boolean disableSecurity) {
|
||||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||||
|
String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
|
||||||
try {
|
try {
|
||||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, !xmlSecurityDisabled(disableSecurity));
|
boolean securityOn = !xmlSecurityDisabled(disableSecurity);
|
||||||
|
factory.setFeature(featureToSet, securityOn);
|
||||||
|
factory.setNamespaceAware(true);
|
||||||
|
if (securityOn) {
|
||||||
|
featureToSet = DISALLOW_DOCTYPE_DECL;
|
||||||
|
factory.setFeature(featureToSet, true);
|
||||||
|
featureToSet = EXTERNAL_GE;
|
||||||
|
factory.setFeature(featureToSet, false);
|
||||||
|
featureToSet = EXTERNAL_PE;
|
||||||
|
factory.setFeature(featureToSet, false);
|
||||||
|
featureToSet = LOAD_EXTERNAL_DTD;
|
||||||
|
factory.setFeature(featureToSet, false);
|
||||||
|
}
|
||||||
} catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) {
|
} catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) {
|
||||||
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()});
|
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[]{factory.getClass().getName()});
|
||||||
}
|
}
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
@ -112,29 +112,13 @@ public class DOMForest {
|
|||||||
this.entityResolver = entityResolver;
|
this.entityResolver = entityResolver;
|
||||||
this.errorReceiver = errReceiver;
|
this.errorReceiver = errReceiver;
|
||||||
this.logic = logic;
|
this.logic = logic;
|
||||||
|
// secure xml processing can be switched off if input requires it
|
||||||
|
boolean disableXmlSecurity = options == null ? false : options.disableXmlSecurity;
|
||||||
|
|
||||||
|
DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(disableXmlSecurity);
|
||||||
|
this.parserFactory = XmlUtil.newSAXParserFactory(disableXmlSecurity);
|
||||||
try {
|
try {
|
||||||
// secure xml processing can be switched off if input requires it
|
|
||||||
boolean secureProcessingEnabled = options == null || !options.disableXmlSecurity;
|
|
||||||
DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(!secureProcessingEnabled);
|
|
||||||
dbf.setNamespaceAware(true);
|
|
||||||
this.documentBuilder = dbf.newDocumentBuilder();
|
this.documentBuilder = dbf.newDocumentBuilder();
|
||||||
|
|
||||||
this.parserFactory = XmlUtil.newSAXParserFactory(secureProcessingEnabled);
|
|
||||||
this.parserFactory.setNamespaceAware(true);
|
|
||||||
|
|
||||||
if(secureProcessingEnabled){
|
|
||||||
dbf.setExpandEntityReferences(false);
|
|
||||||
try {
|
|
||||||
parserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
|
||||||
parserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
|
||||||
parserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
|
||||||
} catch (SAXNotRecognizedException e){
|
|
||||||
throw new ParserConfigurationException(e.getMessage());
|
|
||||||
} catch (SAXNotSupportedException e) {
|
|
||||||
throw new ParserConfigurationException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (ParserConfigurationException e) {
|
} catch (ParserConfigurationException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
|
@ -439,3 +439,5 @@ e069834e2c518a7bc2ffadc8c7e3cd7ec69fa8a0 jdk-10+15
|
|||||||
3281b964ab104002623d744e8b77a12269b70acd jdk-10+16
|
3281b964ab104002623d744e8b77a12269b70acd jdk-10+16
|
||||||
443025bee731eb2225371b92c1c74b519b7baf33 jdk-9+178
|
443025bee731eb2225371b92c1c74b519b7baf33 jdk-9+178
|
||||||
06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179
|
06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179
|
||||||
|
d93f2fd542b7d7855c2cd49ae15ebcc3d441a83b jdk-10+17
|
||||||
|
c4b709bad6c5d29294124de5e74e1e2ac84fcf1f jdk-10+18
|
||||||
|
@ -50,7 +50,12 @@ public class FilterOutputStream extends OutputStream {
|
|||||||
/**
|
/**
|
||||||
* Whether the stream is closed; implicitly initialized to false.
|
* Whether the stream is closed; implicitly initialized to false.
|
||||||
*/
|
*/
|
||||||
private boolean closed;
|
private volatile boolean closed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object used to prevent a race on the 'closed' instance variable.
|
||||||
|
*/
|
||||||
|
private final Object closeLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an output stream filter built on top of the specified
|
* Creates an output stream filter built on top of the specified
|
||||||
@ -165,7 +170,12 @@ public class FilterOutputStream extends OutputStream {
|
|||||||
if (closed) {
|
if (closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
closed = true;
|
synchronized (closeLock) {
|
||||||
|
if (closed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
Throwable flushException = null;
|
Throwable flushException = null;
|
||||||
try {
|
try {
|
||||||
|
@ -364,9 +364,9 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
// Reflective call to get caller class is only needed if a security manager
|
// Reflective call to get caller class is only needed if a security manager
|
||||||
// is present. Avoid the overhead of making this call otherwise.
|
// is present. Avoid the overhead of making this call otherwise.
|
||||||
caller = Reflection.getCallerClass();
|
caller = Reflection.getCallerClass();
|
||||||
if (VM.isSystemDomainLoader(loader)) {
|
if (loader == null) {
|
||||||
ClassLoader ccl = ClassLoader.getClassLoader(caller);
|
ClassLoader ccl = ClassLoader.getClassLoader(caller);
|
||||||
if (!VM.isSystemDomainLoader(ccl)) {
|
if (ccl != null) {
|
||||||
sm.checkPermission(
|
sm.checkPermission(
|
||||||
SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||||
}
|
}
|
||||||
@ -432,18 +432,21 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
Objects.requireNonNull(module);
|
Objects.requireNonNull(module);
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
|
|
||||||
Class<?> caller = Reflection.getCallerClass();
|
ClassLoader cl;
|
||||||
if (caller != null && caller.getModule() != module) {
|
SecurityManager sm = System.getSecurityManager();
|
||||||
// if caller is null, Class.forName is the last java frame on the stack.
|
if (sm != null) {
|
||||||
// java.base has all permissions
|
Class<?> caller = Reflection.getCallerClass();
|
||||||
SecurityManager sm = System.getSecurityManager();
|
if (caller != null && caller.getModule() != module) {
|
||||||
if (sm != null) {
|
// if caller is null, Class.forName is the last java frame on the stack.
|
||||||
|
// java.base has all permissions
|
||||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||||
}
|
}
|
||||||
|
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
|
||||||
|
cl = AccessController.doPrivileged(pa);
|
||||||
|
} else {
|
||||||
|
cl = module.getClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
|
|
||||||
ClassLoader cl = AccessController.doPrivileged(pa);
|
|
||||||
if (cl != null) {
|
if (cl != null) {
|
||||||
return cl.loadClass(module, name);
|
return cl.loadClass(module, name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -246,7 +246,6 @@ public final class Module implements AnnotatedElement {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --
|
// --
|
||||||
|
|
||||||
// special Module to mean "all unnamed modules"
|
// special Module to mean "all unnamed modules"
|
||||||
@ -257,17 +256,38 @@ public final class Module implements AnnotatedElement {
|
|||||||
private static final Module EVERYONE_MODULE = new Module(null);
|
private static final Module EVERYONE_MODULE = new Module(null);
|
||||||
private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
|
private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The holder of data structures to support readability, exports, and
|
||||||
|
* service use added at runtime with the reflective APIs.
|
||||||
|
*/
|
||||||
|
private static class ReflectionData {
|
||||||
|
/**
|
||||||
|
* A module (1st key) reads another module (2nd key)
|
||||||
|
*/
|
||||||
|
static final WeakPairMap<Module, Module, Boolean> reads =
|
||||||
|
new WeakPairMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A module (1st key) exports or opens a package to another module
|
||||||
|
* (2nd key). The map value is a map of package name to a boolean
|
||||||
|
* that indicates if the package is opened.
|
||||||
|
*/
|
||||||
|
static final WeakPairMap<Module, Module, Map<String, Boolean>> exports =
|
||||||
|
new WeakPairMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A module (1st key) uses a service (2nd key)
|
||||||
|
*/
|
||||||
|
static final WeakPairMap<Module, Class<?>, Boolean> uses =
|
||||||
|
new WeakPairMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -- readability --
|
// -- readability --
|
||||||
|
|
||||||
// the modules that this module reads
|
// the modules that this module reads
|
||||||
private volatile Set<Module> reads;
|
private volatile Set<Module> reads;
|
||||||
|
|
||||||
// additional module (2nd key) that some module (1st key) reflectively reads
|
|
||||||
private static final WeakPairMap<Module, Module, Boolean> reflectivelyReads
|
|
||||||
= new WeakPairMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if this module reads the given module. This method returns
|
* Indicates if this module reads the given module. This method returns
|
||||||
* {@code true} if invoked to test if this module reads itself. It also
|
* {@code true} if invoked to test if this module reads itself. It also
|
||||||
@ -300,13 +320,13 @@ public final class Module implements AnnotatedElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if this module reads the other module reflectively
|
// check if this module reads the other module reflectively
|
||||||
if (reflectivelyReads.containsKeyPair(this, other))
|
if (ReflectionData.reads.containsKeyPair(this, other))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// if other is an unnamed module then check if this module reads
|
// if other is an unnamed module then check if this module reads
|
||||||
// all unnamed modules
|
// all unnamed modules
|
||||||
if (!other.isNamed()
|
if (!other.isNamed()
|
||||||
&& reflectivelyReads.containsKeyPair(this, ALL_UNNAMED_MODULE))
|
&& ReflectionData.reads.containsKeyPair(this, ALL_UNNAMED_MODULE))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -393,7 +413,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add reflective read
|
// add reflective read
|
||||||
reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
|
ReflectionData.reads.putIfAbsent(this, other, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,13 +428,6 @@ public final class Module implements AnnotatedElement {
|
|||||||
// if the value contains EVERYONE_MODULE then the package is exported to all
|
// if the value contains EVERYONE_MODULE then the package is exported to all
|
||||||
private volatile Map<String, Set<Module>> exportedPackages;
|
private volatile Map<String, Set<Module>> exportedPackages;
|
||||||
|
|
||||||
// additional exports or opens added at run-time
|
|
||||||
// this module (1st key), other module (2nd key)
|
|
||||||
// (package name, open?) (value)
|
|
||||||
private static final WeakPairMap<Module, Module, Map<String, Boolean>>
|
|
||||||
reflectivelyExports = new WeakPairMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if this module exports the given package to at
|
* Returns {@code true} if this module exports the given package to at
|
||||||
* least the given module.
|
* least the given module.
|
||||||
@ -600,7 +613,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
*/
|
*/
|
||||||
private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
|
private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
|
||||||
// exported or open to all modules
|
// exported or open to all modules
|
||||||
Map<String, Boolean> exports = reflectivelyExports.get(this, EVERYONE_MODULE);
|
Map<String, Boolean> exports = ReflectionData.exports.get(this, EVERYONE_MODULE);
|
||||||
if (exports != null) {
|
if (exports != null) {
|
||||||
Boolean b = exports.get(pn);
|
Boolean b = exports.get(pn);
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
@ -612,7 +625,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
if (other != EVERYONE_MODULE) {
|
if (other != EVERYONE_MODULE) {
|
||||||
|
|
||||||
// exported or open to other
|
// exported or open to other
|
||||||
exports = reflectivelyExports.get(this, other);
|
exports = ReflectionData.exports.get(this, other);
|
||||||
if (exports != null) {
|
if (exports != null) {
|
||||||
Boolean b = exports.get(pn);
|
Boolean b = exports.get(pn);
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
@ -623,7 +636,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
|
|
||||||
// other is an unnamed module && exported or open to all unnamed
|
// other is an unnamed module && exported or open to all unnamed
|
||||||
if (!other.isNamed()) {
|
if (!other.isNamed()) {
|
||||||
exports = reflectivelyExports.get(this, ALL_UNNAMED_MODULE);
|
exports = ReflectionData.exports.get(this, ALL_UNNAMED_MODULE);
|
||||||
if (exports != null) {
|
if (exports != null) {
|
||||||
Boolean b = exports.get(pn);
|
Boolean b = exports.get(pn);
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
@ -886,8 +899,8 @@ public final class Module implements AnnotatedElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add package name to reflectivelyExports if absent
|
// add package name to exports if absent
|
||||||
Map<String, Boolean> map = reflectivelyExports
|
Map<String, Boolean> map = ReflectionData.exports
|
||||||
.computeIfAbsent(this, other,
|
.computeIfAbsent(this, other,
|
||||||
(m1, m2) -> new ConcurrentHashMap<>());
|
(m1, m2) -> new ConcurrentHashMap<>());
|
||||||
if (open) {
|
if (open) {
|
||||||
@ -932,10 +945,6 @@ public final class Module implements AnnotatedElement {
|
|||||||
|
|
||||||
// -- services --
|
// -- services --
|
||||||
|
|
||||||
// additional service type (2nd key) that some module (1st key) uses
|
|
||||||
private static final WeakPairMap<Module, Class<?>, Boolean> reflectivelyUses
|
|
||||||
= new WeakPairMap<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the caller's module is this module then update this module to add a
|
* If the caller's module is this module then update this module to add a
|
||||||
* service dependence on the given service type. This method is intended
|
* service dependence on the given service type. This method is intended
|
||||||
@ -980,7 +989,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
*/
|
*/
|
||||||
void implAddUses(Class<?> service) {
|
void implAddUses(Class<?> service) {
|
||||||
if (!canUse(service)) {
|
if (!canUse(service)) {
|
||||||
reflectivelyUses.putIfAbsent(this, service, Boolean.TRUE);
|
ReflectionData.uses.putIfAbsent(this, service, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,7 +1020,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// uses added via addUses
|
// uses added via addUses
|
||||||
return reflectivelyUses.containsKeyPair(this, service);
|
return ReflectionData.uses.containsKeyPair(this, service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1060,8 +1069,11 @@ public final class Module implements AnnotatedElement {
|
|||||||
Function<String, ClassLoader> clf,
|
Function<String, ClassLoader> clf,
|
||||||
ModuleLayer layer)
|
ModuleLayer layer)
|
||||||
{
|
{
|
||||||
Map<String, Module> nameToModule = new HashMap<>();
|
boolean isBootLayer = (ModuleLayer.boot() == null);
|
||||||
Map<String, ClassLoader> moduleToLoader = new HashMap<>();
|
|
||||||
|
int cap = (int)(cf.modules().size() / 0.75f + 1.0f);
|
||||||
|
Map<String, Module> nameToModule = new HashMap<>(cap);
|
||||||
|
Map<String, ClassLoader> nameToLoader = new HashMap<>(cap);
|
||||||
|
|
||||||
Set<ClassLoader> loaders = new HashSet<>();
|
Set<ClassLoader> loaders = new HashSet<>();
|
||||||
boolean hasPlatformModules = false;
|
boolean hasPlatformModules = false;
|
||||||
@ -1070,7 +1082,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||||
String name = resolvedModule.name();
|
String name = resolvedModule.name();
|
||||||
ClassLoader loader = clf.apply(name);
|
ClassLoader loader = clf.apply(name);
|
||||||
moduleToLoader.put(name, loader);
|
nameToLoader.put(name, loader);
|
||||||
if (loader == null || loader == ClassLoaders.platformClassLoader()) {
|
if (loader == null || loader == ClassLoaders.platformClassLoader()) {
|
||||||
if (!(clf instanceof ModuleLoaderMap.Mapper)) {
|
if (!(clf instanceof ModuleLoaderMap.Mapper)) {
|
||||||
throw new IllegalArgumentException("loader can't be 'null'"
|
throw new IllegalArgumentException("loader can't be 'null'"
|
||||||
@ -1087,20 +1099,19 @@ public final class Module implements AnnotatedElement {
|
|||||||
ModuleReference mref = resolvedModule.reference();
|
ModuleReference mref = resolvedModule.reference();
|
||||||
ModuleDescriptor descriptor = mref.descriptor();
|
ModuleDescriptor descriptor = mref.descriptor();
|
||||||
String name = descriptor.name();
|
String name = descriptor.name();
|
||||||
URI uri = mref.location().orElse(null);
|
ClassLoader loader = nameToLoader.get(name);
|
||||||
ClassLoader loader = moduleToLoader.get(resolvedModule.name());
|
|
||||||
Module m;
|
Module m;
|
||||||
if (loader == null && name.equals("java.base")) {
|
if (loader == null && name.equals("java.base")) {
|
||||||
// java.base is already defined to the VM
|
// java.base is already defined to the VM
|
||||||
m = Object.class.getModule();
|
m = Object.class.getModule();
|
||||||
} else {
|
} else {
|
||||||
|
URI uri = mref.location().orElse(null);
|
||||||
m = new Module(layer, loader, descriptor, uri);
|
m = new Module(layer, loader, descriptor, uri);
|
||||||
}
|
}
|
||||||
nameToModule.put(name, m);
|
nameToModule.put(name, m);
|
||||||
moduleToLoader.put(name, loader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup readability and exports
|
// setup readability and exports/opens
|
||||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||||
ModuleReference mref = resolvedModule.reference();
|
ModuleReference mref = resolvedModule.reference();
|
||||||
ModuleDescriptor descriptor = mref.descriptor();
|
ModuleDescriptor descriptor = mref.descriptor();
|
||||||
@ -1146,7 +1157,18 @@ public final class Module implements AnnotatedElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exports and opens
|
// exports and opens
|
||||||
initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
|
if (descriptor.isOpen() || descriptor.isAutomatic()) {
|
||||||
|
// The VM doesn't special case open or automatic modules yet
|
||||||
|
// so need to export all packages
|
||||||
|
for (String source : descriptor.packages()) {
|
||||||
|
addExportsToAll0(m, source);
|
||||||
|
}
|
||||||
|
} else if (isBootLayer && descriptor.opens().isEmpty()) {
|
||||||
|
// no open packages, no qualified exports to modules in parent layers
|
||||||
|
initExports(m, nameToModule);
|
||||||
|
} else {
|
||||||
|
initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there are modules defined to the boot or platform class loaders
|
// if there are modules defined to the boot or platform class loaders
|
||||||
@ -1161,7 +1183,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
if (!descriptor.provides().isEmpty()) {
|
if (!descriptor.provides().isEmpty()) {
|
||||||
String name = descriptor.name();
|
String name = descriptor.name();
|
||||||
Module m = nameToModule.get(name);
|
Module m = nameToModule.get(name);
|
||||||
ClassLoader loader = moduleToLoader.get(name);
|
ClassLoader loader = nameToLoader.get(name);
|
||||||
if (loader == null) {
|
if (loader == null) {
|
||||||
bootCatalog.register(m);
|
bootCatalog.register(m);
|
||||||
} else if (loader == pcl) {
|
} else if (loader == pcl) {
|
||||||
@ -1179,7 +1201,6 @@ public final class Module implements AnnotatedElement {
|
|||||||
return nameToModule;
|
return nameToModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the runtime Module corresponding to the given ResolvedModule
|
* Find the runtime Module corresponding to the given ResolvedModule
|
||||||
* in the given parent layer (or its parents).
|
* in the given parent layer (or its parents).
|
||||||
@ -1201,25 +1222,55 @@ public final class Module implements AnnotatedElement {
|
|||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize/setup a module's exports.
|
||||||
|
*
|
||||||
|
* @param m the module
|
||||||
|
* @param nameToModule map of module name to Module (for qualified exports)
|
||||||
|
*/
|
||||||
|
private static void initExports(Module m, Map<String, Module> nameToModule) {
|
||||||
|
Map<String, Set<Module>> exportedPackages = new HashMap<>();
|
||||||
|
|
||||||
|
for (Exports exports : m.getDescriptor().exports()) {
|
||||||
|
String source = exports.source();
|
||||||
|
if (exports.isQualified()) {
|
||||||
|
// qualified exports
|
||||||
|
Set<Module> targets = new HashSet<>();
|
||||||
|
for (String target : exports.targets()) {
|
||||||
|
Module m2 = nameToModule.get(target);
|
||||||
|
if (m2 != null) {
|
||||||
|
addExports0(m, source, m2);
|
||||||
|
targets.add(m2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!targets.isEmpty()) {
|
||||||
|
exportedPackages.put(source, targets);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// unqualified exports
|
||||||
|
addExportsToAll0(m, source);
|
||||||
|
exportedPackages.put(source, EVERYONE_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exportedPackages.isEmpty())
|
||||||
|
m.exportedPackages = exportedPackages;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the maps of exported and open packages for module m.
|
* Initialize/setup a module's exports.
|
||||||
|
*
|
||||||
|
* @param m the module
|
||||||
|
* @param nameToSource map of module name to Module for modules that m reads
|
||||||
|
* @param nameToModule map of module name to Module for modules in the layer
|
||||||
|
* under construction
|
||||||
|
* @param parents the parent layers
|
||||||
*/
|
*/
|
||||||
private static void initExportsAndOpens(Module m,
|
private static void initExportsAndOpens(Module m,
|
||||||
Map<String, Module> nameToSource,
|
Map<String, Module> nameToSource,
|
||||||
Map<String, Module> nameToModule,
|
Map<String, Module> nameToModule,
|
||||||
List<ModuleLayer> parents) {
|
List<ModuleLayer> parents) {
|
||||||
// The VM doesn't special case open or automatic modules so need to
|
|
||||||
// export all packages
|
|
||||||
ModuleDescriptor descriptor = m.getDescriptor();
|
ModuleDescriptor descriptor = m.getDescriptor();
|
||||||
if (descriptor.isOpen() || descriptor.isAutomatic()) {
|
|
||||||
assert descriptor.opens().isEmpty();
|
|
||||||
for (String source : descriptor.packages()) {
|
|
||||||
addExportsToAll0(m, source);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Set<Module>> openPackages = new HashMap<>();
|
Map<String, Set<Module>> openPackages = new HashMap<>();
|
||||||
Map<String, Set<Module>> exportedPackages = new HashMap<>();
|
Map<String, Set<Module>> exportedPackages = new HashMap<>();
|
||||||
|
|
||||||
@ -1272,7 +1323,6 @@ public final class Module implements AnnotatedElement {
|
|||||||
if (!targets.isEmpty()) {
|
if (!targets.isEmpty()) {
|
||||||
exportedPackages.put(source, targets);
|
exportedPackages.put(source, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// unqualified exports
|
// unqualified exports
|
||||||
addExportsToAll0(m, source);
|
addExportsToAll0(m, source);
|
||||||
|
@ -313,6 +313,10 @@ public final class System {
|
|||||||
* @see java.lang.RuntimePermission
|
* @see java.lang.RuntimePermission
|
||||||
*/
|
*/
|
||||||
public static void setSecurityManager(final SecurityManager s) {
|
public static void setSecurityManager(final SecurityManager s) {
|
||||||
|
if (security == null) {
|
||||||
|
// ensure image reader is initialized
|
||||||
|
Object.class.getResource("java/lang/ANY");
|
||||||
|
}
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
try {
|
try {
|
||||||
s.checkPackageAccess("java.lang");
|
s.checkPackageAccess("java.lang");
|
||||||
|
@ -2476,7 +2476,7 @@ return mh1;
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ClassLoader loader = defc.getClassLoader();
|
ClassLoader loader = defc.getClassLoader();
|
||||||
if (!jdk.internal.misc.VM.isSystemDomainLoader(loader)) {
|
if (loader != null) {
|
||||||
ClassLoader sysl = ClassLoader.getSystemClassLoader();
|
ClassLoader sysl = ClassLoader.getSystemClassLoader();
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
while (sysl != null) {
|
while (sysl != null) {
|
||||||
|
@ -31,6 +31,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -41,6 +42,9 @@ import java.util.Set;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import jdk.internal.module.ModuleReferenceImpl;
|
||||||
|
import jdk.internal.module.ModuleTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configuration that is the result of <a href="package-summary.html#resolution">
|
* A configuration that is the result of <a href="package-summary.html#resolution">
|
||||||
* resolution</a> or resolution with <a href="#service-binding">service binding</a>.
|
* resolution</a> or resolution with <a href="#service-binding">service binding</a>.
|
||||||
@ -121,11 +125,8 @@ public final class Configuration {
|
|||||||
this.targetPlatform = null;
|
this.targetPlatform = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Configuration(List<Configuration> parents,
|
private Configuration(List<Configuration> parents, Resolver resolver) {
|
||||||
Resolver resolver,
|
Map<ResolvedModule, Set<ResolvedModule>> g = resolver.finish(this);
|
||||||
boolean check)
|
|
||||||
{
|
|
||||||
Map<ResolvedModule, Set<ResolvedModule>> g = resolver.finish(this, check);
|
|
||||||
|
|
||||||
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||||
Entry<String, ResolvedModule>[] nameEntries
|
Entry<String, ResolvedModule>[] nameEntries
|
||||||
@ -146,6 +147,62 @@ public final class Configuration {
|
|||||||
this.targetPlatform = resolver.targetPlatform();
|
this.targetPlatform = resolver.targetPlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the Configuration for the boot layer from a pre-generated
|
||||||
|
* readability graph.
|
||||||
|
*
|
||||||
|
* @apiNote This method is coded for startup performance.
|
||||||
|
*/
|
||||||
|
Configuration(ModuleFinder finder, Map<String, Set<String>> map) {
|
||||||
|
int moduleCount = map.size();
|
||||||
|
|
||||||
|
// create map of name -> ResolvedModule
|
||||||
|
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||||
|
Entry<String, ResolvedModule>[] nameEntries
|
||||||
|
= (Entry<String, ResolvedModule>[])new Entry[moduleCount];
|
||||||
|
ResolvedModule[] moduleArray = new ResolvedModule[moduleCount];
|
||||||
|
String targetPlatform = null;
|
||||||
|
int i = 0;
|
||||||
|
for (String name : map.keySet()) {
|
||||||
|
ModuleReference mref = finder.find(name).orElse(null);
|
||||||
|
assert mref != null;
|
||||||
|
|
||||||
|
if (targetPlatform == null && mref instanceof ModuleReferenceImpl) {
|
||||||
|
ModuleTarget target = ((ModuleReferenceImpl)mref).moduleTarget();
|
||||||
|
if (target != null) {
|
||||||
|
targetPlatform = target.targetPlatform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResolvedModule resolvedModule = new ResolvedModule(this, mref);
|
||||||
|
moduleArray[i] = resolvedModule;
|
||||||
|
nameEntries[i] = Map.entry(name, resolvedModule);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
Map<String, ResolvedModule> nameToModule = Map.ofEntries(nameEntries);
|
||||||
|
|
||||||
|
// create entries for readability graph
|
||||||
|
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||||
|
Entry<ResolvedModule, Set<ResolvedModule>>[] moduleEntries
|
||||||
|
= (Entry<ResolvedModule, Set<ResolvedModule>>[])new Entry[moduleCount];
|
||||||
|
i = 0;
|
||||||
|
for (ResolvedModule resolvedModule : moduleArray) {
|
||||||
|
Set<String> names = map.get(resolvedModule.name());
|
||||||
|
ResolvedModule[] readsArray = new ResolvedModule[names.size()];
|
||||||
|
int j = 0;
|
||||||
|
for (String name : names) {
|
||||||
|
readsArray[j++] = nameToModule.get(name);
|
||||||
|
}
|
||||||
|
moduleEntries[i++] = Map.entry(resolvedModule, Set.of(readsArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.parents = List.of(empty());
|
||||||
|
this.graph = Map.ofEntries(moduleEntries);
|
||||||
|
this.modules = Set.of(moduleArray);
|
||||||
|
this.nameToModule = nameToModule;
|
||||||
|
this.targetPlatform = targetPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a collection of root modules, with this configuration as its
|
* Resolves a collection of root modules, with this configuration as its
|
||||||
* parent, to create a new configuration. This method works exactly as
|
* parent, to create a new configuration. This method works exactly as
|
||||||
@ -233,24 +290,20 @@ public final class Configuration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a collection of root modules, with service binding, and with
|
* Resolves a collection of root modules, with service binding, and with
|
||||||
* the empty configuration as its parent. The consistency checks
|
* the empty configuration as its parent.
|
||||||
* are optionally run.
|
|
||||||
*
|
*
|
||||||
* This method is used to create the configuration for the boot layer.
|
* This method is used to create the configuration for the boot layer.
|
||||||
*/
|
*/
|
||||||
static Configuration resolveAndBind(ModuleFinder finder,
|
static Configuration resolveAndBind(ModuleFinder finder,
|
||||||
Collection<String> roots,
|
Collection<String> roots,
|
||||||
boolean check,
|
|
||||||
PrintStream traceOutput)
|
PrintStream traceOutput)
|
||||||
{
|
{
|
||||||
List<Configuration> parents = List.of(empty());
|
List<Configuration> parents = List.of(empty());
|
||||||
Resolver resolver = new Resolver(finder, parents, ModuleFinder.of(), traceOutput);
|
Resolver resolver = new Resolver(finder, parents, ModuleFinder.of(), traceOutput);
|
||||||
resolver.resolve(roots).bind();
|
resolver.resolve(roots).bind();
|
||||||
|
return new Configuration(parents, resolver);
|
||||||
return new Configuration(parents, resolver, check);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a collection of root modules to create a configuration.
|
* Resolves a collection of root modules to create a configuration.
|
||||||
*
|
*
|
||||||
@ -356,7 +409,7 @@ public final class Configuration {
|
|||||||
Resolver resolver = new Resolver(before, parentList, after, null);
|
Resolver resolver = new Resolver(before, parentList, after, null);
|
||||||
resolver.resolve(roots);
|
resolver.resolve(roots);
|
||||||
|
|
||||||
return new Configuration(parentList, resolver, true);
|
return new Configuration(parentList, resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -427,7 +480,7 @@ public final class Configuration {
|
|||||||
Resolver resolver = new Resolver(before, parentList, after, null);
|
Resolver resolver = new Resolver(before, parentList, after, null);
|
||||||
resolver.resolve(roots).bind();
|
resolver.resolve(roots).bind();
|
||||||
|
|
||||||
return new Configuration(parentList, resolver, true);
|
return new Configuration(parentList, resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2728,10 +2728,15 @@ public class ModuleDescriptor
|
|||||||
@Override
|
@Override
|
||||||
public Configuration resolveAndBind(ModuleFinder finder,
|
public Configuration resolveAndBind(ModuleFinder finder,
|
||||||
Collection<String> roots,
|
Collection<String> roots,
|
||||||
boolean check,
|
|
||||||
PrintStream traceOutput)
|
PrintStream traceOutput)
|
||||||
{
|
{
|
||||||
return Configuration.resolveAndBind(finder, roots, check, traceOutput);
|
return Configuration.resolveAndBind(finder, roots, traceOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Configuration newConfiguration(ModuleFinder finder,
|
||||||
|
Map<String, Set<String>> graph) {
|
||||||
|
return new Configuration(finder, graph);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,7 @@
|
|||||||
|
|
||||||
package java.lang.module;
|
package java.lang.module;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.Permission;
|
import java.security.Permission;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
@ -40,10 +38,8 @@ import java.util.Objects;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import jdk.internal.module.ModuleBootstrap;
|
|
||||||
import jdk.internal.module.ModulePatcher;
|
|
||||||
import jdk.internal.module.ModulePath;
|
import jdk.internal.module.ModulePath;
|
||||||
import jdk.internal.module.SystemModuleFinder;
|
import jdk.internal.module.SystemModuleFinders;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A finder of modules. A {@code ModuleFinder} is used to find modules during
|
* A finder of modules. A {@code ModuleFinder} is used to find modules during
|
||||||
@ -157,52 +153,13 @@ public interface ModuleFinder {
|
|||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm != null) {
|
if (sm != null) {
|
||||||
sm.checkPermission(new RuntimePermission("accessSystemModules"));
|
sm.checkPermission(new RuntimePermission("accessSystemModules"));
|
||||||
PrivilegedAction<ModuleFinder> pa = ModuleFinder::privilegedOfSystem;
|
PrivilegedAction<ModuleFinder> pa = SystemModuleFinders::ofSystem;
|
||||||
return AccessController.doPrivileged(pa);
|
return AccessController.doPrivileged(pa);
|
||||||
} else {
|
} else {
|
||||||
return privilegedOfSystem();
|
return SystemModuleFinders.ofSystem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a module finder that locates the system modules. This method
|
|
||||||
* assumes it has permissions to access the runtime image.
|
|
||||||
*/
|
|
||||||
private static ModuleFinder privilegedOfSystem() {
|
|
||||||
String home = System.getProperty("java.home");
|
|
||||||
Path modules = Paths.get(home, "lib", "modules");
|
|
||||||
if (Files.isRegularFile(modules)) {
|
|
||||||
return SystemModuleFinder.getInstance();
|
|
||||||
} else {
|
|
||||||
Path dir = Paths.get(home, "modules");
|
|
||||||
if (Files.isDirectory(dir)) {
|
|
||||||
return privilegedOf(ModuleBootstrap.patcher(), dir);
|
|
||||||
} else {
|
|
||||||
throw new InternalError("Unable to detect the run-time image");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a module finder that locates the system modules in an exploded
|
|
||||||
* image. The image may be patched.
|
|
||||||
*/
|
|
||||||
private static ModuleFinder privilegedOf(ModulePatcher patcher, Path dir) {
|
|
||||||
ModuleFinder finder = ModulePath.of(patcher, dir);
|
|
||||||
return new ModuleFinder() {
|
|
||||||
@Override
|
|
||||||
public Optional<ModuleReference> find(String name) {
|
|
||||||
PrivilegedAction<Optional<ModuleReference>> pa = () -> finder.find(name);
|
|
||||||
return AccessController.doPrivileged(pa);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Set<ModuleReference> findAll() {
|
|
||||||
PrivilegedAction<Set<ModuleReference>> pa = finder::findAll;
|
|
||||||
return AccessController.doPrivileged(pa);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a module finder that locates modules on the file system by
|
* Returns a module finder that locates modules on the file system by
|
||||||
* searching a sequence of directories and/or packaged modules.
|
* searching a sequence of directories and/or packaged modules.
|
||||||
|
@ -353,25 +353,13 @@ final class Resolver {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute post-resolution checks and returns the module graph of resolved
|
* Execute post-resolution checks and returns the module graph of resolved
|
||||||
* modules as {@code Map}. The resolved modules will be in the given
|
* modules as a map.
|
||||||
* configuration.
|
|
||||||
*
|
|
||||||
* @param check {@true} to execute the post resolution checks
|
|
||||||
*/
|
*/
|
||||||
Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf,
|
Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf) {
|
||||||
boolean check)
|
detectCycles();
|
||||||
{
|
checkHashes();
|
||||||
if (check) {
|
|
||||||
detectCycles();
|
|
||||||
checkHashes();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<ResolvedModule, Set<ResolvedModule>> graph = makeGraph(cf);
|
Map<ResolvedModule, Set<ResolvedModule>> graph = makeGraph(cf);
|
||||||
|
checkExportSuppliers(graph);
|
||||||
if (check) {
|
|
||||||
checkExportSuppliers(graph);
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ public class Proxy implements java.io.Serializable {
|
|||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm != null) {
|
if (sm != null) {
|
||||||
ClassLoader ccl = caller.getClassLoader();
|
ClassLoader ccl = caller.getClassLoader();
|
||||||
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
|
if (loader == null && ccl != null) {
|
||||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||||
}
|
}
|
||||||
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
|
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
|
||||||
|
@ -409,7 +409,7 @@ public final class URL implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol = protocol.toLowerCase(Locale.ROOT);
|
protocol = toLowerCase(protocol);
|
||||||
this.protocol = protocol;
|
this.protocol = protocol;
|
||||||
if (host != null) {
|
if (host != null) {
|
||||||
|
|
||||||
@ -585,7 +585,7 @@ public final class URL implements java.io.Serializable {
|
|||||||
for (i = start ; !aRef && (i < limit) &&
|
for (i = start ; !aRef && (i < limit) &&
|
||||||
((c = spec.charAt(i)) != '/') ; i++) {
|
((c = spec.charAt(i)) != '/') ; i++) {
|
||||||
if (c == ':') {
|
if (c == ':') {
|
||||||
String s = spec.substring(start, i).toLowerCase(Locale.ROOT);
|
String s = toLowerCase(spec.substring(start, i));
|
||||||
if (isValidProtocol(s)) {
|
if (isValidProtocol(s)) {
|
||||||
newProtocol = s;
|
newProtocol = s;
|
||||||
start = i + 1;
|
start = i + 1;
|
||||||
@ -1318,6 +1318,17 @@ public final class URL implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the protocol in lower case. Special cases known protocols
|
||||||
|
* to avoid loading locale classes during startup.
|
||||||
|
*/
|
||||||
|
static String toLowerCase(String protocol) {
|
||||||
|
if (protocol.equals("jrt") || protocol.equals("file") || protocol.equals("jar")) {
|
||||||
|
return protocol;
|
||||||
|
} else {
|
||||||
|
return protocol.toLowerCase(Locale.ROOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-overrideable protocols: "jrt" and "file"
|
* Non-overrideable protocols: "jrt" and "file"
|
||||||
|
@ -70,7 +70,7 @@ public abstract class AbstractSelector
|
|||||||
extends Selector
|
extends Selector
|
||||||
{
|
{
|
||||||
|
|
||||||
private AtomicBoolean selectorOpen = new AtomicBoolean(true);
|
private final AtomicBoolean selectorOpen = new AtomicBoolean(true);
|
||||||
|
|
||||||
// The provider that created this selector
|
// The provider that created this selector
|
||||||
private final SelectorProvider provider;
|
private final SelectorProvider provider;
|
||||||
|
@ -57,7 +57,7 @@ import javax.crypto.SecretKey;
|
|||||||
* and catching the CloneNotSupportedException:
|
* and catching the CloneNotSupportedException:
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* MessageDigest md = MessageDigest.getInstance("SHA");
|
* MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
*
|
*
|
||||||
* try {
|
* try {
|
||||||
* md.update(toChapter1);
|
* md.update(toChapter1);
|
||||||
@ -496,7 +496,7 @@ public abstract class MessageDigest extends MessageDigestSpi {
|
|||||||
/**
|
/**
|
||||||
* Returns a string that identifies the algorithm, independent of
|
* Returns a string that identifies the algorithm, independent of
|
||||||
* implementation details. The name should be a standard
|
* implementation details. The name should be a standard
|
||||||
* Java Security name (such as "SHA", "MD5", and so on).
|
* Java Security name (such as "SHA-256").
|
||||||
* See the MessageDigest section in the <a href=
|
* See the MessageDigest section in the <a href=
|
||||||
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
|
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
|
||||||
* Java Security Standard Algorithm Names Specification</a>
|
* Java Security Standard Algorithm Names Specification</a>
|
||||||
|
@ -51,11 +51,10 @@ import sun.security.jca.GetInstance.Instance;
|
|||||||
* authentication and integrity assurance of digital data.
|
* authentication and integrity assurance of digital data.
|
||||||
*
|
*
|
||||||
* <p> The signature algorithm can be, among others, the NIST standard
|
* <p> The signature algorithm can be, among others, the NIST standard
|
||||||
* DSA, using DSA and SHA-1. The DSA algorithm using the
|
* DSA, using DSA and SHA-256. The DSA algorithm using the
|
||||||
* SHA-1 message digest algorithm can be specified as {@code SHA1withDSA}.
|
* SHA-256 message digest algorithm can be specified as {@code SHA256withDSA}.
|
||||||
* In the case of RSA, there are multiple choices for the message digest
|
* In the case of RSA the signing algorithm could be specified as, for example,
|
||||||
* algorithm, so the signing algorithm could be specified as, for example,
|
* {@code SHA256withRSA}.
|
||||||
* {@code MD2withRSA}, {@code MD5withRSA}, or {@code SHA1withRSA}.
|
|
||||||
* The algorithm name must be specified, as there is no default.
|
* The algorithm name must be specified, as there is no default.
|
||||||
*
|
*
|
||||||
* <p> A Signature object can be used to generate and verify digital
|
* <p> A Signature object can be used to generate and verify digital
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -81,13 +81,12 @@ import java.io.*;
|
|||||||
* verification in an attempt to bypass a security check.
|
* verification in an attempt to bypass a security check.
|
||||||
*
|
*
|
||||||
* <p> The signature algorithm can be, among others, the NIST standard
|
* <p> The signature algorithm can be, among others, the NIST standard
|
||||||
* DSA, using DSA and SHA-1. The algorithm is specified using the
|
* DSA, using DSA and SHA-256. The algorithm is specified using the
|
||||||
* same convention as that for signatures. The DSA algorithm using the
|
* same convention as that for signatures. The DSA algorithm using the
|
||||||
* SHA-1 message digest algorithm can be specified, for example, as
|
* SHA-256 message digest algorithm can be specified, for example, as
|
||||||
* "SHA/DSA" or "SHA-1/DSA" (they are equivalent). In the case of
|
* "SHA256withDSA". In the case of
|
||||||
* RSA, there are multiple choices for the message digest algorithm,
|
* RSA the signing algorithm could be specified as, for example,
|
||||||
* so the signing algorithm could be specified as, for example,
|
* "SHA256withRSA". The algorithm name must be
|
||||||
* "MD2/RSA", "MD5/RSA" or "SHA-1/RSA". The algorithm name must be
|
|
||||||
* specified, as there is no default.
|
* specified, as there is no default.
|
||||||
*
|
*
|
||||||
* <p> The name of the Cryptography Package Provider is designated
|
* <p> The name of the Cryptography Package Provider is designated
|
||||||
|
@ -667,11 +667,11 @@ import java.util.stream.StreamSupport;
|
|||||||
* <tr><td>{@code \p{Alpha}}</td>
|
* <tr><td>{@code \p{Alpha}}</td>
|
||||||
* <td>An alphabetic character:{@code \p{IsAlphabetic}}</td></tr>
|
* <td>An alphabetic character:{@code \p{IsAlphabetic}}</td></tr>
|
||||||
* <tr><td>{@code \p{Digit}}</td>
|
* <tr><td>{@code \p{Digit}}</td>
|
||||||
* <td>A decimal digit character:{@code p{IsDigit}}</td></tr>
|
* <td>A decimal digit character:{@code \p{IsDigit}}</td></tr>
|
||||||
* <tr><td>{@code \p{Alnum}}</td>
|
* <tr><td>{@code \p{Alnum}}</td>
|
||||||
* <td>An alphanumeric character:{@code [\p{IsAlphabetic}\p{IsDigit}]}</td></tr>
|
* <td>An alphanumeric character:{@code [\p{IsAlphabetic}\p{IsDigit}]}</td></tr>
|
||||||
* <tr><td>{@code \p{Punct}}</td>
|
* <tr><td>{@code \p{Punct}}</td>
|
||||||
* <td>A punctuation character:{@code p{IsPunctuation}}</td></tr>
|
* <td>A punctuation character:{@code \p{IsPunctuation}}</td></tr>
|
||||||
* <tr><td>{@code \p{Graph}}</td>
|
* <tr><td>{@code \p{Graph}}</td>
|
||||||
* <td>A visible character: {@code [^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]}</td></tr>
|
* <td>A visible character: {@code [^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]}</td></tr>
|
||||||
* <tr><td>{@code \p{Print}}</td>
|
* <tr><td>{@code \p{Print}}</td>
|
||||||
|
@ -59,7 +59,7 @@ import sun.security.jca.*;
|
|||||||
* <p>A <i>transformation</i> is a string that describes the operation (or
|
* <p>A <i>transformation</i> is a string that describes the operation (or
|
||||||
* set of operations) to be performed on the given input, to produce some
|
* set of operations) to be performed on the given input, to produce some
|
||||||
* output. A transformation always includes the name of a cryptographic
|
* output. A transformation always includes the name of a cryptographic
|
||||||
* algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
|
* algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and
|
||||||
* padding scheme.
|
* padding scheme.
|
||||||
*
|
*
|
||||||
* <p> A transformation is of the form:
|
* <p> A transformation is of the form:
|
||||||
@ -75,17 +75,19 @@ import sun.security.jca.*;
|
|||||||
* For example, the following is a valid transformation:
|
* For example, the following is a valid transformation:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
|
* Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>");
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Using modes such as {@code CFB} and {@code OFB}, block
|
* Using modes such as {@code CFB} and {@code OFB}, block
|
||||||
* ciphers can encrypt data in units smaller than the cipher's actual
|
* ciphers can encrypt data in units smaller than the cipher's actual
|
||||||
* block size. When requesting such a mode, you may optionally specify
|
* block size. When requesting such a mode, you may optionally specify
|
||||||
* the number of bits to be processed at a time by appending this number
|
* the number of bits to be processed at a time by appending this number
|
||||||
* to the mode name as shown in the "{@code DES/CFB8/NoPadding}" and
|
* to the mode name as shown in the "{@code AES/CFB8/NoPadding}" and
|
||||||
* "{@code DES/OFB32/PKCS5Padding}" transformations. If no such
|
* "{@code AES/OFB32/PKCS5Padding}" transformations. If no such
|
||||||
* number is specified, a provider-specific default is used. (For
|
* number is specified, a provider-specific default is used.
|
||||||
* example, the SunJCE provider uses a default of 64 bits for DES.)
|
* (See the
|
||||||
|
* {@extLink security_guide_jdk_providers JDK Providers Documentation}
|
||||||
|
* for the JDK Providers default values.)
|
||||||
* Thus, block ciphers can be turned into byte-oriented stream ciphers by
|
* Thus, block ciphers can be turned into byte-oriented stream ciphers by
|
||||||
* using an 8 bit mode such as CFB8 or OFB8.
|
* using an 8 bit mode such as CFB8 or OFB8.
|
||||||
* <p>
|
* <p>
|
||||||
@ -308,7 +310,7 @@ public class Cipher {
|
|||||||
/*
|
/*
|
||||||
* array containing the components of a Cipher transformation:
|
* array containing the components of a Cipher transformation:
|
||||||
*
|
*
|
||||||
* index 0: algorithm component (e.g., DES)
|
* index 0: algorithm component (e.g., AES)
|
||||||
* index 1: feedback component (e.g., CFB)
|
* index 1: feedback component (e.g., CFB)
|
||||||
* index 2: padding component (e.g., PKCS5Padding)
|
* index 2: padding component (e.g., PKCS5Padding)
|
||||||
*/
|
*/
|
||||||
@ -354,8 +356,8 @@ public class Cipher {
|
|||||||
// transform string to lookup in the provider
|
// transform string to lookup in the provider
|
||||||
final String transform;
|
final String transform;
|
||||||
// the mode/padding suffix in upper case. for example, if the algorithm
|
// the mode/padding suffix in upper case. for example, if the algorithm
|
||||||
// to lookup is "DES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"
|
// to lookup is "AES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"
|
||||||
// if loopup is "DES", suffix is the empty string
|
// if lookup is "AES", suffix is the empty string
|
||||||
// needed because aliases prevent straight transform.equals()
|
// needed because aliases prevent straight transform.equals()
|
||||||
final String suffix;
|
final String suffix;
|
||||||
// value to pass to setMode() or null if no such call required
|
// value to pass to setMode() or null if no such call required
|
||||||
@ -440,11 +442,11 @@ public class Cipher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((mode == null) && (pad == null)) {
|
if ((mode == null) && (pad == null)) {
|
||||||
// DES
|
// AES
|
||||||
Transform tr = new Transform(alg, "", null, null);
|
Transform tr = new Transform(alg, "", null, null);
|
||||||
return Collections.singletonList(tr);
|
return Collections.singletonList(tr);
|
||||||
} else { // if ((mode != null) && (pad != null)) {
|
} else { // if ((mode != null) && (pad != null)) {
|
||||||
// DES/CBC/PKCS5Padding
|
// AES/CBC/PKCS5Padding
|
||||||
List<Transform> list = new ArrayList<>(4);
|
List<Transform> list = new ArrayList<>(4);
|
||||||
list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
|
list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
|
||||||
list.add(new Transform(alg, "/" + mode, null, pad));
|
list.add(new Transform(alg, "/" + mode, null, pad));
|
||||||
@ -488,7 +490,7 @@ public class Cipher {
|
|||||||
* {@link Security#getProviders() Security.getProviders()}.
|
* {@link Security#getProviders() Security.getProviders()}.
|
||||||
*
|
*
|
||||||
* @param transformation the name of the transformation, e.g.,
|
* @param transformation the name of the transformation, e.g.,
|
||||||
* <i>DES/CBC/PKCS5Padding</i>.
|
* <i>AES/CBC/PKCS5Padding</i>.
|
||||||
* See the Cipher section in the <a href=
|
* See the Cipher section in the <a href=
|
||||||
* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
|
* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
|
||||||
* Java Security Standard Algorithm Names Specification</a>
|
* Java Security Standard Algorithm Names Specification</a>
|
||||||
@ -566,7 +568,7 @@ public class Cipher {
|
|||||||
* the {@link Security#getProviders() Security.getProviders()} method.
|
* the {@link Security#getProviders() Security.getProviders()} method.
|
||||||
*
|
*
|
||||||
* @param transformation the name of the transformation,
|
* @param transformation the name of the transformation,
|
||||||
* e.g., <i>DES/CBC/PKCS5Padding</i>.
|
* e.g., <i>AES/CBC/PKCS5Padding</i>.
|
||||||
* See the Cipher section in the <a href=
|
* See the Cipher section in the <a href=
|
||||||
* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
|
* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
|
||||||
* Java Security Standard Algorithm Names Specification</a>
|
* Java Security Standard Algorithm Names Specification</a>
|
||||||
@ -626,7 +628,7 @@ public class Cipher {
|
|||||||
* does not have to be registered in the provider list.
|
* does not have to be registered in the provider list.
|
||||||
*
|
*
|
||||||
* @param transformation the name of the transformation,
|
* @param transformation the name of the transformation,
|
||||||
* e.g., <i>DES/CBC/PKCS5Padding</i>.
|
* e.g., <i>AES/CBC/PKCS5Padding</i>.
|
||||||
* See the Cipher section in the <a href=
|
* See the Cipher section in the <a href=
|
||||||
* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
|
* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
|
||||||
* Java Security Standard Algorithm Names Specification</a>
|
* Java Security Standard Algorithm Names Specification</a>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -59,7 +59,7 @@ import java.nio.ByteBuffer;
|
|||||||
* <p>A <i>transformation</i> is a string that describes the operation (or
|
* <p>A <i>transformation</i> is a string that describes the operation (or
|
||||||
* set of operations) to be performed on the given input, to produce some
|
* set of operations) to be performed on the given input, to produce some
|
||||||
* output. A transformation always includes the name of a cryptographic
|
* output. A transformation always includes the name of a cryptographic
|
||||||
* algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
|
* algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and
|
||||||
* padding scheme.
|
* padding scheme.
|
||||||
*
|
*
|
||||||
* <p> A transformation is of the form:
|
* <p> A transformation is of the form:
|
||||||
@ -75,7 +75,7 @@ import java.nio.ByteBuffer;
|
|||||||
* For example, the following is a valid transformation:
|
* For example, the following is a valid transformation:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
|
* Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>");
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>A provider may supply a separate class for each combination
|
* <p>A provider may supply a separate class for each combination
|
||||||
@ -125,32 +125,32 @@ import java.nio.ByteBuffer;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>For example, a provider may supply a subclass of <code>CipherSpi</code>
|
* <p>For example, a provider may supply a subclass of <code>CipherSpi</code>
|
||||||
* that implements <i>DES/ECB/PKCS5Padding</i>, one that implements
|
* that implements <i>AES/ECB/PKCS5Padding</i>, one that implements
|
||||||
* <i>DES/CBC/PKCS5Padding</i>, one that implements
|
* <i>AES/CBC/PKCS5Padding</i>, one that implements
|
||||||
* <i>DES/CFB/PKCS5Padding</i>, and yet another one that implements
|
* <i>AES/CFB/PKCS5Padding</i>, and yet another one that implements
|
||||||
* <i>DES/OFB/PKCS5Padding</i>. That provider would have the following
|
* <i>AES/OFB/PKCS5Padding</i>. That provider would have the following
|
||||||
* <code>Cipher</code> properties in its master class:
|
* <code>Cipher</code> properties in its master class:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
*
|
*
|
||||||
* <li>
|
* <li>
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>Cipher.</code><i>DES/ECB/PKCS5Padding</i>
|
* <code>Cipher.</code><i>AES/ECB/PKCS5Padding</i>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <li>
|
* <li>
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>Cipher.</code><i>DES/CBC/PKCS5Padding</i>
|
* <code>Cipher.</code><i>AES/CBC/PKCS5Padding</i>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <li>
|
* <li>
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>Cipher.</code><i>DES/CFB/PKCS5Padding</i>
|
* <code>Cipher.</code><i>AES/CFB/PKCS5Padding</i>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <li>
|
* <li>
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>Cipher.</code><i>DES/OFB/PKCS5Padding</i>
|
* <code>Cipher.</code><i>AES/OFB/PKCS5Padding</i>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* </ul>
|
* </ul>
|
||||||
@ -158,7 +158,7 @@ import java.nio.ByteBuffer;
|
|||||||
* <p>Another provider may implement a class for each of the above modes
|
* <p>Another provider may implement a class for each of the above modes
|
||||||
* (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>,
|
* (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>,
|
||||||
* and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>,
|
* and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>,
|
||||||
* and a generic <i>DES</i> class that subclasses from <code>CipherSpi</code>.
|
* and a generic <i>AES</i> class that subclasses from <code>CipherSpi</code>.
|
||||||
* That provider would have the following
|
* That provider would have the following
|
||||||
* <code>Cipher</code> properties in its master class:
|
* <code>Cipher</code> properties in its master class:
|
||||||
*
|
*
|
||||||
@ -166,7 +166,7 @@ import java.nio.ByteBuffer;
|
|||||||
*
|
*
|
||||||
* <li>
|
* <li>
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>Cipher.</code><i>DES</i>
|
* <code>Cipher.</code><i>AES</i>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* </ul>
|
* </ul>
|
||||||
|
@ -50,7 +50,7 @@ import sun.security.jca.GetInstance.Instance;
|
|||||||
*
|
*
|
||||||
* <p> A MAC mechanism that is based on cryptographic hash functions is
|
* <p> A MAC mechanism that is based on cryptographic hash functions is
|
||||||
* referred to as HMAC. HMAC can be used with any cryptographic hash function,
|
* referred to as HMAC. HMAC can be used with any cryptographic hash function,
|
||||||
* e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is
|
* e.g., SHA256 or SHA384, in combination with a secret shared key. HMAC is
|
||||||
* specified in RFC 2104.
|
* specified in RFC 2104.
|
||||||
*
|
*
|
||||||
* <p> Every implementation of the Java platform is required to support
|
* <p> Every implementation of the Java platform is required to support
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -40,7 +40,7 @@ import java.security.NoSuchProviderException;
|
|||||||
* <p> Given any Serializable object, one can create a SealedObject
|
* <p> Given any Serializable object, one can create a SealedObject
|
||||||
* that encapsulates the original object, in serialized
|
* that encapsulates the original object, in serialized
|
||||||
* format (i.e., a "deep copy"), and seals (encrypts) its serialized contents,
|
* format (i.e., a "deep copy"), and seals (encrypts) its serialized contents,
|
||||||
* using a cryptographic algorithm such as DES, to protect its
|
* using a cryptographic algorithm such as AES, to protect its
|
||||||
* confidentiality. The encrypted content can later be decrypted (with
|
* confidentiality. The encrypted content can later be decrypted (with
|
||||||
* the corresponding algorithm using the correct decryption key) and
|
* the corresponding algorithm using the correct decryption key) and
|
||||||
* de-serialized, yielding the original object.
|
* de-serialized, yielding the original object.
|
||||||
|
@ -55,13 +55,13 @@ import java.util.Map;
|
|||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.jar.Attributes;
|
import java.util.jar.Attributes;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
import jdk.internal.module.ModulePatcher.PatchedModuleReader;
|
import jdk.internal.module.ModulePatcher.PatchedModuleReader;
|
||||||
import jdk.internal.module.SystemModules;
|
|
||||||
import jdk.internal.module.Resources;
|
import jdk.internal.module.Resources;
|
||||||
|
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ public class BuiltinClassLoader
|
|||||||
|
|
||||||
// maps package name to loaded module for modules in the boot layer
|
// maps package name to loaded module for modules in the boot layer
|
||||||
private static final Map<String, LoadedModule> packageToModule
|
private static final Map<String, LoadedModule> packageToModule
|
||||||
= new ConcurrentHashMap<>(SystemModules.PACKAGES_IN_BOOT_LAYER);
|
= new ConcurrentHashMap<>(1024);
|
||||||
|
|
||||||
// maps a module name to a module reference
|
// maps a module name to a module reference
|
||||||
private final Map<String, ModuleReference> nameToModule;
|
private final Map<String, ModuleReference> nameToModule;
|
||||||
@ -946,9 +946,16 @@ public class BuiltinClassLoader
|
|||||||
URL url = cs.getLocation();
|
URL url = cs.getLocation();
|
||||||
if (url == null)
|
if (url == null)
|
||||||
return perms;
|
return perms;
|
||||||
Permission p = null;
|
|
||||||
|
// avoid opening connection when URL is to resource in run-time image
|
||||||
|
if (url.getProtocol().equals("jrt")) {
|
||||||
|
perms.add(new RuntimePermission("accessSystemModules"));
|
||||||
|
return perms;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open connection to determine the permission needed
|
||||||
try {
|
try {
|
||||||
p = url.openConnection().getPermission();
|
Permission p = url.openConnection().getPermission();
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
// for directories then need recursive access
|
// for directories then need recursive access
|
||||||
if (p instanceof FilePermission) {
|
if (p instanceof FilePermission) {
|
||||||
@ -969,23 +976,26 @@ public class BuiltinClassLoader
|
|||||||
// -- miscellaneous supporting methods
|
// -- miscellaneous supporting methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ModuleReader for the given module.
|
* Returns the ModuleReader for the given module, creating it if needed
|
||||||
*/
|
*/
|
||||||
private ModuleReader moduleReaderFor(ModuleReference mref) {
|
private ModuleReader moduleReaderFor(ModuleReference mref) {
|
||||||
return moduleToReader.computeIfAbsent(mref, BuiltinClassLoader::createModuleReader);
|
ModuleReader reader = moduleToReader.get(mref);
|
||||||
}
|
if (reader == null) {
|
||||||
|
// avoid method reference during startup
|
||||||
/**
|
Function<ModuleReference, ModuleReader> create = new Function<>() {
|
||||||
* Creates a ModuleReader for the given module.
|
public ModuleReader apply(ModuleReference moduleReference) {
|
||||||
*/
|
try {
|
||||||
private static ModuleReader createModuleReader(ModuleReference mref) {
|
return mref.open();
|
||||||
try {
|
} catch (IOException e) {
|
||||||
return mref.open();
|
// Return a null module reader to avoid a future class
|
||||||
} catch (IOException e) {
|
// load attempting to open the module again.
|
||||||
// Return a null module reader to avoid a future class load
|
return new NullModuleReader();
|
||||||
// attempting to open the module again.
|
}
|
||||||
return new NullModuleReader();
|
}
|
||||||
|
};
|
||||||
|
reader = moduleToReader.computeIfAbsent(mref, create);
|
||||||
}
|
}
|
||||||
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package jdk.internal.loader;
|
package jdk.internal.loader;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.InvalidPathException;
|
import java.nio.file.InvalidPathException;
|
||||||
@ -38,7 +37,6 @@ import jdk.internal.misc.JavaLangAccess;
|
|||||||
import jdk.internal.misc.SharedSecrets;
|
import jdk.internal.misc.SharedSecrets;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and provides access to the built-in platform and application class
|
* Creates and provides access to the built-in platform and application class
|
||||||
* loaders. It also creates the class loader that is used to locate resources
|
* loaders. It also creates the class loader that is used to locate resources
|
||||||
@ -61,23 +59,30 @@ public class ClassLoaders {
|
|||||||
*/
|
*/
|
||||||
static {
|
static {
|
||||||
|
|
||||||
// -Xbootclasspth/a or -javaagent Boot-Class-Path
|
// -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
|
||||||
URLClassPath bcp = null;
|
URLClassPath bcp = null;
|
||||||
String s = VM.getSavedProperty("jdk.boot.class.path.append");
|
String s = VM.getSavedProperty("jdk.boot.class.path.append");
|
||||||
if (s != null && s.length() > 0)
|
if (s != null && s.length() > 0)
|
||||||
bcp = toURLClassPath(s);
|
bcp = new URLClassPath(s, true);
|
||||||
|
|
||||||
// we have a class path if -cp is specified or -m is not specified.
|
// we have a class path if -cp is specified or -m is not specified.
|
||||||
// If neither is specified then default to -cp <working directory>
|
// If neither is specified then default to -cp <working directory>
|
||||||
// If -cp is not specified and -m is specified, the value of
|
// If -cp is not specified and -m is specified, the value of
|
||||||
// java.class.path is an empty string, then no class path.
|
// java.class.path is an empty string, then no class path.
|
||||||
URLClassPath ucp = new URLClassPath(new URL[0]);
|
|
||||||
String mainMid = System.getProperty("jdk.module.main");
|
String mainMid = System.getProperty("jdk.module.main");
|
||||||
String cp = System.getProperty("java.class.path");
|
String cp = System.getProperty("java.class.path");
|
||||||
if (cp == null)
|
if (mainMid == null) {
|
||||||
cp = "";
|
// no main module specified so class path required
|
||||||
if (mainMid == null || cp.length() > 0)
|
if (cp == null) {
|
||||||
addClassPathToUCP(cp, ucp);
|
cp = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// main module specified, ignore empty class path
|
||||||
|
if (cp != null && cp.length() == 0) {
|
||||||
|
cp = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
URLClassPath ucp = new URLClassPath(cp, false);
|
||||||
|
|
||||||
// create the class loaders
|
// create the class loaders
|
||||||
BOOT_LOADER = new BootClassLoader(bcp);
|
BOOT_LOADER = new BootClassLoader(bcp);
|
||||||
@ -198,7 +203,7 @@ public class ClassLoaders {
|
|||||||
* @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch
|
* @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch
|
||||||
*/
|
*/
|
||||||
void appendToClassPathForInstrumentation(String path) {
|
void appendToClassPathForInstrumentation(String path) {
|
||||||
addClassPathToUCP(path, ucp);
|
ucp.addFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,41 +224,12 @@ public class ClassLoaders {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a {@code URLClassPath} of file URLs to each of the elements in
|
|
||||||
* the given class path.
|
|
||||||
*/
|
|
||||||
private static URLClassPath toURLClassPath(String cp) {
|
|
||||||
URLClassPath ucp = new URLClassPath(new URL[0]);
|
|
||||||
addClassPathToUCP(cp, ucp);
|
|
||||||
return ucp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the elements in the given class path to file URLs and adds
|
|
||||||
* them to the given URLClassPath.
|
|
||||||
*/
|
|
||||||
private static void addClassPathToUCP(String cp, URLClassPath ucp) {
|
|
||||||
int off = 0;
|
|
||||||
int next;
|
|
||||||
while ((next = cp.indexOf(File.pathSeparator, off)) != -1) {
|
|
||||||
URL url = toFileURL(cp.substring(off, next));
|
|
||||||
if (url != null)
|
|
||||||
ucp.addURL(url);
|
|
||||||
off = next + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remaining
|
|
||||||
URL url = toFileURL(cp.substring(off));
|
|
||||||
if (url != null)
|
|
||||||
ucp.addURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to convert the given string to a file URL.
|
* Attempts to convert the given string to a file URL.
|
||||||
*
|
*
|
||||||
* @apiNote This is called by the VM
|
* @apiNote This is called by the VM
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
private static URL toFileURL(String s) {
|
private static URL toFileURL(String s) {
|
||||||
try {
|
try {
|
||||||
// Use an intermediate File object to construct a URI/URL without
|
// Use an intermediate File object to construct a URI/URL without
|
||||||
@ -265,5 +241,4 @@ public class ClassLoaders {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ import java.security.Permission;
|
|||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -66,7 +67,6 @@ import java.util.jar.Attributes.Name;
|
|||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
import jdk.internal.misc.JavaNetURLAccess;
|
import jdk.internal.misc.JavaNetURLAccess;
|
||||||
import jdk.internal.misc.JavaNetURLClassLoaderAccess;
|
|
||||||
import jdk.internal.misc.JavaUtilZipFileAccess;
|
import jdk.internal.misc.JavaUtilZipFileAccess;
|
||||||
import jdk.internal.misc.SharedSecrets;
|
import jdk.internal.misc.SharedSecrets;
|
||||||
import jdk.internal.util.jar.InvalidJarIndexError;
|
import jdk.internal.util.jar.InvalidJarIndexError;
|
||||||
@ -100,19 +100,19 @@ public class URLClassPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The original search path of URLs. */
|
/* The original search path of URLs. */
|
||||||
private ArrayList<URL> path = new ArrayList<>();
|
private final List<URL> path;
|
||||||
|
|
||||||
/* The stack of unopened URLs */
|
/* The stack of unopened URLs */
|
||||||
Stack<URL> urls = new Stack<>();
|
private final Stack<URL> urls = new Stack<>();
|
||||||
|
|
||||||
/* The resulting search path of Loaders */
|
/* The resulting search path of Loaders */
|
||||||
ArrayList<Loader> loaders = new ArrayList<>();
|
private final ArrayList<Loader> loaders = new ArrayList<>();
|
||||||
|
|
||||||
/* Map of each URL opened to its corresponding Loader */
|
/* Map of each URL opened to its corresponding Loader */
|
||||||
HashMap<String, Loader> lmap = new HashMap<>();
|
private final HashMap<String, Loader> lmap = new HashMap<>();
|
||||||
|
|
||||||
/* The jar protocol handler to use when creating new URLs */
|
/* The jar protocol handler to use when creating new URLs */
|
||||||
private URLStreamHandler jarHandler;
|
private final URLStreamHandler jarHandler;
|
||||||
|
|
||||||
/* Whether this URLClassLoader has been closed yet */
|
/* Whether this URLClassLoader has been closed yet */
|
||||||
private boolean closed = false;
|
private boolean closed = false;
|
||||||
@ -137,12 +137,16 @@ public class URLClassPath {
|
|||||||
public URLClassPath(URL[] urls,
|
public URLClassPath(URL[] urls,
|
||||||
URLStreamHandlerFactory factory,
|
URLStreamHandlerFactory factory,
|
||||||
AccessControlContext acc) {
|
AccessControlContext acc) {
|
||||||
for (int i = 0; i < urls.length; i++) {
|
List<URL> path = new ArrayList<>(urls.length);
|
||||||
path.add(urls[i]);
|
for (URL url : urls) {
|
||||||
|
path.add(url);
|
||||||
}
|
}
|
||||||
|
this.path = path;
|
||||||
push(urls);
|
push(urls);
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
jarHandler = factory.createURLStreamHandler("jar");
|
jarHandler = factory.createURLStreamHandler("jar");
|
||||||
|
} else {
|
||||||
|
jarHandler = null;
|
||||||
}
|
}
|
||||||
if (DISABLE_ACC_CHECKING)
|
if (DISABLE_ACC_CHECKING)
|
||||||
this.acc = null;
|
this.acc = null;
|
||||||
@ -150,18 +154,52 @@ public class URLClassPath {
|
|||||||
this.acc = acc;
|
this.acc = acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a URLClassPath with no additional security restrictions.
|
|
||||||
* Used by code that implements the class path.
|
|
||||||
*/
|
|
||||||
public URLClassPath(URL[] urls) {
|
|
||||||
this(urls, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public URLClassPath(URL[] urls, AccessControlContext acc) {
|
public URLClassPath(URL[] urls, AccessControlContext acc) {
|
||||||
this(urls, null, acc);
|
this(urls, null, acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a URLClassPath from a class path string.
|
||||||
|
*
|
||||||
|
* @param cp the class path string
|
||||||
|
* @param skipEmptyElements indicates if empty elements are ignored or
|
||||||
|
* treated as the current working directory
|
||||||
|
*
|
||||||
|
* @apiNote Used to create the application class path.
|
||||||
|
*/
|
||||||
|
URLClassPath(String cp, boolean skipEmptyElements) {
|
||||||
|
List<URL> path = new ArrayList<>();
|
||||||
|
if (cp != null) {
|
||||||
|
// map each element of class path to a file URL
|
||||||
|
int off = 0;
|
||||||
|
int next;
|
||||||
|
while ((next = cp.indexOf(File.pathSeparator, off)) != -1) {
|
||||||
|
String element = cp.substring(off, next);
|
||||||
|
if (element.length() > 0 || !skipEmptyElements) {
|
||||||
|
URL url = toFileURL(element);
|
||||||
|
if (url != null) path.add(url);
|
||||||
|
}
|
||||||
|
off = next + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remaining element
|
||||||
|
String element = cp.substring(off);
|
||||||
|
if (element.length() > 0 || !skipEmptyElements) {
|
||||||
|
URL url = toFileURL(element);
|
||||||
|
if (url != null) path.add(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// push the URLs
|
||||||
|
for (int i = path.size() - 1; i >= 0; --i) {
|
||||||
|
urls.push(path.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.path = path;
|
||||||
|
this.jarHandler = null;
|
||||||
|
this.acc = null;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized List<IOException> closeLoaders() {
|
public synchronized List<IOException> closeLoaders() {
|
||||||
if (closed) {
|
if (closed) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -197,6 +235,28 @@ public class URLClassPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the specified file path as a file URL to the search path.
|
||||||
|
*/
|
||||||
|
public void addFile(String s) {
|
||||||
|
URL url = toFileURL(s);
|
||||||
|
if (url != null) {
|
||||||
|
addURL(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a file URL for the given file path.
|
||||||
|
*/
|
||||||
|
private static URL toFileURL(String s) {
|
||||||
|
try {
|
||||||
|
File f = new File(s).getCanonicalFile();
|
||||||
|
return ParseUtil.fileToEncodedURL(f);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the original search path of URLs.
|
* Returns the original search path of URLs.
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
package jdk.internal.logger;
|
package jdk.internal.logger;
|
||||||
|
|
||||||
|
import jdk.internal.misc.VM;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -140,15 +142,9 @@ public class DefaultLoggerFinder extends LoggerFinder {
|
|||||||
return AccessController.doPrivileged(new PrivilegedAction<>() {
|
return AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean run() {
|
public Boolean run() {
|
||||||
final ClassLoader moduleCL = m.getClassLoader();
|
|
||||||
if (moduleCL == null) return true;
|
|
||||||
ClassLoader cl = ClassLoader.getPlatformClassLoader();
|
|
||||||
while (cl != null && moduleCL != cl) {
|
|
||||||
cl = cl.getParent();
|
|
||||||
}
|
|
||||||
// returns true if moduleCL is the platform class loader
|
// returns true if moduleCL is the platform class loader
|
||||||
// or one of its ancestors.
|
// or one of its ancestors.
|
||||||
return moduleCL == cl;
|
return VM.isSystemDomainLoader(m.getClassLoader());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -34,16 +34,10 @@ import java.lang.module.ModuleDescriptor.Requires;
|
|||||||
import java.lang.module.ModuleDescriptor.Provides;
|
import java.lang.module.ModuleDescriptor.Provides;
|
||||||
import java.lang.module.ModuleDescriptor.Version;
|
import java.lang.module.ModuleDescriptor.Version;
|
||||||
import java.lang.module.ModuleFinder;
|
import java.lang.module.ModuleFinder;
|
||||||
import java.lang.module.ModuleReader;
|
|
||||||
import java.lang.module.ModuleReference;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import jdk.internal.module.ModuleHashes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to non-public methods in java.lang.module.
|
* Provides access to non-public methods in java.lang.module.
|
||||||
@ -131,12 +125,16 @@ public interface JavaLangModuleAccess {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a collection of root modules, with service binding
|
* Resolves a collection of root modules, with service binding
|
||||||
* and the empty configuration as the parent. The post resolution
|
* and the empty configuration as the parent.
|
||||||
* checks are optionally run.
|
|
||||||
*/
|
*/
|
||||||
Configuration resolveAndBind(ModuleFinder finder,
|
Configuration resolveAndBind(ModuleFinder finder,
|
||||||
Collection<String> roots,
|
Collection<String> roots,
|
||||||
boolean check,
|
|
||||||
PrintStream traceOutput);
|
PrintStream traceOutput);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a configuration from a pre-generated readability graph.
|
||||||
|
*/
|
||||||
|
Configuration newConfiguration(ModuleFinder finder,
|
||||||
|
Map<String, Set<String>> graph);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -124,11 +124,11 @@ public class VM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given class loader is in the system domain
|
* Returns true if the given class loader is the bootstrap class loader
|
||||||
* in which all permissions are granted.
|
* or the platform class loader.
|
||||||
*/
|
*/
|
||||||
public static boolean isSystemDomainLoader(ClassLoader loader) {
|
public static boolean isSystemDomainLoader(ClassLoader loader) {
|
||||||
return loader == null;
|
return loader == null || loader == ClassLoader.getPlatformClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package jdk.internal.module;
|
||||||
|
|
||||||
|
import java.lang.module.ModuleDescriptor;
|
||||||
|
import java.lang.module.ModuleFinder;
|
||||||
|
import java.lang.module.ModuleReference;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines methods to compute the default set of root modules for the unnamed
|
||||||
|
* module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class DefaultRoots {
|
||||||
|
private static final String JAVA_SE = "java.se";
|
||||||
|
|
||||||
|
private DefaultRoots() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default set of root modules for the unnamed module computed from
|
||||||
|
* the system modules observable with the given module finder.
|
||||||
|
*/
|
||||||
|
static Set<String> compute(ModuleFinder systemModuleFinder, ModuleFinder finder) {
|
||||||
|
Set<String> roots = new HashSet<>();
|
||||||
|
|
||||||
|
boolean hasJava = false;
|
||||||
|
if (systemModuleFinder.find(JAVA_SE).isPresent()) {
|
||||||
|
if (finder == systemModuleFinder || finder.find(JAVA_SE).isPresent()) {
|
||||||
|
// java.se is a system module
|
||||||
|
hasJava = true;
|
||||||
|
roots.add(JAVA_SE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ModuleReference mref : systemModuleFinder.findAll()) {
|
||||||
|
String mn = mref.descriptor().name();
|
||||||
|
if (hasJava && mn.startsWith("java.")) {
|
||||||
|
// not a root
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModuleResolution.doNotResolveByDefault(mref)) {
|
||||||
|
// not a root
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((finder == systemModuleFinder || finder.find(mn).isPresent())) {
|
||||||
|
// add as root if exports at least one package to all modules
|
||||||
|
ModuleDescriptor descriptor = mref.descriptor();
|
||||||
|
for (ModuleDescriptor.Exports e : descriptor.exports()) {
|
||||||
|
if (!e.isQualified()) {
|
||||||
|
roots.add(mn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return roots;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default set of root modules for the unnamed module from the
|
||||||
|
* modules observable with the given module finder.
|
||||||
|
*/
|
||||||
|
public static Set<String> compute(ModuleFinder finder) {
|
||||||
|
return compute(finder, finder);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package jdk.internal.module;
|
||||||
|
|
||||||
|
import java.lang.module.ModuleDescriptor;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A dummy SystemModules for use with exploded builds or testing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ExplodedSystemModules implements SystemModules {
|
||||||
|
@Override
|
||||||
|
public boolean hasSplitPackages() {
|
||||||
|
return true; // not known
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasIncubatorModules() {
|
||||||
|
return true; // not known
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleDescriptor[] moduleDescriptors() {
|
||||||
|
throw new InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleTarget[] moduleTargets() {
|
||||||
|
throw new InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleHashes[] moduleHashes() {
|
||||||
|
throw new InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleResolution[] moduleResolutions() {
|
||||||
|
throw new InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Set<String>> moduleReads() {
|
||||||
|
throw new InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Set<String>> concealedPackagesToOpen() {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Set<String>> exportedPackagesToOpen() {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
}
|
@ -40,16 +40,20 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import jdk.internal.loader.BootLoader;
|
import jdk.internal.loader.BootLoader;
|
||||||
import jdk.internal.loader.BuiltinClassLoader;
|
import jdk.internal.loader.BuiltinClassLoader;
|
||||||
import jdk.internal.misc.JavaLangAccess;
|
import jdk.internal.misc.JavaLangAccess;
|
||||||
|
import jdk.internal.misc.JavaLangModuleAccess;
|
||||||
import jdk.internal.misc.SharedSecrets;
|
import jdk.internal.misc.SharedSecrets;
|
||||||
import jdk.internal.perf.PerfCounter;
|
import jdk.internal.perf.PerfCounter;
|
||||||
|
|
||||||
@ -70,8 +74,6 @@ public final class ModuleBootstrap {
|
|||||||
|
|
||||||
private static final String JAVA_BASE = "java.base";
|
private static final String JAVA_BASE = "java.base";
|
||||||
|
|
||||||
private static final String JAVA_SE = "java.se";
|
|
||||||
|
|
||||||
// the token for "all default modules"
|
// the token for "all default modules"
|
||||||
private static final String ALL_DEFAULT = "ALL-DEFAULT";
|
private static final String ALL_DEFAULT = "ALL-DEFAULT";
|
||||||
|
|
||||||
@ -84,13 +86,13 @@ public final class ModuleBootstrap {
|
|||||||
// the token for "all modules on the module path"
|
// the token for "all modules on the module path"
|
||||||
private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
|
private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
|
||||||
|
|
||||||
|
// access to java.lang/module
|
||||||
|
private static final JavaLangModuleAccess JLMA
|
||||||
|
= SharedSecrets.getJavaLangModuleAccess();
|
||||||
|
|
||||||
// The ModulePatcher for the initial configuration
|
// The ModulePatcher for the initial configuration
|
||||||
private static final ModulePatcher patcher = initModulePatcher();
|
private static final ModulePatcher patcher = initModulePatcher();
|
||||||
|
|
||||||
// ModuleFinders for the initial configuration
|
|
||||||
private static ModuleFinder unlimitedFinder;
|
|
||||||
private static ModuleFinder limitedFinder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ModulePatcher for the initial configuration.
|
* Returns the ModulePatcher for the initial configuration.
|
||||||
*/
|
*/
|
||||||
@ -98,21 +100,38 @@ public final class ModuleBootstrap {
|
|||||||
return patcher;
|
return patcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ModuleFinders for the initial configuration
|
||||||
|
private static volatile ModuleFinder unlimitedFinder;
|
||||||
|
private static volatile ModuleFinder limitedFinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ModuleFinder for the initial configuration before observability
|
* Returns the ModuleFinder for the initial configuration before
|
||||||
* is limited by the --limit-modules command line option.
|
* observability is limited by the --limit-modules command line option.
|
||||||
|
*
|
||||||
|
* @apiNote Used to support locating modules {@code java.instrument} and
|
||||||
|
* {@code jdk.management.agent} modules when they are loaded dynamically.
|
||||||
*/
|
*/
|
||||||
public static ModuleFinder unlimitedFinder() {
|
public static ModuleFinder unlimitedFinder() {
|
||||||
assert unlimitedFinder != null;
|
ModuleFinder finder = unlimitedFinder;
|
||||||
return unlimitedFinder;
|
if (finder == null) {
|
||||||
|
return ModuleFinder.ofSystem();
|
||||||
|
} else {
|
||||||
|
return finder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ModuleFinder for the initial configuration.
|
* Returns the ModuleFinder for the initial configuration.
|
||||||
|
*
|
||||||
|
* @apiNote Used to support "{@code java --list-modules}".
|
||||||
*/
|
*/
|
||||||
public static ModuleFinder limitedFinder() {
|
public static ModuleFinder limitedFinder() {
|
||||||
assert limitedFinder != null;
|
ModuleFinder finder = limitedFinder;
|
||||||
return limitedFinder;
|
if (finder == null) {
|
||||||
|
return unlimitedFinder();
|
||||||
|
} else {
|
||||||
|
return finder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,13 +139,60 @@ public final class ModuleBootstrap {
|
|||||||
*
|
*
|
||||||
* @see java.lang.System#initPhase2()
|
* @see java.lang.System#initPhase2()
|
||||||
*/
|
*/
|
||||||
public static ModuleLayer boot() {
|
public static ModuleLayer boot() throws Exception {
|
||||||
|
|
||||||
// Step 1: Locate system modules (may be patched)
|
// Step 0: Command line options
|
||||||
|
|
||||||
|
long t0 = System.nanoTime();
|
||||||
|
|
||||||
|
ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
|
||||||
|
ModuleFinder appModulePath = finderFor("jdk.module.path");
|
||||||
|
boolean isPatched = patcher.hasPatches();
|
||||||
|
|
||||||
|
String mainModule = System.getProperty("jdk.module.main");
|
||||||
|
Set<String> addModules = addModules();
|
||||||
|
Set<String> limitModules = limitModules();
|
||||||
|
|
||||||
|
PrintStream traceOutput = null;
|
||||||
|
String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
|
||||||
|
if (trace != null && Boolean.parseBoolean(trace))
|
||||||
|
traceOutput = System.out;
|
||||||
|
|
||||||
|
|
||||||
|
// Step 1: The observable system modules, either all system modules
|
||||||
|
// or the system modules pre-generated for the initial module (the
|
||||||
|
// initial module may be the unnamed module). If the system modules
|
||||||
|
// are pre-generated for the initial module then resolution can be
|
||||||
|
// skipped.
|
||||||
|
|
||||||
long t1 = System.nanoTime();
|
long t1 = System.nanoTime();
|
||||||
ModuleFinder systemModules = ModuleFinder.ofSystem();
|
|
||||||
PerfCounters.systemModulesTime.addElapsedTimeFrom(t1);
|
SystemModules systemModules = null;
|
||||||
|
ModuleFinder systemModuleFinder;
|
||||||
|
|
||||||
|
boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
|
||||||
|
boolean needResolution = true;
|
||||||
|
|
||||||
|
if (!haveModulePath && addModules.isEmpty() && limitModules.isEmpty()) {
|
||||||
|
systemModules = SystemModuleFinders.systemModules(mainModule);
|
||||||
|
if (systemModules != null && !isPatched && (traceOutput == null)) {
|
||||||
|
needResolution = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (systemModules == null) {
|
||||||
|
// all system modules are observable
|
||||||
|
systemModules = SystemModuleFinders.allSystemModules();
|
||||||
|
}
|
||||||
|
if (systemModules != null) {
|
||||||
|
// images build
|
||||||
|
systemModuleFinder = SystemModuleFinders.of(systemModules);
|
||||||
|
} else {
|
||||||
|
// exploded build or testing
|
||||||
|
systemModules = new ExplodedSystemModules();
|
||||||
|
systemModuleFinder = SystemModuleFinders.ofSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
Counters.add("jdk.module.boot.1.systemModulesTime", t1);
|
||||||
|
|
||||||
|
|
||||||
// Step 2: Define and load java.base. This patches all classes loaded
|
// Step 2: Define and load java.base. This patches all classes loaded
|
||||||
@ -136,7 +202,7 @@ public final class ModuleBootstrap {
|
|||||||
|
|
||||||
long t2 = System.nanoTime();
|
long t2 = System.nanoTime();
|
||||||
|
|
||||||
ModuleReference base = systemModules.find(JAVA_BASE).orElse(null);
|
ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
|
||||||
if (base == null)
|
if (base == null)
|
||||||
throw new InternalError(JAVA_BASE + " not found");
|
throw new InternalError(JAVA_BASE + " not found");
|
||||||
URI baseUri = base.location().orElse(null);
|
URI baseUri = base.location().orElse(null);
|
||||||
@ -145,171 +211,138 @@ public final class ModuleBootstrap {
|
|||||||
BootLoader.loadModule(base);
|
BootLoader.loadModule(base);
|
||||||
Modules.defineModule(null, base.descriptor(), baseUri);
|
Modules.defineModule(null, base.descriptor(), baseUri);
|
||||||
|
|
||||||
PerfCounters.defineBaseTime.addElapsedTimeFrom(t2);
|
Counters.add("jdk.module.boot.2.defineBaseTime", t2);
|
||||||
|
|
||||||
|
|
||||||
// Step 2a: If --validate-modules is specified then the VM needs to
|
// Step 2a: If --validate-modules is specified then the VM needs to
|
||||||
// start with only java.base, all other options are ignored.
|
// start with only java.base, all other options are ignored.
|
||||||
|
|
||||||
String propValue = getAndRemoveProperty("jdk.module.minimumBoot");
|
if (getAndRemoveProperty("jdk.module.minimumBoot") != null) {
|
||||||
if (propValue != null) {
|
|
||||||
return createMinimalBootLayer();
|
return createMinimalBootLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Step 3: Construct the module path and the set of root modules to
|
// Step 3: If resolution is needed then create the module finder and
|
||||||
// resolve. If --limit-modules is specified then it limits the set
|
// the set of root modules to resolve.
|
||||||
// modules that are observable.
|
|
||||||
|
|
||||||
long t3 = System.nanoTime();
|
long t3 = System.nanoTime();
|
||||||
|
|
||||||
// --upgrade-module-path option specified to launcher
|
ModuleFinder savedModuleFinder = null;
|
||||||
ModuleFinder upgradeModulePath
|
ModuleFinder finder;
|
||||||
= createModulePathFinder("jdk.module.upgrade.path");
|
Set<String> roots;
|
||||||
if (upgradeModulePath != null)
|
if (needResolution) {
|
||||||
systemModules = ModuleFinder.compose(upgradeModulePath, systemModules);
|
|
||||||
|
|
||||||
// --module-path option specified to the launcher
|
// upgraded modules override the modules in the run-time image
|
||||||
ModuleFinder appModulePath = createModulePathFinder("jdk.module.path");
|
if (upgradeModulePath != null)
|
||||||
|
systemModuleFinder = ModuleFinder.compose(upgradeModulePath,
|
||||||
|
systemModuleFinder);
|
||||||
|
|
||||||
// The module finder: [--upgrade-module-path] system [--module-path]
|
// The module finder: [--upgrade-module-path] system [--module-path]
|
||||||
ModuleFinder finder = systemModules;
|
if (appModulePath != null) {
|
||||||
if (appModulePath != null)
|
finder = ModuleFinder.compose(systemModuleFinder, appModulePath);
|
||||||
finder = ModuleFinder.compose(finder, appModulePath);
|
} else {
|
||||||
|
finder = systemModuleFinder;
|
||||||
// The root modules to resolve
|
|
||||||
Set<String> roots = new HashSet<>();
|
|
||||||
|
|
||||||
// launcher -m option to specify the main/initial module
|
|
||||||
String mainModule = System.getProperty("jdk.module.main");
|
|
||||||
if (mainModule != null)
|
|
||||||
roots.add(mainModule);
|
|
||||||
|
|
||||||
// additional module(s) specified by --add-modules
|
|
||||||
boolean addAllDefaultModules = false;
|
|
||||||
boolean addAllSystemModules = false;
|
|
||||||
boolean addAllApplicationModules = false;
|
|
||||||
for (String mod: getExtraAddModules()) {
|
|
||||||
switch (mod) {
|
|
||||||
case ALL_DEFAULT:
|
|
||||||
addAllDefaultModules = true;
|
|
||||||
break;
|
|
||||||
case ALL_SYSTEM:
|
|
||||||
addAllSystemModules = true;
|
|
||||||
break;
|
|
||||||
case ALL_MODULE_PATH:
|
|
||||||
addAllApplicationModules = true;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
roots.add(mod);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// --limit-modules
|
// The root modules to resolve
|
||||||
unlimitedFinder = finder;
|
roots = new HashSet<>();
|
||||||
propValue = getAndRemoveProperty("jdk.module.limitmods");
|
|
||||||
if (propValue != null) {
|
|
||||||
Set<String> mods = new HashSet<>();
|
|
||||||
for (String mod: propValue.split(",")) {
|
|
||||||
mods.add(mod);
|
|
||||||
}
|
|
||||||
finder = limitFinder(finder, mods, roots);
|
|
||||||
}
|
|
||||||
limitedFinder = finder;
|
|
||||||
|
|
||||||
// If there is no initial module specified then assume that the initial
|
// launcher -m option to specify the main/initial module
|
||||||
// module is the unnamed module of the application class loader. This
|
if (mainModule != null)
|
||||||
// is implemented by resolving "java.se" and all (non-java.*) modules
|
roots.add(mainModule);
|
||||||
// that export an API. If "java.se" is not observable then all java.*
|
|
||||||
// modules are resolved. Modules that have the DO_NOT_RESOLVE_BY_DEFAULT
|
// additional module(s) specified by --add-modules
|
||||||
// bit set in their ModuleResolution attribute flags are excluded from
|
boolean addAllDefaultModules = false;
|
||||||
// the default set of roots.
|
boolean addAllSystemModules = false;
|
||||||
if (mainModule == null || addAllDefaultModules) {
|
boolean addAllApplicationModules = false;
|
||||||
boolean hasJava = false;
|
for (String mod : addModules) {
|
||||||
if (systemModules.find(JAVA_SE).isPresent()) {
|
switch (mod) {
|
||||||
// java.se is a system module
|
case ALL_DEFAULT:
|
||||||
if (finder == systemModules || finder.find(JAVA_SE).isPresent()) {
|
addAllDefaultModules = true;
|
||||||
// java.se is observable
|
break;
|
||||||
hasJava = true;
|
case ALL_SYSTEM:
|
||||||
roots.add(JAVA_SE);
|
addAllSystemModules = true;
|
||||||
|
break;
|
||||||
|
case ALL_MODULE_PATH:
|
||||||
|
addAllApplicationModules = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
roots.add(mod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ModuleReference mref : systemModules.findAll()) {
|
// --limit-modules
|
||||||
String mn = mref.descriptor().name();
|
savedModuleFinder = finder;
|
||||||
if (hasJava && mn.startsWith("java."))
|
if (!limitModules.isEmpty()) {
|
||||||
continue;
|
finder = limitFinder(finder, limitModules, roots);
|
||||||
|
|
||||||
if (ModuleResolution.doNotResolveByDefault(mref))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// add as root if observable and exports at least one package
|
|
||||||
if ((finder == systemModules || finder.find(mn).isPresent())) {
|
|
||||||
ModuleDescriptor descriptor = mref.descriptor();
|
|
||||||
for (ModuleDescriptor.Exports e : descriptor.exports()) {
|
|
||||||
if (!e.isQualified()) {
|
|
||||||
roots.add(mn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is no initial module specified then assume that the initial
|
||||||
|
// module is the unnamed module of the application class loader. This
|
||||||
|
// is implemented by resolving "java.se" and all (non-java.*) modules
|
||||||
|
// that export an API. If "java.se" is not observable then all java.*
|
||||||
|
// modules are resolved. Modules that have the DO_NOT_RESOLVE_BY_DEFAULT
|
||||||
|
// bit set in their ModuleResolution attribute flags are excluded from
|
||||||
|
// the default set of roots.
|
||||||
|
if (mainModule == null || addAllDefaultModules) {
|
||||||
|
roots.addAll(DefaultRoots.compute(systemModuleFinder, finder));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `--add-modules ALL-SYSTEM` is specified then all observable system
|
||||||
|
// modules will be resolved.
|
||||||
|
if (addAllSystemModules) {
|
||||||
|
ModuleFinder f = finder; // observable modules
|
||||||
|
systemModuleFinder.findAll()
|
||||||
|
.stream()
|
||||||
|
.map(ModuleReference::descriptor)
|
||||||
|
.map(ModuleDescriptor::name)
|
||||||
|
.filter(mn -> f.find(mn).isPresent()) // observable
|
||||||
|
.forEach(mn -> roots.add(mn));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `--add-modules ALL-MODULE-PATH` is specified then all observable
|
||||||
|
// modules on the application module path will be resolved.
|
||||||
|
if (appModulePath != null && addAllApplicationModules) {
|
||||||
|
ModuleFinder f = finder; // observable modules
|
||||||
|
appModulePath.findAll()
|
||||||
|
.stream()
|
||||||
|
.map(ModuleReference::descriptor)
|
||||||
|
.map(ModuleDescriptor::name)
|
||||||
|
.filter(mn -> f.find(mn).isPresent()) // observable
|
||||||
|
.forEach(mn -> roots.add(mn));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no resolution case
|
||||||
|
finder = systemModuleFinder;
|
||||||
|
roots = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If `--add-modules ALL-SYSTEM` is specified then all observable system
|
Counters.add("jdk.module.boot.3.optionsAndRootsTime", t3);
|
||||||
// modules will be resolved.
|
|
||||||
if (addAllSystemModules) {
|
|
||||||
ModuleFinder f = finder; // observable modules
|
|
||||||
systemModules.findAll()
|
|
||||||
.stream()
|
|
||||||
.map(ModuleReference::descriptor)
|
|
||||||
.map(ModuleDescriptor::name)
|
|
||||||
.filter(mn -> f.find(mn).isPresent()) // observable
|
|
||||||
.forEach(mn -> roots.add(mn));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If `--add-modules ALL-MODULE-PATH` is specified then all observable
|
|
||||||
// modules on the application module path will be resolved.
|
|
||||||
if (appModulePath != null && addAllApplicationModules) {
|
|
||||||
ModuleFinder f = finder; // observable modules
|
|
||||||
appModulePath.findAll()
|
|
||||||
.stream()
|
|
||||||
.map(ModuleReference::descriptor)
|
|
||||||
.map(ModuleDescriptor::name)
|
|
||||||
.filter(mn -> f.find(mn).isPresent()) // observable
|
|
||||||
.forEach(mn -> roots.add(mn));
|
|
||||||
}
|
|
||||||
|
|
||||||
PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t3);
|
|
||||||
|
|
||||||
|
|
||||||
// Step 4: Resolve the root modules, with service binding, to create
|
// Step 4: Resolve the root modules, with service binding, to create
|
||||||
// the configuration for the boot layer.
|
// the configuration for the boot layer. If resolution is not needed
|
||||||
|
// then create the configuration for the boot layer from the
|
||||||
|
// readability graph created at link time.
|
||||||
|
|
||||||
long t4 = System.nanoTime();
|
long t4 = System.nanoTime();
|
||||||
|
|
||||||
// determine if post resolution checks are needed
|
Configuration cf;
|
||||||
boolean needPostResolutionChecks = true;
|
if (needResolution) {
|
||||||
if (baseUri.getScheme().equals("jrt") // toLowerCase not needed here
|
cf = JLMA.resolveAndBind(finder, roots, traceOutput);
|
||||||
&& (upgradeModulePath == null)
|
} else {
|
||||||
&& (appModulePath == null)
|
Map<String, Set<String>> map = systemModules.moduleReads();
|
||||||
&& (patcher.isEmpty())) {
|
cf = JLMA.newConfiguration(systemModuleFinder, map);
|
||||||
needPostResolutionChecks = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintStream traceOutput = null;
|
// check that modules specified to --patch-module are resolved
|
||||||
propValue = getAndRemoveProperty("jdk.module.showModuleResolution");
|
if (isPatched) {
|
||||||
if (propValue != null && Boolean.parseBoolean(propValue))
|
patcher.patchedModules()
|
||||||
traceOutput = System.out;
|
.stream()
|
||||||
|
.filter(mn -> !cf.findModule(mn).isPresent())
|
||||||
|
.forEach(mn -> warnUnknownModule(PATCH_MODULE, mn));
|
||||||
|
}
|
||||||
|
|
||||||
// run the resolver to create the configuration
|
Counters.add("jdk.module.boot.4.resolveTime", t4);
|
||||||
Configuration cf = SharedSecrets.getJavaLangModuleAccess()
|
|
||||||
.resolveAndBind(finder,
|
|
||||||
roots,
|
|
||||||
needPostResolutionChecks,
|
|
||||||
traceOutput);
|
|
||||||
|
|
||||||
PerfCounters.resolveTime.addElapsedTimeFrom(t4);
|
|
||||||
|
|
||||||
|
|
||||||
// Step 5: Map the modules in the configuration to class loaders.
|
// Step 5: Map the modules in the configuration to class loaders.
|
||||||
@ -326,7 +359,7 @@ public final class ModuleBootstrap {
|
|||||||
|
|
||||||
// check that all modules to be mapped to the boot loader will be
|
// check that all modules to be mapped to the boot loader will be
|
||||||
// loaded from the runtime image
|
// loaded from the runtime image
|
||||||
if (needPostResolutionChecks) {
|
if (haveModulePath) {
|
||||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||||
ModuleReference mref = resolvedModule.reference();
|
ModuleReference mref = resolvedModule.reference();
|
||||||
String name = mref.descriptor().name();
|
String name = mref.descriptor().name();
|
||||||
@ -335,51 +368,54 @@ public final class ModuleBootstrap {
|
|||||||
if (upgradeModulePath != null
|
if (upgradeModulePath != null
|
||||||
&& upgradeModulePath.find(name).isPresent())
|
&& upgradeModulePath.find(name).isPresent())
|
||||||
fail(name + ": cannot be loaded from upgrade module path");
|
fail(name + ": cannot be loaded from upgrade module path");
|
||||||
if (!systemModules.find(name).isPresent())
|
if (!systemModuleFinder.find(name).isPresent())
|
||||||
fail(name + ": cannot be loaded from application module path");
|
fail(name + ": cannot be loaded from application module path");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if module specified in --patch-module is present
|
|
||||||
for (String mn: patcher.patchedModules()) {
|
|
||||||
if (!cf.findModule(mn).isPresent()) {
|
|
||||||
warnUnknownModule(PATCH_MODULE, mn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for split packages in the modules mapped to the built-in loaders
|
// check for split packages in the modules mapped to the built-in loaders
|
||||||
if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
|
if (systemModules.hasSplitPackages() || isPatched || haveModulePath) {
|
||||||
checkSplitPackages(cf, clf);
|
checkSplitPackages(cf, clf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load/register the modules with the built-in class loaders
|
// load/register the modules with the built-in class loaders
|
||||||
loadModules(cf, clf);
|
loadModules(cf, clf);
|
||||||
|
|
||||||
PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
|
Counters.add("jdk.module.boot.5.loadModulesTime", t5);
|
||||||
|
|
||||||
|
|
||||||
// Step 6: Define all modules to the VM
|
// Step 6: Define all modules to the VM
|
||||||
|
|
||||||
long t6 = System.nanoTime();
|
long t6 = System.nanoTime();
|
||||||
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
|
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
|
||||||
PerfCounters.layerCreateTime.addElapsedTimeFrom(t6);
|
Counters.add("jdk.module.boot.6.layerCreateTime", t6);
|
||||||
|
|
||||||
|
|
||||||
// Step 7: Miscellaneous
|
// Step 7: Miscellaneous
|
||||||
|
|
||||||
// check incubating status
|
// check incubating status
|
||||||
checkIncubatingStatus(cf);
|
if (systemModules.hasIncubatorModules() || haveModulePath) {
|
||||||
|
checkIncubatingStatus(cf);
|
||||||
|
}
|
||||||
|
|
||||||
// --add-reads, --add-exports/--add-opens, and -illegal-access
|
// --add-reads, --add-exports/--add-opens, and --illegal-access
|
||||||
long t7 = System.nanoTime();
|
long t7 = System.nanoTime();
|
||||||
addExtraReads(bootLayer);
|
addExtraReads(bootLayer);
|
||||||
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
|
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
|
||||||
addIllegalAccess(bootLayer, upgradeModulePath, extraExportsOrOpens);
|
addIllegalAccess(upgradeModulePath, systemModules, bootLayer, extraExportsOrOpens);
|
||||||
PerfCounters.adjustModulesTime.addElapsedTimeFrom(t7);
|
Counters.add("jdk.module.boot.7.adjustModulesTime", t7);
|
||||||
|
|
||||||
|
// save module finders for later use
|
||||||
|
if (savedModuleFinder != null) {
|
||||||
|
unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
|
||||||
|
if (savedModuleFinder != finder)
|
||||||
|
limitedFinder = new SafeModuleFinder(finder);
|
||||||
|
}
|
||||||
|
|
||||||
// total time to initialize
|
// total time to initialize
|
||||||
PerfCounters.bootstrapTime.addElapsedTimeFrom(t1);
|
Counters.add("jdk.module.boot.totalTime", t0);
|
||||||
|
Counters.publish();
|
||||||
|
|
||||||
return bootLayer;
|
return bootLayer;
|
||||||
}
|
}
|
||||||
@ -391,7 +427,6 @@ public final class ModuleBootstrap {
|
|||||||
Configuration cf = SharedSecrets.getJavaLangModuleAccess()
|
Configuration cf = SharedSecrets.getJavaLangModuleAccess()
|
||||||
.resolveAndBind(ModuleFinder.ofSystem(),
|
.resolveAndBind(ModuleFinder.ofSystem(),
|
||||||
Set.of(JAVA_BASE),
|
Set.of(JAVA_BASE),
|
||||||
false,
|
|
||||||
null);
|
null);
|
||||||
|
|
||||||
Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
|
Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
|
||||||
@ -439,7 +474,6 @@ public final class ModuleBootstrap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,7 +523,7 @@ public final class ModuleBootstrap {
|
|||||||
* Creates a finder from the module path that is the value of the given
|
* Creates a finder from the module path that is the value of the given
|
||||||
* system property and optionally patched by --patch-module
|
* system property and optionally patched by --patch-module
|
||||||
*/
|
*/
|
||||||
private static ModuleFinder createModulePathFinder(String prop) {
|
private static ModuleFinder finderFor(String prop) {
|
||||||
String s = System.getProperty(prop);
|
String s = System.getProperty(prop);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -510,35 +544,48 @@ public final class ModuleBootstrap {
|
|||||||
*/
|
*/
|
||||||
private static ModulePatcher initModulePatcher() {
|
private static ModulePatcher initModulePatcher() {
|
||||||
Map<String, List<String>> map = decode("jdk.module.patch.",
|
Map<String, List<String>> map = decode("jdk.module.patch.",
|
||||||
File.pathSeparator,
|
File.pathSeparator,
|
||||||
false);
|
false);
|
||||||
return new ModulePatcher(map);
|
return new ModulePatcher(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the set of module names specified via --add-modules options
|
* Returns the set of module names specified by --add-module options.
|
||||||
* on the command line
|
|
||||||
*/
|
*/
|
||||||
private static Set<String> getExtraAddModules() {
|
private static Set<String> addModules() {
|
||||||
String prefix = "jdk.module.addmods.";
|
String prefix = "jdk.module.addmods.";
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
// the system property is removed after decoding
|
// the system property is removed after decoding
|
||||||
String value = getAndRemoveProperty(prefix + index);
|
String value = getAndRemoveProperty(prefix + index);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
} else {
|
||||||
|
Set<String> modules = new HashSet<>();
|
||||||
Set<String> modules = new HashSet<>();
|
while (value != null) {
|
||||||
while (value != null) {
|
for (String s : value.split(",")) {
|
||||||
for (String s : value.split(",")) {
|
if (s.length() > 0) modules.add(s);
|
||||||
if (s.length() > 0) modules.add(s);
|
}
|
||||||
|
index++;
|
||||||
|
value = getAndRemoveProperty(prefix + index);
|
||||||
}
|
}
|
||||||
index++;
|
return modules;
|
||||||
value = getAndRemoveProperty(prefix + index);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return modules;
|
/**
|
||||||
|
* Returns the set of module names specified by --limit-modules.
|
||||||
|
*/
|
||||||
|
private static Set<String> limitModules() {
|
||||||
|
String value = getAndRemoveProperty("jdk.module.limitmods");
|
||||||
|
if (value == null) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
} else {
|
||||||
|
Set<String> names = new HashSet<>();
|
||||||
|
for (String name : value.split(",")) {
|
||||||
|
if (name.length() > 0) names.add(name);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -676,8 +723,9 @@ public final class ModuleBootstrap {
|
|||||||
* Process the --illegal-access option (and its default) to open packages
|
* Process the --illegal-access option (and its default) to open packages
|
||||||
* of system modules in the boot layer to code in unnamed modules.
|
* of system modules in the boot layer to code in unnamed modules.
|
||||||
*/
|
*/
|
||||||
private static void addIllegalAccess(ModuleLayer bootLayer,
|
private static void addIllegalAccess(ModuleFinder upgradeModulePath,
|
||||||
ModuleFinder upgradeModulePath,
|
SystemModules systemModules,
|
||||||
|
ModuleLayer bootLayer,
|
||||||
boolean extraExportsOrOpens) {
|
boolean extraExportsOrOpens) {
|
||||||
String value = getAndRemoveProperty("jdk.module.illegalAccess");
|
String value = getAndRemoveProperty("jdk.module.illegalAccess");
|
||||||
IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
|
IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
|
||||||
@ -702,10 +750,10 @@ public final class ModuleBootstrap {
|
|||||||
IllegalAccessLogger.Builder builder
|
IllegalAccessLogger.Builder builder
|
||||||
= new IllegalAccessLogger.Builder(mode, System.err);
|
= new IllegalAccessLogger.Builder(mode, System.err);
|
||||||
|
|
||||||
Map<String, Set<String>> map1 = SystemModules.concealedPackagesToOpen();
|
Map<String, Set<String>> map1 = systemModules.concealedPackagesToOpen();
|
||||||
Map<String, Set<String>> map2 = SystemModules.exportedPackagesToOpen();
|
Map<String, Set<String>> map2 = systemModules.exportedPackagesToOpen();
|
||||||
if (map1.isEmpty() && map2.isEmpty()) {
|
if (map1.isEmpty() && map2.isEmpty()) {
|
||||||
// need to generate maps when on exploded build
|
// need to generate (exploded build)
|
||||||
IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
|
IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
|
||||||
map1 = maps.concealedPackagesToOpen();
|
map1 = maps.concealedPackagesToOpen();
|
||||||
map2 = maps.exportedPackagesToOpen();
|
map2 = maps.exportedPackagesToOpen();
|
||||||
@ -906,6 +954,10 @@ public final class ModuleBootstrap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator that yields all elements of the first iterator
|
||||||
|
* followed by all the elements of the second iterator.
|
||||||
|
*/
|
||||||
static <T> Iterator<T> concat(Iterator<T> iterator1, Iterator<T> iterator2) {
|
static <T> Iterator<T> concat(Iterator<T> iterator1, Iterator<T> iterator2) {
|
||||||
return new Iterator<T>() {
|
return new Iterator<T>() {
|
||||||
@Override
|
@Override
|
||||||
@ -921,23 +973,76 @@ public final class ModuleBootstrap {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static class PerfCounters {
|
/**
|
||||||
|
* Wraps a (potentially not thread safe) ModuleFinder created during startup
|
||||||
|
* for use after startup.
|
||||||
|
*/
|
||||||
|
static class SafeModuleFinder implements ModuleFinder {
|
||||||
|
private final Set<ModuleReference> mrefs;
|
||||||
|
private volatile Map<String, ModuleReference> nameToModule;
|
||||||
|
|
||||||
static PerfCounter systemModulesTime
|
SafeModuleFinder(ModuleFinder finder) {
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.systemModulesTime");
|
this.mrefs = Collections.unmodifiableSet(finder.findAll());
|
||||||
static PerfCounter defineBaseTime
|
}
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.defineBaseTime");
|
@Override
|
||||||
static PerfCounter optionsAndRootsTime
|
public Optional<ModuleReference> find(String name) {
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.optionsAndRootsTime");
|
Objects.requireNonNull(name);
|
||||||
static PerfCounter resolveTime
|
Map<String, ModuleReference> nameToModule = this.nameToModule;
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.resolveTime");
|
if (nameToModule == null) {
|
||||||
static PerfCounter layerCreateTime
|
this.nameToModule = nameToModule = mrefs.stream()
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.layerCreateTime");
|
.collect(Collectors.toMap(m -> m.descriptor().name(),
|
||||||
static PerfCounter loadModulesTime
|
Function.identity()));
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.loadModulesTime");
|
}
|
||||||
static PerfCounter adjustModulesTime
|
return Optional.ofNullable(nameToModule.get(name));
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.adjustModulesTime");
|
}
|
||||||
static PerfCounter bootstrapTime
|
@Override
|
||||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.totalTime");
|
public Set<ModuleReference> findAll() {
|
||||||
|
return mrefs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counters for startup performance analysis.
|
||||||
|
*/
|
||||||
|
static class Counters {
|
||||||
|
private static final boolean PUBLISH_COUNTERS;
|
||||||
|
private static final boolean PRINT_COUNTERS;
|
||||||
|
private static Map<String, Long> counters;
|
||||||
|
static {
|
||||||
|
String s = System.getProperty("jdk.module.boot.usePerfData");
|
||||||
|
if (s == null) {
|
||||||
|
PUBLISH_COUNTERS = false;
|
||||||
|
PRINT_COUNTERS = false;
|
||||||
|
} else {
|
||||||
|
PUBLISH_COUNTERS = true;
|
||||||
|
PRINT_COUNTERS = s.equals("debug");
|
||||||
|
counters = new LinkedHashMap<>(); // preserve insert order
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a counter
|
||||||
|
*/
|
||||||
|
static void add(String name, long start) {
|
||||||
|
if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
|
||||||
|
counters.put(name, (System.nanoTime() - start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish the counters to the instrumentation buffer or stdout.
|
||||||
|
*/
|
||||||
|
static void publish() {
|
||||||
|
if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
|
||||||
|
for (Map.Entry<String, Long> e : counters.entrySet()) {
|
||||||
|
String name = e.getKey();
|
||||||
|
long value = e.getValue();
|
||||||
|
if (PUBLISH_COUNTERS)
|
||||||
|
PerfCounter.newPerfCounter(name).set(value);
|
||||||
|
if (PRINT_COUNTERS)
|
||||||
|
System.out.println(name + " = " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,10 +200,10 @@ public final class ModulePatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true is this module patcher has no patches.
|
* Returns true is this module patcher has patches.
|
||||||
*/
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean hasPatches() {
|
||||||
return map.isEmpty();
|
return !map.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -68,14 +68,14 @@ public class ModuleReferenceImpl extends ModuleReference {
|
|||||||
/**
|
/**
|
||||||
* Constructs a new instance of this class.
|
* Constructs a new instance of this class.
|
||||||
*/
|
*/
|
||||||
ModuleReferenceImpl(ModuleDescriptor descriptor,
|
public ModuleReferenceImpl(ModuleDescriptor descriptor,
|
||||||
URI location,
|
URI location,
|
||||||
Supplier<ModuleReader> readerSupplier,
|
Supplier<ModuleReader> readerSupplier,
|
||||||
ModulePatcher patcher,
|
ModulePatcher patcher,
|
||||||
ModuleTarget target,
|
ModuleTarget target,
|
||||||
ModuleHashes recordedHashes,
|
ModuleHashes recordedHashes,
|
||||||
ModuleHashes.HashSupplier hasher,
|
ModuleHashes.HashSupplier hasher,
|
||||||
ModuleResolution moduleResolution)
|
ModuleResolution moduleResolution)
|
||||||
{
|
{
|
||||||
super(descriptor, Objects.requireNonNull(location));
|
super(descriptor, Objects.requireNonNull(location));
|
||||||
this.location = location;
|
this.location = location;
|
||||||
|
@ -1,469 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package jdk.internal.module;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UncheckedIOException;
|
|
||||||
import java.lang.module.ModuleDescriptor;
|
|
||||||
import java.lang.module.ModuleFinder;
|
|
||||||
import java.lang.module.ModuleReader;
|
|
||||||
import java.lang.module.ModuleReference;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Deque;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Spliterator;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import jdk.internal.jimage.ImageLocation;
|
|
||||||
import jdk.internal.jimage.ImageReader;
|
|
||||||
import jdk.internal.jimage.ImageReaderFactory;
|
|
||||||
import jdk.internal.misc.JavaNetUriAccess;
|
|
||||||
import jdk.internal.misc.SharedSecrets;
|
|
||||||
import jdk.internal.module.ModuleHashes.HashSupplier;
|
|
||||||
import jdk.internal.perf.PerfCounter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@code ModuleFinder} that finds modules that are linked into the
|
|
||||||
* run-time image.
|
|
||||||
*
|
|
||||||
* The modules linked into the run-time image are assumed to have the
|
|
||||||
* Packages attribute.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class SystemModuleFinder implements ModuleFinder {
|
|
||||||
|
|
||||||
private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
|
|
||||||
|
|
||||||
private static final PerfCounter initTime
|
|
||||||
= PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");
|
|
||||||
private static final PerfCounter moduleCount
|
|
||||||
= PerfCounter.newPerfCounter("jdk.module.finder.jimage.modules");
|
|
||||||
private static final PerfCounter packageCount
|
|
||||||
= PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
|
|
||||||
private static final PerfCounter exportsCount
|
|
||||||
= PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
|
|
||||||
|
|
||||||
// singleton finder to find modules in the run-time images
|
|
||||||
private static final SystemModuleFinder INSTANCE;
|
|
||||||
|
|
||||||
public static SystemModuleFinder getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For now, the module references are created eagerly on the assumption
|
|
||||||
* that service binding will require all modules to be located.
|
|
||||||
*/
|
|
||||||
static {
|
|
||||||
long t0 = System.nanoTime();
|
|
||||||
|
|
||||||
INSTANCE = new SystemModuleFinder();
|
|
||||||
|
|
||||||
initTime.addElapsedTimeFrom(t0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holder class for the ImageReader
|
|
||||||
*/
|
|
||||||
private static class SystemImage {
|
|
||||||
static final ImageReader READER;
|
|
||||||
static {
|
|
||||||
long t0 = System.nanoTime();
|
|
||||||
READER = ImageReaderFactory.getImageReader();
|
|
||||||
initTime.addElapsedTimeFrom(t0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImageReader reader() {
|
|
||||||
return READER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isFastPathSupported() {
|
|
||||||
return SystemModules.MODULE_NAMES.length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] moduleNames() {
|
|
||||||
if (isFastPathSupported())
|
|
||||||
// module names recorded at link time
|
|
||||||
return SystemModules.MODULE_NAMES;
|
|
||||||
|
|
||||||
// this happens when java.base is patched with java.base
|
|
||||||
// from an exploded image
|
|
||||||
return SystemImage.reader().getModuleNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
// the set of modules in the run-time image
|
|
||||||
private final Set<ModuleReference> modules;
|
|
||||||
|
|
||||||
// maps module name to module reference
|
|
||||||
private final Map<String, ModuleReference> nameToModule;
|
|
||||||
|
|
||||||
// module name to hashes
|
|
||||||
private final Map<String, byte[]> hashes;
|
|
||||||
|
|
||||||
private SystemModuleFinder() {
|
|
||||||
String[] names = moduleNames();
|
|
||||||
int n = names.length;
|
|
||||||
moduleCount.add(n);
|
|
||||||
|
|
||||||
// fastpath is enabled by default.
|
|
||||||
// It can be disabled for troubleshooting purpose.
|
|
||||||
boolean disabled =
|
|
||||||
System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
|
|
||||||
|
|
||||||
ModuleDescriptor[] descriptors;
|
|
||||||
ModuleTarget[] targets;
|
|
||||||
ModuleHashes[] recordedHashes;
|
|
||||||
ModuleResolution[] moduleResolutions;
|
|
||||||
|
|
||||||
// fast loading of ModuleDescriptor of system modules
|
|
||||||
if (isFastPathSupported() && !disabled) {
|
|
||||||
descriptors = SystemModules.descriptors();
|
|
||||||
targets = SystemModules.targets();
|
|
||||||
recordedHashes = SystemModules.hashes();
|
|
||||||
moduleResolutions = SystemModules.moduleResolutions();
|
|
||||||
} else {
|
|
||||||
// if fast loading of ModuleDescriptors is disabled
|
|
||||||
// fallback to read module-info.class
|
|
||||||
descriptors = new ModuleDescriptor[n];
|
|
||||||
targets = new ModuleTarget[n];
|
|
||||||
recordedHashes = new ModuleHashes[n];
|
|
||||||
moduleResolutions = new ModuleResolution[n];
|
|
||||||
ImageReader imageReader = SystemImage.reader();
|
|
||||||
for (int i = 0; i < names.length; i++) {
|
|
||||||
String mn = names[i];
|
|
||||||
ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
|
|
||||||
ModuleInfo.Attributes attrs =
|
|
||||||
ModuleInfo.read(imageReader.getResourceBuffer(loc), null);
|
|
||||||
descriptors[i] = attrs.descriptor();
|
|
||||||
targets[i] = attrs.target();
|
|
||||||
recordedHashes[i] = attrs.recordedHashes();
|
|
||||||
moduleResolutions[i] = attrs.moduleResolution();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, byte[]> hashes = null;
|
|
||||||
boolean secondSeen = false;
|
|
||||||
// record the hashes to build HashSupplier
|
|
||||||
for (ModuleHashes mh : recordedHashes) {
|
|
||||||
if (mh != null) {
|
|
||||||
// if only one module contain ModuleHashes, use it
|
|
||||||
if (hashes == null) {
|
|
||||||
hashes = mh.hashes();
|
|
||||||
} else {
|
|
||||||
if (!secondSeen) {
|
|
||||||
hashes = new HashMap<>(hashes);
|
|
||||||
secondSeen = true;
|
|
||||||
}
|
|
||||||
hashes.putAll(mh.hashes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.hashes = (hashes == null) ? Map.of() : hashes;
|
|
||||||
|
|
||||||
ModuleReference[] mods = new ModuleReference[n];
|
|
||||||
|
|
||||||
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
|
||||||
Entry<String, ModuleReference>[] map
|
|
||||||
= (Entry<String, ModuleReference>[])new Entry[n];
|
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
ModuleDescriptor md = descriptors[i];
|
|
||||||
|
|
||||||
// create the ModuleReference
|
|
||||||
ModuleReference mref = toModuleReference(md,
|
|
||||||
targets[i],
|
|
||||||
recordedHashes[i],
|
|
||||||
hashSupplier(names[i]),
|
|
||||||
moduleResolutions[i]);
|
|
||||||
mods[i] = mref;
|
|
||||||
map[i] = Map.entry(names[i], mref);
|
|
||||||
|
|
||||||
// counters
|
|
||||||
packageCount.add(md.packages().size());
|
|
||||||
exportsCount.add(md.exports().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
modules = Set.of(mods);
|
|
||||||
nameToModule = Map.ofEntries(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<ModuleReference> find(String name) {
|
|
||||||
Objects.requireNonNull(name);
|
|
||||||
return Optional.ofNullable(nameToModule.get(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<ModuleReference> findAll() {
|
|
||||||
return modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ModuleReference toModuleReference(ModuleDescriptor md,
|
|
||||||
ModuleTarget target,
|
|
||||||
ModuleHashes recordedHashes,
|
|
||||||
HashSupplier hasher,
|
|
||||||
ModuleResolution mres) {
|
|
||||||
String mn = md.name();
|
|
||||||
URI uri = JNUA.create("jrt", "/".concat(mn));
|
|
||||||
|
|
||||||
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
|
|
||||||
@Override
|
|
||||||
public ModuleReader get() {
|
|
||||||
return new ImageModuleReader(mn, uri);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ModuleReference mref = new ModuleReferenceImpl(md,
|
|
||||||
uri,
|
|
||||||
readerSupplier,
|
|
||||||
null,
|
|
||||||
target,
|
|
||||||
recordedHashes,
|
|
||||||
hasher,
|
|
||||||
mres);
|
|
||||||
|
|
||||||
// may need a reference to a patched module if --patch-module specified
|
|
||||||
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
|
|
||||||
|
|
||||||
return mref;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HashSupplier hashSupplier(String name) {
|
|
||||||
if (!hashes.containsKey(name))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new HashSupplier() {
|
|
||||||
@Override
|
|
||||||
public byte[] generate(String algorithm) {
|
|
||||||
return hashes.get(name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ModuleReader for reading resources from a module linked into the
|
|
||||||
* run-time image.
|
|
||||||
*/
|
|
||||||
static class ImageModuleReader implements ModuleReader {
|
|
||||||
private final String module;
|
|
||||||
private volatile boolean closed;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If there is a security manager set then check permission to
|
|
||||||
* connect to the run-time image.
|
|
||||||
*/
|
|
||||||
private static void checkPermissionToConnect(URI uri) {
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
try {
|
|
||||||
URLConnection uc = uri.toURL().openConnection();
|
|
||||||
sm.checkPermission(uc.getPermission());
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new UncheckedIOException(ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageModuleReader(String module, URI uri) {
|
|
||||||
checkPermissionToConnect(uri);
|
|
||||||
this.module = module;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the ImageLocation for the given resource, {@code null}
|
|
||||||
* if not found.
|
|
||||||
*/
|
|
||||||
private ImageLocation findImageLocation(String name) throws IOException {
|
|
||||||
Objects.requireNonNull(name);
|
|
||||||
if (closed)
|
|
||||||
throw new IOException("ModuleReader is closed");
|
|
||||||
ImageReader imageReader = SystemImage.reader();
|
|
||||||
if (imageReader != null) {
|
|
||||||
return imageReader.findLocation(module, name);
|
|
||||||
} else {
|
|
||||||
// not an images build
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<URI> find(String name) throws IOException {
|
|
||||||
ImageLocation location = findImageLocation(name);
|
|
||||||
if (location != null) {
|
|
||||||
URI u = URI.create("jrt:/" + module + "/" + name);
|
|
||||||
return Optional.of(u);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<InputStream> open(String name) throws IOException {
|
|
||||||
return read(name).map(this::toInputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private InputStream toInputStream(ByteBuffer bb) { // ## -> ByteBuffer?
|
|
||||||
try {
|
|
||||||
int rem = bb.remaining();
|
|
||||||
byte[] bytes = new byte[rem];
|
|
||||||
bb.get(bytes);
|
|
||||||
return new ByteArrayInputStream(bytes);
|
|
||||||
} finally {
|
|
||||||
release(bb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<ByteBuffer> read(String name) throws IOException {
|
|
||||||
ImageLocation location = findImageLocation(name);
|
|
||||||
if (location != null) {
|
|
||||||
return Optional.of(SystemImage.reader().getResourceBuffer(location));
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release(ByteBuffer bb) {
|
|
||||||
Objects.requireNonNull(bb);
|
|
||||||
ImageReader.releaseByteBuffer(bb);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<String> list() throws IOException {
|
|
||||||
if (closed)
|
|
||||||
throw new IOException("ModuleReader is closed");
|
|
||||||
|
|
||||||
Spliterator<String> s = new ModuleContentSpliterator(module);
|
|
||||||
return StreamSupport.stream(s, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// nothing else to do
|
|
||||||
closed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Spliterator for traversing the resources of a module linked into the
|
|
||||||
* run-time image.
|
|
||||||
*/
|
|
||||||
static class ModuleContentSpliterator implements Spliterator<String> {
|
|
||||||
final String moduleRoot;
|
|
||||||
final Deque<ImageReader.Node> stack;
|
|
||||||
Iterator<ImageReader.Node> iterator;
|
|
||||||
|
|
||||||
ModuleContentSpliterator(String module) throws IOException {
|
|
||||||
moduleRoot = "/modules/" + module;
|
|
||||||
stack = new ArrayDeque<>();
|
|
||||||
|
|
||||||
// push the root node to the stack to get started
|
|
||||||
ImageReader.Node dir = SystemImage.reader().findNode(moduleRoot);
|
|
||||||
if (dir == null || !dir.isDirectory())
|
|
||||||
throw new IOException(moduleRoot + " not a directory");
|
|
||||||
stack.push(dir);
|
|
||||||
iterator = Collections.emptyIterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the next non-directory node or {@code null} if
|
|
||||||
* there are no remaining nodes to visit.
|
|
||||||
*/
|
|
||||||
private String next() throws IOException {
|
|
||||||
for (;;) {
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
ImageReader.Node node = iterator.next();
|
|
||||||
String name = node.getName();
|
|
||||||
if (node.isDirectory()) {
|
|
||||||
// build node
|
|
||||||
ImageReader.Node dir = SystemImage.reader().findNode(name);
|
|
||||||
assert dir.isDirectory();
|
|
||||||
stack.push(dir);
|
|
||||||
} else {
|
|
||||||
// strip /modules/$MODULE/ prefix
|
|
||||||
return name.substring(moduleRoot.length() + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
ImageReader.Node dir = stack.poll();
|
|
||||||
assert dir.isDirectory();
|
|
||||||
iterator = dir.getChildren().iterator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean tryAdvance(Consumer<? super String> action) {
|
|
||||||
String next;
|
|
||||||
try {
|
|
||||||
next = next();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new UncheckedIOException(ioe);
|
|
||||||
}
|
|
||||||
if (next != null) {
|
|
||||||
action.accept(next);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Spliterator<String> trySplit() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int characteristics() {
|
|
||||||
return Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.IMMUTABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long estimateSize() {
|
|
||||||
return Long.MAX_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,576 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package jdk.internal.module;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.lang.module.ModuleDescriptor;
|
||||||
|
import java.lang.module.ModuleFinder;
|
||||||
|
import java.lang.module.ModuleReader;
|
||||||
|
import java.lang.module.ModuleReference;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Spliterator;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import jdk.internal.jimage.ImageLocation;
|
||||||
|
import jdk.internal.jimage.ImageReader;
|
||||||
|
import jdk.internal.jimage.ImageReaderFactory;
|
||||||
|
import jdk.internal.misc.JavaNetUriAccess;
|
||||||
|
import jdk.internal.misc.SharedSecrets;
|
||||||
|
import jdk.internal.module.ModuleHashes.HashSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The factory for SystemModules objects and for creating ModuleFinder objects
|
||||||
|
* that find modules in the runtime image.
|
||||||
|
*
|
||||||
|
* This class supports initializing the module system when the runtime is an
|
||||||
|
* images build, an exploded build, or an images build with java.base patched
|
||||||
|
* by an exploded java.base. It also supports a testing mode that re-parses
|
||||||
|
* the module-info.class resources in the run-time image.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class SystemModuleFinders {
|
||||||
|
private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
|
||||||
|
|
||||||
|
private static final boolean USE_FAST_PATH;
|
||||||
|
static {
|
||||||
|
String value = System.getProperty("jdk.system.module.finder.disableFastPath");
|
||||||
|
if (value == null) {
|
||||||
|
USE_FAST_PATH = true;
|
||||||
|
} else {
|
||||||
|
USE_FAST_PATH = (value.length() > 0) && !Boolean.parseBoolean(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cached ModuleFinder returned from ofSystem
|
||||||
|
private static volatile ModuleFinder cachedSystemModuleFinder;
|
||||||
|
|
||||||
|
private SystemModuleFinders() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the SystemModules object to reconstitute all modules. Returns
|
||||||
|
* null if this is an exploded build or java.base is patched by an exploded
|
||||||
|
* build.
|
||||||
|
*/
|
||||||
|
static SystemModules allSystemModules() {
|
||||||
|
if (USE_FAST_PATH) {
|
||||||
|
return SystemModulesMap.allSystemModules();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a SystemModules object to reconstitute the modules for the
|
||||||
|
* given initial module. If the initial module is null then return the
|
||||||
|
* SystemModules object to reconstitute the default modules.
|
||||||
|
*
|
||||||
|
* Return null if there is no SystemModules class for the initial module,
|
||||||
|
* this is an exploded build, or java.base is patched by an exploded build.
|
||||||
|
*/
|
||||||
|
static SystemModules systemModules(String initialModule) {
|
||||||
|
if (USE_FAST_PATH) {
|
||||||
|
if (initialModule == null) {
|
||||||
|
return SystemModulesMap.defaultSystemModules();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] initialModules = SystemModulesMap.moduleNames();
|
||||||
|
for (int i = 0; i < initialModules.length; i++) {
|
||||||
|
String moduleName = initialModules[i];
|
||||||
|
if (initialModule.equals(moduleName)) {
|
||||||
|
String cn = SystemModulesMap.classNames()[i];
|
||||||
|
try {
|
||||||
|
// one-arg Class.forName as java.base may not be defined
|
||||||
|
Constructor<?> ctor = Class.forName(cn).getConstructor();
|
||||||
|
return (SystemModules) ctor.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InternalError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a ModuleFinder that is backed by the given SystemModules object.
|
||||||
|
*
|
||||||
|
* @apiNote The returned ModuleFinder is thread safe.
|
||||||
|
*/
|
||||||
|
static ModuleFinder of(SystemModules systemModules) {
|
||||||
|
ModuleDescriptor[] descriptors = systemModules.moduleDescriptors();
|
||||||
|
ModuleTarget[] targets = systemModules.moduleTargets();
|
||||||
|
ModuleHashes[] recordedHashes = systemModules.moduleHashes();
|
||||||
|
ModuleResolution[] moduleResolutions = systemModules.moduleResolutions();
|
||||||
|
|
||||||
|
int moduleCount = descriptors.length;
|
||||||
|
ModuleReference[] mrefs = new ModuleReference[moduleCount];
|
||||||
|
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||||
|
Map.Entry<String, ModuleReference>[] map
|
||||||
|
= (Map.Entry<String, ModuleReference>[])new Map.Entry[moduleCount];
|
||||||
|
|
||||||
|
Map<String, byte[]> nameToHash = generateNameToHash(recordedHashes);
|
||||||
|
|
||||||
|
for (int i = 0; i < moduleCount; i++) {
|
||||||
|
String name = descriptors[i].name();
|
||||||
|
HashSupplier hashSupplier = hashSupplier(nameToHash, name);
|
||||||
|
ModuleReference mref = toModuleReference(descriptors[i],
|
||||||
|
targets[i],
|
||||||
|
recordedHashes[i],
|
||||||
|
hashSupplier,
|
||||||
|
moduleResolutions[i]);
|
||||||
|
mrefs[i] = mref;
|
||||||
|
map[i] = Map.entry(name, mref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SystemModuleFinder(mrefs, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ModuleFinder to find all system modules. Supports both
|
||||||
|
* images and exploded builds.
|
||||||
|
*
|
||||||
|
* @apiNote Used by ModuleFinder.ofSystem()
|
||||||
|
*/
|
||||||
|
public static ModuleFinder ofSystem() {
|
||||||
|
ModuleFinder finder = cachedSystemModuleFinder;
|
||||||
|
if (finder != null) {
|
||||||
|
return finder;
|
||||||
|
}
|
||||||
|
|
||||||
|
// probe to see if this is an images build
|
||||||
|
String home = System.getProperty("java.home");
|
||||||
|
Path modules = Paths.get(home, "lib", "modules");
|
||||||
|
if (Files.isRegularFile(modules)) {
|
||||||
|
if (USE_FAST_PATH) {
|
||||||
|
SystemModules systemModules = allSystemModules();
|
||||||
|
if (systemModules != null) {
|
||||||
|
finder = of(systemModules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fall back to parsing the module-info.class files in image
|
||||||
|
if (finder == null) {
|
||||||
|
finder = ofModuleInfos();
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedSystemModuleFinder = finder;
|
||||||
|
return finder;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// exploded build (do not cache module finder)
|
||||||
|
Path dir = Paths.get(home, "modules");
|
||||||
|
if (!Files.isDirectory(dir))
|
||||||
|
throw new InternalError("Unable to detect the run-time image");
|
||||||
|
ModuleFinder f = ModulePath.of(ModuleBootstrap.patcher(), dir);
|
||||||
|
return new ModuleFinder() {
|
||||||
|
@Override
|
||||||
|
public Optional<ModuleReference> find(String name) {
|
||||||
|
PrivilegedAction<Optional<ModuleReference>> pa = () -> f.find(name);
|
||||||
|
return AccessController.doPrivileged(pa);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Set<ModuleReference> findAll() {
|
||||||
|
PrivilegedAction<Set<ModuleReference>> pa = f::findAll;
|
||||||
|
return AccessController.doPrivileged(pa);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the module-info.class of all module in the runtime image and
|
||||||
|
* returns a ModuleFinder to find the modules.
|
||||||
|
*
|
||||||
|
* @apiNote The returned ModuleFinder is thread safe.
|
||||||
|
*/
|
||||||
|
private static ModuleFinder ofModuleInfos() {
|
||||||
|
// parse the module-info.class in every module
|
||||||
|
Map<String, ModuleInfo.Attributes> nameToAttributes = new HashMap<>();
|
||||||
|
Map<String, byte[]> nameToHash = new HashMap<>();
|
||||||
|
ImageReader reader = SystemImage.reader();
|
||||||
|
for (String mn : reader.getModuleNames()) {
|
||||||
|
ImageLocation loc = reader.findLocation(mn, "module-info.class");
|
||||||
|
ModuleInfo.Attributes attrs
|
||||||
|
= ModuleInfo.read(reader.getResourceBuffer(loc), null);
|
||||||
|
|
||||||
|
nameToAttributes.put(mn, attrs);
|
||||||
|
ModuleHashes hashes = attrs.recordedHashes();
|
||||||
|
if (hashes != null) {
|
||||||
|
for (String name : hashes.names()) {
|
||||||
|
nameToHash.computeIfAbsent(name, k -> hashes.hashFor(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a ModuleReference for each module
|
||||||
|
Set<ModuleReference> mrefs = new HashSet<>();
|
||||||
|
Map<String, ModuleReference> nameToModule = new HashMap<>();
|
||||||
|
for (Map.Entry<String, ModuleInfo.Attributes> e : nameToAttributes.entrySet()) {
|
||||||
|
String mn = e.getKey();
|
||||||
|
ModuleInfo.Attributes attrs = e.getValue();
|
||||||
|
HashSupplier hashSupplier = hashSupplier(nameToHash, mn);
|
||||||
|
ModuleReference mref = toModuleReference(attrs.descriptor(),
|
||||||
|
attrs.target(),
|
||||||
|
attrs.recordedHashes(),
|
||||||
|
hashSupplier,
|
||||||
|
attrs.moduleResolution());
|
||||||
|
mrefs.add(mref);
|
||||||
|
nameToModule.put(mn, mref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SystemModuleFinder(mrefs, nameToModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ModuleFinder that finds module in an array or set of modules.
|
||||||
|
*/
|
||||||
|
private static class SystemModuleFinder implements ModuleFinder {
|
||||||
|
final Set<ModuleReference> mrefs;
|
||||||
|
final Map<String, ModuleReference> nameToModule;
|
||||||
|
|
||||||
|
SystemModuleFinder(ModuleReference[] array,
|
||||||
|
Map.Entry<String, ModuleReference>[] map) {
|
||||||
|
this.mrefs = Set.of(array);
|
||||||
|
this.nameToModule = Map.ofEntries(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemModuleFinder(Set<ModuleReference> mrefs,
|
||||||
|
Map<String, ModuleReference> nameToModule) {
|
||||||
|
this.mrefs = Collections.unmodifiableSet(mrefs);
|
||||||
|
this.nameToModule = Collections.unmodifiableMap(nameToModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<ModuleReference> find(String name) {
|
||||||
|
Objects.requireNonNull(name);
|
||||||
|
return Optional.ofNullable(nameToModule.get(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ModuleReference> findAll() {
|
||||||
|
return mrefs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a ModuleReference to the system module.
|
||||||
|
*/
|
||||||
|
static ModuleReference toModuleReference(ModuleDescriptor descriptor,
|
||||||
|
ModuleTarget target,
|
||||||
|
ModuleHashes recordedHashes,
|
||||||
|
HashSupplier hasher,
|
||||||
|
ModuleResolution mres) {
|
||||||
|
String mn = descriptor.name();
|
||||||
|
URI uri = JNUA.create("jrt", "/".concat(mn));
|
||||||
|
|
||||||
|
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
|
||||||
|
@Override
|
||||||
|
public ModuleReader get() {
|
||||||
|
return new SystemModuleReader(mn, uri);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ModuleReference mref = new ModuleReferenceImpl(descriptor,
|
||||||
|
uri,
|
||||||
|
readerSupplier,
|
||||||
|
null,
|
||||||
|
target,
|
||||||
|
recordedHashes,
|
||||||
|
hasher,
|
||||||
|
mres);
|
||||||
|
|
||||||
|
// may need a reference to a patched module if --patch-module specified
|
||||||
|
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
|
||||||
|
|
||||||
|
return mref;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a map of module name to hash value.
|
||||||
|
*/
|
||||||
|
static Map<String, byte[]> generateNameToHash(ModuleHashes[] recordedHashes) {
|
||||||
|
Map<String, byte[]> nameToHash = null;
|
||||||
|
|
||||||
|
boolean secondSeen = false;
|
||||||
|
// record the hashes to build HashSupplier
|
||||||
|
for (ModuleHashes mh : recordedHashes) {
|
||||||
|
if (mh != null) {
|
||||||
|
// if only one module contain ModuleHashes, use it
|
||||||
|
if (nameToHash == null) {
|
||||||
|
nameToHash = mh.hashes();
|
||||||
|
} else {
|
||||||
|
if (!secondSeen) {
|
||||||
|
nameToHash = new HashMap<>(nameToHash);
|
||||||
|
secondSeen = true;
|
||||||
|
}
|
||||||
|
nameToHash.putAll(mh.hashes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (nameToHash != null) ? nameToHash : Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a HashSupplier that returns the hash of the given module.
|
||||||
|
*/
|
||||||
|
static HashSupplier hashSupplier(Map<String, byte[]> nameToHash, String name) {
|
||||||
|
byte[] hash = nameToHash.get(name);
|
||||||
|
if (hash != null) {
|
||||||
|
// avoid lambda here
|
||||||
|
return new HashSupplier() {
|
||||||
|
@Override
|
||||||
|
public byte[] generate(String algorithm) {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holder class for the ImageReader
|
||||||
|
*
|
||||||
|
* @apiNote This class must be loaded before a security manager is set.
|
||||||
|
*/
|
||||||
|
private static class SystemImage {
|
||||||
|
static final ImageReader READER = ImageReaderFactory.getImageReader();
|
||||||
|
static ImageReader reader() {
|
||||||
|
return READER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ModuleReader for reading resources from a module linked into the
|
||||||
|
* run-time image.
|
||||||
|
*/
|
||||||
|
private static class SystemModuleReader implements ModuleReader {
|
||||||
|
private final String module;
|
||||||
|
private volatile boolean closed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is a security manager set then check permission to
|
||||||
|
* connect to the run-time image.
|
||||||
|
*/
|
||||||
|
private static void checkPermissionToConnect(URI uri) {
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (sm != null) {
|
||||||
|
try {
|
||||||
|
URLConnection uc = uri.toURL().openConnection();
|
||||||
|
sm.checkPermission(uc.getPermission());
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new UncheckedIOException(ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemModuleReader(String module, URI uri) {
|
||||||
|
checkPermissionToConnect(uri);
|
||||||
|
this.module = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ImageLocation for the given resource, {@code null}
|
||||||
|
* if not found.
|
||||||
|
*/
|
||||||
|
private ImageLocation findImageLocation(String name) throws IOException {
|
||||||
|
Objects.requireNonNull(name);
|
||||||
|
if (closed)
|
||||||
|
throw new IOException("ModuleReader is closed");
|
||||||
|
ImageReader imageReader = SystemImage.reader();
|
||||||
|
if (imageReader != null) {
|
||||||
|
return imageReader.findLocation(module, name);
|
||||||
|
} else {
|
||||||
|
// not an images build
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<URI> find(String name) throws IOException {
|
||||||
|
ImageLocation location = findImageLocation(name);
|
||||||
|
if (location != null) {
|
||||||
|
URI u = URI.create("jrt:/" + module + "/" + name);
|
||||||
|
return Optional.of(u);
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<InputStream> open(String name) throws IOException {
|
||||||
|
return read(name).map(this::toInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream toInputStream(ByteBuffer bb) { // ## -> ByteBuffer?
|
||||||
|
try {
|
||||||
|
int rem = bb.remaining();
|
||||||
|
byte[] bytes = new byte[rem];
|
||||||
|
bb.get(bytes);
|
||||||
|
return new ByteArrayInputStream(bytes);
|
||||||
|
} finally {
|
||||||
|
release(bb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<ByteBuffer> read(String name) throws IOException {
|
||||||
|
ImageLocation location = findImageLocation(name);
|
||||||
|
if (location != null) {
|
||||||
|
return Optional.of(SystemImage.reader().getResourceBuffer(location));
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release(ByteBuffer bb) {
|
||||||
|
Objects.requireNonNull(bb);
|
||||||
|
ImageReader.releaseByteBuffer(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<String> list() throws IOException {
|
||||||
|
if (closed)
|
||||||
|
throw new IOException("ModuleReader is closed");
|
||||||
|
|
||||||
|
Spliterator<String> s = new ModuleContentSpliterator(module);
|
||||||
|
return StreamSupport.stream(s, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
// nothing else to do
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Spliterator for traversing the resources of a module linked into the
|
||||||
|
* run-time image.
|
||||||
|
*/
|
||||||
|
private static class ModuleContentSpliterator implements Spliterator<String> {
|
||||||
|
final String moduleRoot;
|
||||||
|
final Deque<ImageReader.Node> stack;
|
||||||
|
Iterator<ImageReader.Node> iterator;
|
||||||
|
|
||||||
|
ModuleContentSpliterator(String module) throws IOException {
|
||||||
|
moduleRoot = "/modules/" + module;
|
||||||
|
stack = new ArrayDeque<>();
|
||||||
|
|
||||||
|
// push the root node to the stack to get started
|
||||||
|
ImageReader.Node dir = SystemImage.reader().findNode(moduleRoot);
|
||||||
|
if (dir == null || !dir.isDirectory())
|
||||||
|
throw new IOException(moduleRoot + " not a directory");
|
||||||
|
stack.push(dir);
|
||||||
|
iterator = Collections.emptyIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the next non-directory node or {@code null} if
|
||||||
|
* there are no remaining nodes to visit.
|
||||||
|
*/
|
||||||
|
private String next() throws IOException {
|
||||||
|
for (;;) {
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
ImageReader.Node node = iterator.next();
|
||||||
|
String name = node.getName();
|
||||||
|
if (node.isDirectory()) {
|
||||||
|
// build node
|
||||||
|
ImageReader.Node dir = SystemImage.reader().findNode(name);
|
||||||
|
assert dir.isDirectory();
|
||||||
|
stack.push(dir);
|
||||||
|
} else {
|
||||||
|
// strip /modules/$MODULE/ prefix
|
||||||
|
return name.substring(moduleRoot.length() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
ImageReader.Node dir = stack.poll();
|
||||||
|
assert dir.isDirectory();
|
||||||
|
iterator = dir.getChildren().iterator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(Consumer<? super String> action) {
|
||||||
|
String next;
|
||||||
|
try {
|
||||||
|
next = next();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new UncheckedIOException(ioe);
|
||||||
|
}
|
||||||
|
if (next != null) {
|
||||||
|
action.accept(next);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Spliterator<String> trySplit() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int characteristics() {
|
||||||
|
return Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.IMMUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long estimateSize() {
|
||||||
|
return Long.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,94 +26,73 @@
|
|||||||
package jdk.internal.module;
|
package jdk.internal.module;
|
||||||
|
|
||||||
import java.lang.module.ModuleDescriptor;
|
import java.lang.module.ModuleDescriptor;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SystemModules class will be generated at link time to create
|
* A SystemModules object reconstitutes module descriptors and other modules
|
||||||
* ModuleDescriptor for the system modules directly to improve
|
* attributes in an efficient way to avoid parsing module-info.class files at
|
||||||
* the module descriptor reconstitution time.
|
* startup. Implementations of this class are generated by the "system modules"
|
||||||
*
|
* jlink plugin.
|
||||||
* This will skip parsing of module-info.class file and validating
|
|
||||||
* names such as module name, package name, service and provider type names.
|
|
||||||
* It also avoids taking a defensive copy of any collection.
|
|
||||||
*
|
*
|
||||||
|
* @see SystemModuleFinders
|
||||||
* @see jdk.tools.jlink.internal.plugins.SystemModulesPlugin
|
* @see jdk.tools.jlink.internal.plugins.SystemModulesPlugin
|
||||||
*/
|
*/
|
||||||
public final class SystemModules {
|
|
||||||
/**
|
interface SystemModules {
|
||||||
* Name of the system modules.
|
|
||||||
*
|
|
||||||
* This array provides a way for SystemModuleFinder to fallback
|
|
||||||
* and read module-info.class from the run-time image instead of
|
|
||||||
* the fastpath.
|
|
||||||
*/
|
|
||||||
public static final String[] MODULE_NAMES = new String[0];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of packages in the boot layer from the installed modules.
|
* Returns false if the module reconstituted by this SystemModules object
|
||||||
*
|
* have no overlapping packages. Returns true if there are overlapping
|
||||||
* Don't make it final to avoid inlining during compile time as
|
* packages or unknown.
|
||||||
* the value will be changed at jlink time.
|
|
||||||
*/
|
*/
|
||||||
public static int PACKAGES_IN_BOOT_LAYER = 1024;
|
boolean hasSplitPackages();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if there are no split packages in the run-time image.
|
* Return false if the modules reconstituted by this SystemModules object
|
||||||
|
* do not include any incubator modules. Returns true if there are
|
||||||
|
* incubating modules or unknown.
|
||||||
*/
|
*/
|
||||||
public static boolean hasSplitPackages() {
|
boolean hasIncubatorModules();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a non-empty array of ModuleDescriptor objects in the run-time image.
|
* Returns the non-empty array of ModuleDescriptor objects.
|
||||||
*
|
|
||||||
* When running an exploded image it returns an empty array.
|
|
||||||
*/
|
*/
|
||||||
public static ModuleDescriptor[] descriptors() {
|
ModuleDescriptor[] moduleDescriptors();
|
||||||
throw new InternalError("expected to be overridden at link time");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a non-empty array of ModuleTarget objects in the run-time image.
|
* Returns the array of ModuleTarget objects. The array elements correspond
|
||||||
*
|
* to the array of ModuleDescriptor objects.
|
||||||
* When running an exploded image it returns an empty array.
|
|
||||||
*/
|
*/
|
||||||
public static ModuleTarget[] targets() {
|
ModuleTarget[] moduleTargets();
|
||||||
throw new InternalError("expected to be overridden at link time");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a non-empty array of ModuleHashes recorded in each module
|
* Returns the array of ModuleHashes objects. The array elements correspond
|
||||||
* in the run-time image.
|
* to the array of ModuleDescriptor objects.
|
||||||
*
|
|
||||||
* When running an exploded image it returns an empty array.
|
|
||||||
*/
|
*/
|
||||||
public static ModuleHashes[] hashes() {
|
ModuleHashes[] moduleHashes();
|
||||||
throw new InternalError("expected to be overridden at link time");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a non-empty array of ModuleResolutions in the run-time image.
|
* Returns the array of ModuleResolution objects. The array elements correspond
|
||||||
|
* to the array of ModuleDescriptor objects.
|
||||||
*/
|
*/
|
||||||
public static ModuleResolution[] moduleResolutions() {
|
ModuleResolution[] moduleResolutions();
|
||||||
throw new InternalError("expected to be overridden at link time");
|
|
||||||
}
|
/**
|
||||||
|
* Returns the map representing readability graph for the modules reconstituted
|
||||||
|
* by this SystemModules object.
|
||||||
|
*/
|
||||||
|
Map<String, Set<String>> moduleReads();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the map of module concealed packages to open. The map key is the
|
* Returns the map of module concealed packages to open. The map key is the
|
||||||
* module name, the value is the set of concealed packages to open.
|
* module name, the value is the set of concealed packages to open.
|
||||||
*/
|
*/
|
||||||
public static Map<String, Set<String>> concealedPackagesToOpen() {
|
Map<String, Set<String>> concealedPackagesToOpen();
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the map of module exported packages to open. The map key is the
|
* Returns the map of module exported packages to open. The map key is the
|
||||||
* module name, the value is the set of exported packages to open.
|
* module name, the value is the set of exported packages to open.
|
||||||
*/
|
*/
|
||||||
public static Map<String, Set<String>> exportedPackagesToOpen() {
|
Map<String, Set<String>> exportedPackagesToOpen();
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package jdk.internal.module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is generated/overridden at link time to return the names of the
|
||||||
|
* SystemModules classes generated at link time.
|
||||||
|
*
|
||||||
|
* @see SystemModuleFinders
|
||||||
|
* @see jdk.tools.jlink.internal.plugins.SystemModulesPlugin
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SystemModulesMap {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the SystemModules object to reconstitute all modules or null
|
||||||
|
* if this is an exploded build.
|
||||||
|
*/
|
||||||
|
static SystemModules allSystemModules() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the SystemModules object to reconstitute default modules or null
|
||||||
|
* if this is an exploded build.
|
||||||
|
*/
|
||||||
|
static SystemModules defaultSystemModules() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the array of initial module names identified at link time.
|
||||||
|
*/
|
||||||
|
static String[] moduleNames() {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the array of of SystemModules class names. The elements
|
||||||
|
* correspond to the elements in the array returned by moduleNames().
|
||||||
|
*/
|
||||||
|
static String[] classNames() {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
}
|
@ -316,8 +316,7 @@ public class Reflection {
|
|||||||
*/
|
*/
|
||||||
public static boolean isCallerSensitive(Method m) {
|
public static boolean isCallerSensitive(Method m) {
|
||||||
final ClassLoader loader = m.getDeclaringClass().getClassLoader();
|
final ClassLoader loader = m.getDeclaringClass().getClassLoader();
|
||||||
if (VM.isSystemDomainLoader(loader) ||
|
if (VM.isSystemDomainLoader(loader)) {
|
||||||
loader == ClassLoaders.platformClassLoader()) {
|
|
||||||
return m.isAnnotationPresent(CallerSensitive.class);
|
return m.isAnnotationPresent(CallerSensitive.class);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,10 +26,18 @@
|
|||||||
package sun.nio.ch;
|
package sun.nio.ch;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.*;
|
|
||||||
import java.nio.channels.spi.*;
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.*;
|
import java.nio.channels.ClosedSelectorException;
|
||||||
|
import java.nio.channels.IllegalSelectorException;
|
||||||
|
import java.nio.channels.SelectionKey;
|
||||||
|
import java.nio.channels.Selector;
|
||||||
|
import java.nio.channels.spi.AbstractSelectableChannel;
|
||||||
|
import java.nio.channels.spi.AbstractSelector;
|
||||||
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,23 +62,18 @@ public abstract class SelectorImpl
|
|||||||
super(sp);
|
super(sp);
|
||||||
keys = new HashSet<>();
|
keys = new HashSet<>();
|
||||||
selectedKeys = new HashSet<>();
|
selectedKeys = new HashSet<>();
|
||||||
if (Util.atBugLevel("1.4")) {
|
publicKeys = Collections.unmodifiableSet(keys);
|
||||||
publicKeys = keys;
|
publicSelectedKeys = Util.ungrowableSet(selectedKeys);
|
||||||
publicSelectedKeys = selectedKeys;
|
|
||||||
} else {
|
|
||||||
publicKeys = Collections.unmodifiableSet(keys);
|
|
||||||
publicSelectedKeys = Util.ungrowableSet(selectedKeys);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<SelectionKey> keys() {
|
public Set<SelectionKey> keys() {
|
||||||
if (!isOpen() && !Util.atBugLevel("1.4"))
|
if (!isOpen())
|
||||||
throw new ClosedSelectorException();
|
throw new ClosedSelectorException();
|
||||||
return publicKeys;
|
return publicKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<SelectionKey> selectedKeys() {
|
public Set<SelectionKey> selectedKeys() {
|
||||||
if (!isOpen() && !Util.atBugLevel("1.4"))
|
if (!isOpen())
|
||||||
throw new ClosedSelectorException();
|
throw new ClosedSelectorException();
|
||||||
return publicSelectedKeys;
|
return publicSelectedKeys;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,13 +25,16 @@
|
|||||||
|
|
||||||
package sun.nio.ch;
|
package sun.nio.ch;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.MappedByteBuffer;
|
import java.nio.MappedByteBuffer;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
import sun.security.action.GetPropertyAction;
|
import sun.security.action.GetPropertyAction;
|
||||||
|
|
||||||
@ -456,21 +459,4 @@ public class Util {
|
|||||||
}
|
}
|
||||||
return dbb;
|
return dbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -- Bug compatibility --
|
|
||||||
|
|
||||||
private static volatile String bugLevel;
|
|
||||||
|
|
||||||
static boolean atBugLevel(String bl) { // package-private
|
|
||||||
if (bugLevel == null) {
|
|
||||||
if (!jdk.internal.misc.VM.isBooted())
|
|
||||||
return false;
|
|
||||||
String value = GetPropertyAction
|
|
||||||
.privilegedGetProperty("sun.nio.ch.bugLevel");
|
|
||||||
bugLevel = (value != null) ? value : "";
|
|
||||||
}
|
|
||||||
return bugLevel.equals(bl);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,9 @@ public abstract class HandshakeMessage {
|
|||||||
public static final Debug debug = Debug.getInstance("ssl");
|
public static final Debug debug = Debug.getInstance("ssl");
|
||||||
|
|
||||||
// enum HandshakeType:
|
// enum HandshakeType:
|
||||||
|
//
|
||||||
|
// Please update the isUnsupported() method accordingly if the handshake
|
||||||
|
// types get updated in the future.
|
||||||
static final byte ht_hello_request = 0; // RFC 5246
|
static final byte ht_hello_request = 0; // RFC 5246
|
||||||
static final byte ht_client_hello = 1; // RFC 5246
|
static final byte ht_client_hello = 1; // RFC 5246
|
||||||
static final byte ht_server_hello = 2; // RFC 5246
|
static final byte ht_server_hello = 2; // RFC 5246
|
||||||
@ -130,6 +133,24 @@ public abstract class HandshakeMessage {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isUnsupported(byte handshakeType) {
|
||||||
|
return (handshakeType != ht_hello_request) &&
|
||||||
|
(handshakeType != ht_client_hello) &&
|
||||||
|
(handshakeType != ht_server_hello) &&
|
||||||
|
(handshakeType != ht_hello_verify_request) &&
|
||||||
|
(handshakeType != ht_new_session_ticket) &&
|
||||||
|
(handshakeType != ht_certificate) &&
|
||||||
|
(handshakeType != ht_server_key_exchange) &&
|
||||||
|
(handshakeType != ht_certificate_request) &&
|
||||||
|
(handshakeType != ht_server_hello_done) &&
|
||||||
|
(handshakeType != ht_certificate_verify) &&
|
||||||
|
(handshakeType != ht_client_key_exchange) &&
|
||||||
|
(handshakeType != ht_finished) &&
|
||||||
|
(handshakeType != ht_certificate_url) &&
|
||||||
|
(handshakeType != ht_certificate_status) &&
|
||||||
|
(handshakeType != ht_supplemental_data);
|
||||||
|
}
|
||||||
|
|
||||||
private static byte[] genPad(int b, int count) {
|
private static byte[] genPad(int b, int count) {
|
||||||
byte[] padding = new byte[count];
|
byte[] padding = new byte[count];
|
||||||
Arrays.fill(padding, (byte)b);
|
Arrays.fill(padding, (byte)b);
|
||||||
|
@ -1034,6 +1034,12 @@ abstract class Handshaker {
|
|||||||
input.mark(4);
|
input.mark(4);
|
||||||
|
|
||||||
messageType = (byte)input.getInt8();
|
messageType = (byte)input.getInt8();
|
||||||
|
if (HandshakeMessage.isUnsupported(messageType)) {
|
||||||
|
throw new SSLProtocolException(
|
||||||
|
"Received unsupported or unknown handshake message: " +
|
||||||
|
messageType);
|
||||||
|
}
|
||||||
|
|
||||||
messageLen = input.getInt24();
|
messageLen = input.getInt24();
|
||||||
|
|
||||||
if (input.available() < messageLen) {
|
if (input.available() < messageLen) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -73,8 +73,8 @@ import javax.security.auth.Subject;
|
|||||||
* must not be null; the behavior is unspecified if it is.</p>
|
* must not be null; the behavior is unspecified if it is.</p>
|
||||||
*
|
*
|
||||||
* <p>Class loading aspects are detailed in the
|
* <p>Class loading aspects are detailed in the
|
||||||
* <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
* <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
* JMX Specification, version 1.4</a> PDF document.</p>
|
* JMX Specification, version 1.4</a></p>
|
||||||
*
|
*
|
||||||
* <p>Most methods in this interface parallel methods in the {@link
|
* <p>Most methods in this interface parallel methods in the {@link
|
||||||
* MBeanServerConnection} interface. Where an aspect of the behavior
|
* MBeanServerConnection} interface. Where an aspect of the behavior
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>RMI connector</title>
|
<title>RMI connector</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -316,19 +316,8 @@ questions.
|
|||||||
<p>If an RMI connector client or server receives from its peer an
|
<p>If an RMI connector client or server receives from its peer an
|
||||||
instance of a class that it does not know, and if dynamic code
|
instance of a class that it does not know, and if dynamic code
|
||||||
downloading is active for the RMI connection, then the class can
|
downloading is active for the RMI connection, then the class can
|
||||||
be downloaded from a codebase specified by the peer. The
|
be downloaded from a codebase specified by the peer.
|
||||||
article <a
|
{@extLink rmi_guide Java RMI Guide} explains this in more detail.</p>
|
||||||
href="{@docRoot}/../technotes/guides/rmi/codebase.html"><em>Dynamic
|
|
||||||
code downloading using Java RMI</em></a> explains this in more
|
|
||||||
detail.</p>
|
|
||||||
|
|
||||||
|
|
||||||
@see <a href="{@docRoot}/../technotes/guides/rmi/index.html">
|
|
||||||
Java™ Remote Method
|
|
||||||
Invocation (RMI)</a>
|
|
||||||
|
|
||||||
@see <a href="{@docRoot}/../technotes/guides/jndi/index.html">
|
|
||||||
Java Naming and Directory Interface™ (JNDI)</a>
|
|
||||||
|
|
||||||
@see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045,
|
@see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045,
|
||||||
section 6.8, "Base64 Content-Transfer-Encoding"</a>
|
section 6.8, "Base64 Content-Transfer-Encoding"</a>
|
||||||
|
@ -588,8 +588,8 @@ public class ManagementFactory {
|
|||||||
Class<T> mxbeanInterface)
|
Class<T> mxbeanInterface)
|
||||||
throws java.io.IOException {
|
throws java.io.IOException {
|
||||||
|
|
||||||
// Only allow MXBean interfaces from rt.jar loaded by the
|
// Only allow MXBean interfaces from the platform modules loaded by the
|
||||||
// bootstrap class loader
|
// bootstrap or platform class loader
|
||||||
final Class<?> cls = mxbeanInterface;
|
final Class<?> cls = mxbeanInterface;
|
||||||
ClassLoader loader =
|
ClassLoader loader =
|
||||||
AccessController.doPrivileged(
|
AccessController.doPrivileged(
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>javax.management.loading package</title>
|
<title>javax.management.loading package</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -67,11 +67,8 @@ questions.
|
|||||||
<code>PrivateClassLoader</code>.</p>
|
<code>PrivateClassLoader</code>.</p>
|
||||||
|
|
||||||
<p id="spec">
|
<p id="spec">
|
||||||
@see <a href="{@docRoot}/../technotes/guides/jmx/">
|
@see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
Java Platform documentation on JMX technology</a>,
|
JMX Specification, version 1.4</a>
|
||||||
in particular the
|
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
|
||||||
JMX Specification, version 1.4(pdf).</a>
|
|
||||||
|
|
||||||
@since 1.5
|
@since 1.5
|
||||||
</BODY>
|
</BODY>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>javax.management.modelmbean package</title>
|
<title>javax.management.modelmbean package</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -114,9 +114,8 @@ mbs.invoke(mapName, "get", new Object[] {"key"}, new String[] {Object.class.getN
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>See the <i>JMX 1.4 Specification</i>
|
<li>See the <i>JMX 1.4 Specification</i>
|
||||||
PDF document available from the
|
<a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/">
|
JMX Specification, version 1.4</a>
|
||||||
Java Platform documentation on JMX technology</a>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@since 1.5
|
@since 1.5
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>javax.management.monitor package</title>
|
<title>javax.management.monitor package</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -184,11 +184,8 @@ questions.
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p id="spec">
|
<p id="spec">
|
||||||
@see <a href="{@docRoot}/../technotes/guides/jmx/">
|
@see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
Java Platform documentation on JMX technology</a>,
|
JMX Specification, version 1.4</a>
|
||||||
in particular the
|
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
|
||||||
JMX Specification, version 1.4(pdf).</a>
|
|
||||||
@since 1.5
|
@since 1.5
|
||||||
|
|
||||||
</BODY>
|
</BODY>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>javax.management.openmbean package</title>
|
<title>javax.management.openmbean package</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -142,10 +142,7 @@ questions.
|
|||||||
then {@code minValue} must not be greater than {@code maxValue}.
|
then {@code minValue} must not be greater than {@code maxValue}.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@see <a href="{@docRoot}/../technotes/guides/jmx/">
|
@see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
Java Platform documentation on JMX technology</a>,
|
|
||||||
in particular the
|
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
|
||||||
JMX Specification, version 1.4</a>
|
JMX Specification, version 1.4</a>
|
||||||
|
|
||||||
@since 1.5
|
@since 1.5
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>javax.management package</title>
|
<title>javax.management package</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -389,11 +389,8 @@ questions.
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p id="spec">
|
<p id="spec">
|
||||||
@see <a href="{@docRoot}/../technotes/guides/jmx/index.html">
|
@see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
Java Platform documentation on JMX technology</a>
|
JMX Specification, version 1.4</a>
|
||||||
in particular the
|
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
|
||||||
JMX Specification, version 1.4(pdf).</a>
|
|
||||||
|
|
||||||
@since 1.5
|
@since 1.5
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>javax.management.relation package</title>
|
<title>javax.management.relation package</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -136,10 +136,7 @@ Set<ObjectName> dependentASet = dependentAMap.keySet();
|
|||||||
// Set of ObjectName containing moduleB
|
// Set of ObjectName containing moduleB
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@see <a href="{@docRoot}/../technotes/guides/jmx/">
|
@see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
Java Platform documentation on JMX technology</a>,
|
|
||||||
in particular the
|
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
|
||||||
JMX Specification, version 1.4</a>
|
JMX Specification, version 1.4</a>
|
||||||
|
|
||||||
@since 1.5
|
@since 1.5
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>JMX™ Remote API.</title>
|
<title>JMX™ Remote API.</title>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
This code is free software; you can redistribute it and/or modify it
|
This code is free software; you can redistribute it and/or modify it
|
||||||
@ -32,8 +32,8 @@ questions.
|
|||||||
This package defines the essential interfaces for making a JMX
|
This package defines the essential interfaces for making a JMX
|
||||||
MBean server manageable remotely. The specification of this
|
MBean server manageable remotely. The specification of this
|
||||||
functionality is completed by Part III of the
|
functionality is completed by Part III of the
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
<a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
JMX Specification, version 1.4</a> PDF document.</p>
|
JMX Specification, version 1.4</a></p>
|
||||||
|
|
||||||
<p>The JMX specification defines the notion of <b>connectors</b>.
|
<p>The JMX specification defines the notion of <b>connectors</b>.
|
||||||
A connector is attached to a JMX API MBean server and makes it
|
A connector is attached to a JMX API MBean server and makes it
|
||||||
@ -194,10 +194,7 @@ rmi://192.18.1.9 username 1
|
|||||||
connector server.</p>
|
connector server.</p>
|
||||||
|
|
||||||
|
|
||||||
@see <a href="{@docRoot}/../technotes/guides/jmx/">
|
@see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
|
||||||
Java Platform documentation on JMX technology</a>,
|
|
||||||
in particular the
|
|
||||||
<a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
|
|
||||||
JMX Specification, version 1.4</a>
|
JMX Specification, version 1.4</a>
|
||||||
|
|
||||||
@since 1.5
|
@since 1.5
|
||||||
|
@ -48,7 +48,7 @@ public class CardException extends Exception {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new CardException with the specified cause and a detail message
|
* Constructs a new CardException with the specified cause and a detail message
|
||||||
* of <code>(cause==null ? null : cause.toString())</code>.
|
* of {@code (cause==null ? null : cause.toString())}.
|
||||||
*
|
*
|
||||||
* @param cause the cause of this exception or null
|
* @param cause the cause of this exception or null
|
||||||
*/
|
*/
|
||||||
|
@ -48,7 +48,7 @@ public class CardNotPresentException extends CardException {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new CardNotPresentException with the specified cause and a detail message
|
* Constructs a new CardNotPresentException with the specified cause and a detail message
|
||||||
* of <code>(cause==null ? null : cause.toString())</code>.
|
* of {@code (cause==null ? null : cause.toString())}.
|
||||||
*
|
*
|
||||||
* @param cause the cause of this exception or null
|
* @param cause the cause of this exception or null
|
||||||
*/
|
*/
|
||||||
|
@ -42,14 +42,16 @@ package com.sun.tools.attach;
|
|||||||
*
|
*
|
||||||
* <table class="striped"><caption style="display:none">Table shows permission
|
* <table class="striped"><caption style="display:none">Table shows permission
|
||||||
* target name, what the permission allows, and associated risks</caption>
|
* target name, what the permission allows, and associated risks</caption>
|
||||||
|
* <thead>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th>Permission Target Name</th>
|
* <th scope="col">Permission Target Name</th>
|
||||||
* <th>What the Permission Allows</th>
|
* <th scope="col">What the Permission Allows</th>
|
||||||
* <th>Risks of Allowing this Permission</th>
|
* <th scope="col">Risks of Allowing this Permission</th>
|
||||||
* </tr>
|
* </tr>
|
||||||
*
|
* </thead>
|
||||||
|
* <tbody>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td>attachVirtualMachine</td>
|
* <th scope="row">attachVirtualMachine</th>
|
||||||
* <td>Ability to attach to another Java virtual machine and load agents
|
* <td>Ability to attach to another Java virtual machine and load agents
|
||||||
* into that VM.
|
* into that VM.
|
||||||
* </td>
|
* </td>
|
||||||
@ -59,14 +61,14 @@ package com.sun.tools.attach;
|
|||||||
* </tr>
|
* </tr>
|
||||||
*
|
*
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td>createAttachProvider</td>
|
* <th scope="row">createAttachProvider</th>
|
||||||
* <td>Ability to create an <code>AttachProvider</code> instance.
|
* <td>Ability to create an <code>AttachProvider</code> instance.
|
||||||
* </td>
|
* </td>
|
||||||
* <td>This allows an attacker to create an AttachProvider which can
|
* <td>This allows an attacker to create an AttachProvider which can
|
||||||
* potentially be used to attach to other Java virtual machines.
|
* potentially be used to attach to other Java virtual machines.
|
||||||
* </td>
|
* </td>
|
||||||
* </tr>
|
* </tr>
|
||||||
|
* </tbody>
|
||||||
*
|
*
|
||||||
* </table>
|
* </table>
|
||||||
|
|
||||||
|
@ -59,21 +59,29 @@ import com.sun.net.httpserver.spi.HttpServerProvider;
|
|||||||
* Paths are matched literally, which means that the strings are compared
|
* Paths are matched literally, which means that the strings are compared
|
||||||
* case sensitively, and with no conversion to or from any encoded forms.
|
* case sensitively, and with no conversion to or from any encoded forms.
|
||||||
* For example. Given a HttpServer with the following HttpContexts configured.
|
* For example. Given a HttpServer with the following HttpContexts configured.
|
||||||
* <table><caption style="display:none">description</caption>
|
* <table class="striped"><caption style="display:none">description</caption>
|
||||||
* <tr><td><i>Context</i></td><td><i>Context path</i></td></tr>
|
* <thead>
|
||||||
* <tr><td>ctx1</td><td>"/"</td></tr>
|
* <tr><th scope="col"><i>Context</i></th><th scope="col"><i>Context path</i></th></tr>
|
||||||
* <tr><td>ctx2</td><td>"/apps/"</td></tr>
|
* </thead>
|
||||||
* <tr><td>ctx3</td><td>"/apps/foo/"</td></tr>
|
* <tbody>
|
||||||
|
* <tr><th scope="row">ctx1</th><td>"/"</td></tr>
|
||||||
|
* <tr><th scope="row">ctx2</th><td>"/apps/"</td></tr>
|
||||||
|
* <tr><th scope="row">ctx3</th><td>"/apps/foo/"</td></tr>
|
||||||
|
* </tbody>
|
||||||
* </table>
|
* </table>
|
||||||
* <p>
|
* <p>
|
||||||
* the following table shows some request URIs and which, if any context they would
|
* the following table shows some request URIs and which, if any context they would
|
||||||
* match with.
|
* match with.
|
||||||
* <table><caption style="display:none">description</caption>
|
* <table class="striped"><caption style="display:none">description</caption>
|
||||||
* <tr><td><i>Request URI</i></td><td><i>Matches context</i></td></tr>
|
* <thead>
|
||||||
* <tr><td>"http://foo.com/apps/foo/bar"</td><td>ctx3</td></tr>
|
* <tr><th scope="col"><i>Request URI</i></th><th scope="col"><i>Matches context</i></th></tr>
|
||||||
* <tr><td>"http://foo.com/apps/Foo/bar"</td><td>no match, wrong case</td></tr>
|
* </thead>
|
||||||
* <tr><td>"http://foo.com/apps/app1"</td><td>ctx2</td></tr>
|
* <tbody>
|
||||||
* <tr><td>"http://foo.com/foo"</td><td>ctx1</td></tr>
|
* <tr><th scope="row">"http://foo.com/apps/foo/bar"</th><td>ctx3</td></tr>
|
||||||
|
* <tr><th scope="row">"http://foo.com/apps/Foo/bar"</th><td>no match, wrong case</td></tr>
|
||||||
|
* <tr><th scope="row">"http://foo.com/apps/app1"</th><td>ctx2</td></tr>
|
||||||
|
* <tr><th scope="row">"http://foo.com/foo"</th><td>ctx1</td></tr>
|
||||||
|
* </tbody>
|
||||||
* </table>
|
* </table>
|
||||||
* <p>
|
* <p>
|
||||||
* <b>Note about socket backlogs</b><p>
|
* <b>Note about socket backlogs</b><p>
|
||||||
|
@ -618,7 +618,7 @@ public abstract class HttpResponse<T> {
|
|||||||
* on one of the given {@code CompletableFuture<Void}s which themselves complete
|
* on one of the given {@code CompletableFuture<Void}s which themselves complete
|
||||||
* after all individual responses associated with the multi response
|
* after all individual responses associated with the multi response
|
||||||
* have completed, or after all push promises have been received.
|
* have completed, or after all push promises have been received.
|
||||||
* <p>
|
*
|
||||||
* @implNote Implementations might follow the pattern shown below
|
* @implNote Implementations might follow the pattern shown below
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
@ -633,7 +633,6 @@ public abstract class HttpResponse<T> {
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
* <p>
|
|
||||||
*
|
*
|
||||||
* @param onComplete a CompletableFuture which completes after all
|
* @param onComplete a CompletableFuture which completes after all
|
||||||
* responses have been received relating to this multi request.
|
* responses have been received relating to this multi request.
|
||||||
|
@ -275,6 +275,12 @@ public class SocketTransportService extends TransportService {
|
|||||||
sa = new InetSocketAddress(localaddress, port);
|
sa = new InetSocketAddress(localaddress, port);
|
||||||
}
|
}
|
||||||
ServerSocket ss = new ServerSocket();
|
ServerSocket ss = new ServerSocket();
|
||||||
|
if (port == 0) {
|
||||||
|
// Only need SO_REUSEADDR if we're using a fixed port. If we
|
||||||
|
// start seeing EADDRINUSE due to collisions in free ports
|
||||||
|
// then we should retry the bind() a few times.
|
||||||
|
ss.setReuseAddress(false);
|
||||||
|
}
|
||||||
ss.bind(sa);
|
ss.bind(sa);
|
||||||
return new SocketListenKey(ss);
|
return new SocketListenKey(ss);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -119,8 +119,26 @@ getLastError() {
|
|||||||
return (char *)dbgsysTlsGet(tlsIndex);
|
return (char *)dbgsysTlsGet(tlsIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set options common to client and server sides */
|
||||||
static jdwpTransportError
|
static jdwpTransportError
|
||||||
setOptions(int fd)
|
setOptionsCommon(int fd)
|
||||||
|
{
|
||||||
|
jvalue dontcare;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
dontcare.i = 0; /* keep compiler happy */
|
||||||
|
|
||||||
|
err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare);
|
||||||
|
if (err < 0) {
|
||||||
|
RETURN_IO_ERROR("setsockopt TCPNODELAY failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return JDWPTRANSPORT_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the SO_REUSEADDR option */
|
||||||
|
static jdwpTransportError
|
||||||
|
setReuseAddrOption(int fd)
|
||||||
{
|
{
|
||||||
jvalue dontcare;
|
jvalue dontcare;
|
||||||
int err;
|
int err;
|
||||||
@ -132,11 +150,6 @@ setOptions(int fd)
|
|||||||
RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed");
|
RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare);
|
|
||||||
if (err < 0) {
|
|
||||||
RETURN_IO_ERROR("setsockopt TCPNODELAY failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
return JDWPTRANSPORT_ERROR_NONE;
|
return JDWPTRANSPORT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,10 +363,21 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address,
|
|||||||
RETURN_IO_ERROR("socket creation failed");
|
RETURN_IO_ERROR("socket creation failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setOptions(serverSocketFD);
|
err = setOptionsCommon(serverSocketFD);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
if (sa.sin_port != 0) {
|
||||||
|
/*
|
||||||
|
* Only need SO_REUSEADDR if we're using a fixed port. If we
|
||||||
|
* start seeing EADDRINUSE due to collisions in free ports
|
||||||
|
* then we should retry the dbgsysBind() a few times.
|
||||||
|
*/
|
||||||
|
err = setReuseAddrOption(serverSocketFD);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = dbgsysBind(serverSocketFD, (struct sockaddr *)&sa, sizeof(sa));
|
err = dbgsysBind(serverSocketFD, (struct sockaddr *)&sa, sizeof(sa));
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
@ -510,11 +534,17 @@ socketTransport_attach(jdwpTransportEnv* env, const char* addressString, jlong a
|
|||||||
RETURN_IO_ERROR("unable to create socket");
|
RETURN_IO_ERROR("unable to create socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setOptions(socketFD);
|
err = setOptionsCommon(socketFD);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't call setReuseAddrOption() for the non-server socket
|
||||||
|
* case. If we start seeing EADDRINUSE due to collisions in free
|
||||||
|
* ports then we should retry the dbgsysConnect() a few times.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To do a timed connect we make the socket non-blocking
|
* To do a timed connect we make the socket non-blocking
|
||||||
* and poll with a timeout;
|
* and poll with a timeout;
|
||||||
|
File diff suppressed because it is too large
Load Diff
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