--- a/.hgtags-top-repo Wed Jul 05 16:43:18 2017 +0200
+++ b/.hgtags-top-repo Wed Jul 05 16:43:43 2017 +0200
@@ -13,3 +13,4 @@
4b4f5fea8d7d0743f0c30d91fcd9bf9d96e5d2ad jdk7-b36
744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37
cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
+ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
--- a/corba/.hgtags Wed Jul 05 16:43:18 2017 +0200
+++ b/corba/.hgtags Wed Jul 05 16:43:43 2017 +0200
@@ -13,3 +13,4 @@
0723891eb8d1c27e67c54163af0b4cea05a4e036 jdk7-b36
59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37
08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
+55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
--- a/hotspot/.hgtags Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/.hgtags Wed Jul 05 16:43:43 2017 +0200
@@ -13,3 +13,4 @@
e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
+49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
--- a/hotspot/make/hotspot_version Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/make/hotspot_version Wed Jul 05 16:43:43 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=14
HS_MINOR_VER=0
-HS_BUILD_NUMBER=06
+HS_BUILD_NUMBER=07
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -2615,7 +2615,8 @@
}
}
-void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg,
+void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
+ Register temp_reg,
Label& done, Label* slow_case,
BiasedLockingCounters* counters) {
assert(UseBiasedLocking, "why call this otherwise?");
@@ -2691,8 +2692,7 @@
markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place,
mark_reg);
or3(G2_thread, mark_reg, temp_reg);
- casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ casn(mark_addr.base(), mark_reg, temp_reg);
// If the biasing toward our thread failed, this means that
// another thread succeeded in biasing it toward itself and we
// need to revoke that bias. The revocation will occur in the
@@ -2721,8 +2721,7 @@
load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
or3(G2_thread, temp_reg, temp_reg);
- casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ casn(mark_addr.base(), mark_reg, temp_reg);
// If the biasing toward our thread failed, this means that
// another thread succeeded in biasing it toward itself and we
// need to revoke that bias. The revocation will occur in the
@@ -2752,8 +2751,7 @@
// bits in this situation. Should attempt to preserve them.
load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
- casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ casn(mark_addr.base(), mark_reg, temp_reg);
// Fall through to the normal CAS-based lock, because no matter what
// the result of the above CAS, some thread must have succeeded in
// removing the bias bit from the object's header.
@@ -2815,8 +2813,10 @@
// effect).
-void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
- BiasedLockingCounters* counters) {
+void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
+ Register Rbox, Register Rscratch,
+ BiasedLockingCounters* counters,
+ bool try_bias) {
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
verify_oop(Roop);
@@ -2838,7 +2838,7 @@
// Fetch object's markword
ld_ptr(mark_addr, Rmark);
- if (UseBiasedLocking) {
+ if (try_bias) {
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
}
@@ -2881,7 +2881,7 @@
ld_ptr (mark_addr, Rmark); // fetch obj->mark
// Triage: biased, stack-locked, neutral, inflated
- if (UseBiasedLocking) {
+ if (try_bias) {
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
// Invariant: if control reaches this point in the emitted stream
// then Rmark has not been modified.
@@ -2945,7 +2945,7 @@
ld_ptr (mark_addr, Rmark); // fetch obj->mark
// Triage: biased, stack-locked, neutral, inflated
- if (UseBiasedLocking) {
+ if (try_bias) {
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
// Invariant: if control reaches this point in the emitted stream
// then Rmark has not been modified.
@@ -3039,7 +3039,9 @@
bind (done) ;
}
-void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch) {
+void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
+ Register Rbox, Register Rscratch,
+ bool try_bias) {
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
Label done ;
@@ -3050,7 +3052,7 @@
}
if (EmitSync & 8) {
- if (UseBiasedLocking) {
+ if (try_bias) {
biased_locking_exit(mark_addr, Rscratch, done);
}
@@ -3077,7 +3079,7 @@
// I$ effects.
Label LStacked ;
- if (UseBiasedLocking) {
+ if (try_bias) {
// TODO: eliminate redundant LDs of obj->mark
biased_locking_exit(mark_addr, Rscratch, done);
}
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -2220,9 +2220,13 @@
// These set the icc condition code to equal if the lock succeeded
// and notEqual if it failed and requires a slow case
- void compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
- BiasedLockingCounters* counters = NULL);
- void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch);
+ void compiler_lock_object(Register Roop, Register Rmark, Register Rbox,
+ Register Rscratch,
+ BiasedLockingCounters* counters = NULL,
+ bool try_bias = UseBiasedLocking);
+ void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox,
+ Register Rscratch,
+ bool try_bias = UseBiasedLocking);
// Biased locking support
// Upon entry, lock_reg must point to the lock record on the stack,
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -906,7 +906,7 @@
// load next super to check
if (UseCompressedOops) {
- ld( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
+ lduw( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
// Bump array pointer forward one oop
add( Rtmp2, 4, Rtmp2 );
} else {
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 16:43:43 2017 +0200
@@ -395,6 +395,7 @@
);
reg_class g1_regL(R_G1H,R_G1);
+reg_class g3_regL(R_G3H,R_G3);
reg_class o2_regL(R_O2H,R_O2);
reg_class o7_regL(R_O7H,R_O7);
@@ -1743,7 +1744,7 @@
//
// NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
return false;
}
@@ -1926,18 +1927,23 @@
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
%}
+ enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
+ emit_form3_mem_reg(cbuf, this, $primary, -1,
+ $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
+ %}
+
enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
- emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary,
+ emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
%}
enc_class form3_mem_prefetch_read( memory mem ) %{
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+ emit_form3_mem_reg(cbuf, this, $primary, -1,
$mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
%}
enc_class form3_mem_prefetch_write( memory mem ) %{
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+ emit_form3_mem_reg(cbuf, this, $primary, -1,
$mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
%}
@@ -1945,8 +1951,8 @@
assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" );
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
guarantee($mem$$index == R_G0_enc, "double index?");
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg );
emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
%}
@@ -1956,14 +1962,14 @@
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
guarantee($mem$$index == R_G0_enc, "double index?");
// Load long with 2 instructions
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 );
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
%}
//%%% form3_mem_plus_4_reg is a hack--get rid of it
enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
%}
enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
@@ -2683,7 +2689,7 @@
assert(Rbox != Rscratch, "");
assert(Rbox != Rmark, "");
- __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters);
+ __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters, UseBiasedLocking && !UseOptoBiasInlining);
%}
enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
@@ -2699,7 +2705,7 @@
assert(Rbox != Rscratch, "");
assert(Rbox != Rmark, "");
- __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch);
+ __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch, UseBiasedLocking && !UseOptoBiasInlining);
%}
enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{
@@ -2711,8 +2717,7 @@
// casx_under_lock picks 1 of 3 encodings:
// For 32-bit pointers you get a 32-bit CAS
// For 64-bit pointers you get a 64-bit CASX
- __ casx_under_lock(Rmem, Rold, Rnew, // Swap(*Rmem,Rnew) if *Rmem == Rold
- (address) StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ __ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
__ cmp( Rold, Rnew );
%}
@@ -3761,6 +3766,14 @@
interface(REG_INTER);
%}
+operand g3RegL() %{
+ constraint(ALLOC_IN_RC(g3_regL));
+ match(iRegL);
+
+ format %{ %}
+ interface(REG_INTER);
+%}
+
// Int Register safe
// This is 64bit safe
operand iRegIsafe() %{
@@ -5062,7 +5075,7 @@
size(4);
format %{ "LDF $src,$dst\t! stkI to regF" %}
opcode(Assembler::ldf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadF_stk);
%}
@@ -5073,7 +5086,7 @@
size(4);
format %{ "LDDF $src,$dst\t! stkL to regD" %}
opcode(Assembler::lddf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadD_stk);
%}
@@ -5084,7 +5097,7 @@
size(4);
format %{ "STF $src,$dst\t! regF to stkI" %}
opcode(Assembler::stf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreF_stk_reg);
%}
@@ -5095,7 +5108,7 @@
size(4);
format %{ "STDF $src,$dst\t! regD to stkL" %}
opcode(Assembler::stdf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreD_stk_reg);
%}
@@ -5106,7 +5119,7 @@
format %{ "STW $src,$dst.hi\t! long\n\t"
"STW R_G0,$dst.lo" %}
opcode(Assembler::stw_op3);
- ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
+ ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
ins_pipe(lstoreI_stk_reg);
%}
@@ -5117,7 +5130,7 @@
size(4);
format %{ "STX $src,$dst\t! regL to stkD" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_stk_reg);
%}
@@ -5131,7 +5144,7 @@
size(4);
format %{ "LDUW $src,$dst\t!stk" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
@@ -5143,7 +5156,7 @@
size(4);
format %{ "STW $src,$dst\t!stk" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
@@ -5155,7 +5168,7 @@
size(4);
format %{ "LDX $src,$dst\t! long" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
@@ -5167,7 +5180,7 @@
size(4);
format %{ "STX $src,$dst\t! long" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
@@ -5179,7 +5192,7 @@
size(4);
format %{ "LDX $src,$dst\t!ptr" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
@@ -5190,7 +5203,7 @@
size(4);
format %{ "STX $src,$dst\t!ptr" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
#else // _LP64
@@ -5200,7 +5213,7 @@
ins_cost(MEMORY_REF_COST);
format %{ "LDUW $src,$dst\t!ptr" %}
opcode(Assembler::lduw_op3, Assembler::ldst_op);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
@@ -5210,7 +5223,7 @@
ins_cost(MEMORY_REF_COST);
format %{ "STW $src,$dst\t!ptr" %}
opcode(Assembler::stw_op3, Assembler::ldst_op);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
#endif // _LP64
@@ -5273,7 +5286,7 @@
size(4);
format %{ "LDSB $mem,$dst" %}
opcode(Assembler::ldsb_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
@@ -5285,7 +5298,7 @@
size(4);
format %{ "LDUB $mem,$dst" %}
opcode(Assembler::ldub_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
@@ -5297,7 +5310,7 @@
size(4);
format %{ "LDUB $mem,$dst" %}
opcode(Assembler::ldub_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
@@ -5309,7 +5322,7 @@
size(4);
format %{ "LDUH $mem,$dst" %}
opcode(Assembler::lduh_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
@@ -5321,7 +5334,7 @@
size(4);
format %{ "LDUH $mem,$dst" %}
opcode(Assembler::lduh_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
@@ -5333,7 +5346,7 @@
format %{ "LDUW $mem,$dst" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
@@ -5344,7 +5357,7 @@
size(4);
format %{ "LDX $mem,$dst\t! long" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
@@ -5359,7 +5372,7 @@
"\tSLLX #32, $dst, $dst\n"
"\tOR $dst, R_O7, $dst" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst ));
+ ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst ));
ins_pipe(iload_mem);
%}
@@ -5370,7 +5383,7 @@
size(4);
format %{ "LDDF $mem,$dst\t! packed8B" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
@@ -5381,7 +5394,7 @@
size(4);
format %{ "LDDF $mem,$dst\t! packed4C" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
@@ -5392,7 +5405,7 @@
size(4);
format %{ "LDDF $mem,$dst\t! packed4S" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
@@ -5403,7 +5416,7 @@
size(4);
format %{ "LDDF $mem,$dst\t! packed2I" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
@@ -5415,7 +5428,7 @@
size(4);
format %{ "LDUW $mem,$dst\t! range" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
@@ -5427,7 +5440,7 @@
format %{ "LDF $mem,$dst\t! for fitos/fitod" %}
opcode(Assembler::ldf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadF_mem);
%}
@@ -5514,7 +5527,7 @@
size(4);
format %{ "LDSH $mem,$dst" %}
opcode(Assembler::ldsh_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
@@ -5526,7 +5539,7 @@
size(4);
format %{ "LDDF $mem,$dst" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
@@ -5550,7 +5563,7 @@
size(4);
format %{ "LDF $mem,$dst" %}
opcode(Assembler::ldf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadF_mem);
%}
@@ -5719,7 +5732,7 @@
size(4);
format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
@@ -5730,7 +5743,7 @@
size(4);
format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
@@ -5741,7 +5754,7 @@
size(4);
format %{ "STB $src,$mem\t! CMS card-mark byte 0" %}
opcode(Assembler::stb_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
@@ -5753,7 +5766,7 @@
size(4);
format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
@@ -5764,7 +5777,7 @@
size(4);
format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
@@ -5776,7 +5789,7 @@
size(4);
format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
@@ -5787,7 +5800,7 @@
size(4);
format %{ "STX $src,$mem\t! long" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
@@ -5798,7 +5811,7 @@
size(4);
format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
@@ -5809,7 +5822,7 @@
size(4);
format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
@@ -5821,7 +5834,7 @@
size(4);
format %{ "STF $src,$mem\t! after fstoi/fdtoi" %}
opcode(Assembler::stf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreF_mem_reg);
%}
@@ -5904,7 +5917,7 @@
size(4);
format %{ "STDF $src,$mem" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
@@ -5915,7 +5928,7 @@
size(4);
format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
@@ -5927,7 +5940,7 @@
size(4);
format %{ "STF $src,$mem" %}
opcode(Assembler::stf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreF_mem_reg);
%}
@@ -5938,7 +5951,7 @@
size(4);
format %{ "STW $src,$mem\t! storeF0" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreF_mem_zero);
%}
@@ -5949,7 +5962,7 @@
size(4);
format %{ "STDF $src,$mem\t! packed8B" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
@@ -6004,7 +6017,7 @@
size(4);
format %{ "STX $zero,$mem\t! packed8B" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
@@ -6015,7 +6028,7 @@
size(4);
format %{ "STDF $src,$mem\t! packed4C" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
@@ -6026,7 +6039,7 @@
size(4);
format %{ "STX $zero,$mem\t! packed4C" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
@@ -6037,7 +6050,7 @@
size(4);
format %{ "STDF $src,$mem\t! packed2I" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
@@ -6048,7 +6061,7 @@
size(4);
format %{ "STX $zero,$mem\t! packed2I" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
@@ -6162,7 +6175,7 @@
ins_cost(MEMORY_REF_COST);
format %{ "STDF $src,$stkSlot\t!stk" %}
opcode(Assembler::stdf_op3);
- ins_encode(form3_mem_reg(stkSlot, src));
+ ins_encode(simple_form3_mem_reg(stkSlot, src));
ins_pipe(fstoreD_stk_reg);
%}
@@ -6172,7 +6185,7 @@
ins_cost(MEMORY_REF_COST);
format %{ "LDDF $stkSlot,$dst\t!stk" %}
opcode(Assembler::lddf_op3);
- ins_encode(form3_mem_reg(stkSlot, dst));
+ ins_encode(simple_form3_mem_reg(stkSlot, dst));
ins_pipe(floadD_stk);
%}
@@ -6182,7 +6195,7 @@
ins_cost(MEMORY_REF_COST);
format %{ "STF $src,$stkSlot\t!stk" %}
opcode(Assembler::stf_op3);
- ins_encode(form3_mem_reg(stkSlot, src));
+ ins_encode(simple_form3_mem_reg(stkSlot, src));
ins_pipe(fstoreF_stk_reg);
%}
@@ -6584,7 +6597,7 @@
size(4);
format %{ "LDX $mem,$dst\t! long" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
@@ -6597,32 +6610,23 @@
ins_pipe( long_memory_op );
%}
-instruct storeLConditional_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
- match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
- effect( USE mem_ptr, KILL ccr, KILL tmp1);
- // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
- format %{
- "MOV $newval,R_O7\n\t"
- "CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
- "CMP $oldval,R_O7\t\t! See if we made progress\n\t"
- "MOV 1,$res\n\t"
- "MOVne xcc,R_G0,$res"
- %}
- ins_encode( enc_casx(mem_ptr, oldval, newval),
- enc_lflags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+instruct storeIConditional( iRegP mem_ptr, iRegI oldval, g3RegI newval, flagsReg icc ) %{
+ match(Set icc (StoreIConditional mem_ptr (Binary oldval newval)));
+ effect( KILL newval );
+ format %{ "CASA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+ "CMP $oldval,$newval\t\t! See if we made progress" %}
+ ins_encode( enc_cas(mem_ptr,oldval,newval) );
ins_pipe( long_memory_op );
%}
-instruct storeLConditional_flags(iRegP mem_ptr, iRegL oldval, iRegL newval, flagsRegL xcc, o7RegI tmp1, immI0 zero) %{
- match(Set xcc (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
- effect( USE mem_ptr, KILL tmp1);
- // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
- format %{
- "MOV $newval,R_O7\n\t"
- "CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
- "CMP $oldval,R_O7\t\t! See if we made progress"
- %}
- ins_encode( enc_casx(mem_ptr, oldval, newval));
+// Conditional-store of a long value.
+instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
+ match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
+ effect( KILL newval );
+ format %{ "CASXA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+ "CMP $oldval,$newval\t\t! See if we made progress" %}
+ ins_encode( enc_cas(mem_ptr,oldval,newval) );
ins_pipe( long_memory_op );
%}
@@ -7405,6 +7409,34 @@
ins_pipe(ialu_reg_imm);
%}
+#ifndef _LP64
+
+// Use sp_ptr_RegP to match G2 (TLS register) without spilling.
+instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
+ match(Set dst (OrI src1 (CastP2X src2)));
+
+ size(4);
+ format %{ "OR $src1,$src2,$dst" %}
+ opcode(Assembler::or_op3, Assembler::arith_op);
+ ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+ ins_pipe(ialu_reg_reg);
+%}
+
+#else
+
+instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{
+ match(Set dst (OrL src1 (CastP2X src2)));
+
+ ins_cost(DEFAULT_COST);
+ size(4);
+ format %{ "OR $src1,$src2,$dst\t! long" %}
+ opcode(Assembler::or_op3, Assembler::arith_op);
+ ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+ ins_pipe(ialu_reg_reg);
+%}
+
+#endif
+
// Xor Instructions
// Register Xor
instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
@@ -7666,7 +7698,7 @@
format %{ "LDF $mem,$dst\n\t"
"FITOD $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitod_opf);
- ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+ ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
ins_pipe(floadF_mem);
%}
@@ -7696,7 +7728,7 @@
format %{ "LDF $mem,$dst\n\t"
"FITOS $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitos_opf);
- ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+ ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
ins_pipe(floadF_mem);
%}
@@ -7738,7 +7770,7 @@
size(4);
format %{ "LDUW $src,$dst\t! MoveF2I" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
@@ -7750,7 +7782,7 @@
size(4);
format %{ "LDF $src,$dst\t! MoveI2F" %}
opcode(Assembler::ldf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadF_stk);
%}
@@ -7762,7 +7794,7 @@
size(4);
format %{ "LDX $src,$dst\t! MoveD2L" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
@@ -7774,7 +7806,7 @@
size(4);
format %{ "LDDF $src,$dst\t! MoveL2D" %}
opcode(Assembler::lddf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadD_stk);
%}
@@ -7786,7 +7818,7 @@
size(4);
format %{ "STF $src,$dst\t!MoveF2I" %}
opcode(Assembler::stf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreF_stk_reg);
%}
@@ -7798,7 +7830,7 @@
size(4);
format %{ "STW $src,$dst\t!MoveI2F" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
@@ -7810,7 +7842,7 @@
size(4);
format %{ "STDF $src,$dst\t!MoveD2L" %}
opcode(Assembler::stdf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreD_stk_reg);
%}
@@ -7822,7 +7854,7 @@
size(4);
format %{ "STX $src,$dst\t!MoveL2D" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -956,7 +956,7 @@
// Load a little early; will load 1 off the end of the array.
// Ok for now; revisit if we have other uses of this routine.
if (UseCompressedOops) {
- __ ld(L1_ary_ptr,0,L2_super);// Will load a little early
+ __ lduw(L1_ary_ptr,0,L2_super);// Will load a little early
} else {
__ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
}
@@ -973,7 +973,7 @@
#ifdef _LP64
__ subcc(L2_super,L4_ooptmp,Rret); // Check for match; zero in Rret for a hit
__ br( Assembler::notEqual, false, Assembler::pt, loop );
- __ delayed()->ld(L1_ary_ptr,0,L2_super);// Will load a little early
+ __ delayed()->lduw(L1_ary_ptr,0,L2_super);// Will load a little early
#else
ShouldNotReachHere();
#endif
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -621,6 +621,10 @@
debug_only(has_disp32 = true);
break;
+ case 0xF0: // Lock
+ assert(os::is_MP(), "only on MP");
+ goto again_after_prefix;
+
case 0xF3: // For SSE
case 0xF2: // For SSE2
switch (0xFF & *ip++) {
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -1780,7 +1780,8 @@
// check info (currently consumed only by C1). If
// swap_reg_contains_mark is true then returns -1 as it is assumed
// the calling code has already passed any potential faults.
- int biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg,
+ int biased_locking_enter(Register lock_reg, Register obj_reg,
+ Register swap_reg, Register tmp_reg,
bool swap_reg_contains_mark,
Label& done, Label* slow_case = NULL,
BiasedLockingCounters* counters = NULL);
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 16:43:43 2017 +0200
@@ -495,8 +495,8 @@
void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
Compile* C = ra_->C;
if( C->in_24_bit_fp_mode() ) {
- tty->print("FLDCW 24 bit fpu control word");
- tty->print_cr(""); tty->print("\t");
+ st->print("FLDCW 24 bit fpu control word");
+ st->print_cr(""); st->print("\t");
}
int framesize = C->frame_slots() << LogBytesPerInt;
@@ -510,22 +510,22 @@
// stack. But the stack safety zone should account for that.
// See bugs 4446381, 4468289, 4497237.
if (C->need_stack_bang(framesize)) {
- tty->print_cr("# stack bang"); tty->print("\t");
+ st->print_cr("# stack bang"); st->print("\t");
}
- tty->print_cr("PUSHL EBP"); tty->print("\t");
+ st->print_cr("PUSHL EBP"); st->print("\t");
if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
- tty->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
- tty->print_cr(""); tty->print("\t");
+ st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
+ st->print_cr(""); st->print("\t");
framesize -= wordSize;
}
if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
if (framesize) {
- tty->print("SUB ESP,%d\t# Create frame",framesize);
+ st->print("SUB ESP,%d\t# Create frame",framesize);
}
} else {
- tty->print("SUB ESP,%d\t# Create frame",framesize);
+ st->print("SUB ESP,%d\t# Create frame",framesize);
}
}
#endif
@@ -725,18 +725,19 @@
return rc_xmm;
}
-static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size ) {
+static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
+ int opcode, const char *op_str, int size, outputStream* st ) {
if( cbuf ) {
emit_opcode (*cbuf, opcode );
encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
#ifndef PRODUCT
} else if( !do_size ) {
- if( size != 0 ) tty->print("\n\t");
+ if( size != 0 ) st->print("\n\t");
if( opcode == 0x8B || opcode == 0x89 ) { // MOV
- if( is_load ) tty->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
- else tty->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
+ if( is_load ) st->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
+ else st->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
} else { // FLD, FST, PUSH, POP
- tty->print("%s [ESP + #%d]",op_str,offset);
+ st->print("%s [ESP + #%d]",op_str,offset);
}
#endif
}
@@ -746,7 +747,7 @@
// Helper for XMM registers. Extra opcode bits, limited syntax.
static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
- int offset, int reg_lo, int reg_hi, int size ) {
+ int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
if( cbuf ) {
if( reg_lo+1 == reg_hi ) { // double move?
if( is_load && !UseXmmLoadAndClearUpper )
@@ -764,17 +765,17 @@
encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
#ifndef PRODUCT
} else if( !do_size ) {
- if( size != 0 ) tty->print("\n\t");
+ if( size != 0 ) st->print("\n\t");
if( reg_lo+1 == reg_hi ) { // double move?
- if( is_load ) tty->print("%s %s,[ESP + #%d]",
+ if( is_load ) st->print("%s %s,[ESP + #%d]",
UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
Matcher::regName[reg_lo], offset);
- else tty->print("MOVSD [ESP + #%d],%s",
+ else st->print("MOVSD [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]);
} else {
- if( is_load ) tty->print("MOVSS %s,[ESP + #%d]",
+ if( is_load ) st->print("MOVSS %s,[ESP + #%d]",
Matcher::regName[reg_lo], offset);
- else tty->print("MOVSS [ESP + #%d],%s",
+ else st->print("MOVSS [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]);
}
#endif
@@ -785,7 +786,7 @@
static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
- int src_hi, int dst_hi, int size ) {
+ int src_hi, int dst_hi, int size, outputStream* st ) {
if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
if( cbuf ) {
if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
@@ -796,11 +797,11 @@
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
#ifndef PRODUCT
} else if( !do_size ) {
- if( size != 0 ) tty->print("\n\t");
+ if( size != 0 ) st->print("\n\t");
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
- tty->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+ st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else {
- tty->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+ st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
}
#endif
}
@@ -813,11 +814,11 @@
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
#ifndef PRODUCT
} else if( !do_size ) {
- if( size != 0 ) tty->print("\n\t");
+ if( size != 0 ) st->print("\n\t");
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
- tty->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+ st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else {
- tty->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+ st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
}
#endif
}
@@ -825,28 +826,29 @@
}
}
-static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size ) {
+static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
if( cbuf ) {
emit_opcode(*cbuf, 0x8B );
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
#ifndef PRODUCT
} else if( !do_size ) {
- if( size != 0 ) tty->print("\n\t");
- tty->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]);
+ if( size != 0 ) st->print("\n\t");
+ st->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]);
#endif
}
return size+2;
}
-static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, int offset, int size ) {
+static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
+ int offset, int size, outputStream* st ) {
if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there
if( cbuf ) {
emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it)
emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
#ifndef PRODUCT
} else if( !do_size ) {
- if( size != 0 ) tty->print("\n\t");
- tty->print("FLD %s",Matcher::regName[src_lo]);
+ if( size != 0 ) st->print("\n\t");
+ st->print("FLD %s",Matcher::regName[src_lo]);
#endif
}
size += 2;
@@ -864,7 +866,7 @@
assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
}
- return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size);
+ return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
}
uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
@@ -892,16 +894,16 @@
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
if( src_second == dst_first ) { // overlapping stack copy ranges
assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
- size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size);
- size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size);
+ size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
+ size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
}
// move low bits
- size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size);
- size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size);
+ size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st);
+ size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st);
if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
- size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size);
- size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size);
+ size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
+ size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
}
return size;
}
@@ -909,15 +911,15 @@
// --------------------------------------
// Check for integer reg-reg copy
if( src_first_rc == rc_int && dst_first_rc == rc_int )
- size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size);
+ size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
// Check for integer store
if( src_first_rc == rc_int && dst_first_rc == rc_stack )
- size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size);
+ size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
// Check for integer load
if( dst_first_rc == rc_int && src_first_rc == rc_stack )
- size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size);
+ size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
// --------------------------------------
// Check for float reg-reg copy
@@ -951,7 +953,7 @@
// Check for float store
if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
- return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size);
+ return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
}
// Check for float load
@@ -987,17 +989,17 @@
assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
(src_first+1 == src_second && dst_first+1 == dst_second),
"no non-adjacent float-moves" );
- return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size);
+ return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
}
// Check for xmm store
if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
- return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size);
+ return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
}
// Check for float xmm load
if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
- return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size);
+ return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
}
// Copy from float reg to xmm reg
@@ -1017,10 +1019,10 @@
}
size += 4;
- size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size);
+ size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
// Copy from the temp memory to the xmm reg.
- size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size);
+ size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
if( cbuf ) {
emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8]
@@ -1047,15 +1049,15 @@
// Check for second word int-int move
if( src_second_rc == rc_int && dst_second_rc == rc_int )
- return impl_mov_helper(cbuf,do_size,src_second,dst_second,size);
+ return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
// Check for second word integer store
if( src_second_rc == rc_int && dst_second_rc == rc_stack )
- return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size);
+ return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
// Check for second word integer load
if( dst_second_rc == rc_int && src_second_rc == rc_stack )
- return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size);
+ return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
Unimplemented();
@@ -1318,7 +1320,11 @@
//
// NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+ // the short version of jmpConUCF2 contains multiple branches,
+ // making the reach slightly less
+ if (rule == jmpConUCF2_rule)
+ return (-126 <= offset && offset <= 125);
return (-128 <= offset && offset <= 127);
}
@@ -3307,7 +3313,7 @@
// Beware -- there's a subtle invariant that fetch of the markword
// at [FETCH], below, will never observe a biased encoding (*101b).
// If this invariant is not held we risk exclusion (safety) failure.
- if (UseBiasedLocking) {
+ if (UseBiasedLocking && !UseOptoBiasInlining) {
masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
}
@@ -3528,7 +3534,7 @@
// Critically, the biased locking test must have precedence over
// and appear before the (box->dhw == 0) recursive stack-lock test.
- if (UseBiasedLocking) {
+ if (UseBiasedLocking && !UseOptoBiasInlining) {
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
}
@@ -5272,6 +5278,15 @@
interface(REG_INTER);
%}
+operand eFlagsRegUCF() %{
+ constraint(ALLOC_IN_RC(int_flags));
+ match(RegFlags);
+ predicate(false);
+
+ format %{ "EFLAGS_U_CF" %}
+ interface(REG_INTER);
+%}
+
// Condition Code Register used by long compare
operand flagsReg_long_LTGE() %{
constraint(ALLOC_IN_RC(int_flags));
@@ -5749,12 +5764,12 @@
format %{ "" %}
interface(COND_INTER) %{
- equal(0x4);
- not_equal(0x5);
- less(0xC);
- greater_equal(0xD);
- less_equal(0xE);
- greater(0xF);
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0xC, "l");
+ greater_equal(0xD, "ge");
+ less_equal(0xE, "le");
+ greater(0xF, "g");
%}
%}
@@ -5766,12 +5781,47 @@
format %{ "" %}
interface(COND_INTER) %{
- equal(0x4);
- not_equal(0x5);
- less(0x2);
- greater_equal(0x3);
- less_equal(0x6);
- greater(0x7);
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0x2, "b");
+ greater_equal(0x3, "nb");
+ less_equal(0x6, "be");
+ greater(0x7, "nbe");
+ %}
+%}
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+ match(Bool);
+ predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+ n->as_Bool()->_test._test == BoolTest::ge ||
+ n->as_Bool()->_test._test == BoolTest::le ||
+ n->as_Bool()->_test._test == BoolTest::gt);
+ format %{ "" %}
+ interface(COND_INTER) %{
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0x2, "b");
+ greater_equal(0x3, "nb");
+ less_equal(0x6, "be");
+ greater(0x7, "nbe");
+ %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+ match(Bool);
+ predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+ n->as_Bool()->_test._test == BoolTest::eq);
+ format %{ "" %}
+ interface(COND_INTER) %{
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0x2, "b");
+ greater_equal(0x3, "nb");
+ less_equal(0x6, "be");
+ greater(0x7, "nbe");
%}
%}
@@ -5796,12 +5846,12 @@
format %{ "" %}
interface(COND_INTER) %{
- equal(0x4);
- not_equal(0x5);
- less(0xF);
- greater_equal(0xE);
- less_equal(0xD);
- greater(0xC);
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0xF, "g");
+ greater_equal(0xE, "le");
+ less_equal(0xD, "ge");
+ greater(0xC, "l");
%}
%}
@@ -7357,7 +7407,7 @@
ins_pipe( pipe_cmov_reg );
%}
-instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
ins_cost(200);
@@ -7367,6 +7417,15 @@
ins_pipe( pipe_cmov_reg );
%}
+instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
+ predicate(VM_Version::supports_cmov() );
+ match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovI_regU(cop, cr, dst, src);
+ %}
+%}
+
// Conditional move
instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
predicate(VM_Version::supports_cmov() );
@@ -7379,7 +7438,7 @@
%}
// Conditional move
-instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
+instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250);
@@ -7389,6 +7448,15 @@
ins_pipe( pipe_cmov_mem );
%}
+instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
+ predicate(VM_Version::supports_cmov() );
+ match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+ ins_cost(250);
+ expand %{
+ cmovI_memU(cop, cr, dst, src);
+ %}
+%}
+
// Conditional move
instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
predicate(VM_Version::supports_cmov() );
@@ -7416,7 +7484,7 @@
%}
// Conditional move
-instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
ins_cost(200);
@@ -7426,6 +7494,15 @@
ins_pipe( pipe_cmov_reg );
%}
+instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
+ predicate(VM_Version::supports_cmov() );
+ match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovP_regU(cop, cr, dst, src);
+ %}
+%}
+
// DISABLED: Requires the ADLC to emit a bottom_type call that
// correctly meets the two pointer arguments; one is an incoming
// register but the other is a memory operand. ALSO appears to
@@ -7555,6 +7632,15 @@
ins_pipe( pipe_slow );
%}
+instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
+ predicate (UseSSE>=1);
+ match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ fcmovX_regU(cop, cr, dst, src);
+ %}
+%}
+
// unsigned version
instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
predicate (UseSSE>=2);
@@ -7573,6 +7659,15 @@
ins_pipe( pipe_slow );
%}
+instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
+ predicate (UseSSE>=2);
+ match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ fcmovXD_regU(cop, cr, dst, src);
+ %}
+%}
+
instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
@@ -7595,6 +7690,15 @@
ins_pipe( pipe_cmov_reg_long );
%}
+instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
+ predicate(VM_Version::supports_cmov() );
+ match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovL_regU(cop, cr, dst, src);
+ %}
+%}
+
//----------Arithmetic Instructions--------------------------------------------
//----------Addition Instructions----------------------------------------------
// Integer Addition Instructions
@@ -7826,33 +7930,36 @@
ins_pipe( pipe_cmpxchg );
%}
-// Conditional-store of a long value
-// Returns a boolean value (0/1) on success. Implemented with a CMPXCHG8 on Intel.
-// mem_ptr can actually be in either ESI or EDI
-instruct storeLConditional( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
- match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
- effect(KILL cr);
- // EDX:EAX is killed if there is contention, but then it's also unused.
- // In the common case of no contention, EDX:EAX holds the new oop address.
- format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
- "MOV $res,0\n\t"
- "JNE,s fail\n\t"
- "MOV $res,1\n"
- "fail:" %}
- ins_encode( enc_cmpxchg8(mem_ptr),
- enc_flags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
+instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{
+ match(Set cr (StoreIConditional mem (Binary oldval newval)));
+ effect(KILL oldval);
+ format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
+ ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
ins_pipe( pipe_cmpxchg );
%}
-// Conditional-store of a long value
-// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
-// mem_ptr can actually be in either ESI or EDI
-instruct storeLConditional_flags( eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr, immI0 zero ) %{
- match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
- // EDX:EAX is killed if there is contention, but then it's also unused.
- // In the common case of no contention, EDX:EAX holds the new oop address.
- format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
- ins_encode( enc_cmpxchg8(mem_ptr) );
+// Conditional-store of a long value.
+// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
+instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
+ match(Set cr (StoreLConditional mem (Binary oldval newval)));
+ effect(KILL oldval);
+ format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
+ "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
+ "XCHG EBX,ECX"
+ %}
+ ins_encode %{
+ // Note: we need to swap rbx, and rcx before and after the
+ // cmpxchg8 instruction because the instruction uses
+ // rcx as the high order word of the new value to store but
+ // our register encoding uses rbx.
+ __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
+ if( os::is_MP() )
+ __ lock();
+ __ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp));
+ __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
+ %}
ins_pipe( pipe_cmpxchg );
%}
@@ -8319,6 +8426,7 @@
ins_pipe( ialu_reg );
%}
+
// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
// This idiom is used by the compiler for the i2b bytecode.
instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
@@ -8436,6 +8544,18 @@
ins_pipe( ialu_reg_reg );
%}
+instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{
+ match(Set dst (OrI dst (CastP2X src)));
+ effect(KILL cr);
+
+ size(2);
+ format %{ "OR $dst,$src" %}
+ opcode(0x0B);
+ ins_encode( OpcP, RegReg( dst, src) );
+ ins_pipe( ialu_reg_reg );
+%}
+
+
// Or Register with Immediate
instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
match(Set dst (OrI dst src));
@@ -9200,6 +9320,18 @@
ins_pipe( pipe_slow );
%}
+instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
+ predicate(VM_Version::supports_cmov() && UseSSE <=1);
+ match(Set cr (CmpD src1 src2));
+ ins_cost(150);
+ format %{ "FLD $src1\n\t"
+ "FUCOMIP ST,$src2 // P6 instruction" %}
+ opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+ ins_encode( Push_Reg_D(src1),
+ OpcP, RegOpc(src2));
+ ins_pipe( pipe_slow );
+%}
+
// Compare & branch
instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
predicate(UseSSE<=1);
@@ -9264,6 +9396,16 @@
ins_pipe( pipe_slow );
%}
+instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
+ predicate(UseSSE>=2);
+ match(Set cr (CmpD dst src));
+ ins_cost(100);
+ format %{ "COMISD $dst,$src" %}
+ opcode(0x66, 0x0F, 0x2F);
+ ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
+ ins_pipe( pipe_slow );
+%}
+
// float compare and set condition codes in EFLAGS by XMM regs
instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
predicate(UseSSE>=2);
@@ -9280,6 +9422,16 @@
ins_pipe( pipe_slow );
%}
+instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
+ predicate(UseSSE>=2);
+ match(Set cr (CmpD dst (LoadD src)));
+ ins_cost(100);
+ format %{ "COMISD $dst,$src" %}
+ opcode(0x66, 0x0F, 0x2F);
+ ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
+ ins_pipe( pipe_slow );
+%}
+
// Compare into -1,0,1 in XMM
instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
predicate(UseSSE>=2);
@@ -10167,6 +10319,18 @@
ins_pipe( pipe_slow );
%}
+instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
+ predicate(VM_Version::supports_cmov() && UseSSE == 0);
+ match(Set cr (CmpF src1 src2));
+ ins_cost(100);
+ format %{ "FLD $src1\n\t"
+ "FUCOMIP ST,$src2 // P6 instruction" %}
+ opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+ ins_encode( Push_Reg_D(src1),
+ OpcP, RegOpc(src2));
+ ins_pipe( pipe_slow );
+%}
+
// Compare & branch
instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
@@ -10232,6 +10396,16 @@
ins_pipe( pipe_slow );
%}
+instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
+ predicate(UseSSE>=1);
+ match(Set cr (CmpF dst src));
+ ins_cost(100);
+ format %{ "COMISS $dst,$src" %}
+ opcode(0x0F, 0x2F);
+ ins_encode(OpcP, OpcS, RegReg(dst, src));
+ ins_pipe( pipe_slow );
+%}
+
// float compare and set condition codes in EFLAGS by XMM regs
instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
predicate(UseSSE>=1);
@@ -10248,6 +10422,16 @@
ins_pipe( pipe_slow );
%}
+instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
+ predicate(UseSSE>=1);
+ match(Set cr (CmpF dst (LoadF src)));
+ ins_cost(100);
+ format %{ "COMISS $dst,$src" %}
+ opcode(0x0F, 0x2F);
+ ins_encode(OpcP, OpcS, RegMem(dst, src));
+ ins_pipe( pipe_slow );
+%}
+
// Compare into -1,0,1 in XMM
instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
predicate(UseSSE>=1);
@@ -12099,6 +12283,19 @@
ins_pc_relative(1);
%}
+instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+ match(CountedLoopEnd cop cmp);
+ effect(USE labl);
+
+ ins_cost(200);
+ format %{ "J$cop,u $labl\t# Loop end" %}
+ size(6);
+ opcode(0x0F, 0x80);
+ ins_encode( Jcc( cop, labl) );
+ ins_pipe( pipe_jcc );
+ ins_pc_relative(1);
+%}
+
// Jump Direct Conditional - using unsigned comparison
instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
match(If cop cmp);
@@ -12108,8 +12305,63 @@
format %{ "J$cop,u $labl" %}
size(6);
opcode(0x0F, 0x80);
- ins_encode( Jcc( cop, labl) );
- ins_pipe( pipe_jcc );
+ ins_encode(Jcc(cop, labl));
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(200);
+ format %{ "J$cop,u $labl" %}
+ size(6);
+ opcode(0x0F, 0x80);
+ ins_encode(Jcc(cop, labl));
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+%}
+
+instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(200);
+ format %{ $$template
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ $$emit$$"JP,u $labl\n\t"
+ $$emit$$"J$cop,u $labl"
+ } else {
+ $$emit$$"JP,u done\n\t"
+ $$emit$$"J$cop,u $labl\n\t"
+ $$emit$$"done:"
+ }
+ %}
+ size(12);
+ opcode(0x0F, 0x80);
+ ins_encode %{
+ Label* l = $labl$$label;
+ $$$emit8$primary;
+ emit_cc(cbuf, $secondary, Assembler::parity);
+ int parity_disp = -1;
+ bool ok = false;
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ // the two jumps 6 bytes apart so the jump distances are too
+ parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+ } else if ($cop$$cmpcode == Assembler::equal) {
+ parity_disp = 6;
+ ok = true;
+ } else {
+ ShouldNotReachHere();
+ }
+ emit_d32(cbuf, parity_disp);
+ $$$emit8$primary;
+ emit_cc(cbuf, $secondary, $cop$$cmpcode);
+ int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+ emit_d32(cbuf, disp);
+ %}
+ ins_pipe(pipe_jcc);
ins_pc_relative(1);
%}
@@ -12208,7 +12460,7 @@
effect(USE labl);
ins_cost(300);
- format %{ "J$cop,s $labl" %}
+ format %{ "J$cop,s $labl\t# Loop end" %}
size(2);
opcode(0x70);
ins_encode( JccShort( cop, labl) );
@@ -12223,7 +12475,21 @@
effect(USE labl);
ins_cost(300);
- format %{ "J$cop,us $labl" %}
+ format %{ "J$cop,us $labl\t# Loop end" %}
+ size(2);
+ opcode(0x70);
+ ins_encode( JccShort( cop, labl) );
+ ins_pipe( pipe_jcc );
+ ins_pc_relative(1);
+ ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+ match(CountedLoopEnd cop cmp);
+ effect(USE labl);
+
+ ins_cost(300);
+ format %{ "J$cop,us $labl\t# Loop end" %}
size(2);
opcode(0x70);
ins_encode( JccShort( cop, labl) );
@@ -12247,6 +12513,60 @@
ins_short_branch(1);
%}
+instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(300);
+ format %{ "J$cop,us $labl" %}
+ size(2);
+ opcode(0x70);
+ ins_encode( JccShort( cop, labl) );
+ ins_pipe( pipe_jcc );
+ ins_pc_relative(1);
+ ins_short_branch(1);
+%}
+
+instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(300);
+ format %{ $$template
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ $$emit$$"JP,u,s $labl\n\t"
+ $$emit$$"J$cop,u,s $labl"
+ } else {
+ $$emit$$"JP,u,s done\n\t"
+ $$emit$$"J$cop,u,s $labl\n\t"
+ $$emit$$"done:"
+ }
+ %}
+ size(4);
+ opcode(0x70);
+ ins_encode %{
+ Label* l = $labl$$label;
+ emit_cc(cbuf, $primary, Assembler::parity);
+ int parity_disp = -1;
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+ } else if ($cop$$cmpcode == Assembler::equal) {
+ parity_disp = 2;
+ } else {
+ ShouldNotReachHere();
+ }
+ emit_d8(cbuf, parity_disp);
+ emit_cc(cbuf, $primary, $cop$$cmpcode);
+ int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+ emit_d8(cbuf, disp);
+ assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+ assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+ %}
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+ ins_short_branch(1);
+%}
+
// ============================================================================
// Long Compare
//
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jul 05 16:43:43 2017 +0200
@@ -2004,9 +2004,12 @@
//
// NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset)
-{
- return -0x80 <= offset && offset < 0x80;
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+ // the short version of jmpConUCF2 contains multiple branches,
+ // making the reach slightly less
+ if (rule == jmpConUCF2_rule)
+ return (-126 <= offset && offset <= 125);
+ return (-128 <= offset && offset <= 127);
}
const bool Matcher::isSimpleConstant64(jlong value) {
@@ -3569,7 +3572,7 @@
// at [FETCH], below, will never observe a biased encoding (*101b).
// If this invariant is not held we'll suffer exclusion (safety) failure.
- if (UseBiasedLocking) {
+ if (UseBiasedLocking && !UseOptoBiasInlining) {
masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
}
@@ -3657,7 +3660,7 @@
} else {
Label DONE_LABEL, Stacked, CheckSucc ;
- if (UseBiasedLocking) {
+ if (UseBiasedLocking && !UseOptoBiasInlining) {
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
}
@@ -5134,6 +5137,15 @@
interface(REG_INTER);
%}
+operand rFlagsRegUCF() %{
+ constraint(ALLOC_IN_RC(int_flags));
+ match(RegFlags);
+ predicate(false);
+
+ format %{ "RFLAGS_U_CF" %}
+ interface(REG_INTER);
+%}
+
// Float register operands
operand regF()
%{
@@ -5405,12 +5417,12 @@
format %{ "" %}
interface(COND_INTER) %{
- equal(0x4);
- not_equal(0x5);
- less(0xC);
- greater_equal(0xD);
- less_equal(0xE);
- greater(0xF);
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0xC, "l");
+ greater_equal(0xD, "ge");
+ less_equal(0xE, "le");
+ greater(0xF, "g");
%}
%}
@@ -5423,12 +5435,48 @@
format %{ "" %}
interface(COND_INTER) %{
- equal(0x4);
- not_equal(0x5);
- less(0x2);
- greater_equal(0x3);
- less_equal(0x6);
- greater(0x7);
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0x2, "b");
+ greater_equal(0x3, "nb");
+ less_equal(0x6, "be");
+ greater(0x7, "nbe");
+ %}
+%}
+
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+ match(Bool);
+ predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+ n->as_Bool()->_test._test == BoolTest::ge ||
+ n->as_Bool()->_test._test == BoolTest::le ||
+ n->as_Bool()->_test._test == BoolTest::gt);
+ format %{ "" %}
+ interface(COND_INTER) %{
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0x2, "b");
+ greater_equal(0x3, "nb");
+ less_equal(0x6, "be");
+ greater(0x7, "nbe");
+ %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+ match(Bool);
+ predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+ n->as_Bool()->_test._test == BoolTest::eq);
+ format %{ "" %}
+ interface(COND_INTER) %{
+ equal(0x4, "e");
+ not_equal(0x5, "ne");
+ less(0x2, "b");
+ greater_equal(0x3, "nb");
+ less_equal(0x6, "be");
+ greater(0x7, "nbe");
%}
%}
@@ -7176,8 +7224,7 @@
ins_pipe(pipe_cmov_reg);
%}
-instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop)
-%{
+instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
ins_cost(200); // XXX
@@ -7187,9 +7234,16 @@
ins_pipe(pipe_cmov_reg);
%}
+instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
+ match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovI_regU(cop, cr, dst, src);
+ %}
+%}
+
// Conditional move
-instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src)
-%{
+instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250); // XXX
@@ -7211,6 +7265,14 @@
ins_pipe(pipe_cmov_mem);
%}
+instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
+ match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+ ins_cost(250);
+ expand %{
+ cmovI_memU(cop, cr, dst, src);
+ %}
+%}
+
// Conditional move
instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
%{
@@ -7224,7 +7286,7 @@
%}
// Conditional move
-instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
%{
match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
@@ -7235,6 +7297,14 @@
ins_pipe(pipe_cmov_reg);
%}
+instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
+ match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovN_regU(cop, cr, dst, src);
+ %}
+%}
+
// Conditional move
instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
%{
@@ -7248,7 +7318,7 @@
%}
// Conditional move
-instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
%{
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
@@ -7259,6 +7329,14 @@
ins_pipe(pipe_cmov_reg); // XXX
%}
+instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
+ match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovP_regU(cop, cr, dst, src);
+ %}
+%}
+
// DISABLED: Requires the ADLC to emit a bottom_type call that
// correctly meets the two pointer arguments; one is an incoming
// register but the other is a memory operand. ALSO appears to
@@ -7319,6 +7397,14 @@
ins_pipe(pipe_cmov_reg); // XXX
%}
+instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
+ match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovL_regU(cop, cr, dst, src);
+ %}
+%}
+
instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
%{
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
@@ -7330,6 +7416,14 @@
ins_pipe(pipe_cmov_mem); // XXX
%}
+instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
+ match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
+ ins_cost(200);
+ expand %{
+ cmovL_memU(cop, cr, dst, src);
+ %}
+%}
+
instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
%{
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
@@ -7366,6 +7460,14 @@
ins_pipe(pipe_slow);
%}
+instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
+ match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovF_regU(cop, cr, dst, src);
+ %}
+%}
+
instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
%{
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
@@ -7390,6 +7492,14 @@
ins_pipe(pipe_slow);
%}
+instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
+ match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+ ins_cost(200);
+ expand %{
+ cmovD_regU(cop, cr, dst, src);
+ %}
+%}
+
//----------Arithmetic Instructions--------------------------------------------
//----------Addition Instructions----------------------------------------------
@@ -7735,7 +7845,7 @@
rFlagsReg cr)
%{
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
-
+
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
"If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
opcode(0x0F, 0xB1);
@@ -7746,53 +7856,40 @@
ins_pipe(pipe_cmpxchg);
%}
-// Conditional-store of a long value
-// Returns a boolean value (0/1) on success. Implemented with a
-// CMPXCHG8 on Intel. mem_ptr can actually be in either RSI or RDI
-
-instruct storeLConditional(rRegI res,
- memory mem_ptr,
- rax_RegL oldval, rRegL newval,
- rFlagsReg cr)
-%{
- match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
- effect(KILL cr);
-
- format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
- "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
- "sete $res\n\t"
- "movzbl $res, $res" %}
+// Conditional-store of an int value.
+// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
+instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
+%{
+ match(Set cr (StoreIConditional mem (Binary oldval newval)));
+ effect(KILL oldval);
+
+ format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
- REX_reg_mem_wide(newval, mem_ptr),
+ REX_reg_mem(newval, mem),
OpcP, OpcS,
- reg_mem(newval, mem_ptr),
- REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
- REX_reg_breg(res, res), // movzbl
- Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
+ reg_mem(newval, mem));
ins_pipe(pipe_cmpxchg);
%}
-// Conditional-store of a long value
-// ZF flag is set on success, reset otherwise. Implemented with a
-// CMPXCHG8 on Intel. mem_ptr can actually be in either RSI or RDI
-instruct storeLConditional_flags(memory mem_ptr,
- rax_RegL oldval, rRegL newval,
- rFlagsReg cr,
- immI0 zero)
-%{
- match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-
- format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
- "If rax == $mem_ptr then store $newval into $mem_ptr" %}
+// Conditional-store of a long value.
+// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
+instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
+%{
+ match(Set cr (StoreLConditional mem (Binary oldval newval)));
+ effect(KILL oldval);
+
+ format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
- REX_reg_mem_wide(newval, mem_ptr),
+ REX_reg_mem_wide(newval, mem),
OpcP, OpcS,
- reg_mem(newval, mem_ptr));
+ reg_mem(newval, mem));
ins_pipe(pipe_cmpxchg);
%}
+
+// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
instruct compareAndSwapP(rRegI res,
memory mem_ptr,
rax_RegP oldval, rRegP newval,
@@ -7816,7 +7913,6 @@
ins_pipe( pipe_cmpxchg );
%}
-// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
instruct compareAndSwapL(rRegI res,
memory mem_ptr,
rax_RegL oldval, rRegL newval,
@@ -8766,6 +8862,7 @@
ins_pipe(ialu_reg);
%}
+
// Logical Shift Right by 8-bit immediate
instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
%{
@@ -9475,6 +9572,18 @@
ins_pipe(ialu_reg_reg);
%}
+// Use any_RegP to match R15 (TLS register) without spilling.
+instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
+ match(Set dst (OrL dst (CastP2X src)));
+ effect(KILL cr);
+
+ format %{ "orq $dst, $src\t# long" %}
+ opcode(0x0B);
+ ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
+ ins_pipe(ialu_reg_reg);
+%}
+
+
// Or Register with Immediate
instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
%{
@@ -9716,6 +9825,17 @@
ins_pipe(pipe_slow);
%}
+instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
+ match(Set cr (CmpF src1 src2));
+
+ ins_cost(145);
+ format %{ "ucomiss $src1, $src2" %}
+ ins_encode %{
+ __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
+ %}
+ ins_pipe(pipe_slow);
+%}
+
instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
%{
match(Set cr (CmpF src1 (LoadF src2)));
@@ -9733,6 +9853,16 @@
ins_pipe(pipe_slow);
%}
+instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
+ match(Set cr (CmpF src1 (LoadF src2)));
+
+ ins_cost(100);
+ format %{ "ucomiss $src1, $src2" %}
+ opcode(0x0F, 0x2E);
+ ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
+ ins_pipe(pipe_slow);
+%}
+
instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
%{
match(Set cr (CmpF src1 src2));
@@ -9750,6 +9880,16 @@
ins_pipe(pipe_slow);
%}
+instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
+ match(Set cr (CmpF src1 src2));
+
+ ins_cost(100);
+ format %{ "ucomiss $src1, $src2" %}
+ opcode(0x0F, 0x2E);
+ ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
+ ins_pipe(pipe_slow);
+%}
+
instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
%{
match(Set cr (CmpD src1 src2));
@@ -9767,6 +9907,17 @@
ins_pipe(pipe_slow);
%}
+instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
+ match(Set cr (CmpD src1 src2));
+
+ ins_cost(100);
+ format %{ "ucomisd $src1, $src2 test" %}
+ ins_encode %{
+ __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
+ %}
+ ins_pipe(pipe_slow);
+%}
+
instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
%{
match(Set cr (CmpD src1 (LoadD src2)));
@@ -9784,6 +9935,16 @@
ins_pipe(pipe_slow);
%}
+instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
+ match(Set cr (CmpD src1 (LoadD src2)));
+
+ ins_cost(100);
+ format %{ "ucomisd $src1, $src2" %}
+ opcode(0x66, 0x0F, 0x2E);
+ ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
+ ins_pipe(pipe_slow);
+%}
+
instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
%{
match(Set cr (CmpD src1 src2));
@@ -9801,6 +9962,16 @@
ins_pipe(pipe_slow);
%}
+instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
+ match(Set cr (CmpD src1 src2));
+
+ ins_cost(100);
+ format %{ "ucomisd $src1, [$src2]" %}
+ opcode(0x66, 0x0F, 0x2E);
+ ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
+ ins_pipe(pipe_slow);
+%}
+
// Compare into -1,0,1
instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
%{
@@ -11406,8 +11577,7 @@
%}
// Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
match(CountedLoopEnd cop cmp);
effect(USE labl);
@@ -11420,14 +11590,39 @@
ins_pc_relative(1);
%}
+instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+ match(CountedLoopEnd cop cmp);
+ effect(USE labl);
+
+ ins_cost(200);
+ format %{ "j$cop,u $labl\t# loop end" %}
+ size(6);
+ opcode(0x0F, 0x80);
+ ins_encode(Jcc(cop, labl));
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+%}
+
// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(300);
- format %{ "j$cop,u $labl" %}
+ format %{ "j$cop,u $labl" %}
+ size(6);
+ opcode(0x0F, 0x80);
+ ins_encode(Jcc(cop, labl));
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(200);
+ format %{ "j$cop,u $labl" %}
size(6);
opcode(0x0F, 0x80);
ins_encode(Jcc(cop, labl));
@@ -11435,6 +11630,46 @@
ins_pc_relative(1);
%}
+instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(200);
+ format %{ $$template
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ $$emit$$"jp,u $labl\n\t"
+ $$emit$$"j$cop,u $labl"
+ } else {
+ $$emit$$"jp,u done\n\t"
+ $$emit$$"j$cop,u $labl\n\t"
+ $$emit$$"done:"
+ }
+ %}
+ size(12);
+ opcode(0x0F, 0x80);
+ ins_encode %{
+ Label* l = $labl$$label;
+ $$$emit8$primary;
+ emit_cc(cbuf, $secondary, Assembler::parity);
+ int parity_disp = -1;
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ // the two jumps 6 bytes apart so the jump distances are too
+ parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+ } else if ($cop$$cmpcode == Assembler::equal) {
+ parity_disp = 6;
+ } else {
+ ShouldNotReachHere();
+ }
+ emit_d32(cbuf, parity_disp);
+ $$$emit8$primary;
+ emit_cc(cbuf, $secondary, $cop$$cmpcode);
+ int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+ emit_d32(cbuf, disp);
+ %}
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+%}
+
// ============================================================================
// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
// superklass array for an instance of the superklass. Set a hidden
@@ -11505,8 +11740,7 @@
// specific code section of the file.
// Jump Direct - Label defines a relative address from JMP+1
-instruct jmpDir_short(label labl)
-%{
+instruct jmpDir_short(label labl) %{
match(Goto);
effect(USE labl);
@@ -11521,8 +11755,7 @@
%}
// Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
match(If cop cr);
effect(USE labl);
@@ -11537,13 +11770,12 @@
%}
// Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
match(CountedLoopEnd cop cr);
effect(USE labl);
ins_cost(300);
- format %{ "j$cop,s $labl" %}
+ format %{ "j$cop,s $labl\t# loop end" %}
size(2);
opcode(0x70);
ins_encode(JccShort(cop, labl));
@@ -11553,12 +11785,40 @@
%}
// Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+ match(CountedLoopEnd cop cmp);
+ effect(USE labl);
+
+ ins_cost(300);
+ format %{ "j$cop,us $labl\t# loop end" %}
+ size(2);
+ opcode(0x70);
+ ins_encode(JccShort(cop, labl));
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+ ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
match(CountedLoopEnd cop cmp);
effect(USE labl);
ins_cost(300);
+ format %{ "j$cop,us $labl\t# loop end" %}
+ size(2);
+ opcode(0x70);
+ ins_encode(JccShort(cop, labl));
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+ ins_short_branch(1);
+%}
+
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(300);
format %{ "j$cop,us $labl" %}
size(2);
opcode(0x70);
@@ -11568,9 +11828,7 @@
ins_short_branch(1);
%}
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
@@ -11584,6 +11842,46 @@
ins_short_branch(1);
%}
+instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+ match(If cop cmp);
+ effect(USE labl);
+
+ ins_cost(300);
+ format %{ $$template
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ $$emit$$"jp,u,s $labl\n\t"
+ $$emit$$"j$cop,u,s $labl"
+ } else {
+ $$emit$$"jp,u,s done\n\t"
+ $$emit$$"j$cop,u,s $labl\n\t"
+ $$emit$$"done:"
+ }
+ %}
+ size(4);
+ opcode(0x70);
+ ins_encode %{
+ Label* l = $labl$$label;
+ emit_cc(cbuf, $primary, Assembler::parity);
+ int parity_disp = -1;
+ if ($cop$$cmpcode == Assembler::notEqual) {
+ parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+ } else if ($cop$$cmpcode == Assembler::equal) {
+ parity_disp = 2;
+ } else {
+ ShouldNotReachHere();
+ }
+ emit_d8(cbuf, parity_disp);
+ emit_cc(cbuf, $primary, $cop$$cmpcode);
+ int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+ emit_d8(cbuf, disp);
+ assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+ assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+ %}
+ ins_pipe(pipe_jcc);
+ ins_pc_relative(1);
+ ins_short_branch(1);
+%}
+
// ============================================================================
// inlined locking and unlocking
--- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad Wed Jul 05 16:43:43 2017 +0200
@@ -103,16 +103,16 @@
// This name is KNOWN by the ADLC and cannot be changed.
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
// for this guy.
-instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
+instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
match(Set dst (ThreadLocal));
effect(DEF dst, KILL cr);
- format %{ "MOV EAX, Thread::current()" %}
+ format %{ "MOV $dst, Thread::current()" %}
ins_encode( linux_tlsencode(dst) );
ins_pipe( ialu_reg_fat );
%}
-instruct TLS(eAXRegP dst) %{
+instruct TLS(eRegP dst) %{
match(Set dst (ThreadLocal));
expand %{
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad Wed Jul 05 16:43:43 2017 +0200
@@ -110,16 +110,16 @@
// This name is KNOWN by the ADLC and cannot be changed.
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
// for this guy.
-instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
+instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
match(Set dst (ThreadLocal));
effect(DEF dst, KILL cr);
- format %{ "MOV EAX, Thread::current()" %}
+ format %{ "MOV $dst, Thread::current()" %}
ins_encode( solaris_tlsencode(dst) );
ins_pipe( ialu_reg_fat );
%}
-instruct TLS(eAXRegP dst) %{
+instruct TLS(eRegP dst) %{
match(Set dst (ThreadLocal));
expand %{
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java Wed Jul 05 16:43:43 2017 +0200
@@ -28,6 +28,7 @@
import com.sun.hotspot.igv.data.services.InputGraphProvider;
import java.awt.BorderLayout;
import java.io.Serializable;
+import javax.swing.SwingUtilities;
import org.openide.ErrorManager;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
@@ -151,14 +152,18 @@
}
public void resultChanged(LookupEvent lookupEvent) {
- InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+ final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
if (p != null) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
InputGraph graph = p.getGraph();
if (graph != null) {
Group g = graph.getGroup();
rootNode.update(graph, g.getMethod());
}
}
+ });
+ }
}
final static class ResolvableHelper implements Serializable {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java Wed Jul 05 16:43:43 2017 +0200
@@ -33,7 +33,7 @@
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.Set;
import javax.swing.BorderFactory;
import org.netbeans.api.visual.action.ActionFactory;
@@ -44,7 +44,6 @@
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.anchor.AnchorFactory;
import org.netbeans.api.visual.anchor.AnchorShape;
-import com.sun.hotspot.igv.controlflow.HierarchicalGraphLayout;
import org.netbeans.api.visual.layout.LayoutFactory;
import org.netbeans.api.visual.router.RouterFactory;
import org.netbeans.api.visual.widget.LayerWidget;
@@ -61,8 +60,8 @@
*/
public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
- private Set<BlockWidget> selection;
- private Hashtable<InputBlock, BlockWidget> blockMap;
+ private HashSet<BlockWidget> selection;
+ private HashMap<InputBlock, BlockWidget> blockMap;
private InputGraph oldGraph;
private LayerWidget edgeLayer;
private LayerWidget mainLayer;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java Wed Jul 05 16:43:43 2017 +0200
@@ -28,6 +28,7 @@
import java.awt.BorderLayout;
import java.io.Serializable;
import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
import org.openide.ErrorManager;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
@@ -143,13 +144,17 @@
public void resultChanged(LookupEvent lookupEvent) {
- InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+ final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
if (p != null) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
InputGraph g = p.getGraph();
if (g != null) {
scene.setGraph(g);
}
}
+ });
+ }
}
@Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java Wed Jul 05 16:43:43 2017 +0200
@@ -24,6 +24,7 @@
package com.sun.hotspot.igv.coordinator;
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
+import com.sun.hotspot.igv.data.ChangedListener;
import com.sun.hotspot.igv.data.Group;
import com.sun.hotspot.igv.data.services.GroupOrganizer;
import com.sun.hotspot.igv.data.InputGraph;
@@ -50,17 +51,24 @@
private List<String> subFolders;
private FolderChildren children;
- private static class FolderChildren extends Children.Keys {
+ private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
private FolderNode parent;
+ private List<Group> registeredGroups;
public void setParent(FolderNode parent) {
this.parent = parent;
+ this.registeredGroups = new ArrayList<Group>();
}
@Override
protected Node[] createNodes(Object arg0) {
+ for(Group g : registeredGroups) {
+ g.getChangedEvent().removeListener(this);
+ }
+ registeredGroups.clear();
+
Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
if (p.getLeft().length() == 0) {
@@ -69,6 +77,8 @@
for (InputGraph graph : g.getGraphs()) {
curNodes.add(new GraphNode(graph));
}
+ g.getChangedEvent().addListener(this);
+ registeredGroups.add(g);
}
Node[] result = new Node[curNodes.size()];
@@ -85,7 +95,13 @@
@Override
public void addNotify() {
this.setKeys(parent.structure);
+ }
+ public void changed(Group source) {
+ List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
+ for(Pair<String, List<Group>> p : parent.structure) {
+ refreshKey(p);
+ }
}
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java Wed Jul 05 16:43:43 2017 +0200
@@ -31,7 +31,7 @@
*
* @author Thomas Wuerthinger
*/
-public class GraphDocument extends Properties.Object implements ChangedEventProvider<GraphDocument> {
+public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
private List<Group> groups;
private ChangedEvent<GraphDocument> changedEvent;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java Wed Jul 05 16:43:43 2017 +0200
@@ -37,7 +37,7 @@
*
* @author Thomas Wuerthinger
*/
-public class Group extends Properties.Object implements ChangedEventProvider<Group> {
+public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
private List<InputGraph> graphs;
private transient ChangedEvent<Group> changedEvent;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java Wed Jul 05 16:43:43 2017 +0200
@@ -23,26 +23,25 @@
*/
package com.sun.hotspot.igv.data;
-import com.sun.hotspot.igv.data.Properties;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
*
* @author Thomas Wuerthinger
*/
-public class InputGraph extends Properties.Object {
+public class InputGraph extends Properties.Entity {
- private Map<Integer, InputNode> nodes;
- private Set<InputEdge> edges;
+ private HashMap<Integer, InputNode> nodes;
+ private ArrayList<InputEdge> edges;
private Group parent;
- private Map<String, InputBlock> blocks;
- private Map<Integer, InputBlock> nodeToBlock;
+ private HashMap<String, InputBlock> blocks;
+ private HashMap<Integer, InputBlock> nodeToBlock;
private boolean isDifferenceGraph;
public InputGraph(Group parent) {
@@ -61,10 +60,10 @@
public InputGraph(Group parent, InputGraph last, String name) {
this.parent = parent;
setName(name);
- nodes = new Hashtable<Integer, InputNode>();
- edges = new HashSet<InputEdge>();
- blocks = new Hashtable<String, InputBlock>();
- nodeToBlock = new Hashtable<Integer, InputBlock>();
+ nodes = new HashMap<Integer, InputNode>();
+ edges = new ArrayList<InputEdge>();
+ blocks = new HashMap<String, InputBlock>();
+ nodeToBlock = new HashMap<Integer, InputBlock>();
if (last != null) {
for (InputNode n : last.getNodes()) {
@@ -182,8 +181,8 @@
return nodes.remove(index);
}
- public Set<InputEdge> getEdges() {
- return Collections.unmodifiableSet(edges);
+ public Collection<InputEdge> getEdges() {
+ return Collections.unmodifiableList(edges);
}
public void removeEdge(InputEdge c) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java Wed Jul 05 16:43:43 2017 +0200
@@ -32,7 +32,7 @@
*
* @author Thomas Wuerthinger
*/
-public class InputMethod extends Properties.Object {
+public class InputMethod extends Properties.Entity {
private String name;
private int bci;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java Wed Jul 05 16:43:43 2017 +0200
@@ -27,7 +27,7 @@
*
* @author Thomas Wuerthinger
*/
-public class InputNode extends Properties.Object {
+public class InputNode extends Properties.Entity {
private int id;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Wed Jul 05 16:43:43 2017 +0200
@@ -26,24 +26,22 @@
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+
/**
*
* @author Thomas Wuerthinger
*/
-public class Properties implements Serializable {
+public class Properties implements Serializable, Iterable<Property> {
public static final long serialVersionUID = 1L;
- private Map<String, Property> map;
+ private String[] map = new String[4];
public Properties() {
- map = new HashMap<String, Property>(5);
}
@Override
@@ -54,10 +52,7 @@
Properties p = (Properties) o;
- if (getProperties().size() != p.getProperties().size()) {
- return false;
- }
- for (Property prop : getProperties()) {
+ for (Property prop : this) {
String value = p.get(prop.getName());
if (value == null || !value.equals(prop.getValue())) {
return false;
@@ -75,32 +70,33 @@
public Properties(String name, String value) {
this();
- this.add(new Property(name, value));
+ this.setProperty(name, value);
}
public Properties(String name, String value, String name1, String value1) {
this(name, value);
- this.add(new Property(name1, value1));
+ this.setProperty(name1, value1);
}
public Properties(String name, String value, String name1, String value1, String name2, String value2) {
this(name, value, name1, value1);
- this.add(new Property(name2, value2));
+ this.setProperty(name2, value2);
}
public Properties(Properties p) {
- map = new HashMap<String, Property>(p.map);
+ map = new String[p.map.length];
+ System.arraycopy(map, 0, p.map, 0, p.map.length);
}
- public static class Object implements Provider {
+ public static class Entity implements Provider {
private Properties properties;
- public Object() {
+ public Entity() {
properties = new Properties();
}
- public Object(Properties.Object object) {
+ public Entity(Properties.Entity object) {
properties = new Properties(object.getProperties());
}
@@ -109,6 +105,14 @@
}
}
+ private String getProperty(String key) {
+ for (int i = 0; i < map.length; i += 2)
+ if (map[i] != null && map[i].equals(key)) {
+ return map[i + 1];
+ }
+ return null;
+ }
+
public interface PropertyMatcher {
String getName();
@@ -173,13 +177,15 @@
}
public Property selectSingle(PropertyMatcher matcher) {
-
- Property p = this.map.get(matcher.getName());
- if (p == null) {
- return null;
+ String value = null;
+ for (int i = 0; i < map.length; i += 2) {
+ if (map[i] != null && matcher.getName().equals(map[i])) {
+ value = map[i + 1];
+ break;
+ }
}
- if (matcher.match(p.getValue())) {
- return p;
+ if (value != null && matcher.match(value)) {
+ return new Property(matcher.getName(), value);
} else {
return null;
}
@@ -194,8 +200,11 @@
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
- for (Property p : map.values()) {
- sb.append(p.toString());
+ for (int i = 0; i < map.length; i += 2) {
+ if (map[i + 1] != null) {
+ String p = map[i + 1];
+ sb.append(map[i] + " = " + map[i + 1] + "; ");
+ }
}
return sb.append("]").toString();
}
@@ -241,41 +250,51 @@
}
public String get(String key) {
- Property p = map.get(key);
- if (p == null) {
- return null;
- } else {
- return p.getValue();
+ for (int i = 0; i < map.length; i += 2) {
+ if (map[i] != null && map[i].equals(key)) {
+ return map[i + 1];
+ }
}
- }
-
- public String getProperty(String string) {
- return get(string);
+ return null;
}
- public Property setProperty(String name, String value) {
-
+ public void setProperty(String name, String value) {
+ for (int i = 0; i < map.length; i += 2) {
+ if (map[i] != null && map[i].equals(name)) {
+ String p = map[i + 1];
+ if (value == null) {
+ // remove this property
+ map[i] = null;
+ map[i + 1] = null;
+ } else {
+ map[i + 1] = value;
+ }
+ return;
+ }
+ }
if (value == null) {
- // remove this property
- return map.remove(name);
- } else {
- Property p = map.get(name);
- if (p == null) {
- p = new Property(name, value);
- map.put(name, p);
- } else {
- p.setValue(value);
+ return;
+ }
+ for (int i = 0; i < map.length; i += 2) {
+ if (map[i] == null) {
+ map[i] = name;
+ map[i + 1] = value;
+ return;
}
- return p;
}
+ String[] newMap = new String[map.length + 4];
+ System.arraycopy(map, 0, newMap, 0, map.length);
+ newMap[map.length] = name;
+ newMap[map.length + 1] = value;
+ map = newMap;
}
- public Collection<Property> getProperties() {
- return Collections.unmodifiableCollection(map.values());
+ public Iterator<Property> getProperties() {
+ return iterator();
}
public void add(Properties properties) {
- for (Property p : properties.getProperties()) {
+ for (Property p : properties) {
add(p);
}
}
@@ -283,6 +302,35 @@
public void add(Property property) {
assert property.getName() != null;
assert property.getValue() != null;
- map.put(property.getName(), property);
+ setProperty(property.getName(), property.getValue());
+ }
+ class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
+ public Iterator<Property> iterator() {
+ return this;
+ }
+
+ int index;
+
+ public boolean hasNext() {
+ while (index < map.length && map[index + 1] == null)
+ index += 2;
+ return index < map.length;
+ }
+
+ public Property next() {
+ if (index < map.length) {
+ index += 2;
+ return new Property(map[index - 2], map[index - 1]);
+ }
+ return null;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ }
+ public Iterator<Property> iterator() {
+ return new PropertiesIterator();
}
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java Wed Jul 05 16:43:43 2017 +0200
@@ -32,18 +32,19 @@
public class Property implements Serializable {
public static final long serialVersionUID = 1L;
+
private String name;
private String value;
- public Property() {
+ private Property() {
this(null, null);
}
- public Property(Property p) {
+ private Property(Property p) {
this(p.getName(), p.getValue());
}
- public Property(String name) {
+ private Property(String name) {
this(name, null);
}
@@ -60,16 +61,19 @@
return value;
}
- public void setName(String s) {
- this.name = s;
- }
-
- public void setValue(String s) {
- this.value = s;
- }
-
@Override
public String toString() {
return name + " = " + value + "; ";
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Property)) return false;
+ Property p2 = (Property)o;
+ return name.equals(p2.name) && value.equals(p2.value);
+ }
+ @Override
+ public int hashCode() {
+ return name.hashCode() + value == null ? 0 : value.hashCode();
+ }
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java Wed Jul 05 16:43:43 2017 +0200
@@ -38,6 +38,7 @@
import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
import java.io.IOException;
+import java.util.HashMap;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
@@ -88,6 +89,18 @@
private TopElementHandler xmlDocument = new TopElementHandler();
private boolean difference;
private GroupCallback groupCallback;
+ private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
+ private int maxId = 0;
+
+ private int lookupID(String i) {
+ Integer id = idCache.get(i);
+ if (id == null) {
+ id = maxId++;
+ idCache.put(i, id);
+ }
+ return id.intValue();
+ }
+
// <graphDocument>
private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
@@ -187,13 +200,13 @@
previous = null;
}
InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
- getParentObject().addGraph(curGraph);
this.graph = curGraph;
return curGraph;
}
@Override
protected void end(String text) throws SAXException {
+ getParentObject().addGraph(graph);
graph.resolveBlockLinks();
}
};
@@ -207,7 +220,7 @@
@Override
protected InputBlock start() throws SAXException {
InputGraph graph = getParentObject();
- String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+ String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
InputBlock b = new InputBlock(getParentObject(), name);
graph.addBlock(b);
return b;
@@ -224,7 +237,7 @@
int id = 0;
try {
- id = Integer.parseInt(s);
+ id = lookupID(s);
} catch (NumberFormatException e) {
throw new SAXException(e);
}
@@ -252,7 +265,7 @@
String s = readRequiredAttribute(NODE_ID_PROPERTY);
int id = 0;
try {
- id = Integer.parseInt(s);
+ id = lookupID(s);
} catch (NumberFormatException e) {
throw new SAXException(e);
}
@@ -269,7 +282,7 @@
String s = readRequiredAttribute(NODE_ID_PROPERTY);
int id = 0;
try {
- id = Integer.parseInt(s);
+ id = lookupID(s);
} catch (NumberFormatException e) {
throw new SAXException(e);
}
@@ -280,7 +293,7 @@
private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
// Local class for edge elements
- private static class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
+ private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
public EdgeElementHandler(String name) {
super(name);
@@ -298,8 +311,8 @@
toIndex = Integer.parseInt(toIndexString);
}
- from = Integer.parseInt(readRequiredAttribute(FROM_PROPERTY));
- to = Integer.parseInt(readRequiredAttribute(TO_PROPERTY));
+ from = lookupID(readRequiredAttribute(FROM_PROPERTY));
+ to = lookupID(readRequiredAttribute(TO_PROPERTY));
} catch (NumberFormatException e) {
throw new SAXException(e);
}
@@ -344,18 +357,16 @@
}
};
// <property>
- private ElementHandler<Property, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<Property, Properties.Provider>(PROPERTY_ELEMENT, true) {
+ private ElementHandler<String, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<String, Properties.Provider>(PROPERTY_ELEMENT, true) {
@Override
- public Property start() throws SAXException {
- String value = "";
- String name = readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
- return getParentObject().getProperties().setProperty(name, value);
+ public String start() throws SAXException {
+ return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
}
@Override
public void end(String text) {
- getObject().setValue(text.trim().intern());
+ getParentObject().getProperties().setProperty(getObject(), text.trim().intern());
}
};
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java Wed Jul 05 16:43:43 2017 +0200
@@ -67,7 +67,7 @@
private void export(XMLWriter writer, Group g) throws IOException {
Properties attributes = new Properties();
- attributes.add(new Property("difference", Boolean.toString(true)));
+ attributes.setProperty("difference", Boolean.toString(true));
writer.startTag(Parser.GROUP_ELEMENT, attributes);
writer.writeProperties(g.getProperties());
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java Wed Jul 05 16:43:43 2017 +0200
@@ -25,7 +25,7 @@
import com.sun.hotspot.igv.data.Property;
import com.sun.hotspot.igv.data.Properties;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
@@ -89,7 +89,7 @@
private Attributes attr;
private StringBuilder currentText;
private ParseMonitor monitor;
- private Hashtable<String, ElementHandler<?, ? super T>> hashtable;
+ private HashMap<String, ElementHandler<?, ? super T>> hashtable;
private boolean needsText;
private ElementHandler<P, ?> parentElement;
@@ -110,7 +110,7 @@
}
public ElementHandler(String name, boolean needsText) {
- this.hashtable = new Hashtable<String, ElementHandler<?, ? super T>>();
+ this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
this.name = name;
this.needsText = needsText;
}
@@ -153,7 +153,7 @@
for (int i = 0; i < length; i++) {
String val = attr.getValue(i).intern();
String localName = attr.getLocalName(i).intern();
- p.add(new Property(val, localName));
+ p.setProperty(val, localName);
}
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java Wed Jul 05 16:43:43 2017 +0200
@@ -89,7 +89,7 @@
inner.write("<" + name);
elementStack.push(name);
- for (Property p : attributes.getProperties()) {
+ for (Property p : attributes) {
inner.write(" " + p.getName() + "=\"");
write(p.getValue().toCharArray());
inner.write("\"");
@@ -101,7 +101,7 @@
public void simpleTag(String name, Properties attributes) throws IOException {
inner.write("<" + name);
- for (Property p : attributes.getProperties()) {
+ for (Property p : attributes) {
inner.write(" " + p.getName() + "=\"");
write(p.getValue().toCharArray());
inner.write("\"");
@@ -111,13 +111,13 @@
}
public void writeProperties(Properties props) throws IOException {
- if (props.getProperties().size() == 0) {
+ if (props.getProperties().hasNext() == false) {
return;
}
startTag(Parser.PROPERTIES_ELEMENT);
- for (Property p : props.getProperties()) {
+ for (Property p : props) {
startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
this.write(p.getValue().toCharArray());
endTag();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java Wed Jul 05 16:43:43 2017 +0200
@@ -29,6 +29,7 @@
import com.sun.hotspot.igv.data.InputGraph;
import com.sun.hotspot.igv.data.InputNode;
import com.sun.hotspot.igv.data.Property;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -124,8 +125,8 @@
inputNodeMap.put(n, n2);
}
- Set<InputEdge> edgesA = a.getEdges();
- Set<InputEdge> edgesB = b.getEdges();
+ Collection<InputEdge> edgesA = a.getEdges();
+ Collection<InputEdge> edgesB = b.getEdges();
Set<InputEdge> newEdges = new HashSet<InputEdge>();
@@ -182,7 +183,7 @@
public double getValue() {
double result = 0.0;
- for (Property p : n1.getProperties().getProperties()) {
+ for (Property p : n1.getProperties()) {
double faktor = 1.0;
for (String forbidden : IGNORE_PROPERTIES) {
if (p.getName().equals(forbidden)) {
@@ -287,34 +288,34 @@
private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
boolean difference = false;
- for (Property p : otherNode.getProperties().getProperties()) {
- String s = firstNode.getProperties().getProperty(p.getName());
+ for (Property p : otherNode.getProperties()) {
+ String s = firstNode.getProperties().get(p.getName());
if (!p.getValue().equals(s)) {
difference = true;
- n.getProperties().add(new Property(OLD_PREFIX + p.getName(), p.getValue()));
+ n.getProperties().setProperty(OLD_PREFIX + p.getName(), p.getValue());
}
}
- for (Property p : firstNode.getProperties().getProperties()) {
- String s = otherNode.getProperties().getProperty(p.getName());
+ for (Property p : firstNode.getProperties()) {
+ String s = otherNode.getProperties().get(p.getName());
if (s == null && p.getValue().length() > 0) {
difference = true;
- n.getProperties().add(new Property(OLD_PREFIX + p.getName(), ""));
+ n.getProperties().setProperty(OLD_PREFIX + p.getName(), "");
}
}
if (difference) {
- n.getProperties().add(new Property(PROPERTY_STATE, VALUE_CHANGED));
+ n.getProperties().setProperty(PROPERTY_STATE, VALUE_CHANGED);
} else {
- n.getProperties().add(new Property(PROPERTY_STATE, VALUE_SAME));
+ n.getProperties().setProperty(PROPERTY_STATE, VALUE_SAME);
}
}
private static void markAsDeleted(InputNode n) {
- n.getProperties().add(new Property(PROPERTY_STATE, VALUE_DELETED));
+ n.getProperties().setProperty(PROPERTY_STATE, VALUE_DELETED);
}
private static void markAsNew(InputNode n) {
- n.getProperties().add(new Property(PROPERTY_STATE, VALUE_NEW));
+ n.getProperties().setProperty(PROPERTY_STATE, VALUE_NEW);
}
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf Wed Jul 05 16:43:43 2017 +0200
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.filter
-OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.filter
+OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java Wed Jul 05 16:43:43 2017 +0200
@@ -25,7 +25,6 @@
package com.sun.hotspot.igv.filter;
import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.data.Property;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -56,7 +55,7 @@
public CustomFilter(String name, String code) {
this.name = name;
this.code = code;
- getProperties().add(new Property("name", name));
+ getProperties().setProperty("name", name);
}
public String getName() {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java Wed Jul 05 16:43:43 2017 +0200
@@ -56,8 +56,8 @@
for (OutputSlot os : f.getOutputSlots()) {
for (Connection c : os.getConnections()) {
InputSlot is = c.getInputSlot();
- is.setName(f.getProperties().getProperty("dump_spec"));
- String s = f.getProperties().getProperty("short_name");
+ is.setName(f.getProperties().get("dump_spec"));
+ String s = f.getProperties().get("short_name");
if (s != null) {
is.setShortName(s);
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java Wed Jul 05 16:43:43 2017 +0200
@@ -35,7 +35,7 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -126,7 +126,7 @@
d.updateBlocks();
Collection<InputNode> nodes = graph.getNodes();
- Hashtable<Integer, Figure> figureHash = new Hashtable<Integer, Figure>();
+ HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
for (InputNode n : nodes) {
Figure f = d.createFigure();
f.getSource().addSourceNode(n);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java Wed Jul 05 16:43:43 2017 +0200
@@ -42,7 +42,7 @@
*
* @author Thomas Wuerthinger
*/
-public class Figure extends Properties.Object implements Source.Provider, Vertex {
+public class Figure extends Properties.Entity implements Source.Provider, Vertex {
public static final int INSET = 6;
public static final int SLOT_WIDTH = 10;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java Wed Jul 05 16:43:43 2017 +0200
@@ -26,7 +26,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
@@ -37,13 +37,13 @@
*/
public class Graph<N, E> {
- private Hashtable<Object, Node<N, E>> nodes;
- private Hashtable<Object, Edge<N, E>> edges;
+ private HashMap<Object, Node<N, E>> nodes;
+ private HashMap<Object, Edge<N, E>> edges;
private List<Node<N, E>> nodeList;
public Graph() {
- nodes = new Hashtable<Object, Node<N, E>>();
- edges = new Hashtable<Object, Edge<N, E>>();
+ nodes = new HashMap<Object, Node<N, E>>();
+ edges = new HashMap<Object, Edge<N, E>>();
nodeList = new ArrayList<Node<N, E>>();
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java Wed Jul 05 16:43:43 2017 +0200
@@ -25,7 +25,7 @@
import java.awt.Point;
import java.awt.Rectangle;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.ArrayList;
@@ -69,19 +69,19 @@
assert graph.verify();
- Hashtable<Cluster, List<Vertex>> lists = new Hashtable<Cluster, List<Vertex>>();
- Hashtable<Cluster, List<Link>> listsConnection = new Hashtable<Cluster, List<Link>>();
- Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>> clusterInputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>>();
- Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>>();
+ HashMap<Cluster, List<Vertex>> lists = new HashMap<Cluster, List<Vertex>>();
+ HashMap<Cluster, List<Link>> listsConnection = new HashMap<Cluster, List<Link>>();
+ HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>> clusterInputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>>();
+ HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>>();
- Hashtable<Cluster, ClusterNode> clusterNodes = new Hashtable<Cluster, ClusterNode>();
- Hashtable<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new Hashtable<Cluster, Set<ClusterInputSlotNode>>();
- Hashtable<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new Hashtable<Cluster, Set<ClusterOutputSlotNode>>();
+ HashMap<Cluster, ClusterNode> clusterNodes = new HashMap<Cluster, ClusterNode>();
+ HashMap<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new HashMap<Cluster, Set<ClusterInputSlotNode>>();
+ HashMap<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new HashMap<Cluster, Set<ClusterOutputSlotNode>>();
Set<Link> clusterEdges = new HashSet<Link>();
Set<Link> interClusterEdges = new HashSet<Link>();
- Hashtable<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new Hashtable<Link, ClusterOutgoingConnection>();
- Hashtable<Link, InterClusterConnection> linkInterClusterConnection = new Hashtable<Link, InterClusterConnection>();
- Hashtable<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new Hashtable<Link, ClusterIngoingConnection>();
+ HashMap<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new HashMap<Link, ClusterOutgoingConnection>();
+ HashMap<Link, InterClusterConnection> linkInterClusterConnection = new HashMap<Link, InterClusterConnection>();
+ HashMap<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new HashMap<Link, ClusterIngoingConnection>();
Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
Set<Cluster> cluster = graph.getClusters();
@@ -89,8 +89,8 @@
for (Cluster c : cluster) {
lists.put(c, new ArrayList<Vertex>());
listsConnection.put(c, new ArrayList<Link>());
- clusterInputSlotHash.put(c, new Hashtable<Port, ClusterInputSlotNode>());
- clusterOutputSlotHash.put(c, new Hashtable<Port, ClusterOutputSlotNode>());
+ clusterInputSlotHash.put(c, new HashMap<Port, ClusterInputSlotNode>());
+ clusterOutputSlotHash.put(c, new HashMap<Port, ClusterOutputSlotNode>());
clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
ClusterNode cn = new ClusterNode(c, "" + z);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java Wed Jul 05 16:43:43 2017 +0200
@@ -24,7 +24,7 @@
package com.sun.hotspot.igv.layout;
import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -37,9 +37,9 @@
private Set<? extends Link> links;
private SortedSet<Vertex> vertices;
- private Hashtable<Vertex, Set<Port>> inputPorts;
- private Hashtable<Vertex, Set<Port>> outputPorts;
- private Hashtable<Port, Set<Link>> portLinks;
+ private HashMap<Vertex, Set<Port>> inputPorts;
+ private HashMap<Vertex, Set<Port>> outputPorts;
+ private HashMap<Port, Set<Link>> portLinks;
public LayoutGraph(Set<? extends Link> links) {
this(links, new HashSet<Vertex>());
@@ -50,9 +50,9 @@
assert verify();
vertices = new TreeSet<Vertex>();
- portLinks = new Hashtable<Port, Set<Link>>();
- inputPorts = new Hashtable<Vertex, Set<Port>>();
- outputPorts = new Hashtable<Vertex, Set<Port>>();
+ portLinks = new HashMap<Port, Set<Link>>();
+ inputPorts = new HashMap<Vertex, Set<Port>>();
+ outputPorts = new HashMap<Vertex, Set<Port>>();
for (Link l : links) {
Port p = l.getFrom();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/README Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/README Wed Jul 05 16:43:43 2017 +0200
@@ -5,21 +5,16 @@
was the primary target of the tool. The tool itself is fairly general
with only a few modules that contain C2 specific elements.
-The tool is built on top of the NetBeans 6.0 rich client
+The tool is built on top of the NetBeans 6.1 rich client
infrastructure and so requires NetBeans to build. It currently
requires Java 6 to run as it needs support for JavaScript for its
filtering mechanism and assumes it's built into the platform. It
-should build out of the box whit NetBeans 6 and Java 6 or later. It's
-possible to run it on 1.5 by including Rhino on the classpath though
-that currently isn't working correctly. Support for exporting graphs
-as SVG can be enabled by adding batik to the classpath which isn't
-included by default.
-
-It can be built on top of NetBeans 6.1 if you change the required
-modules to be platform8 instead of platform7. The tool could run on
-JDK 1.5 with some reworking of the how the JavaScript support is
-enabled but currently it requires some tweaking of the setup. This
-will be fixed in a later setup.
+should build out of the box with NetBeans 6.1 and Java 6 or later.
+It's possible to run it on 1.5 by including Rhino on the classpath
+though that currently isn't working correctly. Support for exporting
+graphs as SVG can be enabled by adding batik to the classpath which
+isn't included by default. It can be built on top of NetBeans 6.0 if
+you change the required modules to be platform7 instead of platform8.
The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
where # is:
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java Wed Jul 05 16:43:43 2017 +0200
@@ -36,11 +36,11 @@
*/
public class PropertiesSheet {
- public static void initializeSheet(Properties properties, Sheet s) {
+ public static void initializeSheet(final Properties properties, Sheet s) {
Sheet.Set set1 = Sheet.createPropertiesSet();
set1.setDisplayName("Properties");
- for (final Property p : properties.getProperties()) {
+ for (final Property p : properties) {
Node.Property<String> prop = new Node.Property<String>(String.class) {
@Override
@@ -60,7 +60,7 @@
@Override
public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- p.setValue(arg0);
+ properties.setProperty(p.getName(), arg0);
}
};
prop.setName(p.getName());
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java Wed Jul 05 16:43:43 2017 +0200
@@ -65,13 +65,19 @@
public RangeSliderModel(List<String> positions) {
assert positions.size() > 0;
- this.positions = positions;
this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
+ setPositions(positions);
+ }
+
+ protected void setPositions(List<String> positions) {
+ this.positions = positions;
colors = new ArrayList<Color>();
for (int i = 0; i < positions.size(); i++) {
colors.add(Color.black);
}
+ changedEvent.fire();
+ colorChangedEvent.fire();
}
public void setColors(List<Color> colors) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java Wed Jul 05 16:43:43 2017 +0200
@@ -63,7 +63,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -104,10 +104,10 @@
*/
public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
- private Hashtable<Figure, FigureWidget> figureWidgets;
- private Hashtable<Slot, SlotWidget> slotWidgets;
- private Hashtable<Connection, ConnectionWidget> connectionWidgets;
- private Hashtable<InputBlock, BlockWidget> blockWidgets;
+ private HashMap<Figure, FigureWidget> figureWidgets;
+ private HashMap<Slot, SlotWidget> slotWidgets;
+ private HashMap<Connection, ConnectionWidget> connectionWidgets;
+ private HashMap<InputBlock, BlockWidget> blockWidgets;
private Widget hoverWidget;
private WidgetAction hoverAction;
private List<FigureWidget> selectedWidgets;
@@ -414,7 +414,7 @@
this.addChild(selectLayer);
this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
- blockWidgets = new Hashtable<InputBlock, BlockWidget>();
+ blockWidgets = new HashMap<InputBlock, BlockWidget>();
boolean b = this.getUndoRedoEnabled();
this.setUndoRedoEnabled(false);
@@ -543,9 +543,9 @@
blockLayer.removeChildren();
blockWidgets.clear();
- figureWidgets = new Hashtable<Figure, FigureWidget>();
- slotWidgets = new Hashtable<Slot, SlotWidget>();
- connectionWidgets = new Hashtable<Connection, ConnectionWidget>();
+ figureWidgets = new HashMap<Figure, FigureWidget>();
+ slotWidgets = new HashMap<Slot, SlotWidget>();
+ connectionWidgets = new HashMap<Connection, ConnectionWidget>();
WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
Diagram d = getModel().getDiagramToView();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Wed Jul 05 16:43:43 2017 +0200
@@ -55,6 +55,7 @@
private FilterChain filterChain;
private FilterChain sequenceFilterChain;
private Diagram diagram;
+ private ChangedEvent<DiagramViewModel> groupChangedEvent;
private ChangedEvent<DiagramViewModel> diagramChangedEvent;
private ChangedEvent<DiagramViewModel> viewChangedEvent;
private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
@@ -67,6 +68,7 @@
}
};
+ @Override
public DiagramViewModel copy() {
DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
result.setData(this);
@@ -79,6 +81,7 @@
boolean viewChanged = false;
boolean viewPropertiesChanged = false;
+ boolean groupChanged = (group == newModel.group);
this.group = newModel.group;
diagramChanged |= (filterChain != newModel.filterChain);
this.filterChain = newModel.filterChain;
@@ -97,6 +100,10 @@
viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
this.showNodeHull = newModel.showNodeHull;
+ if(groupChanged) {
+ groupChangedEvent.fire();
+ }
+
if (diagramChanged) {
diagramChangedEvent.fire();
}
@@ -143,11 +150,38 @@
diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+ groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+ groupChangedEvent.addListener(groupChangedListener);
+ groupChangedEvent.fire();
filterChain.getChangedEvent().addListener(filterChainChangedListener);
sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
}
+ private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
+
+ private Group oldGroup;
+
+ public void changed(DiagramViewModel source) {
+ if(oldGroup != null) {
+ oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
+ }
+ group.getChangedEvent().addListener(groupContentChangedListener);
+ oldGroup = group;
+ }
+ };
+
+
+ private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
+
+ public void changed(Group source) {
+ assert source == group;
+ setPositions(calculateStringList(source));
+ setSelectedNodes(selectedNodes);
+ }
+
+ };
+
public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
return diagramChangedEvent;
}
@@ -268,7 +302,10 @@
}
public InputGraph getSecondGraph() {
- return group.getGraphs().get(getSecondPosition());
+ List<InputGraph> graphs = group.getGraphs();
+ if (graphs.size() >= getSecondPosition())
+ return group.getGraphs().get(getSecondPosition());
+ return getFirstGraph();
}
public void selectGraph(InputGraph g) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java Wed Jul 05 16:43:43 2017 +0200
@@ -67,7 +67,7 @@
for (Figure f : figures) {
Properties prop = f.getProperties();
- for (Property p : prop.getProperties()) {
+ for (Property p : prop) {
if (!propertyNames.contains(p.getName())) {
propertyNames.add(p.getName());
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties Wed Jul 05 16:43:43 2017 +0200
@@ -1,16 +1,16 @@
# Deprecated since 5.0u1; for compatibility with 5.0:
disabled.clusters=\
apisupport1,\
+ gsf1,\
harness,\
- ide8,\
- java1,\
- nb6.0,\
- profiler2
+ ide9,\
+ java2,\
+ nb6.1,\
+ profiler3
disabled.modules=\
org.netbeans.core.execution,\
org.netbeans.core.multiview,\
org.netbeans.core.output2,\
- org.netbeans.modules.applemenu,\
org.netbeans.modules.autoupdate.services,\
org.netbeans.modules.autoupdate.ui,\
org.netbeans.modules.core.kit,\
@@ -24,6 +24,6 @@
org.openide.execution,\
org.openide.util.enumerations
enabled.clusters=\
- platform7
+ platform8
nbjdk.active=default
nbplatform.active=default
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Wed Jul 05 16:43:43 2017 +0200
@@ -15,7 +15,6 @@
${project.com.sun.hotspot.igv.difference}:\
${project.com.sun.hotspot.igv.settings}:\
${project.com.sun.hotspot.igv.util}:\
- ${project.com.sun.hotspot.igv.rhino}:\
${project.com.sun.hotspot.igv.svg}:\
${project.com.sun.hotspot.connection}:\
${project.com.sun.hotspot.igv.servercompilerscheduler}:\
@@ -31,10 +30,10 @@
project.com.sun.hotspot.igv.graph=Graph
project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
project.com.sun.hotspot.igv.layout=Layout
-project.com.sun.hotspot.igv.rhino=RhinoScriptEngineProxy
project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
project.com.sun.hotspot.igv.settings=Settings
project.com.sun.hotspot.igv.svg=BatikSVGProxy
project.com.sun.hotspot.igv.view=View
project.com.sun.hotspot.igv.util=Util
-run.args = -server -J-Xms64m -J-Xmx512m -J-da
+run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
+run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
--- a/hotspot/src/share/vm/adlc/adlparse.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/adlparse.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -33,7 +33,6 @@
_globalNames(archDesc.globalNames()) {
_AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
_AD._warnings = 0; // No warnings either
- _linenum = 0; // Will increment to first line
_curline = _ptr = NULL; // No pointers into buffer yet
_preproc_depth = 0;
@@ -76,7 +75,7 @@
}
if (!_AD._quiet_mode)
fprintf(stderr,"-----------------------------------------------------------------------------\n");
- _AD._TotalLines += _linenum-1; // -1 for overshoot in "nextline" routine
+ _AD._TotalLines += linenum()-1; // -1 for overshoot in "nextline" routine
// Write out information we have stored
// // UNIXism == fsync(stderr);
@@ -148,7 +147,7 @@
if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
return;
instr = new InstructForm(ident); // Create new instruction form
- instr->_linenum = _linenum;
+ instr->_linenum = linenum();
_globalNames.Insert(ident, instr); // Add name to the name table
// Debugging Stuff
if (_AD._adl_debug > 1)
@@ -404,7 +403,7 @@
if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
return;
oper = new OperandForm(ident); // Create new operand form
- oper->_linenum = _linenum;
+ oper->_linenum = linenum();
_globalNames.Insert(ident, oper); // Add name to the name table
// Debugging Stuff
@@ -774,7 +773,7 @@
// Create the RegisterForm for the architecture description.
RegisterForm *regBlock = new RegisterForm(); // Build new Source object
- regBlock->_linenum = _linenum;
+ regBlock->_linenum = linenum();
_AD.addForm(regBlock);
skipws(); // Skip leading whitespace
@@ -847,7 +846,7 @@
}
EncClass *encoding = _AD._encode->add_EncClass(ec_name);
- encoding->_linenum = _linenum;
+ encoding->_linenum = linenum();
skipws(); // Skip leading whitespace
// Check for optional parameter list
@@ -905,7 +904,7 @@
// Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
if (_AD._adlocation_debug) {
const char* file = _AD._ADL_file._name;
- int line = _linenum;
+ int line = linenum();
char* location = (char *)malloc(strlen(file) + 100);
sprintf(location, "#line %d \"%s\"\n", line, file);
encoding->add_code(location);
@@ -2776,7 +2775,7 @@
assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
EncClass *encoding = _AD._encode->add_EncClass(ec_name);
- encoding->_linenum = _linenum;
+ encoding->_linenum = linenum();
// synthesize the arguments list for the enc_class from the
// arguments to the instruct definition.
@@ -2852,7 +2851,7 @@
skipws();
InsEncode *encrule = new InsEncode(); // Encode class for instruction
- encrule->_linenum = _linenum;
+ encrule->_linenum = linenum();
char *ec_name = NULL; // String representation of encode rule
// identifier is optional.
while (_curchar != ')') {
@@ -3203,6 +3202,12 @@
char *greater_equal;
char *less_equal;
char *greater;
+ const char *equal_format = "eq";
+ const char *not_equal_format = "ne";
+ const char *less_format = "lt";
+ const char *greater_equal_format = "ge";
+ const char *less_equal_format = "le";
+ const char *greater_format = "gt";
if (_curchar != '%') {
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
@@ -3222,22 +3227,22 @@
return NULL;
}
if ( strcmp(field,"equal") == 0 ) {
- equal = interface_field_parse();
+ equal = interface_field_parse(&equal_format);
}
else if ( strcmp(field,"not_equal") == 0 ) {
- not_equal = interface_field_parse();
+ not_equal = interface_field_parse(¬_equal_format);
}
else if ( strcmp(field,"less") == 0 ) {
- less = interface_field_parse();
+ less = interface_field_parse(&less_format);
}
else if ( strcmp(field,"greater_equal") == 0 ) {
- greater_equal = interface_field_parse();
+ greater_equal = interface_field_parse(&greater_equal_format);
}
else if ( strcmp(field,"less_equal") == 0 ) {
- less_equal = interface_field_parse();
+ less_equal = interface_field_parse(&less_equal_format);
}
else if ( strcmp(field,"greater") == 0 ) {
- greater = interface_field_parse();
+ greater = interface_field_parse(&greater_format);
}
else {
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
@@ -3252,14 +3257,18 @@
next_char(); // Skip '}'
// Construct desired object and return
- Interface *inter = new CondInterface(equal, not_equal, less, greater_equal,
- less_equal, greater);
+ Interface *inter = new CondInterface(equal, equal_format,
+ not_equal, not_equal_format,
+ less, less_format,
+ greater_equal, greater_equal_format,
+ less_equal, less_equal_format,
+ greater, greater_format);
return inter;
}
//------------------------------interface_field_parse--------------------------
-char *ADLParser::interface_field_parse(void) {
+char *ADLParser::interface_field_parse(const char ** format) {
char *iface_field = NULL;
// Get interface field
@@ -3280,6 +3289,32 @@
return NULL;
}
skipws();
+ if (format != NULL && _curchar == ',') {
+ next_char();
+ skipws();
+ if (_curchar != '"') {
+ parse_err(SYNERR, "Missing '\"' in field format .\n");
+ return NULL;
+ }
+ next_char();
+ char *start = _ptr; // Record start of the next string
+ while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
+ if (_curchar == '\\') next_char(); // superquote
+ if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
+ next_char();
+ }
+ if (_curchar != '"') {
+ parse_err(SYNERR, "Missing '\"' at end of field format .\n");
+ return NULL;
+ }
+ // If a string was found, terminate it and record in FormatRule
+ if ( start != _ptr ) {
+ *_ptr = '\0'; // Terminate the string
+ *format = start;
+ }
+ next_char();
+ skipws();
+ }
if (_curchar != ')') {
parse_err(SYNERR, "Missing ')' after interface field.\n");
return NULL;
@@ -3342,6 +3377,12 @@
next_char(); // Move past the '{'
skipws();
+ if (_curchar == '$') {
+ char* ident = get_rep_var_ident();
+ if (strcmp(ident, "$$template") == 0) return template_parse();
+ parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
+ return NULL;
+ }
// Check for the opening '"' inside the format description
if ( _curchar == '"' ) {
next_char(); // Move past the initial '"'
@@ -3433,6 +3474,131 @@
}
+//------------------------------template_parse-----------------------------------
+FormatRule* ADLParser::template_parse(void) {
+ char *desc = NULL;
+ FormatRule *format = (new FormatRule(desc));
+
+ skipws();
+ while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
+
+ // (1)
+ // Check if there is a string to pass through to output
+ char *start = _ptr; // Record start of the next string
+ while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
+ // If at the start of a comment, skip past it
+ if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
+ skipws_no_preproc();
+ } else {
+ // ELSE advance to the next character, or start of the next line
+ next_char_or_line();
+ }
+ }
+ // If a string was found, terminate it and record in EncClass
+ if ( start != _ptr ) {
+ *_ptr = '\0'; // Terminate the string
+ // Add flag to _strings list indicating we should check _rep_vars
+ format->_strings.addName(NameList::_signal2);
+ format->_strings.addName(start);
+ }
+
+ // (2)
+ // If we are at a replacement variable,
+ // copy it and record in EncClass
+ if ( _curchar == '$' ) {
+ // Found replacement Variable
+ char *rep_var = get_rep_var_ident_dup();
+ if (strcmp(rep_var, "$emit") == 0) {
+ // switch to normal format parsing
+ next_char();
+ next_char();
+ skipws();
+ // Check for the opening '"' inside the format description
+ if ( _curchar == '"' ) {
+ next_char(); // Move past the initial '"'
+ if( _curchar == '"' ) { // Handle empty format string case
+ *_ptr = '\0'; // Terminate empty string
+ format->_strings.addName(_ptr);
+ }
+
+ // Collect the parts of the format description
+ // (1) strings that are passed through to tty->print
+ // (2) replacement/substitution variable, preceeded by a '$'
+ // (3) multi-token ANSIY C style strings
+ while ( true ) {
+ if ( _curchar == '%' || _curchar == '\n' ) {
+ parse_err(SYNERR, "missing '\"' at end of format block");
+ return NULL;
+ }
+
+ // (1)
+ // Check if there is a string to pass through to output
+ char *start = _ptr; // Record start of the next string
+ while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
+ if (_curchar == '\\') next_char(); // superquote
+ if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
+ next_char();
+ }
+ // If a string was found, terminate it and record in FormatRule
+ if ( start != _ptr ) {
+ *_ptr = '\0'; // Terminate the string
+ format->_strings.addName(start);
+ }
+
+ // (2)
+ // If we are at a replacement variable,
+ // copy it and record in FormatRule
+ if ( _curchar == '$' ) {
+ next_char(); // Move past the '$'
+ char* rep_var = get_ident(); // Nil terminate the variable name
+ rep_var = strdup(rep_var);// Copy the string
+ *_ptr = _curchar; // and replace Nil with original character
+ format->_rep_vars.addName(rep_var);
+ // Add flag to _strings list indicating we should check _rep_vars
+ format->_strings.addName(NameList::_signal);
+ }
+
+ // (3)
+ // Allow very long strings to be broken up,
+ // using the ANSI C syntax "foo\n" <newline> "bar"
+ if ( _curchar == '"') {
+ next_char(); // Move past the '"'
+ skipws(); // Skip white space before next string token
+ if ( _curchar != '"') {
+ break;
+ } else {
+ // Found one. Skip both " and the whitespace in between.
+ next_char();
+ }
+ }
+ } // end while part of format description
+ }
+ } else {
+ // Add flag to _strings list indicating we should check _rep_vars
+ format->_rep_vars.addName(rep_var);
+ // Add flag to _strings list indicating we should check _rep_vars
+ format->_strings.addName(NameList::_signal3);
+ }
+ } // end while part of format description
+ }
+
+ skipws();
+ // Past format description, at '%'
+ if ( _curchar != '%' || *(_ptr+1) != '}' ) {
+ parse_err(SYNERR, "missing '%}' at end of format block");
+ return NULL;
+ }
+ next_char(); // Move past the '%'
+ next_char(); // Move past the '}'
+
+ // Debug Stuff
+ if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
+
+ skipws();
+ return format;
+}
+
+
//------------------------------effect_parse-----------------------------------
void ADLParser::effect_parse(InstructForm *instr) {
char* desc = NULL;
@@ -3777,7 +3943,7 @@
skipws_no_preproc(); // Skip leading whitespace
cppBlock = _ptr; // Point to start of expression
const char* file = _AD._ADL_file._name;
- int line = _linenum;
+ int line = linenum();
next = _ptr + 1;
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
next_char_or_line();
@@ -4297,11 +4463,11 @@
va_start(args, fmt);
if (flag == 1)
- _AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+ _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
else if (flag == 2)
- _AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+ _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
else
- _AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args);
+ _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
int error_char = _curchar;
char* error_ptr = _ptr+1;
@@ -4515,7 +4681,7 @@
//---------------------------next_line-----------------------------------------
void ADLParser::next_line() {
- _curline = _buf.get_line(); _linenum++;
+ _curline = _buf.get_line();
}
//-------------------------is_literal_constant---------------------------------
--- a/hotspot/src/share/vm/adlc/adlparse.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/adlparse.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -70,7 +70,6 @@
protected:
char *_curline; // Start of current line
char *_ptr; // Pointer into current location in File Buffer
- int _linenum; // Count of line numbers seen so far
char _curchar; // Current character from buffer
FormDict &_globalNames; // Global names
@@ -160,9 +159,10 @@
Interface *interface_parse(); // Parse operand interface rule
Interface *mem_interface_parse(); // Parse memory interface rule
Interface *cond_interface_parse(); // Parse conditional interface rule
- char *interface_field_parse();// Parse field contents
+ char *interface_field_parse(const char** format = NULL);// Parse field contents
FormatRule *format_parse(void); // Parse format rule
+ FormatRule *template_parse(void); // Parse format rule
void effect_parse(InstructForm *instr); // Parse effect rule
ExpandRule *expand_parse(InstructForm *instr); // Parse expand rule
RewriteRule *rewrite_parse(void); // Parse rewrite rule
@@ -263,7 +263,7 @@
void parse(void); // Do the parsing & build forms lists
- int getlines( ) { return _linenum; }
+ int linenum() { return _buf.linenum(); }
static bool is_literal_constant(const char *hex_string);
static bool is_hex_digit(char digit);
--- a/hotspot/src/share/vm/adlc/filebuff.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/filebuff.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -41,6 +41,7 @@
exit(1); // Exit on seek error
}
_filepos = ftell(_fp->_fp); // Reset current file position
+ _linenum = 0;
_bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
if( !_bigbuf ) {
@@ -76,6 +77,7 @@
// Check for end of file & return NULL
if (_bufeol >= _bufmax) return NULL;
+ _linenum++;
retval = ++_bufeol; // return character following end of previous line
if (*retval == '\0') return NULL; // Check for EOF sentinal
// Search for newline character which must end each line
--- a/hotspot/src/share/vm/adlc/filebuff.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/filebuff.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -51,6 +51,7 @@
int _err; // Error flag for file seek/read operations
long _filepos; // Current offset from start of file
+ int _linenum;
ArchDesc& _AD; // Reference to Architecture Description
@@ -66,6 +67,7 @@
// This returns a pointer to the start of the current line in the buffer,
// and increments bufeol and filepos to point at the end of that line.
char *get_line(void);
+ int linenum() const { return _linenum; }
// This converts a pointer into the buffer to a file offset. It only works
// when the pointer is valid (i.e. just obtained from getline()).
--- a/hotspot/src/share/vm/adlc/forms.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/forms.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -35,6 +35,8 @@
//------------------------------NameList---------------------------------------
// reserved user-defined string
const char *NameList::_signal = "$$SIGNAL$$";
+const char *NameList::_signal2 = "$$SIGNAL2$$";
+const char *NameList::_signal3 = "$$SIGNAL3$$";
// Constructor and Destructor
NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
--- a/hotspot/src/share/vm/adlc/forms.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/forms.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -329,6 +329,8 @@
public:
static const char *_signal; // reserved user-defined string
+ static const char *_signal2; // reserved user-defined string
+ static const char *_signal3; // reserved user-defined string
enum { Not_in_list = -1 };
void addName(const char *name);
--- a/hotspot/src/share/vm/adlc/formssel.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/formssel.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -1574,10 +1574,10 @@
return Opcode::NOT_AN_OPCODE;
}
-void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
+bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
// Default values previously provided by MachNode::primary()...
- const char *description = "default_opcode()";
- const char *value = "-1";
+ const char *description = NULL;
+ const char *value = NULL;
// Check if user provided any opcode definitions
if( this != NULL ) {
// Update 'value' if user provided a definition in the instruction
@@ -1599,7 +1599,10 @@
break;
}
}
- fprintf(fp, "(%s /*%s*/)", value, description);
+ if (value != NULL) {
+ fprintf(fp, "(%s /*%s*/)", value, description);
+ }
+ return value != NULL;
}
void Opcode::dump() {
@@ -2610,14 +2613,19 @@
}
//------------------------------CondInterface----------------------------------
-CondInterface::CondInterface(char *equal, char *not_equal,
- char *less, char *greater_equal,
- char *less_equal, char *greater)
+CondInterface::CondInterface(const char* equal, const char* equal_format,
+ const char* not_equal, const char* not_equal_format,
+ const char* less, const char* less_format,
+ const char* greater_equal, const char* greater_equal_format,
+ const char* less_equal, const char* less_equal_format,
+ const char* greater, const char* greater_format)
: Interface("COND_INTER"),
- _equal(equal), _not_equal(not_equal),
- _less(less), _greater_equal(greater_equal),
- _less_equal(less_equal), _greater(greater) {
- //
+ _equal(equal), _equal_format(equal_format),
+ _not_equal(not_equal), _not_equal_format(not_equal_format),
+ _less(less), _less_format(less_format),
+ _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
+ _less_equal(less_equal), _less_equal_format(less_equal_format),
+ _greater(greater), _greater_format(greater_format) {
}
CondInterface::~CondInterface() {
// not owner of any character arrays
@@ -3316,7 +3324,7 @@
"Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
"LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
"LoadPLocked", "LoadLLocked",
- "StorePConditional", "StoreLConditional",
+ "StorePConditional", "StoreIConditional", "StoreLConditional",
"CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
"StoreCM",
"ClearArray"
--- a/hotspot/src/share/vm/adlc/formssel.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/formssel.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -397,7 +397,7 @@
void output(FILE *fp);
// --------------------------- FILE *output_routines
- void print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
+ bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
};
//------------------------------InsEncode--------------------------------------
@@ -779,10 +779,20 @@
const char *_greater_equal;
const char *_less_equal;
const char *_greater;
+ const char *_equal_format;
+ const char *_not_equal_format;
+ const char *_less_format;
+ const char *_greater_equal_format;
+ const char *_less_equal_format;
+ const char *_greater_format;
// Public Methods
- CondInterface(char *equal, char *not_equal, char *less, char *greater_equal,
- char *less_equal, char *greater);
+ CondInterface(const char* equal, const char* equal_format,
+ const char* not_equal, const char* not_equal_format,
+ const char* less, const char* less_format,
+ const char* greater_equal, const char* greater_equal_format,
+ const char* less_equal, const char* less_equal_format,
+ const char* greater, const char* greater_format);
~CondInterface();
void dump();
--- a/hotspot/src/share/vm/adlc/output_c.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/output_c.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -1619,6 +1619,7 @@
}
// Iterate over the new instruction's operands
+ int prev_pos = -1;
for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
// Use 'parameter' at current position in list of new instruction's formals
// instead of 'opid' when looking up info internal to new_inst
@@ -1642,6 +1643,18 @@
// ins = (InstructForm *) _globalNames[new_id];
exp_pos = node->operand_position_format(opid);
assert(exp_pos != -1, "Bad expand rule");
+ if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
+ // For the add_req calls below to work correctly they need
+ // to added in the same order that a match would add them.
+ // This means that they would need to be in the order of
+ // the components list instead of the formal parameters.
+ // This is a sort of hidden invariant that previously
+ // wasn't checked and could lead to incorrectly
+ // constructed nodes.
+ syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
+ node->_ident, new_inst->_ident);
+ }
+ prev_pos = exp_pos;
new_pos = new_inst->operand_position(parameter,Component::USE);
if (new_pos != -1) {
@@ -2306,7 +2319,12 @@
_processing_noninput = false;
// A replacement variable, originally '$'
if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
- _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );
+ if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
+ // Missing opcode
+ _AD.syntax_err( _inst._linenum,
+ "Missing $%s opcode definition in %s, used by encoding %s\n",
+ rep_var, _inst._ident, _encoding._name);
+ }
}
else {
// Lookup its position in parameter list
@@ -2348,7 +2366,13 @@
else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
// else check if "primary", "secondary", "tertiary"
assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
- _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );
+ if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
+ // Missing opcode
+ _AD.syntax_err( _inst._linenum,
+ "Missing $%s opcode definition in %s\n",
+ rep_var, _inst._ident);
+
+ }
_constant_status = LITERAL_OUTPUT;
}
else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
--- a/hotspot/src/share/vm/adlc/output_h.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/adlc/output_h.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -355,17 +355,19 @@
// ---------------------------------------------------------------------------
// Generate the format rule for condition codes
-static void defineCCodeDump(FILE *fp, int i) {
- fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i);
- fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i);
- fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i);
- fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i);
- fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i);
- fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i);
+static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
+ assert(oper != NULL, "what");
+ CondInterface* cond = oper->_interface->is_CondInterface();
+ fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
+ fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
+ fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
+ fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
+ fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
+ fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
}
// Output code that dumps constant values, increment "i" if type is constant
-static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
+static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
if (!strcmp(ideal_type, "ConI")) {
fprintf(fp," st->print(\"#%%d\", _c%d);\n", i);
++i;
@@ -375,7 +377,7 @@
++i;
}
else if (!strcmp(ideal_type, "ConN")) {
- fprintf(fp," _c%d->dump();\n", i);
+ fprintf(fp," _c%d->dump_on(st);\n", i);
++i;
}
else if (!strcmp(ideal_type, "ConL")) {
@@ -391,7 +393,7 @@
++i;
}
else if (!strcmp(ideal_type, "Bool")) {
- defineCCodeDump(fp,i);
+ defineCCodeDump(oper, fp,i);
++i;
}
@@ -476,7 +478,7 @@
}
// ALWAYS! Provide a special case output for condition codes.
if( oper.is_ideal_bool() ) {
- defineCCodeDump(fp,0);
+ defineCCodeDump(&oper, fp,0);
}
fprintf(fp,"}\n");
@@ -549,7 +551,7 @@
}
// ALWAYS! Provide a special case output for condition codes.
if( oper.is_ideal_bool() ) {
- defineCCodeDump(fp,0);
+ defineCCodeDump(&oper, fp,0);
}
fprintf(fp, "}\n");
fprintf(fp, "#endif\n");
@@ -583,10 +585,53 @@
while( (string = inst._format->_strings.iter()) != NULL ) {
fprintf(fp," ");
// Check if this is a standard string or a replacement variable
- if( string != NameList::_signal ) // Normal string. Pass through.
+ if( string == NameList::_signal ) { // Replacement variable
+ const char* rep_var = inst._format->_rep_vars.iter();
+ inst.rep_var_format( fp, rep_var);
+ } else if( string == NameList::_signal3 ) { // Replacement variable in raw text
+ const char* rep_var = inst._format->_rep_vars.iter();
+ const Form *form = inst._localNames[rep_var];
+ if (form == NULL) {
+ fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
+ assert(false, "ShouldNotReachHere()");
+ }
+ OpClassForm *opc = form->is_opclass();
+ assert( opc, "replacement variable was not found in local names");
+ // Lookup the index position of the replacement variable
+ int idx = inst.operand_position_format(rep_var);
+ if ( idx == -1 ) {
+ assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
+ assert( false, "ShouldNotReachHere()");
+ }
+
+ if (inst.is_noninput_operand(idx)) {
+ assert( false, "ShouldNotReachHere()");
+ } else {
+ // Output the format call for this operand
+ fprintf(fp,"opnd_array(%d)",idx);
+ }
+ rep_var = inst._format->_rep_vars.iter();
+ inst._format->_strings.iter();
+ if ( strcmp(rep_var,"$constant") == 0 && opc->is_operand()) {
+ Form::DataType constant_type = form->is_operand()->is_base_constant(globals);
+ if ( constant_type == Form::idealD ) {
+ fprintf(fp,"->constantD()");
+ } else if ( constant_type == Form::idealF ) {
+ fprintf(fp,"->constantF()");
+ } else if ( constant_type == Form::idealL ) {
+ fprintf(fp,"->constantL()");
+ } else {
+ fprintf(fp,"->constant()");
+ }
+ } else if ( strcmp(rep_var,"$cmpcode") == 0) {
+ fprintf(fp,"->ccode()");
+ } else {
+ assert( false, "ShouldNotReachHere()");
+ }
+ } else if( string == NameList::_signal2 ) // Raw program text
+ fputs(inst._format->_strings.iter(), fp);
+ else
fprintf(fp,"st->print(\"%s\");\n", string);
- else // Replacement variable
- inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
} // Done with all format strings
} // Done generating the user-defined portion of the format
@@ -1404,7 +1449,7 @@
oper->_components.reset();
if ((comp = oper->_components.iter()) == NULL) {
assert(num_consts == 1, "Bad component list detected.\n");
- i = dump_spec_constant( fp, type, i );
+ i = dump_spec_constant( fp, type, i, oper );
// Check that type actually matched
assert( i != 0, "Non-constant operand lacks component list.");
} // end if NULL
@@ -1414,7 +1459,7 @@
oper->_components.reset();
while((comp = oper->_components.iter()) != NULL) {
type = comp->base_type(_globalNames);
- i = dump_spec_constant( fp, type, i );
+ i = dump_spec_constant( fp, type, i, NULL );
}
}
// finish line (3)
--- a/hotspot/src/share/vm/interpreter/bytecodeStream.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodeStream.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -28,8 +28,9 @@
Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
assert(!is_last_bytecode(), "should have been checked");
// set next bytecode position
- address bcp = RawBytecodeStream::bcp();
- int l = Bytecodes::raw_special_length_at(bcp);
+ address bcp = RawBytecodeStream::bcp();
+ address end = method()->code_base() + end_bci();
+ int l = Bytecodes::raw_special_length_at(bcp, end);
if (l <= 0 || (_bci + l) > _end_bci) {
code = Bytecodes::_illegal;
} else {
@@ -39,8 +40,12 @@
_is_wide = false;
// check for special (uncommon) cases
if (code == Bytecodes::_wide) {
- code = (Bytecodes::Code)bcp[1];
- _is_wide = true;
+ if (bcp + 1 >= end) {
+ code = Bytecodes::_illegal;
+ } else {
+ code = (Bytecodes::Code)bcp[1];
+ _is_wide = true;
+ }
}
}
_code = code;
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -54,13 +54,19 @@
return method->orig_bytecode_at(method->bci_from(bcp));
}
-int Bytecodes::special_length_at(address bcp) {
+int Bytecodes::special_length_at(address bcp, address end) {
Code code = code_at(bcp);
switch (code) {
case _wide:
+ if (end != NULL && bcp + 1 >= end) {
+ return -1; // don't read past end of code buffer
+ }
return wide_length_for(cast(*(bcp + 1)));
case _tableswitch:
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
+ if (end != NULL && aligned_bcp + 3*jintSize >= end) {
+ return -1; // don't read past end of code buffer
+ }
jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
@@ -73,6 +79,9 @@
case _fast_binaryswitch: // fall through
case _fast_linearswitch:
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
+ if (end != NULL && aligned_bcp + 2*jintSize >= end) {
+ return -1; // don't read past end of code buffer
+ }
jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
// only return len if it can be represented as a positive int;
@@ -90,14 +99,17 @@
// verifier when reading in bytecode to verify. Other mechanisms that
// run at runtime (such as generateOopMaps) need to iterate over the code
// and don't expect to see breakpoints: they want to see the instruction
-// which was replaces so that they can get the correct length and find
+// which was replaced so that they can get the correct length and find
// the next bytecode.
-int Bytecodes::raw_special_length_at(address bcp) {
+//
+// 'end' indicates the end of the code buffer, which we should not try to read
+// past.
+int Bytecodes::raw_special_length_at(address bcp, address end) {
Code code = code_or_bp_at(bcp);
if (code == _breakpoint) {
return 1;
} else {
- return special_length_at(bcp);
+ return special_length_at(bcp, end);
}
}
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -340,8 +340,10 @@
const char* wf = wide_format(code);
return (wf == NULL) ? 0 : (int)strlen(wf);
}
- static int special_length_at(address bcp);
- static int raw_special_length_at(address bcp);
+ // if 'end' is provided, it indicates the end of the code buffer which
+ // should not be read past when parsing.
+ static int special_length_at(address bcp, address end = NULL);
+ static int raw_special_length_at(address bcp, address end = NULL);
static int length_at (address bcp) { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
static int java_length_at (address bcp) { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
--- a/hotspot/src/share/vm/opto/block.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/block.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -57,6 +57,14 @@
_blocks[i] = b;
}
+#ifndef PRODUCT
+void Block_List::print() {
+ for (uint i=0; i < size(); i++) {
+ tty->print("B%d ", _blocks[i]->_pre_order);
+ }
+ tty->print("size = %d\n", size());
+}
+#endif
//=============================================================================
@@ -66,6 +74,12 @@
// Check for Start block
if( _pre_order == 1 ) return InteriorEntryAlignment;
// Check for loop alignment
+ if (has_loop_alignment()) return loop_alignment();
+
+ return 1; // no particular alignment
+}
+
+uint Block::compute_loop_alignment() {
Node *h = head();
if( h->is_Loop() && h->as_Loop()->is_inner_loop() ) {
// Pre- and post-loops have low trip count so do not bother with
@@ -83,13 +97,15 @@
}
return OptoLoopAlignment; // Otherwise align loop head
}
+
return 1; // no particular alignment
}
//-----------------------------------------------------------------------------
// Compute the size of first 'inst_cnt' instructions in this block.
// Return the number of instructions left to compute if the block has
-// less then 'inst_cnt' instructions.
+// less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
+// exceeds OptoLoopAlignment.
uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
PhaseRegAlloc* ra) {
uint last_inst = _nodes.size();
@@ -307,6 +323,8 @@
tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
// Dump any loop-specific bits, especially for CountedLoops.
loop->dump_spec(tty);
+ } else if (has_loop_alignment()) {
+ tty->print(" top-of-loop");
}
tty->print(" Freq: %g",_freq);
if( Verbose || WizardMode ) {
@@ -509,9 +527,11 @@
int branch_idx = b->_nodes.size() - b->_num_succs-1;
if( branch_idx < 1 ) return false;
Node *bra = b->_nodes[branch_idx];
- if( bra->is_Catch() ) return true;
+ if( bra->is_Catch() )
+ return true;
if( bra->is_Mach() ) {
- if( bra->is_MachNullCheck() ) return true;
+ if( bra->is_MachNullCheck() )
+ return true;
int iop = bra->as_Mach()->ideal_Opcode();
if( iop == Op_FastLock || iop == Op_FastUnlock )
return true;
@@ -557,10 +577,10 @@
dead->_nodes[k]->del_req(j);
}
-//------------------------------MoveToNext-------------------------------------
+//------------------------------move_to_next-----------------------------------
// Helper function to move block bx to the slot following b_index. Return
// true if the move is successful, otherwise false
-bool PhaseCFG::MoveToNext(Block* bx, uint b_index) {
+bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
if (bx == NULL) return false;
// Return false if bx is already scheduled.
@@ -591,9 +611,9 @@
return true;
}
-//------------------------------MoveToEnd--------------------------------------
+//------------------------------move_to_end------------------------------------
// Move empty and uncommon blocks to the end.
-void PhaseCFG::MoveToEnd(Block *b, uint i) {
+void PhaseCFG::move_to_end(Block *b, uint i) {
int e = b->is_Empty();
if (e != Block::not_empty) {
if (e == Block::empty_with_goto) {
@@ -609,15 +629,31 @@
_blocks.push(b);
}
-//------------------------------RemoveEmpty------------------------------------
-// Remove empty basic blocks and useless branches.
-void PhaseCFG::RemoveEmpty() {
+//---------------------------set_loop_alignment--------------------------------
+// Set loop alignment for every block
+void PhaseCFG::set_loop_alignment() {
+ uint last = _num_blocks;
+ assert( _blocks[0] == _broot, "" );
+
+ for (uint i = 1; i < last; i++ ) {
+ Block *b = _blocks[i];
+ if (b->head()->is_Loop()) {
+ b->set_loop_alignment(b);
+ }
+ }
+}
+
+//-----------------------------remove_empty------------------------------------
+// Make empty basic blocks to be "connector" blocks, Move uncommon blocks
+// to the end.
+void PhaseCFG::remove_empty() {
// Move uncommon blocks to the end
uint last = _num_blocks;
- uint i;
assert( _blocks[0] == _broot, "" );
- for( i = 1; i < last; i++ ) {
+
+ for (uint i = 1; i < last; i++) {
Block *b = _blocks[i];
+ if (b->is_connector()) break;
// Check for NeverBranch at block end. This needs to become a GOTO to the
// true target. NeverBranch are treated as a conditional branch that
@@ -629,37 +665,40 @@
convert_NeverBranch_to_Goto(b);
// Look for uncommon blocks and move to end.
- if( b->is_uncommon(_bbs) ) {
- MoveToEnd(b, i);
- last--; // No longer check for being uncommon!
- if( no_flip_branch(b) ) { // Fall-thru case must follow?
- b = _blocks[i]; // Find the fall-thru block
- MoveToEnd(b, i);
- last--;
+ if (!C->do_freq_based_layout()) {
+ if( b->is_uncommon(_bbs) ) {
+ move_to_end(b, i);
+ last--; // No longer check for being uncommon!
+ if( no_flip_branch(b) ) { // Fall-thru case must follow?
+ b = _blocks[i]; // Find the fall-thru block
+ move_to_end(b, i);
+ last--;
+ }
+ i--; // backup block counter post-increment
}
- i--; // backup block counter post-increment
}
}
- // Remove empty blocks
- uint j1;
+ // Move empty blocks to the end
last = _num_blocks;
- for( i=0; i < last; i++ ) {
+ for (uint i = 1; i < last; i++) {
Block *b = _blocks[i];
- if (i > 0) {
- if (b->is_Empty() != Block::not_empty) {
- MoveToEnd(b, i);
- last--;
- i--;
- }
+ if (b->is_Empty() != Block::not_empty) {
+ move_to_end(b, i);
+ last--;
+ i--;
}
} // End of for all blocks
+}
+//-----------------------------fixup_flow--------------------------------------
+// Fix up the final control flow for basic blocks.
+void PhaseCFG::fixup_flow() {
// Fixup final control flow for the blocks. Remove jump-to-next
// block. If neither arm of a IF follows the conditional branch, we
// have to add a second jump after the conditional. We place the
// TRUE branch target in succs[0] for both GOTOs and IFs.
- for( i=0; i < _num_blocks; i++ ) {
+ for (uint i=0; i < _num_blocks; i++) {
Block *b = _blocks[i];
b->_pre_order = i; // turn pre-order into block-index
@@ -700,7 +739,7 @@
}
}
// Remove all CatchProjs
- for (j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
+ for (uint j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
} else if (b->_num_succs == 1) {
// Block ends in a Goto?
@@ -730,8 +769,7 @@
// successors after the current one, provided that the
// successor was previously unscheduled, but moveable
// (i.e., all paths to it involve a branch).
- if( bnext != bs0 && bnext != bs1 ) {
-
+ if( !C->do_freq_based_layout() && bnext != bs0 && bnext != bs1 ) {
// Choose the more common successor based on the probability
// of the conditional branch.
Block *bx = bs0;
@@ -751,9 +789,9 @@
}
// Attempt the more common successor first
- if (MoveToNext(bx, i)) {
+ if (move_to_next(bx, i)) {
bnext = bx;
- } else if (MoveToNext(by, i)) {
+ } else if (move_to_next(by, i)) {
bnext = by;
}
}
@@ -774,10 +812,8 @@
// Flip projection for each target
{ ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
- } else if( bnext == bs1 ) { // Fall-thru is already in succs[1]
-
- } else { // Else need a double-branch
-
+ } else if( bnext != bs1 ) {
+ // Need a double-branch
// The existing conditional branch need not change.
// Add a unconditional branch to the false target.
// Alas, it must appear in its own block and adding a
@@ -786,8 +822,9 @@
}
// Make sure we TRUE branch to the target
- if( proj0->Opcode() == Op_IfFalse )
+ if( proj0->Opcode() == Op_IfFalse ) {
iff->negate();
+ }
b->_nodes.pop(); // Remove IfFalse & IfTrue projections
b->_nodes.pop();
@@ -796,9 +833,7 @@
// Multi-exit block, e.g. a switch statement
// But we don't need to do anything here
}
-
} // End of for all blocks
-
}
@@ -905,7 +940,7 @@
// Force the Union-Find mapping to be at least this large
extend(max,0);
// Initialize to be the ID mapping.
- for( uint i=0; i<_max; i++ ) map(i,i);
+ for( uint i=0; i<max; i++ ) map(i,i);
}
//------------------------------Find_compress----------------------------------
@@ -937,7 +972,6 @@
if( idx >= _max ) return idx;
uint next = lookup(idx);
while( next != idx ) { // Scan chain of equivalences
- assert( next < idx, "always union smaller" );
idx = next; // until find a fixed-point
next = lookup(idx);
}
@@ -956,3 +990,491 @@
assert( src < dst, "always union smaller" );
map(dst,src);
}
+
+#ifndef PRODUCT
+static void edge_dump(GrowableArray<CFGEdge *> *edges) {
+ tty->print_cr("---- Edges ----");
+ for (int i = 0; i < edges->length(); i++) {
+ CFGEdge *e = edges->at(i);
+ if (e != NULL) {
+ edges->at(i)->dump();
+ }
+ }
+}
+
+static void trace_dump(Trace *traces[], int count) {
+ tty->print_cr("---- Traces ----");
+ for (int i = 0; i < count; i++) {
+ Trace *tr = traces[i];
+ if (tr != NULL) {
+ tr->dump();
+ }
+ }
+}
+
+void Trace::dump( ) const {
+ tty->print_cr("Trace (freq %f)", first_block()->_freq);
+ for (Block *b = first_block(); b != NULL; b = next(b)) {
+ tty->print(" B%d", b->_pre_order);
+ if (b->head()->is_Loop()) {
+ tty->print(" (L%d)", b->compute_loop_alignment());
+ }
+ if (b->has_loop_alignment()) {
+ tty->print(" (T%d)", b->code_alignment());
+ }
+ }
+ tty->cr();
+}
+
+void CFGEdge::dump( ) const {
+ tty->print(" B%d --> B%d Freq: %f out:%3d%% in:%3d%% State: ",
+ from()->_pre_order, to()->_pre_order, freq(), _from_pct, _to_pct);
+ switch(state()) {
+ case connected:
+ tty->print("connected");
+ break;
+ case open:
+ tty->print("open");
+ break;
+ case interior:
+ tty->print("interior");
+ break;
+ }
+ if (infrequent()) {
+ tty->print(" infrequent");
+ }
+ tty->cr();
+}
+#endif
+
+//=============================================================================
+
+//------------------------------edge_order-------------------------------------
+// Comparison function for edges
+static int edge_order(CFGEdge **e0, CFGEdge **e1) {
+ float freq0 = (*e0)->freq();
+ float freq1 = (*e1)->freq();
+ if (freq0 != freq1) {
+ return freq0 > freq1 ? -1 : 1;
+ }
+
+ int dist0 = (*e0)->to()->_rpo - (*e0)->from()->_rpo;
+ int dist1 = (*e1)->to()->_rpo - (*e1)->from()->_rpo;
+
+ return dist1 - dist0;
+}
+
+//------------------------------trace_frequency_order--------------------------
+// Comparison function for edges
+static int trace_frequency_order(const void *p0, const void *p1) {
+ Trace *tr0 = *(Trace **) p0;
+ Trace *tr1 = *(Trace **) p1;
+ Block *b0 = tr0->first_block();
+ Block *b1 = tr1->first_block();
+
+ // The trace of connector blocks goes at the end;
+ // we only expect one such trace
+ if (b0->is_connector() != b1->is_connector()) {
+ return b1->is_connector() ? -1 : 1;
+ }
+
+ // Pull more frequently executed blocks to the beginning
+ float freq0 = b0->_freq;
+ float freq1 = b1->_freq;
+ if (freq0 != freq1) {
+ return freq0 > freq1 ? -1 : 1;
+ }
+
+ int diff = tr0->first_block()->_rpo - tr1->first_block()->_rpo;
+
+ return diff;
+}
+
+//------------------------------find_edges-------------------------------------
+// Find edges of interest, i.e, those which can fall through. Presumes that
+// edges which don't fall through are of low frequency and can be generally
+// ignored. Initialize the list of traces.
+void PhaseBlockLayout::find_edges()
+{
+ // Walk the blocks, creating edges and Traces
+ uint i;
+ Trace *tr = NULL;
+ for (i = 0; i < _cfg._num_blocks; i++) {
+ Block *b = _cfg._blocks[i];
+ tr = new Trace(b, next, prev);
+ traces[tr->id()] = tr;
+
+ // All connector blocks should be at the end of the list
+ if (b->is_connector()) break;
+
+ // If this block and the next one have a one-to-one successor
+ // predecessor relationship, simply append the next block
+ int nfallthru = b->num_fall_throughs();
+ while (nfallthru == 1 &&
+ b->succ_fall_through(0)) {
+ Block *n = b->_succs[0];
+
+ // Skip over single-entry connector blocks, we don't want to
+ // add them to the trace.
+ while (n->is_connector() && n->num_preds() == 1) {
+ n = n->_succs[0];
+ }
+
+ // We see a merge point, so stop search for the next block
+ if (n->num_preds() != 1) break;
+
+ i++;
+ assert(n = _cfg._blocks[i], "expecting next block");
+ tr->append(n);
+ uf->map(n->_pre_order, tr->id());
+ traces[n->_pre_order] = NULL;
+ nfallthru = b->num_fall_throughs();
+ b = n;
+ }
+
+ if (nfallthru > 0) {
+ // Create a CFGEdge for each outgoing
+ // edge that could be a fall-through.
+ for (uint j = 0; j < b->_num_succs; j++ ) {
+ if (b->succ_fall_through(j)) {
+ Block *target = b->non_connector_successor(j);
+ float freq = b->_freq * b->succ_prob(j);
+ int from_pct = (int) ((100 * freq) / b->_freq);
+ int to_pct = (int) ((100 * freq) / target->_freq);
+ edges->append(new CFGEdge(b, target, freq, from_pct, to_pct));
+ }
+ }
+ }
+ }
+
+ // Group connector blocks into one trace
+ for (i++; i < _cfg._num_blocks; i++) {
+ Block *b = _cfg._blocks[i];
+ assert(b->is_connector(), "connector blocks at the end");
+ tr->append(b);
+ uf->map(b->_pre_order, tr->id());
+ traces[b->_pre_order] = NULL;
+ }
+}
+
+//------------------------------union_traces----------------------------------
+// Union two traces together in uf, and null out the trace in the list
+void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
+{
+ uint old_id = old_trace->id();
+ uint updated_id = updated_trace->id();
+
+ uint lo_id = updated_id;
+ uint hi_id = old_id;
+
+ // If from is greater than to, swap values to meet
+ // UnionFind guarantee.
+ if (updated_id > old_id) {
+ lo_id = old_id;
+ hi_id = updated_id;
+
+ // Fix up the trace ids
+ traces[lo_id] = traces[updated_id];
+ updated_trace->set_id(lo_id);
+ }
+
+ // Union the lower with the higher and remove the pointer
+ // to the higher.
+ uf->Union(lo_id, hi_id);
+ traces[hi_id] = NULL;
+}
+
+//------------------------------grow_traces-------------------------------------
+// Append traces together via the most frequently executed edges
+void PhaseBlockLayout::grow_traces()
+{
+ // Order the edges, and drive the growth of Traces via the most
+ // frequently executed edges.
+ edges->sort(edge_order);
+ for (int i = 0; i < edges->length(); i++) {
+ CFGEdge *e = edges->at(i);
+
+ if (e->state() != CFGEdge::open) continue;
+
+ Block *src_block = e->from();
+ Block *targ_block = e->to();
+
+ // Don't grow traces along backedges?
+ if (!BlockLayoutRotateLoops) {
+ if (targ_block->_rpo <= src_block->_rpo) {
+ targ_block->set_loop_alignment(targ_block);
+ continue;
+ }
+ }
+
+ Trace *src_trace = trace(src_block);
+ Trace *targ_trace = trace(targ_block);
+
+ // If the edge in question can join two traces at their ends,
+ // append one trace to the other.
+ if (src_trace->last_block() == src_block) {
+ if (src_trace == targ_trace) {
+ e->set_state(CFGEdge::interior);
+ if (targ_trace->backedge(e)) {
+ // Reset i to catch any newly eligible edge
+ // (Or we could remember the first "open" edge, and reset there)
+ i = 0;
+ }
+ } else if (targ_trace->first_block() == targ_block) {
+ e->set_state(CFGEdge::connected);
+ src_trace->append(targ_trace);
+ union_traces(src_trace, targ_trace);
+ }
+ }
+ }
+}
+
+//------------------------------merge_traces-----------------------------------
+// Embed one trace into another, if the fork or join points are sufficiently
+// balanced.
+void PhaseBlockLayout::merge_traces(bool fall_thru_only)
+{
+ // Walk the edge list a another time, looking at unprocessed edges.
+ // Fold in diamonds
+ for (int i = 0; i < edges->length(); i++) {
+ CFGEdge *e = edges->at(i);
+
+ if (e->state() != CFGEdge::open) continue;
+ if (fall_thru_only) {
+ if (e->infrequent()) continue;
+ }
+
+ Block *src_block = e->from();
+ Trace *src_trace = trace(src_block);
+ bool src_at_tail = src_trace->last_block() == src_block;
+
+ Block *targ_block = e->to();
+ Trace *targ_trace = trace(targ_block);
+ bool targ_at_start = targ_trace->first_block() == targ_block;
+
+ if (src_trace == targ_trace) {
+ // This may be a loop, but we can't do much about it.
+ e->set_state(CFGEdge::interior);
+ continue;
+ }
+
+ if (fall_thru_only) {
+ // If the edge links the middle of two traces, we can't do anything.
+ // Mark the edge and continue.
+ if (!src_at_tail & !targ_at_start) {
+ continue;
+ }
+
+ // Don't grow traces along backedges?
+ if (!BlockLayoutRotateLoops && (targ_block->_rpo <= src_block->_rpo)) {
+ continue;
+ }
+
+ // If both ends of the edge are available, why didn't we handle it earlier?
+ assert(src_at_tail ^ targ_at_start, "Should have caught this edge earlier.");
+
+ if (targ_at_start) {
+ // Insert the "targ" trace in the "src" trace if the insertion point
+ // is a two way branch.
+ // Better profitability check possible, but may not be worth it.
+ // Someday, see if the this "fork" has an associated "join";
+ // then make a policy on merging this trace at the fork or join.
+ // For example, other things being equal, it may be better to place this
+ // trace at the join point if the "src" trace ends in a two-way, but
+ // the insertion point is one-way.
+ assert(src_block->num_fall_throughs() == 2, "unexpected diamond");
+ e->set_state(CFGEdge::connected);
+ src_trace->insert_after(src_block, targ_trace);
+ union_traces(src_trace, targ_trace);
+ } else if (src_at_tail) {
+ if (src_trace != trace(_cfg._broot)) {
+ e->set_state(CFGEdge::connected);
+ targ_trace->insert_before(targ_block, src_trace);
+ union_traces(targ_trace, src_trace);
+ }
+ }
+ } else if (e->state() == CFGEdge::open) {
+ // Append traces, even without a fall-thru connection.
+ // But leave root entry at the begining of the block list.
+ if (targ_trace != trace(_cfg._broot)) {
+ e->set_state(CFGEdge::connected);
+ src_trace->append(targ_trace);
+ union_traces(src_trace, targ_trace);
+ }
+ }
+ }
+}
+
+//----------------------------reorder_traces-----------------------------------
+// Order the sequence of the traces in some desirable way, and fixup the
+// jumps at the end of each block.
+void PhaseBlockLayout::reorder_traces(int count)
+{
+ ResourceArea *area = Thread::current()->resource_area();
+ Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
+ Block_List worklist;
+ int new_count = 0;
+
+ // Compact the traces.
+ for (int i = 0; i < count; i++) {
+ Trace *tr = traces[i];
+ if (tr != NULL) {
+ new_traces[new_count++] = tr;
+ }
+ }
+
+ // The entry block should be first on the new trace list.
+ Trace *tr = trace(_cfg._broot);
+ assert(tr == new_traces[0], "entry trace misplaced");
+
+ // Sort the new trace list by frequency
+ qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);
+
+ // Patch up the successor blocks
+ _cfg._blocks.reset();
+ _cfg._num_blocks = 0;
+ for (int i = 0; i < new_count; i++) {
+ Trace *tr = new_traces[i];
+ if (tr != NULL) {
+ tr->fixup_blocks(_cfg);
+ }
+ }
+}
+
+//------------------------------PhaseBlockLayout-------------------------------
+// Order basic blocks based on frequency
+PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
+ Phase(BlockLayout),
+ _cfg(cfg)
+{
+ ResourceMark rm;
+ ResourceArea *area = Thread::current()->resource_area();
+
+ // List of traces
+ int size = _cfg._num_blocks + 1;
+ traces = NEW_ARENA_ARRAY(area, Trace *, size);
+ memset(traces, 0, size*sizeof(Trace*));
+ next = NEW_ARENA_ARRAY(area, Block *, size);
+ memset(next, 0, size*sizeof(Block *));
+ prev = NEW_ARENA_ARRAY(area, Block *, size);
+ memset(prev , 0, size*sizeof(Block *));
+
+ // List of edges
+ edges = new GrowableArray<CFGEdge*>;
+
+ // Mapping block index --> block_trace
+ uf = new UnionFind(size);
+ uf->reset(size);
+
+ // Find edges and create traces.
+ find_edges();
+
+ // Grow traces at their ends via most frequent edges.
+ grow_traces();
+
+ // Merge one trace into another, but only at fall-through points.
+ // This may make diamonds and other related shapes in a trace.
+ merge_traces(true);
+
+ // Run merge again, allowing two traces to be catenated, even if
+ // one does not fall through into the other. This appends loosely
+ // related traces to be near each other.
+ merge_traces(false);
+
+ // Re-order all the remaining traces by frequency
+ reorder_traces(size);
+
+ assert(_cfg._num_blocks >= (uint) (size - 1), "number of blocks can not shrink");
+}
+
+
+//------------------------------backedge---------------------------------------
+// Edge e completes a loop in a trace. If the target block is head of the
+// loop, rotate the loop block so that the loop ends in a conditional branch.
+bool Trace::backedge(CFGEdge *e) {
+ bool loop_rotated = false;
+ Block *src_block = e->from();
+ Block *targ_block = e->to();
+
+ assert(last_block() == src_block, "loop discovery at back branch");
+ if (first_block() == targ_block) {
+ if (BlockLayoutRotateLoops && last_block()->num_fall_throughs() < 2) {
+ // Find the last block in the trace that has a conditional
+ // branch.
+ Block *b;
+ for (b = last_block(); b != NULL; b = prev(b)) {
+ if (b->num_fall_throughs() == 2) {
+ break;
+ }
+ }
+
+ if (b != last_block() && b != NULL) {
+ loop_rotated = true;
+
+ // Rotate the loop by doing two-part linked-list surgery.
+ append(first_block());
+ break_loop_after(b);
+ }
+ }
+
+ // Backbranch to the top of a trace
+ // Scroll foward through the trace from the targ_block. If we find
+ // a loop head before another loop top, use the the loop head alignment.
+ for (Block *b = targ_block; b != NULL; b = next(b)) {
+ if (b->has_loop_alignment()) {
+ break;
+ }
+ if (b->head()->is_Loop()) {
+ targ_block = b;
+ break;
+ }
+ }
+
+ first_block()->set_loop_alignment(targ_block);
+
+ } else {
+ // Backbranch into the middle of a trace
+ targ_block->set_loop_alignment(targ_block);
+ }
+
+ return loop_rotated;
+}
+
+//------------------------------fixup_blocks-----------------------------------
+// push blocks onto the CFG list
+// ensure that blocks have the correct two-way branch sense
+void Trace::fixup_blocks(PhaseCFG &cfg) {
+ Block *last = last_block();
+ for (Block *b = first_block(); b != NULL; b = next(b)) {
+ cfg._blocks.push(b);
+ cfg._num_blocks++;
+ if (!b->is_connector()) {
+ int nfallthru = b->num_fall_throughs();
+ if (b != last) {
+ if (nfallthru == 2) {
+ // Ensure that the sense of the branch is correct
+ Block *bnext = next(b);
+ Block *bs0 = b->non_connector_successor(0);
+
+ MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
+ ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
+ ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
+
+ if (bnext == bs0) {
+ // Fall-thru case in succs[0], should be in succs[1]
+
+ // Flip targets in _succs map
+ Block *tbs0 = b->_succs[0];
+ Block *tbs1 = b->_succs[1];
+ b->_succs.map( 0, tbs1 );
+ b->_succs.map( 1, tbs0 );
+
+ // Flip projections to match targets
+ b->_nodes.map(b->_nodes.size()-2, proj1);
+ b->_nodes.map(b->_nodes.size()-1, proj0);
+ }
+ }
+ }
+ }
+ }
+}
--- a/hotspot/src/share/vm/opto/block.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/block.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -75,6 +75,7 @@
void insert( uint i, Block *n );
uint size() const { return _cnt; }
void reset() { _cnt = 0; }
+ void print();
};
@@ -129,7 +130,11 @@
uint _rpo; // Number in reverse post order walk
virtual bool is_block() { return true; }
- float succ_prob(uint i); // return probability of i'th successor
+ float succ_prob(uint i); // return probability of i'th successor
+ int num_fall_throughs(); // How many fall-through candidate this block has
+ void update_uncommon_branch(Block* un); // Lower branch prob to uncommon code
+ bool succ_fall_through(uint i); // Is successor "i" is a fall-through candidate
+ Block* lone_fall_through(); // Return lone fall-through Block or null
Block* dom_lca(Block* that); // Compute LCA in dominator tree.
#ifdef ASSERT
@@ -144,6 +149,7 @@
// Report the alignment required by this block. Must be a power of 2.
// The previous block will insert nops to get this alignment.
uint code_alignment();
+ uint compute_loop_alignment();
// BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies.
// It is currently also used to scale such frequencies relative to
@@ -184,11 +190,12 @@
int current_alignment = current_offset & max_pad;
if( current_alignment != 0 ) {
uint padding = (block_alignment-current_alignment) & max_pad;
- if( !head()->is_Loop() ||
- padding <= (uint)MaxLoopPad ||
- first_inst_size() > padding ) {
- return padding;
+ if( has_loop_alignment() &&
+ padding > (uint)MaxLoopPad &&
+ first_inst_size() <= padding ) {
+ return 0;
}
+ return padding;
}
}
return 0;
@@ -202,6 +209,21 @@
void set_connector() { _connector = true; }
bool is_connector() const { return _connector; };
+ // Loop_alignment will be set for blocks which are at the top of loops.
+ // The block layout pass may rotate loops such that the loop head may not
+ // be the sequentially first block of the loop encountered in the linear
+ // list of blocks. If the layout pass is not run, loop alignment is set
+ // for each block which is the head of a loop.
+ uint _loop_alignment;
+ void set_loop_alignment(Block *loop_top) {
+ uint new_alignment = loop_top->compute_loop_alignment();
+ if (new_alignment > _loop_alignment) {
+ _loop_alignment = new_alignment;
+ }
+ }
+ uint loop_alignment() const { return _loop_alignment; }
+ bool has_loop_alignment() const { return loop_alignment() > 0; }
+
// Create a new Block with given head Node.
// Creates the (empty) predecessor arrays.
Block( Arena *a, Node *headnode )
@@ -219,7 +241,8 @@
_raise_LCA_mark(0),
_raise_LCA_visited(0),
_first_inst_size(999999),
- _connector(false) {
+ _connector(false),
+ _loop_alignment(0) {
_nodes.push(headnode);
}
@@ -275,6 +298,16 @@
return s;
}
+ // Return true if b is a successor of this block
+ bool has_successor(Block* b) const {
+ for (uint i = 0; i < _num_succs; i++ ) {
+ if (non_connector_successor(i) == b) {
+ return true;
+ }
+ }
+ return false;
+ }
+
// Successor block, after forwarding through connectors
Block* non_connector_successor(int i) const {
return _succs[i]->non_connector();
@@ -319,7 +352,6 @@
// I'll need a few machine-specific GotoNodes. Clone from this one.
MachNode *_goto;
- void insert_goto_at(uint block_no, uint succ_no);
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
void verify_anti_dependences(Block* LCA, Node* load) {
@@ -379,10 +411,15 @@
// Compute the instruction global latency with a backwards walk
void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
+ // Set loop alignment
+ void set_loop_alignment();
+
// Remove empty basic blocks
- void RemoveEmpty();
- bool MoveToNext(Block* bx, uint b_index);
- void MoveToEnd(Block* bx, uint b_index);
+ void remove_empty();
+ void fixup_flow();
+ bool move_to_next(Block* bx, uint b_index);
+ void move_to_end(Block* bx, uint b_index);
+ void insert_goto_at(uint block_no, uint succ_no);
// Check for NeverBranch at block end. This needs to become a GOTO to the
// true target. NeverBranch are treated as a conditional branch that always
@@ -413,7 +450,7 @@
};
-//------------------------------UnionFindInfo----------------------------------
+//------------------------------UnionFind--------------------------------------
// Map Block indices to a block-index for a cfg-cover.
// Array lookup in the optimized case.
class UnionFind : public ResourceObj {
@@ -508,3 +545,166 @@
void dump_tree() const;
#endif
};
+
+
+//----------------------------------CFGEdge------------------------------------
+// A edge between two basic blocks that will be embodied by a branch or a
+// fall-through.
+class CFGEdge : public ResourceObj {
+ private:
+ Block * _from; // Source basic block
+ Block * _to; // Destination basic block
+ float _freq; // Execution frequency (estimate)
+ int _state;
+ bool _infrequent;
+ int _from_pct;
+ int _to_pct;
+
+ // Private accessors
+ int from_pct() const { return _from_pct; }
+ int to_pct() const { return _to_pct; }
+ int from_infrequent() const { return from_pct() < BlockLayoutMinDiamondPercentage; }
+ int to_infrequent() const { return to_pct() < BlockLayoutMinDiamondPercentage; }
+
+ public:
+ enum {
+ open, // initial edge state; unprocessed
+ connected, // edge used to connect two traces together
+ interior // edge is interior to trace (could be backedge)
+ };
+
+ CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) :
+ _from(from), _to(to), _freq(freq),
+ _from_pct(from_pct), _to_pct(to_pct), _state(open) {
+ _infrequent = from_infrequent() || to_infrequent();
+ }
+
+ float freq() const { return _freq; }
+ Block* from() const { return _from; }
+ Block* to () const { return _to; }
+ int infrequent() const { return _infrequent; }
+ int state() const { return _state; }
+
+ void set_state(int state) { _state = state; }
+
+#ifndef PRODUCT
+ void dump( ) const;
+#endif
+};
+
+
+//-----------------------------------Trace-------------------------------------
+// An ordered list of basic blocks.
+class Trace : public ResourceObj {
+ private:
+ uint _id; // Unique Trace id (derived from initial block)
+ Block ** _next_list; // Array mapping index to next block
+ Block ** _prev_list; // Array mapping index to previous block
+ Block * _first; // First block in the trace
+ Block * _last; // Last block in the trace
+
+ // Return the block that follows "b" in the trace.
+ Block * next(Block *b) const { return _next_list[b->_pre_order]; }
+ void set_next(Block *b, Block *n) const { _next_list[b->_pre_order] = n; }
+
+ // Return the block that preceeds "b" in the trace.
+ Block * prev(Block *b) const { return _prev_list[b->_pre_order]; }
+ void set_prev(Block *b, Block *p) const { _prev_list[b->_pre_order] = p; }
+
+ // We've discovered a loop in this trace. Reset last to be "b", and first as
+ // the block following "b
+ void break_loop_after(Block *b) {
+ _last = b;
+ _first = next(b);
+ set_prev(_first, NULL);
+ set_next(_last, NULL);
+ }
+
+ public:
+
+ Trace(Block *b, Block **next_list, Block **prev_list) :
+ _first(b),
+ _last(b),
+ _next_list(next_list),
+ _prev_list(prev_list),
+ _id(b->_pre_order) {
+ set_next(b, NULL);
+ set_prev(b, NULL);
+ };
+
+ // Return the id number
+ uint id() const { return _id; }
+ void set_id(uint id) { _id = id; }
+
+ // Return the first block in the trace
+ Block * first_block() const { return _first; }
+
+ // Return the last block in the trace
+ Block * last_block() const { return _last; }
+
+ // Insert a trace in the middle of this one after b
+ void insert_after(Block *b, Trace *tr) {
+ set_next(tr->last_block(), next(b));
+ if (next(b) != NULL) {
+ set_prev(next(b), tr->last_block());
+ }
+
+ set_next(b, tr->first_block());
+ set_prev(tr->first_block(), b);
+
+ if (b == _last) {
+ _last = tr->last_block();
+ }
+ }
+
+ void insert_before(Block *b, Trace *tr) {
+ Block *p = prev(b);
+ assert(p != NULL, "use append instead");
+ insert_after(p, tr);
+ }
+
+ // Append another trace to this one.
+ void append(Trace *tr) {
+ insert_after(_last, tr);
+ }
+
+ // Append a block at the end of this trace
+ void append(Block *b) {
+ set_next(_last, b);
+ set_prev(b, _last);
+ _last = b;
+ }
+
+ // Adjust the the blocks in this trace
+ void fixup_blocks(PhaseCFG &cfg);
+ bool backedge(CFGEdge *e);
+
+#ifndef PRODUCT
+ void dump( ) const;
+#endif
+};
+
+//------------------------------PhaseBlockLayout-------------------------------
+// Rearrange blocks into some canonical order, based on edges and their frequencies
+class PhaseBlockLayout : public Phase {
+ PhaseCFG &_cfg; // Control flow graph
+
+ GrowableArray<CFGEdge *> *edges;
+ Trace **traces;
+ Block **next;
+ Block **prev;
+ UnionFind *uf;
+
+ // Given a block, find its encompassing Trace
+ Trace * trace(Block *b) {
+ return traces[uf->Find_compress(b->_pre_order)];
+ }
+ public:
+ PhaseBlockLayout(PhaseCFG &cfg);
+
+ void find_edges();
+ void grow_traces();
+ void merge_traces(bool loose_connections);
+ void reorder_traces(int count);
+ void union_traces(Trace* from, Trace* to);
+};
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -388,6 +388,9 @@
product(intx, EliminateAllocationArraySizeLimit, 64, \
"Array size (number of elements) limit for scalar replacement") \
\
+ product(bool, UseOptoBiasInlining, true, \
+ "Generate biased locking code in C2 ideal graph") \
+ \
product(intx, ValueSearchLimit, 1000, \
"Recursion limit in PhaseMacroExpand::value_from_mem_phi") \
\
@@ -396,5 +399,15 @@
\
diagnostic(intx, DominatorSearchLimit, 1000, \
"Iterations limit in Node::dominates") \
+ \
+ product(bool, BlockLayoutByFrequency, true, \
+ "Use edge frequencies to drive block ordering") \
+ \
+ product(intx, BlockLayoutMinDiamondPercentage, 20, \
+ "Miniumum %% of a successor (predecessor) for which block layout "\
+ "a will allow a fork (join) in a single chain") \
+ \
+ product(bool, BlockLayoutRotateLoops, false, \
+ "Allow back branches to be fall throughs in the block layour") \
C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -967,6 +967,7 @@
init_class_id(Class_SafePointScalarObject);
}
+bool SafePointScalarObjectNode::pinned() const { return true; }
uint SafePointScalarObjectNode::ideal_reg() const {
return 0; // No matching to machine instruction
--- a/hotspot/src/share/vm/opto/callnode.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/callnode.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -433,6 +433,10 @@
uint n_fields() const { return _n_fields; }
DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
+ // SafePointScalarObject should be always pinned to the control edge
+ // of the SafePoint node for which it was generated.
+ virtual bool pinned() const; // { return true; }
+
virtual uint size_of() const { return sizeof(*this); }
// Assumes that "this" is an argument to a safepoint node "s", and that
--- a/hotspot/src/share/vm/opto/chaitin.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -440,9 +440,7 @@
assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
// This frame must preserve the required fp alignment
- const int stack_alignment_in_words = Matcher::stack_alignment_in_slots();
- if (stack_alignment_in_words > 0)
- _framesize = round_to(_framesize, Matcher::stack_alignment_in_bytes());
+ _framesize = round_to(_framesize, Matcher::stack_alignment_in_slots());
assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
#ifndef PRODUCT
_total_framesize += _framesize;
--- a/hotspot/src/share/vm/opto/classes.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/classes.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -205,6 +205,7 @@
macro(StoreC)
macro(StoreCM)
macro(StorePConditional)
+macro(StoreIConditional)
macro(StoreLConditional)
macro(StoreD)
macro(StoreF)
--- a/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -551,7 +551,7 @@
rethrow_exceptions(kit.transfer_exceptions_into_jvms());
}
- print_method("Before RemoveUseless");
+ print_method("Before RemoveUseless", 3);
// Remove clutter produced by parsing.
if (!failing()) {
@@ -822,6 +822,7 @@
Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
set_decompile_count(0);
+ set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency"));
// Compilation level related initialization
if (env()->comp_level() == CompLevel_fast_compile) {
set_num_loop_opts(Tier1LoopOptsCount);
@@ -1701,8 +1702,14 @@
// are not adding any new instructions. If any basic block is empty, we
// can now safely remove it.
{
- NOT_PRODUCT( TracePhase t2("removeEmpty", &_t_removeEmptyBlocks, TimeCompiler); )
- cfg.RemoveEmpty();
+ NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); )
+ cfg.remove_empty();
+ if (do_freq_based_layout()) {
+ PhaseBlockLayout layout(cfg);
+ } else {
+ cfg.set_loop_alignment();
+ }
+ cfg.fixup_flow();
}
// Perform any platform dependent postallocation verifications.
@@ -1994,6 +2001,7 @@
case Op_StorePConditional:
case Op_StoreI:
case Op_StoreL:
+ case Op_StoreIConditional:
case Op_StoreLConditional:
case Op_CompareAndSwapI:
case Op_CompareAndSwapL:
--- a/hotspot/src/share/vm/opto/compile.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -154,6 +154,7 @@
uint _decompile_count; // Cumulative decompilation counts.
bool _do_inlining; // True if we intend to do inlining
bool _do_scheduling; // True if we intend to do scheduling
+ bool _do_freq_based_layout; // True if we intend to do frequency based block layout
bool _do_count_invocations; // True if we generate code to count invocations
bool _do_method_data_update; // True if we generate code to update methodDataOops
int _AliasLevel; // Locally-adjusted version of AliasLevel flag.
@@ -307,6 +308,8 @@
void set_do_inlining(bool z) { _do_inlining = z; }
bool do_scheduling() const { return _do_scheduling; }
void set_do_scheduling(bool z) { _do_scheduling = z; }
+ bool do_freq_based_layout() const{ return _do_freq_based_layout; }
+ void set_do_freq_based_layout(bool z){ _do_freq_based_layout = z; }
bool do_count_invocations() const{ return _do_count_invocations; }
void set_do_count_invocations(bool z){ _do_count_invocations = z; }
bool do_method_data_update() const { return _do_method_data_update; }
--- a/hotspot/src/share/vm/opto/gcm.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/gcm.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -1319,11 +1319,33 @@
//------------------------------Estimate_Block_Frequency-----------------------
// Estimate block frequencies based on IfNode probabilities.
void PhaseCFG::Estimate_Block_Frequency() {
- int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1;
- // Most of our algorithms will die horribly if frequency can become
- // negative so make sure cnts is a sane value.
- if( cnts <= 0 ) cnts = 1;
- float f = (float)cnts/(float)FreqCountInvocations;
+
+ // Force conditional branches leading to uncommon traps to be unlikely,
+ // not because we get to the uncommon_trap with less relative frequency,
+ // but because an uncommon_trap typically causes a deopt, so we only get
+ // there once.
+ if (C->do_freq_based_layout()) {
+ Block_List worklist;
+ Block* root_blk = _blocks[0];
+ for (uint i = 1; i < root_blk->num_preds(); i++) {
+ Block *pb = _bbs[root_blk->pred(i)->_idx];
+ if (pb->has_uncommon_code()) {
+ worklist.push(pb);
+ }
+ }
+ while (worklist.size() > 0) {
+ Block* uct = worklist.pop();
+ if (uct == _broot) continue;
+ for (uint i = 1; i < uct->num_preds(); i++) {
+ Block *pb = _bbs[uct->pred(i)->_idx];
+ if (pb->_num_succs == 1) {
+ worklist.push(pb);
+ } else if (pb->num_fall_throughs() == 2) {
+ pb->update_uncommon_branch(uct);
+ }
+ }
+ }
+ }
// Create the loop tree and calculate loop depth.
_root_loop = create_loop_tree();
@@ -1333,25 +1355,27 @@
_root_loop->compute_freq();
// Adjust all frequencies to be relative to a single method entry
- _root_loop->_freq = f * 1.0;
+ _root_loop->_freq = 1.0;
_root_loop->scale_freq();
// force paths ending at uncommon traps to be infrequent
- Block_List worklist;
- Block* root_blk = _blocks[0];
- for (uint i = 0; i < root_blk->num_preds(); i++) {
- Block *pb = _bbs[root_blk->pred(i)->_idx];
- if (pb->has_uncommon_code()) {
- worklist.push(pb);
+ if (!C->do_freq_based_layout()) {
+ Block_List worklist;
+ Block* root_blk = _blocks[0];
+ for (uint i = 1; i < root_blk->num_preds(); i++) {
+ Block *pb = _bbs[root_blk->pred(i)->_idx];
+ if (pb->has_uncommon_code()) {
+ worklist.push(pb);
+ }
}
- }
- while (worklist.size() > 0) {
- Block* uct = worklist.pop();
- uct->_freq = PROB_MIN;
- for (uint i = 0; i < uct->num_preds(); i++) {
- Block *pb = _bbs[uct->pred(i)->_idx];
- if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
- worklist.push(pb);
+ while (worklist.size() > 0) {
+ Block* uct = worklist.pop();
+ uct->_freq = PROB_MIN;
+ for (uint i = 1; i < uct->num_preds(); i++) {
+ Block *pb = _bbs[uct->pred(i)->_idx];
+ if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
+ worklist.push(pb);
+ }
}
}
}
@@ -1556,22 +1580,6 @@
}
}
-#if 0
- // Raise frequency of the loop backedge block, in an effort
- // to keep it empty. Skip the method level "loop".
- if (_parent != NULL) {
- CFGElement* s = _members.at(_members.length() - 1);
- if (s->is_block()) {
- Block* bk = s->as_Block();
- if (bk->_num_succs == 1 && bk->_succs[0] == hd) {
- // almost any value >= 1.0f works
- // FIXME: raw constant
- bk->_freq = 1.05f;
- }
- }
- }
-#endif
-
// For all loops other than the outer, "method" loop,
// sum and normalize the exit probability. The "method" loop
// should keep the initial exit probability of 1, so that
@@ -1589,12 +1597,15 @@
// the probability of exit per loop entry.
for (int i = 0; i < _exits.length(); i++) {
Block* et = _exits.at(i).get_target();
- float new_prob = _exits.at(i).get_prob() / exits_sum;
+ float new_prob = 0.0f;
+ if (_exits.at(i).get_prob() > 0.0f) {
+ new_prob = _exits.at(i).get_prob() / exits_sum;
+ }
BlockProbPair bpp(et, new_prob);
_exits.at_put(i, bpp);
}
- // Save the total, but guard against unreasoable probability,
+ // Save the total, but guard against unreasonable probability,
// as the value is used to estimate the loop trip count.
// An infinite trip count would blur relative block
// frequencies.
@@ -1688,6 +1699,137 @@
return 0.0f;
}
+//------------------------------num_fall_throughs-----------------------------
+// Return the number of fall-through candidates for a block
+int Block::num_fall_throughs() {
+ int eidx = end_idx();
+ Node *n = _nodes[eidx]; // Get ending Node
+
+ int op = n->Opcode();
+ if (n->is_Mach()) {
+ if (n->is_MachNullCheck()) {
+ // In theory, either side can fall-thru, for simplicity sake,
+ // let's say only the false branch can now.
+ return 1;
+ }
+ op = n->as_Mach()->ideal_Opcode();
+ }
+
+ // Switch on branch type
+ switch( op ) {
+ case Op_CountedLoopEnd:
+ case Op_If:
+ return 2;
+
+ case Op_Root:
+ case Op_Goto:
+ return 1;
+
+ case Op_Catch: {
+ for (uint i = 0; i < _num_succs; i++) {
+ const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+ if (ci->_con == CatchProjNode::fall_through_index) {
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ case Op_Jump:
+ case Op_NeverBranch:
+ case Op_TailCall:
+ case Op_TailJump:
+ case Op_Return:
+ case Op_Halt:
+ case Op_Rethrow:
+ return 0;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ return 0;
+}
+
+//------------------------------succ_fall_through-----------------------------
+// Return true if a specific successor could be fall-through target.
+bool Block::succ_fall_through(uint i) {
+ int eidx = end_idx();
+ Node *n = _nodes[eidx]; // Get ending Node
+
+ int op = n->Opcode();
+ if (n->is_Mach()) {
+ if (n->is_MachNullCheck()) {
+ // In theory, either side can fall-thru, for simplicity sake,
+ // let's say only the false branch can now.
+ return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
+ }
+ op = n->as_Mach()->ideal_Opcode();
+ }
+
+ // Switch on branch type
+ switch( op ) {
+ case Op_CountedLoopEnd:
+ case Op_If:
+ case Op_Root:
+ case Op_Goto:
+ return true;
+
+ case Op_Catch: {
+ const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+ return ci->_con == CatchProjNode::fall_through_index;
+ }
+
+ case Op_Jump:
+ case Op_NeverBranch:
+ case Op_TailCall:
+ case Op_TailJump:
+ case Op_Return:
+ case Op_Halt:
+ case Op_Rethrow:
+ return false;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ return false;
+}
+
+//------------------------------update_uncommon_branch------------------------
+// Update the probability of a two-branch to be uncommon
+void Block::update_uncommon_branch(Block* ub) {
+ int eidx = end_idx();
+ Node *n = _nodes[eidx]; // Get ending Node
+
+ int op = n->as_Mach()->ideal_Opcode();
+
+ assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If");
+ assert(num_fall_throughs() == 2, "must be a two way branch block");
+
+ // Which successor is ub?
+ uint s;
+ for (s = 0; s <_num_succs; s++) {
+ if (_succs[s] == ub) break;
+ }
+ assert(s < 2, "uncommon successor must be found");
+
+ // If ub is the true path, make the proability small, else
+ // ub is the false path, and make the probability large
+ bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
+
+ // Get existing probability
+ float p = n->as_MachIf()->_prob;
+
+ if (invert) p = 1.0 - p;
+ if (p > PROB_MIN) {
+ p = PROB_MIN;
+ }
+ if (invert) p = 1.0 - p;
+
+ n->as_MachIf()->_prob = p;
+}
+
//------------------------------update_succ_freq-------------------------------
// Update the appropriate frequency associated with block 'b', a succesor of
// a block in this loop.
--- a/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -3485,11 +3485,32 @@
const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
int alias_idx = C->get_alias_index(adr_type);
- Node *result = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
- Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(result));
+ Node *cas = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
+ Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(cas));
set_memory(store_proj, alias_idx);
-
- push(result);
+ Node *bol = _gvn.transform( new (C, 2) BoolNode( cas, BoolTest::eq ) );
+
+ Node *result;
+ // CMove node is not used to be able fold a possible check code
+ // after attemptUpdate() call. This code could be transformed
+ // into CMove node by loop optimizations.
+ {
+ RegionNode *r = new (C, 3) RegionNode(3);
+ result = new (C, 3) PhiNode(r, TypeInt::BOOL);
+
+ Node *iff = create_and_xform_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
+ Node *iftrue = opt_iff(r, iff);
+ r->init_req(1, iftrue);
+ result->init_req(1, intcon(1));
+ result->init_req(2, intcon(0));
+
+ set_control(_gvn.transform(r));
+ record_for_igvn(r);
+
+ C->set_has_split_ifs(true); // Has chance for split-if optimization
+ }
+
+ push(_gvn.transform(result));
return true;
}
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -1519,6 +1519,7 @@
Node *bol = iff->in(1);
if( bol && bol->req() > 1 && bol->in(1) &&
((bol->in(1)->Opcode() == Op_StorePConditional ) ||
+ (bol->in(1)->Opcode() == Op_StoreIConditional ) ||
(bol->in(1)->Opcode() == Op_StoreLConditional ) ||
(bol->in(1)->Opcode() == Op_CompareAndSwapI ) ||
(bol->in(1)->Opcode() == Op_CompareAndSwapL ) ||
--- a/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -82,16 +82,31 @@
}
}
-Node* PhaseMacroExpand::opt_iff(Node* region, Node* iff) {
- IfNode *opt_iff = transform_later(iff)->as_If();
+Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) {
+ Node* cmp;
+ if (mask != 0) {
+ Node* and_node = transform_later(new (C, 3) AndXNode(word, MakeConX(mask)));
+ cmp = transform_later(new (C, 3) CmpXNode(and_node, MakeConX(bits)));
+ } else {
+ cmp = word;
+ }
+ Node* bol = transform_later(new (C, 2) BoolNode(cmp, BoolTest::ne));
+ IfNode* iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
+ transform_later(iff);
- // Fast path taken; set region slot 2
- Node *fast_taken = transform_later( new (C, 1) IfFalseNode(opt_iff) );
- region->init_req(2,fast_taken); // Capture fast-control
+ // Fast path taken.
+ Node *fast_taken = transform_later( new (C, 1) IfFalseNode(iff) );
// Fast path not-taken, i.e. slow path
- Node *slow_taken = transform_later( new (C, 1) IfTrueNode(opt_iff) );
- return slow_taken;
+ Node *slow_taken = transform_later( new (C, 1) IfTrueNode(iff) );
+
+ if (return_fast_path) {
+ region->init_req(edge, slow_taken); // Capture slow-control
+ return fast_taken;
+ } else {
+ region->init_req(edge, fast_taken); // Capture fast-control
+ return slow_taken;
+ }
}
//--------------------copy_predefined_input_for_runtime_call--------------------
@@ -854,7 +869,7 @@
Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) {
Node* adr = basic_plus_adr(base, offset);
- const TypePtr* adr_type = TypeRawPtr::BOTTOM;
+ const TypePtr* adr_type = adr->bottom_type()->is_ptr();
Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt);
transform_later(value);
return value;
@@ -1583,12 +1598,194 @@
Node* flock = lock->fastlock_node();
// Make the merge point
- Node *region = new (C, 3) RegionNode(3);
+ Node *region;
+ Node *mem_phi;
+ Node *slow_path;
+
+ if (UseOptoBiasInlining) {
+ /*
+ * See the full descrition in MacroAssembler::biased_locking_enter().
+ *
+ * if( (mark_word & biased_lock_mask) == biased_lock_pattern ) {
+ * // The object is biased.
+ * proto_node = klass->prototype_header;
+ * o_node = thread | proto_node;
+ * x_node = o_node ^ mark_word;
+ * if( (x_node & ~age_mask) == 0 ) { // Biased to the current thread ?
+ * // Done.
+ * } else {
+ * if( (x_node & biased_lock_mask) != 0 ) {
+ * // The klass's prototype header is no longer biased.
+ * cas(&mark_word, mark_word, proto_node)
+ * goto cas_lock;
+ * } else {
+ * // The klass's prototype header is still biased.
+ * if( (x_node & epoch_mask) != 0 ) { // Expired epoch?
+ * old = mark_word;
+ * new = o_node;
+ * } else {
+ * // Different thread or anonymous biased.
+ * old = mark_word & (epoch_mask | age_mask | biased_lock_mask);
+ * new = thread | old;
+ * }
+ * // Try to rebias.
+ * if( cas(&mark_word, old, new) == 0 ) {
+ * // Done.
+ * } else {
+ * goto slow_path; // Failed.
+ * }
+ * }
+ * }
+ * } else {
+ * // The object is not biased.
+ * cas_lock:
+ * if( FastLock(obj) == 0 ) {
+ * // Done.
+ * } else {
+ * slow_path:
+ * OptoRuntime::complete_monitor_locking_Java(obj);
+ * }
+ * }
+ */
+
+ region = new (C, 5) RegionNode(5);
+ // create a Phi for the memory state
+ mem_phi = new (C, 5) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+ Node* fast_lock_region = new (C, 3) RegionNode(3);
+ Node* fast_lock_mem_phi = new (C, 3) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+ // First, check mark word for the biased lock pattern.
+ Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
+
+ // Get fast path - mark word has the biased lock pattern.
+ ctrl = opt_bits_test(ctrl, fast_lock_region, 1, mark_node,
+ markOopDesc::biased_lock_mask_in_place,
+ markOopDesc::biased_lock_pattern, true);
+ // fast_lock_region->in(1) is set to slow path.
+ fast_lock_mem_phi->init_req(1, mem);
+
+ // Now check that the lock is biased to the current thread and has
+ // the same epoch and bias as Klass::_prototype_header.
+
+ // Special-case a fresh allocation to avoid building nodes:
+ Node* klass_node = AllocateNode::Ideal_klass(obj, &_igvn);
+ if (klass_node == NULL) {
+ Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
+ klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
+ klass_node->init_req(0, ctrl);
+ }
+ Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
+
+ Node* thread = transform_later(new (C, 1) ThreadLocalNode());
+ Node* cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
+ Node* o_node = transform_later(new (C, 3) OrXNode(cast_thread, proto_node));
+ Node* x_node = transform_later(new (C, 3) XorXNode(o_node, mark_node));
+
+ // Get slow path - mark word does NOT match the value.
+ Node* not_biased_ctrl = opt_bits_test(ctrl, region, 3, x_node,
+ (~markOopDesc::age_mask_in_place), 0);
+ // region->in(3) is set to fast path - the object is biased to the current thread.
+ mem_phi->init_req(3, mem);
+
+
+ // Mark word does NOT match the value (thread | Klass::_prototype_header).
+
- Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne));
- Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
- // Optimize test; set region slot 2
- Node *slow_path = opt_iff(region,iff);
+ // First, check biased pattern.
+ // Get fast path - _prototype_header has the same biased lock pattern.
+ ctrl = opt_bits_test(not_biased_ctrl, fast_lock_region, 2, x_node,
+ markOopDesc::biased_lock_mask_in_place, 0, true);
+
+ not_biased_ctrl = fast_lock_region->in(2); // Slow path
+ // fast_lock_region->in(2) - the prototype header is no longer biased
+ // and we have to revoke the bias on this object.
+ // We are going to try to reset the mark of this object to the prototype
+ // value and fall through to the CAS-based locking scheme.
+ Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
+ Node* cas = new (C, 5) StoreXConditionalNode(not_biased_ctrl, mem, adr,
+ proto_node, mark_node);
+ transform_later(cas);
+ Node* proj = transform_later( new (C, 1) SCMemProjNode(cas));
+ fast_lock_mem_phi->init_req(2, proj);
+
+
+ // Second, check epoch bits.
+ Node* rebiased_region = new (C, 3) RegionNode(3);
+ Node* old_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
+ Node* new_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
+
+ // Get slow path - mark word does NOT match epoch bits.
+ Node* epoch_ctrl = opt_bits_test(ctrl, rebiased_region, 1, x_node,
+ markOopDesc::epoch_mask_in_place, 0);
+ // The epoch of the current bias is not valid, attempt to rebias the object
+ // toward the current thread.
+ rebiased_region->init_req(2, epoch_ctrl);
+ old_phi->init_req(2, mark_node);
+ new_phi->init_req(2, o_node);
+
+ // rebiased_region->in(1) is set to fast path.
+ // The epoch of the current bias is still valid but we know
+ // nothing about the owner; it might be set or it might be clear.
+ Node* cmask = MakeConX(markOopDesc::biased_lock_mask_in_place |
+ markOopDesc::age_mask_in_place |
+ markOopDesc::epoch_mask_in_place);
+ Node* old = transform_later(new (C, 3) AndXNode(mark_node, cmask));
+ cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
+ Node* new_mark = transform_later(new (C, 3) OrXNode(cast_thread, old));
+ old_phi->init_req(1, old);
+ new_phi->init_req(1, new_mark);
+
+ transform_later(rebiased_region);
+ transform_later(old_phi);
+ transform_later(new_phi);
+
+ // Try to acquire the bias of the object using an atomic operation.
+ // If this fails we will go in to the runtime to revoke the object's bias.
+ cas = new (C, 5) StoreXConditionalNode(rebiased_region, mem, adr,
+ new_phi, old_phi);
+ transform_later(cas);
+ proj = transform_later( new (C, 1) SCMemProjNode(cas));
+
+ // Get slow path - Failed to CAS.
+ not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0);
+ mem_phi->init_req(4, proj);
+ // region->in(4) is set to fast path - the object is rebiased to the current thread.
+
+ // Failed to CAS.
+ slow_path = new (C, 3) RegionNode(3);
+ Node *slow_mem = new (C, 3) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+ slow_path->init_req(1, not_biased_ctrl); // Capture slow-control
+ slow_mem->init_req(1, proj);
+
+ // Call CAS-based locking scheme (FastLock node).
+
+ transform_later(fast_lock_region);
+ transform_later(fast_lock_mem_phi);
+
+ // Get slow path - FastLock failed to lock the object.
+ ctrl = opt_bits_test(fast_lock_region, region, 2, flock, 0, 0);
+ mem_phi->init_req(2, fast_lock_mem_phi);
+ // region->in(2) is set to fast path - the object is locked to the current thread.
+
+ slow_path->init_req(2, ctrl); // Capture slow-control
+ slow_mem->init_req(2, fast_lock_mem_phi);
+
+ transform_later(slow_path);
+ transform_later(slow_mem);
+ // Reset lock's memory edge.
+ lock->set_req(TypeFunc::Memory, slow_mem);
+
+ } else {
+ region = new (C, 3) RegionNode(3);
+ // create a Phi for the memory state
+ mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+ // Optimize test; set region slot 2
+ slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0);
+ mem_phi->init_req(2, mem);
+ }
// Make slow path call
CallNode *call = make_slow_call( (CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(), OptoRuntime::complete_monitor_locking_Java(), NULL, slow_path, obj, box );
@@ -1614,16 +1811,11 @@
transform_later(region);
_igvn.subsume_node(_fallthroughproj, region);
- // create a Phi for the memory state
- Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
- Node *memproj = transform_later( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+ Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
mem_phi->init_req(1, memproj );
- mem_phi->init_req(2, mem);
transform_later(mem_phi);
- _igvn.hash_delete(_memproj_fallthrough);
+ _igvn.hash_delete(_memproj_fallthrough);
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
-
-
}
//------------------------------expand_unlock_node----------------------
@@ -1637,14 +1829,31 @@
// No need for a null check on unlock
// Make the merge point
- RegionNode *region = new (C, 3) RegionNode(3);
+ Node *region;
+ Node *mem_phi;
+
+ if (UseOptoBiasInlining) {
+ // Check for biased locking unlock case, which is a no-op.
+ // See the full descrition in MacroAssembler::biased_locking_exit().
+ region = new (C, 4) RegionNode(4);
+ // create a Phi for the memory state
+ mem_phi = new (C, 4) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+ mem_phi->init_req(3, mem);
+
+ Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
+ ctrl = opt_bits_test(ctrl, region, 3, mark_node,
+ markOopDesc::biased_lock_mask_in_place,
+ markOopDesc::biased_lock_pattern);
+ } else {
+ region = new (C, 3) RegionNode(3);
+ // create a Phi for the memory state
+ mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+ }
FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box );
funlock = transform_later( funlock )->as_FastUnlock();
- Node *bol = transform_later(new (C, 2) BoolNode(funlock,BoolTest::ne));
- Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
// Optimize test; set region slot 2
- Node *slow_path = opt_iff(region,iff);
+ Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0);
CallNode *call = make_slow_call( (CallNode *) unlock, OptoRuntime::complete_monitor_exit_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), "complete_monitor_unlocking_C", slow_path, obj, box );
@@ -1666,16 +1875,12 @@
transform_later(region);
_igvn.subsume_node(_fallthroughproj, region);
- // create a Phi for the memory state
- Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
mem_phi->init_req(1, memproj );
mem_phi->init_req(2, mem);
transform_later(mem_phi);
- _igvn.hash_delete(_memproj_fallthrough);
+ _igvn.hash_delete(_memproj_fallthrough);
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
-
-
}
//------------------------------expand_macro_nodes----------------------
--- a/hotspot/src/share/vm/opto/macro.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/macro.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -93,7 +93,7 @@
int replace_input(Node *use, Node *oldref, Node *newref);
void copy_call_debug_info(CallNode *oldcall, CallNode * newcall);
- Node* opt_iff(Node* region, Node* iff);
+ Node* opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path = false);
void copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call);
CallNode* make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call,
const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1);
--- a/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -1951,6 +1951,7 @@
// Now hack a few special opcodes
switch( n->Opcode() ) { // Handle some opcodes special
case Op_StorePConditional:
+ case Op_StoreIConditional:
case Op_StoreLConditional:
case Op_CompareAndSwapI:
case Op_CompareAndSwapL:
--- a/hotspot/src/share/vm/opto/matcher.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/matcher.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -324,7 +324,7 @@
virtual int regnum_to_fpu_offset(int regnum);
// Is this branch offset small enough to be addressed by a short branch?
- bool is_short_branch_offset(int offset);
+ bool is_short_branch_offset(int rule, int offset);
// Optional scaling for the parameter to the ClearArray/CopyArray node.
static const bool init_array_count_is_in_bytes;
--- a/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -227,6 +227,14 @@
const Type *t_adr = phase->type( address );
if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL
+ PhaseIterGVN *igvn = phase->is_IterGVN();
+ if( can_reshape && igvn != NULL && igvn->_worklist.member(address) ) {
+ // The address's base and type may change when the address is processed.
+ // Delay this mem node transformation until the address is processed.
+ phase->is_IterGVN()->_worklist.push(this);
+ return NodeSentinel; // caller will return NULL
+ }
+
// Avoid independent memory operations
Node* old_mem = mem;
--- a/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -632,6 +632,17 @@
virtual uint ideal_reg() const { return Op_RegFlags; }
};
+//------------------------------StoreIConditionalNode---------------------------
+// Conditionally store int to memory, if no change since prior
+// load-locked. Sets flags for success or failure of the store.
+class StoreIConditionalNode : public LoadStoreNode {
+public:
+ StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreNode(c, mem, adr, val, ii) { }
+ virtual int Opcode() const;
+ // Produces flags
+ virtual uint ideal_reg() const { return Op_RegFlags; }
+};
+
//------------------------------StoreLConditionalNode---------------------------
// Conditionally store long to memory, if no change since prior
// load-locked. Sets flags for success or failure of the store.
@@ -639,6 +650,8 @@
public:
StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { }
virtual int Opcode() const;
+ // Produces flags
+ virtual uint ideal_reg() const { return Op_RegFlags; }
};
--- a/hotspot/src/share/vm/opto/output.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/output.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -263,7 +263,7 @@
# endif // ENABLE_ZAP_DEAD_LOCALS
//------------------------------compute_loop_first_inst_sizes------------------
-// Compute the size of first NumberOfLoopInstrToAlign instructions at head
+// Compute the size of first NumberOfLoopInstrToAlign instructions at the top
// of a loop. When aligning a loop we need to provide enough instructions
// in cpu's fetch buffer to feed decoders. The loop alignment could be
// avoided if we have enough instructions in fetch buffer at the head of a loop.
@@ -284,34 +284,23 @@
for( uint i=1; i <= last_block; i++ ) {
Block *b = _cfg->_blocks[i];
// Check the first loop's block which requires an alignment.
- if( b->head()->is_Loop() &&
- b->code_alignment() > (uint)relocInfo::addr_unit() ) {
+ if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) {
uint sum_size = 0;
uint inst_cnt = NumberOfLoopInstrToAlign;
- inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt,
- _regalloc);
- // Check the next fallthrough block if first loop's block does not have
- // enough instructions.
- if( inst_cnt > 0 && i < last_block ) {
- // First, check if the first loop's block contains whole loop.
- // LoopNode::LoopBackControl == 2.
- Block *bx = _cfg->_bbs[b->pred(2)->_idx];
- // Skip connector blocks (with limit in case of irreducible loops).
- int search_limit = 16;
- while( bx->is_connector() && search_limit-- > 0) {
- bx = _cfg->_bbs[bx->pred(1)->_idx];
- }
- if( bx != b ) { // loop body is in several blocks.
- Block *nb = NULL;
- while( inst_cnt > 0 && i < last_block && nb != bx &&
- !_cfg->_blocks[i+1]->head()->is_Loop() ) {
- i++;
- nb = _cfg->_blocks[i];
- inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt,
- _regalloc);
- } // while( inst_cnt > 0 && i < last_block )
- } // if( bx != b )
- } // if( inst_cnt > 0 && i < last_block )
+ inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+
+ // Check subsequent fallthrough blocks if the loop's first
+ // block(s) does not have enough instructions.
+ Block *nb = b;
+ while( inst_cnt > 0 &&
+ i < last_block &&
+ !_cfg->_blocks[i+1]->has_loop_alignment() &&
+ !nb->has_successor(b) ) {
+ i++;
+ nb = _cfg->_blocks[i];
+ inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+ } // while( inst_cnt > 0 && i < last_block )
+
b->set_first_inst_size(sum_size);
} // f( b->head()->is_Loop() )
} // for( i <= last_block )
@@ -332,6 +321,7 @@
uint *jmp_end = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks);
uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
+ DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
blk_starts[0] = 0;
// Initialize the sizes to 0
@@ -443,9 +433,9 @@
uintptr_t target = blk_starts[bnum];
if( mach->is_pc_relative() ) {
int offset = target-(blk_starts[i] + jmp_end[i]);
- if (_matcher->is_short_branch_offset(offset)) {
+ if (_matcher->is_short_branch_offset(mach->rule(), offset)) {
// We've got a winner. Replace this branch.
- MachNode *replacement = mach->short_branch_version(this);
+ MachNode* replacement = mach->short_branch_version(this);
b->_nodes.map(j, replacement);
mach->subsume_by(replacement);
@@ -453,6 +443,7 @@
// next pass.
jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc));
DEBUG_ONLY( jmp_target[i] = bnum; );
+ DEBUG_ONLY( jmp_rule[i] = mach->rule(); );
}
} else {
#ifndef PRODUCT
@@ -510,7 +501,7 @@
// Get the size of the block
uint blk_size = adr - blk_starts[i];
- // When the next block starts a loop, we may insert pad NOP
+ // When the next block is the top of a loop, we may insert pad NOP
// instructions.
Block *nb = _cfg->_blocks[i+1];
int current_offset = blk_starts[i] + blk_size;
@@ -524,10 +515,10 @@
for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks
if( jmp_target[i] != 0 ) {
int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]);
- if (!_matcher->is_short_branch_offset(offset)) {
+ if (!_matcher->is_short_branch_offset(jmp_rule[i], offset)) {
tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]);
}
- assert(_matcher->is_short_branch_offset(offset), "Displacement too large for short jmp");
+ assert(_matcher->is_short_branch_offset(jmp_rule[i], offset), "Displacement too large for short jmp");
}
}
#endif
@@ -1069,7 +1060,7 @@
// If this machine supports different size branch offsets, then pre-compute
// the length of the blocks
- if( _matcher->is_short_branch_offset(0) ) {
+ if( _matcher->is_short_branch_offset(-1, 0) ) {
Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
labels_not_set = false;
}
@@ -1380,8 +1371,8 @@
} // End for all instructions in block
- // If the next block _starts_ a loop, pad this block out to align
- // the loop start a little. Helps prevent pipe stalls at loop starts
+ // If the next block is the top of a loop, pad this block out to align
+ // the loop top a little. Helps prevent pipe stalls at loop back branches.
int nop_size = (new (this) MachNopNode())->size(_regalloc);
if( i<_cfg->_num_blocks-1 ) {
Block *nb = _cfg->_blocks[i+1];
--- a/hotspot/src/share/vm/opto/phase.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/phase.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -46,7 +46,7 @@
#ifndef PRODUCT
elapsedTimer Phase::_t_graphReshaping;
elapsedTimer Phase::_t_scheduler;
-elapsedTimer Phase::_t_removeEmptyBlocks;
+elapsedTimer Phase::_t_blockOrdering;
elapsedTimer Phase::_t_macroExpand;
elapsedTimer Phase::_t_peephole;
elapsedTimer Phase::_t_codeGeneration;
@@ -128,7 +128,7 @@
tty->print_cr (" subtotal : %3.3f sec, %3.2f %%", regalloc_subtotal, percent_of_regalloc);
}
tty->print_cr (" macroExpand : %3.3f sec", Phase::_t_macroExpand.seconds());
- tty->print_cr (" removeEmpty : %3.3f sec", Phase::_t_removeEmptyBlocks.seconds());
+ tty->print_cr (" blockOrdering: %3.3f sec", Phase::_t_blockOrdering.seconds());
tty->print_cr (" peephole : %3.3f sec", Phase::_t_peephole.seconds());
tty->print_cr (" codeGen : %3.3f sec", Phase::_t_codeGeneration.seconds());
tty->print_cr (" install_code : %3.3f sec", Phase::_t_registerMethod.seconds());
@@ -137,7 +137,7 @@
(DoEscapeAnalysis ? Phase::_t_escapeAnalysis.seconds() : 0.0) +
Phase::_t_optimizer.seconds() + Phase::_t_graphReshaping.seconds() +
Phase::_t_matcher.seconds() + Phase::_t_scheduler.seconds() +
- Phase::_t_registerAllocation.seconds() + Phase::_t_removeEmptyBlocks.seconds() +
+ Phase::_t_registerAllocation.seconds() + Phase::_t_blockOrdering.seconds() +
Phase::_t_macroExpand.seconds() + Phase::_t_peephole.seconds() +
Phase::_t_codeGeneration.seconds() + Phase::_t_registerMethod.seconds();
double percent_of_method_compile = ((phase_subtotal == 0.0) ? 0.0 : phase_subtotal / Phase::_t_methodCompilation.seconds()) * 100.0;
--- a/hotspot/src/share/vm/opto/phase.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/phase.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -40,16 +40,12 @@
Optimistic, // Optimistic analysis phase
GVN, // Pessimistic global value numbering phase
Ins_Select, // Instruction selection phase
- Copy_Elimination, // Copy Elimination
- Dead_Code_Elimination, // DCE and compress Nodes
- Conditional_Constant, // Conditional Constant Propagation
CFG, // Build a CFG
- DefUse, // Build Def->Use chains
+ BlockLayout, // Linear ordering of blocks
Register_Allocation, // Register allocation, duh
LIVE, // Dragon-book LIVE range problem
Interference_Graph, // Building the IFG
Coalesce, // Coalescing copies
- Conditional_CProp, // Conditional Constant Propagation
Ideal_Loop, // Find idealized trip-counted loops
Macro_Expand, // Expand macro nodes
Peephole, // Apply peephole optimizations
@@ -80,7 +76,7 @@
#ifndef PRODUCT
static elapsedTimer _t_graphReshaping;
static elapsedTimer _t_scheduler;
- static elapsedTimer _t_removeEmptyBlocks;
+ static elapsedTimer _t_blockOrdering;
static elapsedTimer _t_macroExpand;
static elapsedTimer _t_peephole;
static elapsedTimer _t_codeGeneration;
--- a/hotspot/src/share/vm/opto/reg_split.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/reg_split.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -53,6 +53,7 @@
// Bail rather than abort
int ireg = def->ideal_reg();
if( ireg == 0 || ireg == Op_RegFlags ) {
+ assert(false, "attempted to spill a non-spillable item");
C->record_method_not_compilable("attempted to spill a non-spillable item");
return NULL;
}
--- a/hotspot/src/share/vm/opto/type.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -3541,7 +3541,7 @@
#ifndef PRODUCT
void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
- tty->print("narrowoop: ");
+ st->print("narrowoop: ");
_ooptype->dump2(d, depth, st);
}
#endif
--- a/hotspot/src/share/vm/opto/type.hpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.hpp Wed Jul 05 16:43:43 2017 +0200
@@ -1183,6 +1183,9 @@
#define RShiftXNode RShiftLNode
// For card marks and hashcodes
#define URShiftXNode URShiftLNode
+// UseOptoBiasInlining
+#define XorXNode XorLNode
+#define StoreXConditionalNode StoreLConditionalNode
// Opcodes
#define Op_LShiftX Op_LShiftL
#define Op_AndX Op_AndL
@@ -1222,6 +1225,9 @@
#define RShiftXNode RShiftINode
// For card marks and hashcodes
#define URShiftXNode URShiftINode
+// UseOptoBiasInlining
+#define XorXNode XorINode
+#define StoreXConditionalNode StoreIConditionalNode
// Opcodes
#define Op_LShiftX Op_LShiftI
#define Op_AndX Op_AndI
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -1365,6 +1365,9 @@
if (AggressiveOpts && FLAG_IS_DEFAULT(SpecialArraysEquals)) {
FLAG_SET_DEFAULT(SpecialArraysEquals, true);
}
+ if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) {
+ FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500);
+ }
#endif
if (AggressiveOpts) {
@@ -2625,6 +2628,12 @@
FLAG_SET_DEFAULT(UseBiasedLocking, false);
#endif /* CC_INTERP */
+#ifdef COMPILER2
+ if (!UseBiasedLocking || EmitSync != 0) {
+ UseOptoBiasInlining = false;
+ }
+#endif
+
if (PrintCommandLineFlags) {
CommandLineFlags::printSetFlags();
}
--- a/hotspot/src/share/vm/runtime/frame.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/runtime/frame.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -83,12 +83,12 @@
intptr_t* src = (intptr_t*) location(r);
if (src != NULL) {
- r->print();
- tty->print(" [" INTPTR_FORMAT "] = ", src);
+ r->print_on(st);
+ st->print(" [" INTPTR_FORMAT "] = ", src);
if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
- tty->print_cr("<misaligned>");
+ st->print_cr("<misaligned>");
} else {
- tty->print_cr(INTPTR_FORMAT, *src);
+ st->print_cr(INTPTR_FORMAT, *src);
}
}
}
--- a/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 05 16:43:18 2017 +0200
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 05 16:43:43 2017 +0200
@@ -263,7 +263,7 @@
st->print("# java.lang.OutOfMemoryError: ");
if (_size) {
st->print("requested ");
- sprintf(buf,"%d",_size);
+ sprintf(buf,SIZE_FORMAT,_size);
st->print(buf);
st->print(" bytes");
if (_message != NULL) {
--- a/jaxp/.hgtags Wed Jul 05 16:43:18 2017 +0200
+++ b/jaxp/.hgtags Wed Jul 05 16:43:43 2017 +0200
@@ -13,3 +13,4 @@
c84ca638db42a8b6b227b4e3b63bca192c5ca634 jdk7-b36
af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37
e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
+831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39
--- a/jaxws/.hgtags Wed Jul 05 16:43:18 2017 +0200
+++ b/jaxws/.hgtags Wed Jul 05 16:43:43 2017 +0200
@@ -13,3 +13,4 @@
f60187f44a0d62906a5e2f6bd0989b5b24c1ca1e jdk7-b36
a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37
9ce439969184c753a9ba3caf8ed277b05230f2e5 jdk7-b38
+077bc9b1b035a409a76bd5366f73ed9dd9846934 jdk7-b39
--- a/jdk/.hgtags Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/.hgtags Wed Jul 05 16:43:43 2017 +0200
@@ -13,3 +13,4 @@
134fd1a656ea85acd1f97f6700f75029b9b472a0 jdk7-b36
14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37
cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38
+4e51997582effa006dde5c6d8b8820b2045b9c7f jdk7-b39
--- a/jdk/make/netbeans/jmx/build.xml Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/make/netbeans/jmx/build.xml Wed Jul 05 16:43:43 2017 +0200
@@ -44,13 +44,13 @@
<!-- because they depend on the values of BUILD_DATE and BUILD_DATE_SIMPLE -->
<!-- At this time, ./build.properties has not been loaded yet. -->
<property name="project.build.name" value="openjdk-bXX"/>
- <property name="project.build.fulltag"
+ <property name="project.build.fulltag"
value="${ant.project.name}-${project.build.name}-${BUILD_DATE}" />
<!-- unchecked warnings will be fixed in JMX 2.0 as part of the work
being done on JSR 255 new features -->
- <property name="javac.options"
- value="-Xlint -Xlint:-unchecked -Xlint:-deprecation"/>
+ <property name="javac.options"
+ value="-Xlint -Xlint:-deprecation"/>
</target>
@@ -58,13 +58,13 @@
<!-- Dir to keep generated stub source -->
<mkdir dir="${gensrc.dir}" />
</target>
-
+
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Call rmic-jmx subtargets -->
<target name="-rmic-jmx" depends="-init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
- description="Calls -init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
+ description="Calls -init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
/>
@@ -96,7 +96,7 @@
<target name="-rmic-jmx-iiop" depends="-init,-check-jmx-iiop-uptodate" unless="jmx-iiop-uptodate"
description="Generate RMI IIOP stub class files for remote objects. Do not keep generated java files." >
-
+
<rmic base="${classes.dir}"
includeAntRuntime="no"
includeJavaRuntime="no"
@@ -115,11 +115,11 @@
<target name="-check-jmx-iiop-uptodate" depends="-init">
- <uptodate property="jmx-iiop-uptodate"
+ <uptodate property="jmx-iiop-uptodate"
srcfile="${classes.dir}/javax/management/remote/rmi/RMIConnectionImpl.class"
targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIConnectionImpl_Tie.class"
/>
- <uptodate property="jmx-iiop-uptodate"
+ <uptodate property="jmx-iiop-uptodate"
srcfile="${classes.dir}/javax/management/remote/rmi/RMIServerImpl.class"
targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIServerImpl_Tie.class"
/>
@@ -131,7 +131,7 @@
<target name="-post-compile" depends="-init,-rmic-jmx"
description="Jar JMX class files (including RMI stubs)" >
<mkdir dir="${dist.dir}/lib"/>
- <jar jarfile="${dist.dir}/lib/${jar.jmx.name}"
+ <jar jarfile="${dist.dir}/lib/${jar.jmx.name}"
update="true"
index="false"
duplicate="fail">
@@ -144,7 +144,7 @@
<attribute name="Specification-Version" value="${jar.jmx.spec.version}" />
<attribute name="Specification-Vendor" value="${jar.jmx.spec.vendor}" />
<attribute name="Implementation-Title" value="${jar.jmx.impl.title}" />
- <attribute name="Implementation-Version" value="${project.build.fulltag}" />
+ <attribute name="Implementation-Version" value="${project.build.fulltag}" />
<attribute name="Implementation-Vendor" value="${jar.jmx.impl.vendor}" />
</section>
</manifest>
--- a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Wed Jul 05 16:43:43 2017 +0200
@@ -141,7 +141,7 @@
}
private final Runnable callback;
- private ScheduledFuture scheduled; // If null, the lease has expired.
+ private ScheduledFuture<?> scheduled; // If null, the lease has expired.
private final ScheduledExecutorService executor
= Executors.newScheduledThreadPool(1,
--- a/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java Wed Jul 05 16:43:43 2017 +0200
@@ -128,7 +128,7 @@
};
private final Callable<Long> doRenew;
- private ScheduledFuture future;
+ private ScheduledFuture<?> future;
private boolean closed = false;
private long nextRenewTime;
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Wed Jul 05 16:43:43 2017 +0200
@@ -247,7 +247,7 @@
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException {
- Class theClass;
+ Class<?> theClass;
if (className == null) {
final RuntimeException wrapped =
@@ -327,7 +327,7 @@
// ------------------------------
// ------------------------------
- Class theClass = object.getClass();
+ Class<?> theClass = object.getClass();
Introspector.checkCompliance(theClass);
@@ -808,9 +808,8 @@
// on each specific attribute
//
allowedAttributes = new AttributeList(attributes.size());
- for (Iterator i = attributes.iterator(); i.hasNext();) {
+ for (Attribute attribute : attributes.asList()) {
try {
- Attribute attribute = (Attribute) i.next();
checkMBeanPermission(mbeanServerName, classname, attribute.getName(),
name, "setAttribute");
allowedAttributes.add(attribute);
@@ -1857,7 +1856,7 @@
}
}
- private static void checkMBeanTrustPermission(final Class theClass)
+ private static void checkMBeanTrustPermission(final Class<?> theClass)
throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java Wed Jul 05 16:43:43 2017 +0200
@@ -136,14 +136,14 @@
new Hashtable<ObjectName,ClassLoader>(10);
// from javax.management.loading.DefaultLoaderRepository
- public final Class loadClass(String className)
+ public final Class<?> loadClass(String className)
throws ClassNotFoundException {
return loadClass(loaders, className, null, null);
}
// from javax.management.loading.DefaultLoaderRepository
- public final Class loadClassWithout(ClassLoader without, String className)
+ public final Class<?> loadClassWithout(ClassLoader without, String className)
throws ClassNotFoundException {
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
@@ -167,7 +167,7 @@
}
- public final Class loadClassBefore(ClassLoader stop, String className)
+ public final Class<?> loadClassBefore(ClassLoader stop, String className)
throws ClassNotFoundException {
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
@@ -187,10 +187,10 @@
}
- private Class loadClass(final LoaderEntry list[],
- final String className,
- final ClassLoader without,
- final ClassLoader stop)
+ private Class<?> loadClass(final LoaderEntry list[],
+ final String className,
+ final ClassLoader without,
+ final ClassLoader stop)
throws ClassNotFoundException {
final int size = list.length;
for(int i=0; i<size; i++) {
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java Wed Jul 05 16:43:43 2017 +0200
@@ -68,12 +68,12 @@
return method.getName();
}
- OpenType getOpenReturnType() {
+ OpenType<?> getOpenReturnType() {
return returnMapping.getOpenType();
}
- OpenType[] getOpenParameterTypes() {
- final OpenType[] types = new OpenType[paramMappings.length];
+ OpenType<?>[] getOpenParameterTypes() {
+ final OpenType<?>[] types = new OpenType<?>[paramMappings.length];
for (int i = 0; i < paramMappings.length; i++)
types[i] = paramMappings[i].getOpenType();
return types;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Wed Jul 05 16:43:43 2017 +0200
@@ -26,7 +26,8 @@
package com.sun.jmx.mbeanserver;
import static com.sun.jmx.mbeanserver.Util.*;
-import java.lang.annotation.ElementType;
+import static com.sun.jmx.mbeanserver.MXBeanIntrospector.typeName;
+
import javax.management.openmbean.MXBeanMappingClass;
import static javax.management.openmbean.SimpleType.*;
@@ -120,7 +121,7 @@
*/
public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
static abstract class NonNullMXBeanMapping extends MXBeanMapping {
- NonNullMXBeanMapping(Type javaType, OpenType openType) {
+ NonNullMXBeanMapping(Type javaType, OpenType<?> openType) {
super(javaType, openType);
}
@@ -195,15 +196,15 @@
static {
/* Set up the mappings for Java types that map to SimpleType. */
- final OpenType[] simpleTypes = {
+ final OpenType<?>[] simpleTypes = {
BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE,
DOUBLE, FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING,
VOID,
};
for (int i = 0; i < simpleTypes.length; i++) {
- final OpenType t = simpleTypes[i];
- Class c;
+ final OpenType<?> t = simpleTypes[i];
+ Class<?> c;
try {
c = Class.forName(t.getClassName(), false,
ObjectName.class.getClassLoader());
@@ -224,7 +225,7 @@
if (primitiveType != void.class) {
final Class<?> primitiveArrayType =
Array.newInstance(primitiveType, 0).getClass();
- final OpenType primitiveArrayOpenType =
+ final OpenType<?> primitiveArrayOpenType =
ArrayType.getPrimitiveArrayType(primitiveArrayType);
final MXBeanMapping primitiveArrayMapping =
new IdentityMapping(primitiveArrayType,
@@ -247,8 +248,10 @@
public synchronized MXBeanMapping mappingForType(Type objType,
MXBeanMappingFactory factory)
throws OpenDataException {
- if (inProgress.containsKey(objType))
- throw new OpenDataException("Recursive data structure");
+ if (inProgress.containsKey(objType)) {
+ throw new OpenDataException(
+ "Recursive data structure, including " + typeName(objType));
+ }
MXBeanMapping mapping;
@@ -259,6 +262,8 @@
inProgress.put(objType, objType);
try {
mapping = makeMapping(objType, factory);
+ } catch (OpenDataException e) {
+ throw openDataException("Cannot convert type: " + typeName(objType), e);
} finally {
inProgress.remove(objType);
}
@@ -285,13 +290,13 @@
Type componentType =
((GenericArrayType) objType).getGenericComponentType();
return makeArrayOrCollectionMapping(objType, componentType, factory);
- } else if (objType instanceof Class) {
+ } else if (objType instanceof Class<?>) {
Class<?> objClass = (Class<?>) objType;
if (objClass.isEnum()) {
// Huge hack to avoid compiler warnings here. The ElementType
// parameter is ignored but allows us to obtain a type variable
// T that matches <T extends Enum<T>>.
- return makeEnumMapping((Class) objClass, ElementType.class);
+ return makeEnumMapping((Class<?>) objClass, ElementType.class);
} else if (objClass.isArray()) {
Type componentType = objClass.getComponentType();
return makeArrayOrCollectionMapping(objClass, componentType,
@@ -354,7 +359,7 @@
}
private static <T extends Enum<T>> MXBeanMapping
- makeEnumMapping(Class enumClass, Class<T> fake) {
+ makeEnumMapping(Class<?> enumClass, Class<T> fake) {
return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
}
@@ -411,17 +416,17 @@
MXBeanMappingFactory factory)
throws OpenDataException {
- final String objTypeName = objType.toString();
+ final String objTypeName = typeName(objType);
final MXBeanMapping keyMapping = factory.mappingForType(keyType, factory);
final MXBeanMapping valueMapping = factory.mappingForType(valueType, factory);
- final OpenType keyOpenType = keyMapping.getOpenType();
- final OpenType valueOpenType = valueMapping.getOpenType();
+ final OpenType<?> keyOpenType = keyMapping.getOpenType();
+ final OpenType<?> valueOpenType = valueMapping.getOpenType();
final CompositeType rowType =
new CompositeType(objTypeName,
objTypeName,
keyValueArray,
keyValueArray,
- new OpenType[] {keyOpenType, valueOpenType});
+ new OpenType<?>[] {keyOpenType, valueOpenType});
final TabularType tabularType =
new TabularType(objTypeName, objTypeName, rowType, keyArray);
return new TabularMapping(objType, sortedMap, tabularType,
@@ -440,8 +445,8 @@
final Type rawType = objType.getRawType();
- if (rawType instanceof Class) {
- Class c = (Class<?>) rawType;
+ if (rawType instanceof Class<?>) {
+ Class<?> c = (Class<?>) rawType;
if (c == List.class || c == Set.class || c == SortedSet.class) {
Type[] actuals = objType.getActualTypeArguments();
assert(actuals.length == 1);
@@ -468,7 +473,7 @@
return new MXBeanRefMapping(t);
}
- private MXBeanMapping makeCompositeMapping(Class c,
+ private MXBeanMapping makeCompositeMapping(Class<?> c,
MXBeanMappingFactory factory)
throws OpenDataException {
@@ -514,7 +519,7 @@
final Method[] getters = new Method[nitems];
final String[] itemNames = new String[nitems];
- final OpenType[] openTypes = new OpenType[nitems];
+ final OpenType<?>[] openTypes = new OpenType<?>[nitems];
int i = 0;
for (Map.Entry<String,Method> entry : getterMap.entrySet()) {
itemNames[i] = entry.getKey();
@@ -546,7 +551,7 @@
can be directly represented by an ArrayType, and an int needs no mapping
because reflection takes care of it. */
private static final class IdentityMapping extends NonNullMXBeanMapping {
- IdentityMapping(Type targetType, OpenType openType) {
+ IdentityMapping(Type targetType, OpenType<?> openType) {
super(targetType, openType);
}
@@ -576,7 +581,7 @@
@Override
final Object toNonNullOpenValue(Object value) {
- return ((Enum) value).name();
+ return ((Enum<?>) value).name();
}
@Override
@@ -595,7 +600,7 @@
private static final class ArrayMapping extends NonNullMXBeanMapping {
ArrayMapping(Type targetType,
- ArrayType openArrayType, Class openArrayClass,
+ ArrayType<?> openArrayType, Class<?> openArrayClass,
MXBeanMapping elementMapping) {
super(targetType, openArrayType);
this.elementMapping = elementMapping;
@@ -623,7 +628,7 @@
if (javaType instanceof GenericArrayType) {
componentType =
((GenericArrayType) javaType).getGenericComponentType();
- } else if (javaType instanceof Class &&
+ } else if (javaType instanceof Class<?> &&
((Class<?>) javaType).isArray()) {
componentType = ((Class<?>) javaType).getComponentType();
} else {
@@ -651,8 +656,8 @@
private static final class CollectionMapping extends NonNullMXBeanMapping {
CollectionMapping(Type targetType,
- ArrayType openArrayType,
- Class openArrayClass,
+ ArrayType<?> openArrayType,
+ Class<?> openArrayClass,
MXBeanMapping elementMapping) {
super(targetType, openArrayType);
this.elementMapping = elementMapping;
@@ -662,26 +667,28 @@
and all Sets to TreeSet. (TreeSet because it is a SortedSet,
so works for both Set and SortedSet.) */
Type raw = ((ParameterizedType) targetType).getRawType();
- Class c = (Class<?>) raw;
+ Class<?> c = (Class<?>) raw;
+ final Class<?> collC;
if (c == List.class)
- collectionClass = ArrayList.class;
+ collC = ArrayList.class;
else if (c == Set.class)
- collectionClass = HashSet.class;
+ collC = HashSet.class;
else if (c == SortedSet.class)
- collectionClass = TreeSet.class;
+ collC = TreeSet.class;
else { // can't happen
assert(false);
- collectionClass = null;
+ collC = null;
}
+ collectionClass = Util.cast(collC);
}
@Override
final Object toNonNullOpenValue(Object value)
throws OpenDataException {
- final Collection valueCollection = (Collection) value;
- if (valueCollection instanceof SortedSet) {
- Comparator comparator =
- ((SortedSet) valueCollection).comparator();
+ final Collection<?> valueCollection = (Collection<?>) value;
+ if (valueCollection instanceof SortedSet<?>) {
+ Comparator<?> comparator =
+ ((SortedSet<?>) valueCollection).comparator();
if (comparator != null) {
final String msg =
"Cannot convert SortedSet with non-null comparator: " +
@@ -725,7 +732,7 @@
elementMapping.checkReconstructible();
}
- private final Class<? extends Collection> collectionClass;
+ private final Class<? extends Collection<?>> collectionClass;
private final MXBeanMapping elementMapping;
}
@@ -794,8 +801,8 @@
@Override
final Object toNonNullOpenValue(Object value) throws OpenDataException {
final Map<Object, Object> valueMap = cast(value);
- if (valueMap instanceof SortedMap) {
- Comparator comparator = ((SortedMap) valueMap).comparator();
+ if (valueMap instanceof SortedMap<?,?>) {
+ Comparator<?> comparator = ((SortedMap<?,?>) valueMap).comparator();
if (comparator != null) {
final String msg =
"Cannot convert SortedMap with non-null comparator: " +
@@ -806,7 +813,7 @@
final TabularType tabularType = (TabularType) getOpenType();
final TabularData table = new TabularDataSupport(tabularType);
final CompositeType rowType = tabularType.getRowType();
- for (Map.Entry entry : valueMap.entrySet()) {
+ for (Map.Entry<Object, Object> entry : valueMap.entrySet()) {
final Object openKey = keyMapping.toOpenValue(entry.getKey());
final Object openValue = valueMapping.toOpenValue(entry.getValue());
final CompositeData row;
@@ -852,7 +859,7 @@
}
private final class CompositeMapping extends NonNullMXBeanMapping {
- CompositeMapping(Class targetClass,
+ CompositeMapping(Class<?> targetClass,
CompositeType compositeType,
String[] itemNames,
Method[] getters,
@@ -901,7 +908,7 @@
if (compositeBuilder != null)
return;
- Class targetClass = (Class<?>) getJavaType();
+ Class<?> targetClass = (Class<?>) getJavaType();
/* In this 2D array, each subarray is a set of builders where
there is no point in consulting the ones after the first if
the first refuses. */
@@ -924,6 +931,7 @@
concatenating each Builder's explanation of why it
isn't applicable. */
final StringBuilder whyNots = new StringBuilder();
+ Throwable possibleCause = null;
find:
for (CompositeBuilder[] relatedBuilders : builders) {
for (int i = 0; i < relatedBuilders.length; i++) {
@@ -933,6 +941,9 @@
foundBuilder = builder;
break find;
}
+ Throwable cause = builder.possibleCause();
+ if (cause != null)
+ possibleCause = cause;
if (whyNot.length() > 0) {
if (whyNots.length() > 0)
whyNots.append("; ");
@@ -943,10 +954,12 @@
}
}
if (foundBuilder == null) {
- final String msg =
+ String msg =
"Do not know how to make a " + targetClass.getName() +
" from a CompositeData: " + whyNots;
- throw new InvalidObjectException(msg);
+ if (possibleCause != null)
+ msg += ". Remaining exceptions show a POSSIBLE cause.";
+ throw invalidObjectException(msg, possibleCause);
}
compositeBuilder = foundBuilder;
}
@@ -973,7 +986,7 @@
/** Converts from a CompositeData to an instance of the targetClass. */
private static abstract class CompositeBuilder {
- CompositeBuilder(Class targetClass, String[] itemNames) {
+ CompositeBuilder(Class<?> targetClass, String[] itemNames) {
this.targetClass = targetClass;
this.itemNames = itemNames;
}
@@ -994,6 +1007,16 @@
abstract String applicable(Method[] getters)
throws InvalidObjectException;
+ /** If the subclass returns an explanation of why it is not applicable,
+ it can additionally indicate an exception with details. This is
+ potentially confusing, because the real problem could be that one
+ of the other subclasses is supposed to be applicable but isn't.
+ But the advantage of less information loss probably outweighs the
+ disadvantage of possible confusion. */
+ Throwable possibleCause() {
+ return null;
+ }
+
abstract Object fromCompositeData(CompositeData cd,
String[] itemNames,
MXBeanMapping[] converters)
@@ -1008,7 +1031,7 @@
private static final class CompositeBuilderViaFrom
extends CompositeBuilder {
- CompositeBuilderViaFrom(Class targetClass, String[] itemNames) {
+ CompositeBuilderViaFrom(Class<?> targetClass, String[] itemNames) {
super(targetClass, itemNames);
}
@@ -1018,8 +1041,7 @@
Class<?> targetClass = getTargetClass();
try {
Method fromMethod =
- targetClass.getMethod("from",
- new Class[] {CompositeData.class});
+ targetClass.getMethod("from", CompositeData.class);
if (!Modifier.isStatic(fromMethod.getModifiers())) {
final String msg =
@@ -1030,8 +1052,8 @@
if (fromMethod.getReturnType() != getTargetClass()) {
final String msg =
"Method from(CompositeData) returns " +
- fromMethod.getReturnType().getName() +
- " not " + targetClass.getName();
+ typeName(fromMethod.getReturnType()) +
+ " not " + typeName(targetClass);
throw new InvalidObjectException(msg);
}
@@ -1071,7 +1093,7 @@
If all the getters are OK, then the "applicable" method will return
an empty string and the other builders will be tried. */
private static class CompositeBuilderCheckGetters extends CompositeBuilder {
- CompositeBuilderCheckGetters(Class targetClass, String[] itemNames,
+ CompositeBuilderCheckGetters(Class<?> targetClass, String[] itemNames,
MXBeanMapping[] getterConverters) {
super(targetClass, itemNames);
this.getterConverters = getterConverters;
@@ -1082,6 +1104,7 @@
try {
getterConverters[i].checkReconstructible();
} catch (InvalidObjectException e) {
+ possibleCause = e;
return "method " + getters[i].getName() + " returns type " +
"that cannot be mapped back from OpenData";
}
@@ -1089,6 +1112,11 @@
return "";
}
+ @Override
+ Throwable possibleCause() {
+ return possibleCause;
+ }
+
final Object fromCompositeData(CompositeData cd,
String[] itemNames,
MXBeanMapping[] converters) {
@@ -1096,6 +1124,7 @@
}
private final MXBeanMapping[] getterConverters;
+ private Throwable possibleCause;
}
/** Builder for when the target class has a setter for every getter. */
@@ -1115,7 +1144,7 @@
Method[] setters = new Method[getters.length];
for (int i = 0; i < getters.length; i++) {
Method getter = getters[i];
- Class returnType = getter.getReturnType();
+ Class<?> returnType = getter.getReturnType();
String name = propertyName(getter);
String setterName = "set" + name;
Method setter;
@@ -1163,7 +1192,7 @@
private static final class CompositeBuilderViaConstructor
extends CompositeBuilder {
- CompositeBuilderViaConstructor(Class targetClass, String[] itemNames) {
+ CompositeBuilderViaConstructor(Class<?> targetClass, String[] itemNames) {
super(targetClass, itemNames);
}
@@ -1171,7 +1200,7 @@
final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
- Class targetClass = getTargetClass();
+ Class<?> targetClass = getTargetClass();
Constructor<?>[] constrs = targetClass.getConstructors();
// Applicable if and only if there are any annotated constructors
@@ -1226,10 +1255,16 @@
for (int i = 0; i < propertyNames.length; i++) {
String propertyName = propertyNames[i];
if (!getterMap.containsKey(propertyName)) {
- final String msg =
+ String msg =
"@ConstructorProperties includes name " + propertyName +
- " which does not correspond to a property: " +
- constr;
+ " which does not correspond to a property";
+ for (String getterName : getterMap.keySet()) {
+ if (getterName.equalsIgnoreCase(propertyName)) {
+ msg += " (differs only in case from property " +
+ getterName + ")";
+ }
+ }
+ msg += ": " + constr;
throw new InvalidObjectException(msg);
}
int getterIndex = getterMap.get(propertyName);
@@ -1384,12 +1419,12 @@
private static final class CompositeBuilderViaProxy
extends CompositeBuilder {
- CompositeBuilderViaProxy(Class targetClass, String[] itemNames) {
+ CompositeBuilderViaProxy(Class<?> targetClass, String[] itemNames) {
super(targetClass, itemNames);
}
String applicable(Method[] getters) {
- Class targetClass = getTargetClass();
+ Class<?> targetClass = getTargetClass();
if (!targetClass.isInterface())
return "not an interface";
Set<Method> methods =
@@ -1401,7 +1436,7 @@
String bad = null;
for (Method m : methods) {
String mname = m.getName();
- Class[] mparams = m.getParameterTypes();
+ Class<?>[] mparams = m.getParameterTypes();
try {
Method om = Object.class.getMethod(mname, mparams);
if (!Modifier.isPublic(om.getModifiers()))
@@ -1422,10 +1457,10 @@
final Object fromCompositeData(CompositeData cd,
String[] itemNames,
MXBeanMapping[] converters) {
- final Class targetClass = getTargetClass();
+ final Class<?> targetClass = getTargetClass();
return
Proxy.newProxyInstance(targetClass.getClassLoader(),
- new Class[] {targetClass},
+ new Class<?>[] {targetClass},
new CompositeDataInvocationHandler(cd));
}
}
@@ -1447,9 +1482,9 @@
return openDataException(cause.getMessage(), cause);
}
- static void mustBeComparable(Class collection, Type element)
+ static void mustBeComparable(Class<?> collection, Type element)
throws OpenDataException {
- if (!(element instanceof Class)
+ if (!(element instanceof Class<?>)
|| !Comparable.class.isAssignableFrom((Class<?>) element)) {
final String msg =
"Parameter class " + element + " of " +
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Wed Jul 05 16:43:43 2017 +0200
@@ -115,7 +115,7 @@
* Dynamic MBeans, <code>false</code> otherwise.
*
**/
- public static final boolean isDynamic(final Class c) {
+ public static final boolean isDynamic(final Class<?> c) {
// Check if the MBean implements the DynamicMBean interface
return javax.management.DynamicMBean.class.isAssignableFrom(c);
}
@@ -134,7 +134,7 @@
* MBeanServer.
*
**/
- public static void testCreation(Class c)
+ public static void testCreation(Class<?> c)
throws NotCompliantMBeanException {
// Check if the class is a concrete class
final int mods = c.getModifiers();
@@ -143,7 +143,7 @@
}
// Check if the MBean has a public constructor
- final Constructor[] consList = c.getConstructors();
+ final Constructor<?>[] consList = c.getConstructors();
if (consList.length == 0) {
throw new NotCompliantMBeanException("MBean class must have public constructor");
}
@@ -253,7 +253,7 @@
* @exception NotCompliantMBeanException The specified class is not a
* JMX compliant MBean
*/
- public static MBeanInfo testCompliance(Class baseClass)
+ public static MBeanInfo testCompliance(Class<?> baseClass)
throws NotCompliantMBeanException {
// ------------------------------
@@ -267,7 +267,7 @@
return testCompliance(baseClass, null);
}
- public static void testComplianceMXBeanInterface(Class interfaceClass,
+ public static void testComplianceMXBeanInterface(Class<?> interfaceClass,
MXBeanMappingFactory factory)
throws NotCompliantMBeanException {
MXBeanIntrospector.getInstance(factory).getAnalyzer(interfaceClass);
@@ -596,10 +596,10 @@
ss[i] = (String) annotationToField(xx[i]);
return ss;
}
- if (x instanceof Class)
+ if (x instanceof Class<?>)
return ((Class<?>) x).getName();
- if (x instanceof Enum)
- return ((Enum) x).name();
+ if (x instanceof Enum<?>)
+ return ((Enum<?>) x).name();
// The only other possibility is that the value is another
// annotation, or that the language has evolved since this code
// was written. We don't allow for either of those currently.
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Wed Jul 05 16:43:43 2017 +0200
@@ -33,6 +33,7 @@
import java.security.Permission;
import java.security.PrivilegedExceptionAction;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -1144,7 +1145,7 @@
// This call requires MBeanPermission 'getClassLoaderRepository'
final ClassLoaderRepository clr = getClassLoaderRepository();
- Class theClass;
+ Class<?> theClass;
try {
if (clr == null) throw new ClassNotFoundException(className);
theClass = clr.loadClass(className);
@@ -1457,23 +1458,22 @@
*/
private AttributeList cloneAttributeList(AttributeList list) {
if (list != null) {
+ List<Attribute> alist = list.asList();
if (!list.getClass().equals(AttributeList.class)) {
// Create new attribute list
//
- AttributeList newList = new AttributeList(list.size());
+ AttributeList newList = new AttributeList(alist.size());
// Iterate through list and replace non JMX attributes
//
- for (Iterator i = list.iterator(); i.hasNext(); ) {
- Attribute attribute = (Attribute) i.next();
+ for (Attribute attribute : alist)
newList.add(cloneAttribute(attribute));
- }
return newList;
} else {
// Iterate through list and replace non JMX attributes
//
- for (int i = 0; i < list.size(); i++) {
- Attribute attribute = (Attribute) list.get(i);
+ for (int i = 0; i < alist.size(); i++) {
+ Attribute attribute = alist.get(i);
if (!attribute.getClass().equals(Attribute.class)) {
list.set(i, cloneAttribute(attribute));
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Wed Jul 05 16:43:43 2017 +0200
@@ -70,7 +70,7 @@
* instantiate an MBean of this class in the MBeanServer.
* e.g. it must have a public constructor, be a concrete class...
*/
- public void testCreation(Class c) throws NotCompliantMBeanException {
+ public void testCreation(Class<?> c) throws NotCompliantMBeanException {
Introspector.testCreation(c);
}
@@ -78,10 +78,10 @@
* Loads the class with the specified name using this object's
* Default Loader Repository.
**/
- public Class findClassWithDefaultLoaderRepository(String className)
+ public Class<?> findClassWithDefaultLoaderRepository(String className)
throws ReflectionException {
- Class theClass;
+ Class<?> theClass;
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),
@@ -105,7 +105,7 @@
* Gets the class for the specified class name using the MBean
* Interceptor's classloader
*/
- public Class findClass(String className, ClassLoader loader)
+ public Class<?> findClass(String className, ClassLoader loader)
throws ReflectionException {
return loadClass(className,loader);
@@ -115,7 +115,7 @@
* Gets the class for the specified class name using the specified
* class loader
*/
- public Class findClass(String className, ObjectName aLoader)
+ public Class<?> findClass(String className, ObjectName aLoader)
throws ReflectionException, InstanceNotFoundException {
if (aLoader == null)
@@ -140,14 +140,14 @@
* Return an array of Class corresponding to the given signature, using
* the specified class loader.
*/
- public Class[] findSignatureClasses(String signature[],
- ClassLoader loader)
- throws ReflectionException {
+ public Class<?>[] findSignatureClasses(String signature[],
+ ClassLoader loader)
+ throws ReflectionException {
if (signature == null) return null;
final ClassLoader aLoader = loader;
final int length= signature.length;
- final Class tab[]=new Class[length];
+ final Class<?> tab[]=new Class<?>[length];
if (length == 0) return tab;
try {
@@ -156,7 +156,7 @@
// forth)
//
- final Class primCla = primitiveClasses.get(signature[i]);
+ final Class<?> primCla = primitiveClasses.get(signature[i]);
if (primCla != null) {
tab[i] = primCla;
continue;
@@ -203,14 +203,14 @@
* Instantiates an object given its class, using its empty constructor.
* The call returns a reference to the newly created object.
*/
- public Object instantiate(Class theClass)
+ public Object instantiate(Class<?> theClass)
throws ReflectionException, MBeanException {
Object moi;
// ------------------------------
// ------------------------------
- Constructor cons = findConstructor(theClass, null);
+ Constructor<?> cons = findConstructor(theClass, null);
if (cons == null) {
throw new ReflectionException(new
NoSuchMethodException("No such constructor"));
@@ -257,14 +257,14 @@
* signature of its constructor The call returns a reference to
* the newly created object.
*/
- public Object instantiate(Class theClass, Object params[],
+ public Object instantiate(Class<?> theClass, Object params[],
String signature[], ClassLoader loader)
throws ReflectionException, MBeanException {
// Instantiate the new object
// ------------------------------
// ------------------------------
- final Class[] tab;
+ final Class<?>[] tab;
Object moi;
try {
// Build the signature of the method
@@ -283,7 +283,7 @@
}
// Query the metadata service to get the right constructor
- Constructor cons = findConstructor(theClass, tab);
+ Constructor<?> cons = findConstructor(theClass, tab);
if (cons == null) {
throw new ReflectionException(new
@@ -407,7 +407,7 @@
throw new RuntimeOperationsException(new
IllegalArgumentException(), "Null className passed in parameter");
}
- Class theClass;
+ Class<?> theClass;
if (loaderName == null) {
// Load the class using the agent class loader
theClass = findClass(className, loader);
@@ -547,7 +547,7 @@
throws ReflectionException,
MBeanException {
- Class theClass = findClassWithDefaultLoaderRepository(className);
+ Class<?> theClass = findClassWithDefaultLoaderRepository(className);
return instantiate(theClass, params, signature, loader);
}
@@ -595,7 +595,7 @@
// ------------------------------
// ------------------------------
- Class theClass;
+ Class<?> theClass;
if (loaderName == null) {
theClass = findClass(className, loader);
@@ -617,10 +617,10 @@
* Load a class with the specified loader, or with this object
* class loader if the specified loader is null.
**/
- static Class loadClass(String className, ClassLoader loader)
+ static Class<?> loadClass(String className, ClassLoader loader)
throws ReflectionException {
- Class theClass;
+ Class<?> theClass;
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),
@@ -647,15 +647,15 @@
* Load the classes specified in the signature with the given loader,
* or with this object class loader.
**/
- static Class[] loadSignatureClasses(String signature[],
- ClassLoader loader)
+ static Class<?>[] loadSignatureClasses(String signature[],
+ ClassLoader loader)
throws ReflectionException {
if (signature == null) return null;
final ClassLoader aLoader =
(loader==null?MBeanInstantiator.class.getClassLoader():loader);
final int length= signature.length;
- final Class tab[]=new Class[length];
+ final Class<?> tab[]=new Class<?>[length];
if (length == 0) return tab;
try {
@@ -664,7 +664,7 @@
// forth)
//
- final Class primCla = primitiveClasses.get(signature[i]);
+ final Class<?> primCla = primitiveClasses.get(signature[i]);
if (primCla != null) {
tab[i] = primCla;
continue;
@@ -710,9 +710,9 @@
private static final Map<String, Class<?>> primitiveClasses = Util.newMap();
static {
- for (Class<?> c : new Class[] {byte.class, short.class, int.class,
- long.class, float.class, double.class,
- char.class, boolean.class})
+ for (Class<?> c : new Class<?>[] {byte.class, short.class, int.class,
+ long.class, float.class, double.class,
+ char.class, boolean.class})
primitiveClasses.put(c.getName(), c);
}
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java Wed Jul 05 16:43:43 2017 +0200
@@ -160,7 +160,7 @@
// matched to the corresponding Java type, except when that
// type is primitive.
Type t = m.getGenericParameterTypes()[paramNo];
- return (!(t instanceof Class) || !((Class) t).isPrimitive());
+ return (!(t instanceof Class<?>) || !((Class<?>) t).isPrimitive());
} else {
Object v;
try {
@@ -354,7 +354,7 @@
}
}
- private static Descriptor typeDescriptor(OpenType openType,
+ private static Descriptor typeDescriptor(OpenType<?> openType,
Type originalType) {
return new ImmutableDescriptor(
new String[] {"openType",
@@ -380,37 +380,37 @@
if (type instanceof GenericArrayType) {
return canUseOpenInfo(
((GenericArrayType) type).getGenericComponentType());
- } else if (type instanceof Class && ((Class<?>) type).isArray()) {
+ } else if (type instanceof Class<?> && ((Class<?>) type).isArray()) {
return canUseOpenInfo(
((Class<?>) type).getComponentType());
}
- return (!(type instanceof Class && ((Class<?>) type).isPrimitive()));
+ return (!(type instanceof Class<?> && ((Class<?>) type).isPrimitive()));
}
private static String originalTypeString(Type type) {
- if (type instanceof Class)
- return ((Class) type).getName();
+ if (type instanceof Class<?>)
+ return ((Class<?>) type).getName();
else
- return genericTypeString(type);
+ return typeName(type);
}
- private static String genericTypeString(Type type) {
+ static String typeName(Type type) {
if (type instanceof Class<?>) {
Class<?> c = (Class<?>) type;
if (c.isArray())
- return genericTypeString(c.getComponentType()) + "[]";
+ return typeName(c.getComponentType()) + "[]";
else
return c.getName();
} else if (type instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) type;
- return genericTypeString(gat.getGenericComponentType()) + "[]";
+ return typeName(gat.getGenericComponentType()) + "[]";
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
StringBuilder sb = new StringBuilder();
- sb.append(genericTypeString(pt.getRawType())).append("<");
+ sb.append(typeName(pt.getRawType())).append("<");
String sep = "";
for (Type t : pt.getActualTypeArguments()) {
- sb.append(sep).append(genericTypeString(t));
+ sb.append(sep).append(typeName(t));
sep = ", ";
}
return sb.append(">").toString();
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ObjectInputStreamWithLoader.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ObjectInputStreamWithLoader.java Wed Jul 05 16:43:43 2017 +0200
@@ -54,7 +54,8 @@
this.loader = theLoader;
}
- protected Class resolveClass(ObjectStreamClass aClass)
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass aClass)
throws IOException, ClassNotFoundException {
if (loader == null) {
return super.resolveClass(aClass);
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/SecureClassLoaderRepository.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/SecureClassLoaderRepository.java Wed Jul 05 16:43:43 2017 +0200
@@ -47,16 +47,16 @@
public SecureClassLoaderRepository(ClassLoaderRepository clr) {
this.clr=clr;
}
- public final Class loadClass(String className)
+ public final Class<?> loadClass(String className)
throws ClassNotFoundException {
return clr.loadClass(className);
}
- public final Class loadClassWithout(ClassLoader loader,
+ public final Class<?> loadClassWithout(ClassLoader loader,
String className)
throws ClassNotFoundException {
return clr.loadClassWithout(loader,className);
}
- public final Class loadClassBefore(ClassLoader loader,
+ public final Class<?> loadClassBefore(ClassLoader loader,
String className)
throws ClassNotFoundException {
return clr.loadClassBefore(loader,className);
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Wed Jul 05 16:43:43 2017 +0200
@@ -669,7 +669,7 @@
}
public static <T> Set<T> cloneSet(Set<T> set) {
- if (set instanceof SortedSet) {
+ if (set instanceof SortedSet<?>) {
@SuppressWarnings("unchecked")
SortedSet<T> sset = (SortedSet<T>) set;
set = new TreeSet<T>(sset.comparator());
@@ -680,7 +680,7 @@
}
public static <T> Set<T> equivalentEmptySet(Set<T> set) {
- if (set instanceof SortedSet) {
+ if (set instanceof SortedSet<?>) {
@SuppressWarnings("unchecked")
SortedSet<T> sset = (SortedSet<T>) set;
set = new TreeSet<T>(sset.comparator());
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/WeakIdentityHashMap.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/WeakIdentityHashMap.java Wed Jul 05 16:43:43 2017 +0200
@@ -118,9 +118,9 @@
public boolean equals(Object o) {
if (this == o)
return true;
- if (!(o instanceof IdentityWeakReference))
+ if (!(o instanceof IdentityWeakReference<?>))
return false;
- IdentityWeakReference wr = (IdentityWeakReference) o;
+ IdentityWeakReference<?> wr = (IdentityWeakReference<?>) o;
Object got = get();
return (got != null && got == wr.get());
}
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java Wed Jul 05 16:43:43 2017 +0200
@@ -120,7 +120,7 @@
private final Collection<ShareBuffer> sharers = new HashSet<ShareBuffer>(1);
public static NotificationBuffer getNotificationBuffer(
- MBeanServer mbs, Map env) {
+ MBeanServer mbs, Map<String, ?> env) {
if (env == null)
env = Collections.emptyMap();
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Wed Jul 05 16:43:43 2017 +0200
@@ -54,7 +54,7 @@
public abstract class ClientNotifForwarder {
- public ClientNotifForwarder(Map env) {
+ public ClientNotifForwarder(Map<String, ?> env) {
this(null, env);
}
@@ -113,7 +113,7 @@
private Thread thread;
}
- public ClientNotifForwarder(ClassLoader defaultClassLoader, Map env) {
+ public ClientNotifForwarder(ClassLoader defaultClassLoader, Map<String, ?> env) {
maxNotifications = EnvHelp.getMaxFetchNotifNumber(env);
timeout = EnvHelp.getFetchTimeout(env);
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java Wed Jul 05 16:43:43 2017 +0200
@@ -36,7 +36,7 @@
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.portable.BoxedValueHelper;
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation", "rawtypes"})
public class ProxyInputStream extends org.omg.CORBA_2_3.portable.InputStream {
public ProxyInputStream(org.omg.CORBA.portable.InputStream in) {
this.in = in;
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Wed Jul 05 16:43:43 2017 +0200
@@ -59,7 +59,7 @@
public ServerNotifForwarder(MBeanServer mbeanServer,
- Map env,
+ Map<String, ?> env,
NotificationBuffer notifBuffer,
String connectionId) {
this.mbeanServer = mbeanServer;
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java Wed Jul 05 16:43:43 2017 +0200
@@ -29,6 +29,6 @@
import java.rmi.MarshalledObject;
public interface Unmarshal {
- public Object get(MarshalledObject mo)
+ public Object get(MarshalledObject<?> mo)
throws IOException, ClassNotFoundException;
}
--- a/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java Wed Jul 05 16:43:43 2017 +0200
@@ -26,6 +26,7 @@
package com.sun.jmx.remote.security;
import com.sun.jmx.mbeanserver.GetPropertyAction;
+import com.sun.jmx.mbeanserver.Util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -146,8 +147,8 @@
// Initial state
private Subject subject;
private CallbackHandler callbackHandler;
- private Map<String, ?> sharedState;
- private Map options;
+ private Map<String, Object> sharedState;
+ private Map<String, ?> options;
private String passwordFile;
private String passwordFileDisplayName;
private boolean userSuppliedPasswordFile;
@@ -172,7 +173,7 @@
this.subject = subject;
this.callbackHandler = callbackHandler;
- this.sharedState = sharedState;
+ this.sharedState = Util.cast(sharedState);
this.options = options;
// initialize any configured options
@@ -454,8 +455,8 @@
if (storePass &&
!sharedState.containsKey(USERNAME_KEY) &&
!sharedState.containsKey(PASSWORD_KEY)) {
- ((Map) sharedState).put(USERNAME_KEY, username);
- ((Map) sharedState).put(PASSWORD_KEY, password);
+ sharedState.put(USERNAME_KEY, username);
+ sharedState.put(PASSWORD_KEY, password);
}
// Create a new user principal
--- a/jdk/src/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java Wed Jul 05 16:43:43 2017 +0200
@@ -87,7 +87,7 @@
* @exception SecurityException if the authentication mechanism cannot be
* initialized.
*/
- public JMXPluggableAuthenticator(Map env) {
+ public JMXPluggableAuthenticator(Map<?, ?> env) {
String loginConfigName = null;
String passwordFile = null;
--- a/jdk/src/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java Wed Jul 05 16:43:43 2017 +0200
@@ -249,9 +249,8 @@
}
});
if (s == null) return; /* security has not been enabled */
- final Set principals = s.getPrincipals();
- for (Iterator i = principals.iterator(); i.hasNext(); ) {
- final Principal p = (Principal) i.next();
+ final Set<Principal> principals = s.getPrincipals();
+ for (Principal p : principals) {
String grantedAccessLevel;
synchronized (props) {
grantedAccessLevel = props.getProperty(p.getName());
@@ -271,8 +270,8 @@
}
private void checkValues(Properties props) {
- Collection c = props.values();
- for (Iterator i = c.iterator(); i.hasNext(); ) {
+ Collection<?> c = props.values();
+ for (Iterator<?> i = c.iterator(); i.hasNext(); ) {
final String accessLevel = (String) i.next();
if (!accessLevel.equals(READONLY) &&
!accessLevel.equals(READWRITE)) {
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Jul 05 16:43:43 2017 +0200
@@ -38,7 +38,7 @@
this.cl2 = cl2;
}
- protected Class findClass(String name) throws ClassNotFoundException {
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
return repository.loadClass(name);
} catch (ClassNotFoundException cne) {
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLogger.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLogger.java Wed Jul 05 16:43:43 2017 +0200
@@ -41,7 +41,7 @@
people to use at least J2SE 1.4. */
boolean loaded = false;
try {
- Class c = java.util.logging.Logger.class;
+ Class<?> c = java.util.logging.Logger.class;
loaded = true;
} catch (Error e) {
// OK.
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Wed Jul 05 16:43:43 2017 +0200
@@ -117,7 +117,7 @@
* <code>jmx.remote.default.class.loader.name</code> is specified
* and the ClassLoader MBean is not found in <var>mbs</var>.
*/
- public static ClassLoader resolveServerClassLoader(Map env,
+ public static ClassLoader resolveServerClassLoader(Map<String, ?> env,
MBeanServer mbs)
throws InstanceNotFoundException {
@@ -194,7 +194,7 @@
* <code>jmx.remote.default.class.loader</code> is specified
* and is not an instance of {@link ClassLoader}.
*/
- public static ClassLoader resolveClientClassLoader(Map env) {
+ public static ClassLoader resolveClientClassLoader(Map<String, ?> env) {
if (env == null)
return Thread.currentThread().getContextClassLoader();
@@ -241,7 +241,7 @@
try {
java.lang.reflect.Method getCause =
- t.getClass().getMethod("getCause", (Class[]) null);
+ t.getClass().getMethod("getCause", (Class<?>[]) null);
ret = (Throwable)getCause.invoke(t, (Object[]) null);
} catch (Exception e) {
@@ -264,7 +264,7 @@
* Returns the size of a notification buffer for a connector server.
* The default value is 1000.
*/
- public static int getNotifBufferSize(Map env) {
+ public static int getNotifBufferSize(Map<String, ?> env) {
int defaultQueueSize = 1000; // default value
// keep it for the compability for the fix:
@@ -327,7 +327,7 @@
* Returns the maximum notification number which a client will
* fetch every time.
*/
- public static int getMaxFetchNotifNumber(Map env) {
+ public static int getMaxFetchNotifNumber(Map<String, ?> env) {
return (int) getIntegerAttribute(env, MAX_FETCH_NOTIFS, 1000, 1,
Integer.MAX_VALUE);
}
@@ -344,7 +344,7 @@
/**
* Returns the timeout for a client to fetch notifications.
*/
- public static long getFetchTimeout(Map env) {
+ public static long getFetchTimeout(Map<String, ?> env) {
return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0,
Long.MAX_VALUE);
}
@@ -361,7 +361,7 @@
"com.sun.jmx.remote.notification.access.controller";
public static NotificationAccessController getNotificationAccessController(
- Map env) {
+ Map<String, ?> env) {
return (env == null) ? null :
(NotificationAccessController) env.get(NOTIF_ACCESS_CONTROLLER);
}
@@ -378,7 +378,7 @@
* an entry for <code>name</code> but it does not meet the
* constraints above.
*/
- public static long getIntegerAttribute(Map env, String name,
+ public static long getIntegerAttribute(Map<String, ?> env, String name,
long defaultValue, long minValue,
long maxValue) {
final Object o;
@@ -421,9 +421,8 @@
/* Check that all attributes have a key that is a String.
Could make further checks, e.g. appropriate types for attributes. */
- public static void checkAttributes(Map attributes) {
- for (Iterator it = attributes.keySet().iterator(); it.hasNext(); ) {
- Object key = it.next();
+ public static void checkAttributes(Map<?, ?> attributes) {
+ for (Object key : attributes.keySet()) {
if (!(key instanceof String)) {
final String msg =
"Attributes contain key that is not a string: " + key;
@@ -455,7 +454,7 @@
logger.trace("purgeUnserializable", "starts");
ObjectOutputStream oos = null;
int i = 0;
- for (Iterator it = objects.iterator(); it.hasNext(); i++) {
+ for (Iterator<?> it = objects.iterator(); it.hasNext(); i++) {
Object v = it.next();
if (v == null || v instanceof String) {
@@ -564,18 +563,18 @@
guarantees that we will never call next() on the corresponding
iterator. */
String sentinelKey = map.lastKey() + "X";
- Iterator keyIterator = map.keySet().iterator();
- Iterator stringIterator = hiddenStrings.iterator();
- Iterator prefixIterator = hiddenPrefixes.iterator();
+ Iterator<String> keyIterator = map.keySet().iterator();
+ Iterator<String> stringIterator = hiddenStrings.iterator();
+ Iterator<String> prefixIterator = hiddenPrefixes.iterator();
String nextString;
if (stringIterator.hasNext())
- nextString = (String) stringIterator.next();
+ nextString = stringIterator.next();
else
nextString = sentinelKey;
String nextPrefix;
if (prefixIterator.hasNext())
- nextPrefix = (String) prefixIterator.next();
+ nextPrefix = prefixIterator.next();
else
nextPrefix = sentinelKey;
@@ -583,7 +582,7 @@
or prefix, remove it. */
keys:
while (keyIterator.hasNext()) {
- String key = (String) keyIterator.next();
+ String key = keyIterator.next();
/* Continue through string-match values until we find one
that is either greater than the current key, or equal
@@ -591,7 +590,7 @@
int cmp = +1;
while ((cmp = nextString.compareTo(key)) < 0) {
if (stringIterator.hasNext())
- nextString = (String) stringIterator.next();
+ nextString = stringIterator.next();
else
nextString = sentinelKey;
}
@@ -609,7 +608,7 @@
continue keys;
}
if (prefixIterator.hasNext())
- nextPrefix = (String) prefixIterator.next();
+ nextPrefix = prefixIterator.next();
else
nextPrefix = sentinelKey;
}
@@ -640,7 +639,7 @@
/**
* Returns the server side connection timeout.
*/
- public static long getServerConnectionTimeout(Map env) {
+ public static long getServerConnectionTimeout(Map<String, ?> env) {
return getIntegerAttribute(env, SERVER_CONNECTION_TIMEOUT, 120000L,
0, Long.MAX_VALUE);
}
@@ -656,7 +655,7 @@
/**
* Returns the client connection check period.
*/
- public static long getConnectionCheckPeriod(Map env) {
+ public static long getConnectionCheckPeriod(Map<String, ?> env) {
return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L,
0, Long.MAX_VALUE);
}
@@ -691,7 +690,7 @@
* to {@code String}.
*/
public static boolean computeBooleanFromString(
- Map env, String prop, boolean systemProperty) {
+ Map<String, ?> env, String prop, boolean systemProperty) {
if (env == null)
throw new IllegalArgumentException("env map cannot be null");
@@ -744,7 +743,8 @@
* to {@code String}.
*/
public static boolean computeBooleanFromString(
- Map env, String prop, boolean systemProperty, boolean defaultValue) {
+ Map<String, ?> env, String prop,
+ boolean systemProperty, boolean defaultValue) {
if (env == null)
throw new IllegalArgumentException("env map cannot be null");
@@ -774,7 +774,7 @@
public static <K, V> Hashtable<K, V> mapToHashtable(Map<K, V> map) {
HashMap<K, V> m = new HashMap<K, V>(map);
if (m.containsKey(null)) m.remove(null);
- for (Iterator i = m.values().iterator(); i.hasNext(); )
+ for (Iterator<?> i = m.values().iterator(); i.hasNext(); )
if (i.next() == null) i.remove();
return new Hashtable<K, V>(m);
}
@@ -783,7 +783,7 @@
* Returns true if the parameter JMXConnector.USE_EVENT_SERVICE is set to a
* String equals "true" by ignoring case in the map or in the System.
*/
- public static boolean eventServiceEnabled(Map env) {
+ public static boolean eventServiceEnabled(Map<String, ?> env) {
return computeBooleanFromString(env, JMXConnector.USE_EVENT_SERVICE, true);
}
@@ -793,7 +793,7 @@
* If the property DELEGATE_TO_EVENT_SERVICE is not set, returns
* a default value of "true".
*/
- public static boolean delegateToEventService(Map env) {
+ public static boolean delegateToEventService(Map<String, ?> env) {
return computeBooleanFromString(env,
JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE, true, true);
}
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java Wed Jul 05 16:43:43 2017 +0200
@@ -138,8 +138,8 @@
Class<T> interfaceClass, Callable<EventClient> eventClientFactory) {
final InvocationHandler handler =
new EventClientConnection(connection,eventClientFactory);
- final Class[] interfaces =
- new Class[] {interfaceClass, EventClientFactory.class};
+ final Class<?>[] interfaces =
+ new Class<?>[] {interfaceClass, EventClientFactory.class};
Object proxy =
Proxy.newProxyInstance(interfaceClass.getClassLoader(),
@@ -156,7 +156,7 @@
// add/remove notification listener are routed to the EventClient
if (methodName.equals("addNotificationListener")
|| methodName.equals("removeNotificationListener")) {
- final Class[] sig = method.getParameterTypes();
+ final Class<?>[] sig = method.getParameterTypes();
if (sig.length>1 &&
NotificationListener.class.isAssignableFrom(sig[1])) {
return invokeBroadcasterMethod(proxy,method,args);
@@ -164,7 +164,7 @@
}
// subscribe/unsubscribe are also routed to the EventClient.
- final Class clazz = method.getDeclaringClass();
+ final Class<?> clazz = method.getDeclaringClass();
if (clazz.equals(EventClientFactory.class)) {
return invokeEventClientSubscriberMethod(proxy,method,args);
}
@@ -319,7 +319,7 @@
return true;
if (methodName.equals("equals")
&& Arrays.equals(method.getParameterTypes(),
- new Class[] {Object.class})
+ new Class<?>[] {Object.class})
&& isLocal(proxy, method))
return true;
return false;
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/OrderClassLoaders.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/OrderClassLoaders.java Wed Jul 05 16:43:43 2017 +0200
@@ -32,7 +32,7 @@
this.cl2 = cl2;
}
- protected Class findClass(String name) throws ClassNotFoundException {
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
return super.findClass(name);
} catch (ClassNotFoundException cne) {
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java Wed Jul 05 16:43:43 2017 +0200
@@ -70,10 +70,13 @@
*/
public static void registerElementById(Element element, String idValue) {
Document doc = element.getOwnerDocument();
- WeakHashMap elementMap = (WeakHashMap) docMap.get(doc);
- if(elementMap == null) {
- elementMap = new WeakHashMap();
- docMap.put(doc, elementMap);
+ WeakHashMap elementMap;
+ synchronized (docMap) {
+ elementMap = (WeakHashMap) docMap.get(doc);
+ if (elementMap == null) {
+ elementMap = new WeakHashMap();
+ docMap.put(doc, elementMap);
+ }
}
elementMap.put(idValue, new WeakReference(element));
}
@@ -153,7 +156,10 @@
private static Element getElementByIdType(Document doc, String id) {
if (log.isLoggable(java.util.logging.Level.FINE))
log.log(java.util.logging.Level.FINE, "getElementByIdType() Search for ID " + id);
- WeakHashMap elementMap = (WeakHashMap) docMap.get(doc);
+ WeakHashMap elementMap;
+ synchronized (docMap) {
+ elementMap = (WeakHashMap) docMap.get(doc);
+ }
if (elementMap != null) {
WeakReference weakReference = (WeakReference) elementMap.get(id);
if (weakReference != null) {
--- a/jdk/src/share/classes/javax/management/AttributeList.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/AttributeList.java Wed Jul 05 16:43:43 2017 +0200
@@ -159,7 +159,7 @@
checkTypeSafe(this);
typeSafe = true;
}
- return (List<Attribute>) (List) this;
+ return (List<Attribute>) (List<?>) this;
}
/**
--- a/jdk/src/share/classes/javax/management/DefaultLoaderRepository.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/DefaultLoaderRepository.java Wed Jul 05 16:43:43 2017 +0200
@@ -62,7 +62,7 @@
*
* @exception ClassNotFoundException The specified class could not be found.
*/
- public static Class loadClass(String className)
+ public static Class<?> loadClass(String className)
throws ClassNotFoundException {
return javax.management.loading.DefaultLoaderRepository.loadClass(className);
}
@@ -82,7 +82,7 @@
*
* @exception ClassNotFoundException The specified class could not be found.
*/
- public static Class loadClassWithout(ClassLoader loader,String className)
+ public static Class<?> loadClassWithout(ClassLoader loader,String className)
throws ClassNotFoundException {
return javax.management.loading.DefaultLoaderRepository.loadClassWithout(loader, className);
}
--- a/jdk/src/share/classes/javax/management/Descriptor.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/Descriptor.java Wed Jul 05 16:43:43 2017 +0200
@@ -101,7 +101,7 @@
*
* <tr><th>Name</th><th>Type</th><th>Used in</th><th>Meaning</th></tr>
*
- * <tr><td><a name="defaultValue"><i>defaultValue</i></a><td>Object</td>
+ * <tr id="defaultValue"><td><i>defaultValue</i><td>Object</td>
* <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
*
* <td>Default value for an attribute or parameter. See
@@ -144,7 +144,7 @@
* might be disabled if it cannot currently be emitted but could be in
* other circumstances.</td>
*
- * <tr><td><a name="immutableInfo"><i>immutableInfo</i></a><td>String</td>
+ * <tr id="immutableInfo"><td><i>immutableInfo</i><td>String</td>
* <td>MBeanInfo</td>
*
* <td>The string {@code "true"} or {@code "false"} according as this
@@ -153,20 +153,24 @@
* the lifetime of the MBean. Hence, a client can read it once and
* cache the read value. When this field is false or absent, there is
* no such guarantee, although that does not mean that the MBeanInfo
- * will necessarily change.</td>
+ * will necessarily change. See also the <a
+ * href="MBeanInfo.html#info-changed">{@code "jmx.mbean.info.changed"}</a>
+ * notification.</td>
*
* <tr><td>infoTimeout</td><td>String<br>Long</td><td>MBeanInfo</td>
*
- * <td>The time in milli-seconds that the MBeanInfo can reasonably be
- * expected to be unchanged. The value can be a {@code Long} or a
- * decimal string. This provides a hint from a DynamicMBean or any
+ * <td id="infoTimeout">The time in milli-seconds that the MBeanInfo can
+ * reasonably be expected to be unchanged. The value can be a {@code Long}
+ * or a decimal string. This provides a hint from a DynamicMBean or any
* MBean that does not define {@code immutableInfo} as {@code true}
* that the MBeanInfo is not likely to change within this period and
* therefore can be cached. When this field is missing or has the
* value zero, it is not recommended to cache the MBeanInfo unless it
- * has the {@code immutableInfo} set to {@code true}.</td></tr>
+ * has the {@code immutableInfo} set to {@code true} or it has <a
+ * href="MBeanInfo.html#info-changed">{@code "jmx.mbean.info.changed"}</a> in
+ * its {@link MBeanNotificationInfo} array.</td></tr>
*
- * <tr><td><a name="interfaceClassName"><i>interfaceClassName</i></a></td>
+ * <tr id="interfaceClassName"><td><i>interfaceClassName</i></td>
* <td>String</td><td>MBeanInfo</td>
*
* <td>The Java interface name for a Standard MBean or MXBean, as
@@ -175,19 +179,19 @@
* StandardMBean} class will have this field in its MBeanInfo
* Descriptor.</td>
*
- * <tr><td><a name="legalValues"><i>legalValues</i></a></td>
+ * <tr id="legalValues"><td><i>legalValues</i></td>
* <td>{@literal Set<?>}</td><td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
*
* <td>Legal values for an attribute or parameter. See
* {@link javax.management.openmbean}.</td>
*
- * <tr><td><a name="maxValue"><i>maxValue</i></a><td>Object</td>
+ * <tr id="maxValue"><td><i>maxValue</i><td>Object</td>
* <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
*
* <td>Maximum legal value for an attribute or parameter. See
* {@link javax.management.openmbean}.</td>
*
- * <tr><td><a name="metricType">metricType</a><td>String</td>
+ * <tr id="metricType"><td>metricType</td><td>String</td>
* <td>MBeanAttributeInfo<br>MBeanOperationInfo</td>
*
* <td>The type of a metric, one of the strings "counter" or "gauge".
@@ -200,13 +204,13 @@
* that can increase or decrease. Examples might be the number of
* open connections or a cache hit rate or a temperature reading.
*
- * <tr><td><a name="minValue"><i>minValue</i></a><td>Object</td>
+ * <tr id="minValue"><td><i>minValue</i><td>Object</td>
* <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
*
* <td>Minimum legal value for an attribute or parameter. See
* {@link javax.management.openmbean}.</td>
*
- * <tr><td><a name="mxbean"><i>mxbean</i></a><td>String</td>
+ * <tr id="mxbean"><td><i>mxbean</i><td>String</td>
* <td>MBeanInfo</td>
*
* <td>The string {@code "true"} or {@code "false"} according as this
@@ -223,7 +227,7 @@
* MXBean, if it was not the {@linkplain MXBeanMappingFactory#DEFAULT default}
* one.</td>
*
- * <tr><td><a name="openType"><i>openType</i></a><td>{@link OpenType}</td>
+ * <tr id="openType"><td><i>openType</i><td>{@link OpenType}</td>
* <td>MBeanAttributeInfo<br>MBeanOperationInfo<br>MBeanParameterInfo</td>
*
* <td><p>The Open Type of this element. In the case of {@code
@@ -240,7 +244,7 @@
* which case it indicates the Open Type that the {@link
* Notification#getUserData() user data} will have.</td>
*
- * <tr><td><a name="originalType"><i>originalType</i></a><td>String</td>
+ * <tr id="originalType"><td><i>originalType</i><td>String</td>
* <td>MBeanAttributeInfo<br>MBeanOperationInfo<br>MBeanParameterInfo</td>
*
* <td><p>The original Java type of this element as it appeared in the
@@ -282,11 +286,132 @@
*
* </table>
*
- * <p>Some additional fields are defined by Model MBeans. See
- * {@link javax.management.modelmbean.ModelMBeanInfo ModelMBeanInfo}
- * and related classes and the chapter "Model MBeans" of the
- * <a href="http://java.sun.com/products/JavaManagement/download.html">
- * JMX Specification</a>.</p>
+ * <p>Some additional fields are defined by Model MBeans. See the
+ * information for <a href="modelmbean/ModelMBeanInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanInfo}</a>,
+ * <a href="modelmbean/ModelMBeanAttributeInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanAttributeInfo}</a>,
+ * <a href="modelmbean/ModelMBeanConstructorInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanConstructorInfo}</a>,
+ * <a href="modelmbean/ModelMBeanNotificationInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanNotificationInfo}</a>, and
+ * <a href="modelmbean/ModelMBeanOperationInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanOperationInfo}</a>, as
+ * well as the chapter "Model MBeans" of the <a
+ * href="http://java.sun.com/products/JavaManagement/download.html">JMX
+ * Specification</a>. The following table summarizes these fields. Note
+ * that when the Type in this table is Number, a String that is the decimal
+ * representation of a Long can also be used.</p>
+ *
+ * <p>Nothing prevents the use of these fields in MBeans that are not Model
+ * MBeans. The <a href="#displayName">displayName</a>, <a href="#severity"><!--
+ * -->severity</a>, and <a href="#visibility">visibility</a> fields are of
+ * interest outside Model MBeans, for example. But only Model MBeans have
+ * a predefined behavior for these fields.</p>
+ *
+ * <table border="1" cellpadding="5">
+ *
+ * <tr><th>Name</th><th>Type</th><th>Used in</th><th>Meaning</th></tr>
+ *
+ * <tr><td>class</td><td>String</td><td>ModelMBeanOperationInfo</td>
+ * <td>Class where method is defined (fully qualified).</td></tr>
+ *
+ * <tr><td>currencyTimeLimit</td><td>Number</td>
+ * <td>ModelMBeanInfo<br>ModelMBeanAttributeInfo<br>ModelMBeanOperationInfo</td>
+ * <td>How long cached value is valid: <0 never, =0 always,
+ * >0 seconds.</td></tr>
+ *
+ * <tr><td>default</td><td>Object</td><td>ModelMBeanAttributeInfo</td>
+ * <td>Default value for attribute.</td></tr>
+ *
+ * <tr><td>descriptorType</td><td>String</td><td>Any</td>
+ * <td>Type of descriptor, "mbean", "attribute", "constructor", "operation",
+ * or "notification".</td></tr>
+ *
+ * <tr id="displayName"><td>displayName</td><td>String</td><td>Any</td>
+ * <td>Human readable name of this item.</td></tr>
+ *
+ * <tr><td>export</td><td>String</td><td>ModelMBeanInfo</td>
+ * <td>Name to be used to export/expose this MBean so that it is
+ * findable by other JMX Agents.</td></tr>
+ *
+ * <tr><td>getMethod</td><td>String</td><td>ModelMBeanAttributeInfo</td>
+ * <td>Name of operation descriptor for get method.</td></tr>
+ *
+ * <tr><td>lastUpdatedTimeStamp</td><td>Number</td>
+ * <td>ModelMBeanAttributeInfo<br>ModelMBeanOperationInfo</td>
+ * <td>When <a href="#value-field">value</a> was set.</td></tr>
+ *
+ * <tr><td>log</td><td>String</td><td>ModelMBeanInfo<br>ModelMBeanNotificationInfo</td>
+ * <td>t or T: log all notifications, f or F: log no notifications.</td></tr>
+ *
+ * <tr><td>logFile</td><td>String</td><td>ModelMBeanInfo<br>ModelMBeanNotificationInfo</td>
+ * <td>Fully qualified filename to log events to.</td></tr>
+ *
+ * <tr><td>messageID</td><td>String</td><td>ModelMBeanNotificationInfo</td>
+ * <td>Unique key for message text (to allow translation, analysis).</td></tr>
+ *
+ * <tr><td>messageText</td><td>String</td><td>ModelMBeanNotificationInfo</td>
+ * <td>Text of notification.</td></tr>
+ *
+ * <tr><td>name</td><td>String</td><td>Any</td>
+ * <td>Name of this item.</td></tr>
+ *
+ * <tr><td>persistFile</td><td>String</td><td>ModelMBeanInfo</td>
+ * <td>File name into which the MBean should be persisted.</td></tr>
+ *
+ * <tr><td>persistLocation</td><td>String</td><td>ModelMBeanInfo</td>
+ * <td>The fully qualified directory name where the MBean should be
+ * persisted (if appropriate).</td></tr>
+ *
+ * <tr><td>persistPeriod</td><td>Number</td>
+ * <td>ModelMBeanInfo<br>ModelMBeanAttributeInfo</td>
+ * <td>Frequency of persist cycle in seconds. Used when persistPolicy is
+ * "OnTimer" or "NoMoreOftenThan".</td></tr>
+ *
+ * <tr><td>persistPolicy</td><td>String</td>
+ * <td>ModelMBeanInfo<br>ModelMBeanAttributeInfo</td>
+ * <td>One of: OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never.
+ * See the section "MBean Descriptor Fields" in the JMX specification
+ * document.</td></tr>
+ *
+ * <tr><td>presentationString</td><td>String</td><td>Any</td>
+ * <td>XML formatted string to allow presentation of data.</td></tr>
+ *
+ * <tr><td>protocolMap</td><td>Descriptor</td><td>ModelMBeanAttributeInfo</td>
+ * <td>See the section "Protocol Map Support" in the JMX specification
+ * document. Mappings must be appropriate for the attribute and entries
+ * can be updated or augmented at runtime.</td></tr>
+ *
+ * <tr><td>role</td><td>String</td>
+ * <td>ModelMBeanConstructorInfo<br>ModelMBeanOperationInfo</td>
+ * <td>One of "constructor", "operation", "getter", or "setter".</td></tr>
+ *
+ * <tr><td>setMethod</td><td>String</td><td>ModelMBeanAttributeInfo</td>
+ * <td>Name of operation descriptor for set method.</td></tr>
+ *
+ * <tr id="severity"><td>severity</td><td>Number</td>
+ * <td>ModelMBeanNotificationInfo</td>
+ * <td>0-6 where 0: unknown; 1: non-recoverable;
+ * 2: critical, failure; 3: major, severe;
+ * 4: minor, marginal, error; 5: warning;
+ * 6: normal, cleared, informative</td></tr>
+ *
+ * <tr><td>targetObject</td><td>Object</td><td>ModelMBeanOperationInfo</td>
+ * <td>Object on which to execute this method.</td></tr>
+ *
+ * <tr><td>targetType</td><td>String</td><td>ModelMBeanOperationInfo</td>
+ * <td>type of object reference for targetObject. Can be:
+ * ObjectReference | Handle | EJBHandle | IOR | RMIReference.</td></tr>
+ *
+ * <tr id="value-field"><td>value</td><td>Object</td>
+ * <td>ModelMBeanAttributeInfo<br>ModelMBeanOperationInfo</td>
+ * <td>Current (cached) value for attribute or operation.</td></tr>
+ *
+ * <tr id="visibility"><td>visibility</td><td>Number</td><td>Any</td>
+ * <td>1-4 where 1: always visible, 4: rarely visible.</td></tr>
+ *
+ * </table>
*
* @since 1.5
*/
@@ -439,7 +564,7 @@
public boolean isValid() throws RuntimeOperationsException;
/**
- * Compares this descriptor to the given object. The objects are equal if
+ * <p>Compares this descriptor to the given object. The objects are equal if
* the given object is also a Descriptor, and if the two Descriptors have
* the same field names (possibly differing in case) and the same
* associated values. The respective values for a field in the two
--- a/jdk/src/share/classes/javax/management/JMRuntimeException.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/JMRuntimeException.java Wed Jul 05 16:43:43 2017 +0200
@@ -70,7 +70,7 @@
try {
java.lang.reflect.Method initCause =
Throwable.class.getMethod("initCause",
- new Class[] {Throwable.class});
+ new Class<?>[] {Throwable.class});
initCause.invoke(this, new Object[] {cause});
} catch (Exception e) {
// OK: just means we won't have debugging info
--- a/jdk/src/share/classes/javax/management/JMX.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/JMX.java Wed Jul 05 16:43:43 2017 +0200
@@ -463,6 +463,12 @@
* likewise for the other methods of {@link
* NotificationBroadcaster} and {@link NotificationEmitter}.</p>
*
+ * <p>This method is equivalent to {@link
+ * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions)
+ * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where
+ * {@code opts} is a {@link JMX.ProxyOptions} representing the
+ * {@code notificationEmitter} parameter.</p>
+ *
* @param connection the MBean server to forward to.
* @param objectName the name of the MBean within
* {@code connection} to forward to.
@@ -555,10 +561,6 @@
*
* </ul>
*
- * <p>The object returned by this method is a
- * {@link Proxy} whose {@code InvocationHandler} is an
- * {@link MBeanServerInvocationHandler}.</p>
- *
* <p>This method is equivalent to {@link
* #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
* boolean) newMXBeanProxy(connection, objectName, interfaceClass,
@@ -601,6 +603,17 @@
* likewise for the other methods of {@link
* NotificationBroadcaster} and {@link NotificationEmitter}.</p>
*
+ * <p>This method is equivalent to {@link
+ * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions)
+ * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where
+ * {@code opts} is a {@link JMX.ProxyOptions} where the {@link
+ * JMX.ProxyOptions#getMXBeanMappingFactory() MXBeanMappingFactory}
+ * property is
+ * {@link MXBeanMappingFactory#forInterface(Class)
+ * MXBeanMappingFactory.forInterface(interfaceClass)} and the {@link
+ * JMX.ProxyOptions#isNotificationEmitter() notificationEmitter} property
+ * is equal to the {@code notificationEmitter} parameter.</p>
+ *
* @param connection the MBean server to forward to.
* @param objectName the name of the MBean within
* {@code connection} to forward to.
@@ -655,6 +668,36 @@
* arbitrary Java types and Open Types.</li>
* </ul>
*
+ * <p>The object returned by this method is a
+ * {@link Proxy} whose {@code InvocationHandler} is an
+ * {@link MBeanServerInvocationHandler}. This means that it is possible
+ * to retrieve the parameters that were used to produce the proxy. If the
+ * proxy was produced as follows...</p>
+ *
+ * <pre>
+ * FooMBean proxy =
+ * JMX.newMBeanProxy(connection, objectName, FooMBean.class, opts);
+ * </pre>
+ *
+ * <p>...then you can get the {@code MBeanServerInvocationHandler} like
+ * this...</p>
+ *
+ * <pre>
+ * MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
+ * {@link Proxy#getInvocationHandler(Object)
+ * Proxy.getInvocationHandler}(proxy);
+ * </pre>
+ *
+ * <p>...and you can retrieve {@code connection}, {@code
+ * objectName}, and {@code opts} using the {@link
+ * MBeanServerInvocationHandler#getMBeanServerConnection()
+ * getMBeanServerConnection()}, {@link
+ * MBeanServerInvocationHandler#getObjectName() getObjectName()}, and
+ * {@link MBeanServerInvocationHandler#getMBeanOptions() getMBeanOptions()}
+ * methods on {@code mbsih}. You can retrieve {@code FooMBean.class}
+ * using {@code proxy.getClass().}{@link
+ * Class#getInterfaces() getInterfaces()}.</p>
+ *
* @param connection the MBean server to forward to.
* @param objectName the name of the MBean within
* {@code connection} to forward to.
@@ -703,12 +746,12 @@
InvocationHandler handler = new MBeanServerInvocationHandler(
connection, objectName, opts);
- final Class[] interfaces;
+ final Class<?>[] interfaces;
if (notificationEmitter) {
interfaces =
new Class<?>[] {interfaceClass, NotificationEmitter.class};
} else
- interfaces = new Class[] {interfaceClass};
+ interfaces = new Class<?>[] {interfaceClass};
Object proxy = Proxy.newProxyInstance(
interfaceClass.getClassLoader(),
interfaces,
--- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -316,7 +316,7 @@
*/
private static String attributeType(Method getter, Method setter)
throws IntrospectionException {
- Class type = null;
+ Class<?> type = null;
if (getter != null) {
if (getter.getParameterTypes().length != 0) {
@@ -330,7 +330,7 @@
}
if (setter != null) {
- Class params[] = setter.getParameterTypes();
+ Class<?> params[] = setter.getParameterTypes();
if (params.length != 1) {
throw new IntrospectionException("bad setter arg count");
}
--- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -64,7 +64,7 @@
* @param constructor The <CODE>java.lang.reflect.Constructor</CODE>
* object describing the MBean constructor.
*/
- public MBeanConstructorInfo(String description, Constructor constructor) {
+ public MBeanConstructorInfo(String description, Constructor<?> constructor) {
this(constructor.getName(), description,
constructorSignature(constructor),
Introspector.descriptorForElement(constructor));
@@ -210,8 +210,8 @@
return hash;
}
- private static MBeanParameterInfo[] constructorSignature(Constructor cn) {
- final Class[] classes = cn.getParameterTypes();
+ private static MBeanParameterInfo[] constructorSignature(Constructor<?> cn) {
+ final Class<?>[] classes = cn.getParameterTypes();
final Annotation[][] annots = cn.getParameterAnnotations();
return MBeanOperationInfo.parameters(classes, annots);
}
--- a/jdk/src/share/classes/javax/management/MBeanInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -45,6 +45,17 @@
* management operations. Instances of this class are immutable.
* Subclasses may be mutable but this is not recommended.</p>
*
+ * <p id="info-changed">Usually the {@code MBeanInfo} for any given MBean does
+ * not change over the lifetime of that MBean. Dynamic MBeans can change their
+ * {@code MBeanInfo} and in that case it is recommended that they emit a {@link
+ * Notification} with a {@linkplain Notification#getType() type} of {@code
+ * "jmx.mbean.info.changed"} and a {@linkplain Notification#getUserData()
+ * userData} that is the new {@code MBeanInfo}. This is not required, but
+ * provides a conventional way for clients of the MBean to discover the change.
+ * See also the <a href="Descriptor.html#immutableInfo">immutableInfo</a> and
+ * <a href="Descriptor.html#infoTimeout">infoTimeout</a> fields in the {@code
+ * MBeanInfo} {@link Descriptor}.</p>
+ *
* <p>The contents of the <code>MBeanInfo</code> for a Dynamic MBean
* are determined by its {@link DynamicMBean#getMBeanInfo
* getMBeanInfo()} method. This includes Open MBeans and Model
@@ -62,27 +73,49 @@
* constructors in that object;
*
* <li>{@link #getAttributes()} returns the list of all attributes
- * whose existence is deduced from the presence in the MBean interface
- * of a <code>get<i>Name</i></code>, <code>is<i>Name</i></code>, or
- * <code>set<i>Name</i></code> method that conforms to the conventions
+ * whose existence is deduced as follows:
+ * <ul>
+ * <li>if the Standard MBean is defined with an MBean interface,
+ * from <code>get<i>Name</i></code>, <code>is<i>Name</i></code>, or
+ * <code>set<i>Name</i></code> methods that conform to the conventions
* for Standard MBeans;
+ * <li>if the Standard MBean is defined with the {@link MBean @MBean} or
+ * {@link MXBean @MXBean} annotation on a class, from methods with the
+ * {@link ManagedAttribute @ManagedAttribute} annotation;
+ * </ul>
*
- * <li>{@link #getOperations()} returns the list of all methods in
+ * <li>{@link #getOperations()} returns the list of all operations whose
+ * existence is deduced as follows:
+ * <ul>
+ * <li>if the Standard MBean is defined with an MBean interface, from methods in
* the MBean interface that do not represent attributes;
+ * <li>if the Standard MBean is defined with the {@link MBean @MBean} or
+ * {@link MXBean @MXBean} annotation on a class, from methods with the
+ * {@link ManagedOperation @ManagedOperation} annotation;
+ * </ul>
*
- * <li>{@link #getNotifications()} returns an empty array if the MBean
- * does not implement the {@link NotificationBroadcaster} interface,
- * otherwise the result of calling {@link
+ * <li>{@link #getNotifications()} returns:
+ * <ul>
+ * <li>if the MBean implements the {@link NotificationBroadcaster} interface,
+ * the result of calling {@link
* NotificationBroadcaster#getNotificationInfo()} on it;
+ * <li>otherwise, if there is a {@link NotificationInfo @NotificationInfo}
+ * or {@link NotificationInfos @NotificationInfos} annotation on the
+ * MBean interface or <code>@MBean</code> or <code>@MXBean</code>
+ * class, the array implied by those annotations;
+ * <li>otherwise an empty array;
+ * </ul>
*
* <li>{@link #getDescriptor()} returns a descriptor containing the contents
- * of any descriptor annotations in the MBean interface.
+ * of any descriptor annotations in the MBean interface (see
+ * {@link DescriptorFields @DescriptorFields} and
+ * {@link DescriptorKey @DescriptorKey}).
*
* </ul>
*
* <p>The description returned by {@link #getDescription()} and the
* descriptions of the contained attributes and operations are determined
- * by the corresponding <!-- link here --> Description annotations if any;
+ * by the corresponding {@link Description} annotations if any;
* otherwise their contents are not specified.</p>
*
* <p>The remaining details of the <code>MBeanInfo</code> for a
@@ -524,8 +557,8 @@
* a WeakHashMap so that we don't prevent a class from being
* garbage collected just because we know whether it's immutable.
*/
- private static final Map<Class, Boolean> arrayGettersSafeMap =
- new WeakHashMap<Class, Boolean>();
+ private static final Map<Class<?>, Boolean> arrayGettersSafeMap =
+ new WeakHashMap<Class<?>, Boolean>();
/**
* Return true if <code>subclass</code> is known to preserve the
@@ -537,7 +570,7 @@
* This is obviously not an infallible test for immutability,
* but it works for the public interfaces of the MBean*Info classes.
*/
- static boolean arrayGettersSafe(Class subclass, Class immutableClass) {
+ static boolean arrayGettersSafe(Class<?> subclass, Class<?> immutableClass) {
if (subclass == immutableClass)
return true;
synchronized (arrayGettersSafeMap) {
--- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -308,17 +308,18 @@
wrong should be less than the penalty we would pay if it were
right and we needlessly hashed in the description and the
parameter array. */
+ @Override
public int hashCode() {
return getName().hashCode() ^ getReturnType().hashCode();
}
private static MBeanParameterInfo[] methodSignature(Method method) {
- final Class[] classes = method.getParameterTypes();
+ final Class<?>[] classes = method.getParameterTypes();
final Annotation[][] annots = method.getParameterAnnotations();
return parameters(classes, annots);
}
- static MBeanParameterInfo[] parameters(Class[] classes,
+ static MBeanParameterInfo[] parameters(Class<?>[] classes,
Annotation[][] annots) {
final MBeanParameterInfo[] params =
new MBeanParameterInfo[classes.length];
--- a/jdk/src/share/classes/javax/management/MBeanServer.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanServer.java Wed Jul 05 16:43:43 2017 +0200
@@ -377,19 +377,19 @@
* MBean will not be registered.
* @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
- * <CODE>RuntimeException</CODE>, the <CODE>registerMBean<CODE> method will
+ * <CODE>RuntimeException</CODE>, the <CODE>registerMBean</CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean
* registration succeeded. In such a case, the MBean will be actually
- * registered even though the <CODE>registerMBean<CODE> method
+ * registered even though the <CODE>registerMBean</CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception RuntimeErrorException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
- * <CODE>Error</CODE>, the <CODE>registerMBean<CODE> method will
+ * <CODE>Error</CODE>, the <CODE>registerMBean</CODE> method will
* throw a <CODE>RuntimeErrorException</CODE>, although the MBean
* registration succeeded. In such a case, the MBean will be actually
- * registered even though the <CODE>registerMBean<CODE> method
+ * registered even though the <CODE>registerMBean</CODE> method
* threw an exception. Note that <CODE>RuntimeErrorException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
@@ -411,6 +411,8 @@
* is sent as described <a href="#notif">above</a>.</p>
*
* @throws RuntimeOperationsException {@inheritDoc}
+ * @throws RuntimeMBeanException {@inheritDoc}
+ * @throws RuntimeErrorException {@inheritDoc}
*/
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException;
--- a/jdk/src/share/classes/javax/management/MBeanServerConnection.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanServerConnection.java Wed Jul 05 16:43:43 2017 +0200
@@ -76,7 +76,9 @@
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
- * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+ * @exception RuntimeMBeanException If the MBean's constructor or its
+ * {@code preRegister} or {@code postRegister} method threw
+ * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
@@ -148,7 +150,9 @@
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
- * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+ * @exception RuntimeMBeanException If the MBean's constructor or its
+ * {@code preRegister} or {@code postRegister} method threw
+ * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
@@ -223,7 +227,9 @@
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
- * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+ * @exception RuntimeMBeanException If the MBean's constructor or its
+ * {@code preRegister} or {@code postRegister} method threw
+ * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
@@ -295,7 +301,9 @@
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
- * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+ * @exception RuntimeMBeanException The MBean's constructor or its
+ * {@code preRegister} or {@code postRegister} method threw
+ * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
--- a/jdk/src/share/classes/javax/management/MBeanServerFactory.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanServerFactory.java Wed Jul 05 16:43:43 2017 +0200
@@ -747,7 +747,7 @@
* Load the builder class through the context class loader.
* @param builderClassName The name of the builder class.
**/
- private static Class loadBuilderClass(String builderClassName)
+ private static Class<?> loadBuilderClass(String builderClassName)
throws ClassNotFoundException {
final ClassLoader loader =
Thread.currentThread().getContextClassLoader();
@@ -767,7 +767,7 @@
* If any checked exception needs to be thrown, it is embedded in
* a JMRuntimeException.
**/
- private static MBeanServerBuilder newBuilder(Class builderClass) {
+ private static MBeanServerBuilder newBuilder(Class<?> builderClass) {
try {
final Object abuilder = builderClass.newInstance();
return (MBeanServerBuilder)abuilder;
@@ -792,7 +792,7 @@
String builderClassName = AccessController.doPrivileged(act);
try {
- final Class newBuilderClass;
+ final Class<?> newBuilderClass;
if (builderClassName == null || builderClassName.length() == 0)
newBuilderClass = MBeanServerBuilder.class;
else
@@ -800,7 +800,7 @@
// Check whether a new builder needs to be created
if (builder != null) {
- final Class builderClass = builder.getClass();
+ final Class<?> builderClass = builder.getClass();
if (newBuilderClass == builderClass)
return; // no need to create a new builder...
}
--- a/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java Wed Jul 05 16:43:43 2017 +0200
@@ -253,12 +253,12 @@
boolean notificationBroadcaster) {
final InvocationHandler handler =
new MBeanServerInvocationHandler(connection, objectName);
- final Class[] interfaces;
+ final Class<?>[] interfaces;
if (notificationBroadcaster) {
interfaces =
- new Class[] {interfaceClass, NotificationEmitter.class};
+ new Class<?>[] {interfaceClass, NotificationEmitter.class};
} else
- interfaces = new Class[] {interfaceClass};
+ interfaces = new Class<?>[] {interfaceClass};
Object proxy =
Proxy.newProxyInstance(interfaceClass.getClassLoader(),
@@ -269,7 +269,7 @@
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
- final Class methodClass = method.getDeclaringClass();
+ final Class<?> methodClass = method.getDeclaringClass();
if (methodClass.equals(NotificationBroadcaster.class)
|| methodClass.equals(NotificationEmitter.class))
@@ -285,8 +285,8 @@
return p.invoke(connection, objectName, method, args);
} else {
final String methodName = method.getName();
- final Class[] paramTypes = method.getParameterTypes();
- final Class returnType = method.getReturnType();
+ final Class<?>[] paramTypes = method.getParameterTypes();
+ final Class<?> returnType = method.getReturnType();
/* Inexplicably, InvocationHandler specifies that args is null
when the method takes no arguments rather than a
@@ -361,7 +361,13 @@
if (p != null)
return p;
}
- p = new MXBeanProxy(mxbeanInterface, mappingFactory);
+ try {
+ p = new MXBeanProxy(mxbeanInterface, mappingFactory);
+ } catch (IllegalArgumentException e) {
+ String msg = "Cannot make MXBean proxy for " +
+ mxbeanInterface.getName() + ": " + e.getMessage();
+ throw new IllegalArgumentException(msg, e.getCause());
+ }
classToProxy.put(mxbeanInterface, new WeakReference<MXBeanProxy>(p));
return p;
}
@@ -452,7 +458,7 @@
return true;
if (methodName.equals("equals")
&& Arrays.equals(method.getParameterTypes(),
- new Class[] {Object.class})
+ new Class<?>[] {Object.class})
&& isLocal(proxy, method))
return true;
return false;
--- a/jdk/src/share/classes/javax/management/NotificationListener.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/NotificationListener.java Wed Jul 05 16:43:43 2017 +0200
@@ -39,11 +39,10 @@
* blocking its notification broadcaster.
*
* @param notification The notification.
- * @param handback An opaque object which helps the listener to associate information
- * regarding the MBean emitter. This object is passed to the MBean during the
- * addListener call and resent, without modification, to the listener. The MBean object
- * should not use or modify the object.
- *
+ * @param handback An opaque object which helps the listener to associate
+ * information regarding the MBean emitter. This object is passed to the
+ * addNotificationListener call and resent, without modification, to the
+ * listener.
*/
- public void handleNotification(Notification notification, Object handback) ;
+ public void handleNotification(Notification notification, Object handback);
}
--- a/jdk/src/share/classes/javax/management/StandardMBean.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/StandardMBean.java Wed Jul 05 16:43:43 2017 +0200
@@ -689,7 +689,7 @@
getImplementationClass().getName());
}
- MBeanSupport msupport = mbean;
+ MBeanSupport<?> msupport = mbean;
final MBeanInfo bi = msupport.getMBeanInfo();
final Object impl = msupport.getWrappedObject();
@@ -1391,8 +1391,8 @@
* garbage collected just because we know whether its MBeanInfo
* is immutable.
*/
- private static final Map<Class, Boolean> mbeanInfoSafeMap =
- new WeakHashMap<Class, Boolean>();
+ private static final Map<Class<?>, Boolean> mbeanInfoSafeMap =
+ new WeakHashMap<Class<?>, Boolean>();
/**
* Return true if {@code subclass} is known to preserve the immutability
@@ -1438,9 +1438,9 @@
private static class MBeanInfoSafeAction
implements PrivilegedAction<Boolean> {
- private final Class subclass;
+ private final Class<?> subclass;
- MBeanInfoSafeAction(Class subclass) {
+ MBeanInfoSafeAction(Class<?> subclass) {
this.subclass = subclass;
}
@@ -1454,13 +1454,13 @@
// Check for "MBeanInfo getCachedMBeanInfo()" method.
//
if (overrides(subclass, StandardMBean.class,
- "getCachedMBeanInfo", (Class[]) null))
+ "getCachedMBeanInfo", (Class<?>[]) null))
return false;
// Check for "MBeanInfo getMBeanInfo()" method.
//
if (overrides(subclass, StandardMBean.class,
- "getMBeanInfo", (Class[]) null))
+ "getMBeanInfo", (Class<?>[]) null))
return false;
// Check for "MBeanNotificationInfo[] getNotificationInfo()"
@@ -1473,7 +1473,7 @@
//
if (StandardEmitterMBean.class.isAssignableFrom(subclass))
if (overrides(subclass, StandardEmitterMBean.class,
- "getNotificationInfo", (Class[]) null))
+ "getNotificationInfo", (Class<?>[]) null))
return false;
return true;
}
--- a/jdk/src/share/classes/javax/management/event/EventClient.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/event/EventClient.java Wed Jul 05 16:43:43 2017 +0200
@@ -117,12 +117,12 @@
public static final String NONFATAL = "jmx.event.service.nonfatal";
/**
- * <p>A notification string type used by an {@code EventClient} object to
- * inform a listener added by {@code #addEventClientListener} that it
- * has detected that notifications have been lost. The {@link
- * Notification#getUserData() userData} of the notification is a Long which
- * is an upper bound on the number of lost notifications that have just
- * been detected.</p>
+ * <p>A notification string type used by an {@code EventClient} object
+ * to inform a listener added by {@link #addEventClientListener
+ * addEventClientListener} that it has detected that notifications have
+ * been lost. The {@link Notification#getUserData() userData} of the
+ * notification is a Long which is an upper bound on the number of lost
+ * notifications that have just been detected.</p>
*
* @see #addEventClientListener
*/
@@ -577,8 +577,13 @@
}
/**
- * Returns the set of listeners that have been added through
- * this {@code EventClient} and not subsequently removed.
+ * <p>Returns the collection of listeners that have been added through
+ * this {@code EventClient} and not subsequently removed. The returned
+ * collection contains one entry for every listener added with
+ * {@link #addNotificationListener addNotificationListener} or
+ * {@link #subscribe subscribe} and not subsequently removed with
+ * {@link #removeNotificationListener removeNotificationListener} or
+ * {@link #unsubscribe unsubscribe}, respectively.</p>
*
* @return A collection of listener information. Empty if there are no
* current listeners or if this {@code EventClient} has been {@linkplain
@@ -927,8 +932,10 @@
private final static MBeanNotificationInfo[] myInfo =
new MBeanNotificationInfo[] {
new MBeanNotificationInfo(
- new String[] {FAILED, NOTIFS_LOST},
- Notification.class.getName(), "")};
+ new String[] {FAILED, NONFATAL, NOTIFS_LOST},
+ Notification.class.getName(),
+ "Notifications that can be sent to a listener added with " +
+ "EventClient.addEventClientListener")};
private final NotificationBroadcasterSupport broadcaster =
new NotificationBroadcasterSupport();
--- a/jdk/src/share/classes/javax/management/event/EventClientDelegate.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/event/EventClientDelegate.java Wed Jul 05 16:43:43 2017 +0200
@@ -104,8 +104,8 @@
public static EventClientDelegate getEventClientDelegate(MBeanServer server) {
EventClientDelegate delegate = null;
synchronized(delegateMap) {
- final WeakReference wrf = delegateMap.get(server);
- delegate = (wrf == null) ? null : (EventClientDelegate)wrf.get();
+ final WeakReference<EventClientDelegate> wrf = delegateMap.get(server);
+ delegate = (wrf == null) ? null : wrf.get();
if (delegate == null) {
delegate = new EventClientDelegate(server);
@@ -282,7 +282,7 @@
Constructor<?> foundCons = null;
if (sig == null)
sig = new String[0];
- for (Constructor cons : c.getConstructors()) {
+ for (Constructor<?> cons : c.getConstructors()) {
Class<?>[] types = cons.getParameterTypes();
String[] consSig = new String[types.length];
for (int i = 0; i < types.length; i++)
--- a/jdk/src/share/classes/javax/management/event/EventSubscriber.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/event/EventSubscriber.java Wed Jul 05 16:43:43 2017 +0200
@@ -350,8 +350,7 @@
static {
QueryExp broadcasterExp;
try {
- final Method m = Query.class.getMethod("isInstanceOf",
- new Class[] {String.class});
+ final Method m = Query.class.getMethod("isInstanceOf", String.class);
broadcasterExp = (QueryExp)m.invoke(Query.class,
new Object[] {NotificationBroadcaster.class.getName()});
} catch (Exception e) {
--- a/jdk/src/share/classes/javax/management/loading/DefaultLoaderRepository.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/loading/DefaultLoaderRepository.java Wed Jul 05 16:43:43 2017 +0200
@@ -69,7 +69,7 @@
* @exception ClassNotFoundException The specified class could not be
* found.
*/
- public static Class loadClass(String className)
+ public static Class<?> loadClass(String className)
throws ClassNotFoundException {
MBEANSERVER_LOGGER.logp(Level.FINEST,
DefaultLoaderRepository.class.getName(),
@@ -93,7 +93,7 @@
* @exception ClassNotFoundException The specified class could not be
* found.
*/
- public static Class loadClassWithout(ClassLoader loader,
+ public static Class<?> loadClassWithout(ClassLoader loader,
String className)
throws ClassNotFoundException {
MBEANSERVER_LOGGER.logp(Level.FINEST,
@@ -102,12 +102,11 @@
return load(loader, className);
}
- private static Class load(ClassLoader without, String className)
+ private static Class<?> load(ClassLoader without, String className)
throws ClassNotFoundException {
- final List mbsList = MBeanServerFactory.findMBeanServer(null);
+ final List<MBeanServer> mbsList = MBeanServerFactory.findMBeanServer(null);
- for (Iterator it = mbsList.iterator(); it.hasNext(); ) {
- MBeanServer mbs = (MBeanServer) it.next();
+ for (MBeanServer mbs : mbsList) {
ClassLoaderRepository clr = mbs.getClassLoaderRepository();
try {
return clr.loadClassWithout(without, className);
--- a/jdk/src/share/classes/javax/management/loading/MLet.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/loading/MLet.java Wed Jul 05 16:43:43 2017 +0200
@@ -1291,7 +1291,7 @@
if (c != null) {
try {
Constructor<?> cons =
- c.getConstructor(new Class[] {String.class});
+ c.getConstructor(String.class);
Object[] oo = new Object[1];
oo[0]=param;
return(cons.newInstance(oo));
--- a/jdk/src/share/classes/javax/management/loading/MLetObjectInputStream.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/loading/MLetObjectInputStream.java Wed Jul 05 16:43:43 2017 +0200
@@ -55,30 +55,30 @@
this.loader = loader;
}
- private Class primitiveType(char c) {
+ private Class<?> primitiveType(char c) {
switch(c) {
- case 66: /* 'B' */
+ case 'B':
return Byte.TYPE;
- case 67: /* 'C' */
+ case 'C':
return Character.TYPE;
- case 68: /* 'D' */
+ case 'D':
return Double.TYPE;
- case 70: /* 'F' */
+ case 'F':
return Float.TYPE;
- case 73: /* 'I' */
+ case 'I':
return Integer.TYPE;
- case 74: /* 'J' */
+ case 'J':
return Long.TYPE;
- case 83: /* 'S' */
+ case 'S':
return Short.TYPE;
- case 90: /* 'Z' */
+ case 'Z':
return Boolean.TYPE;
}
return null;
@@ -87,14 +87,15 @@
/**
* Use the given ClassLoader rather than using the system class
*/
- protected Class resolveClass(ObjectStreamClass objectstreamclass)
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass objectstreamclass)
throws IOException, ClassNotFoundException {
String s = objectstreamclass.getName();
if (s.startsWith("[")) {
int i;
for (i = 1; s.charAt(i) == '['; i++);
- Class class1;
+ Class<?> class1;
if (s.charAt(i) == 'L') {
class1 = loader.loadClass(s.substring(i + 1, s.length() - 1));
} else {
--- a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Wed Jul 05 16:43:43 2017 +0200
@@ -589,7 +589,7 @@
int numberOfEntries = descriptorMap.size();
String[] responseFields = new String[numberOfEntries];
- Set returnedSet = descriptorMap.entrySet();
+ Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();
int i = 0;
@@ -598,8 +598,9 @@
DescriptorSupport.class.getName(),
"getFields()", "Returning " + numberOfEntries + " fields");
}
- for (Iterator iter = returnedSet.iterator(); iter.hasNext(); i++) {
- Map.Entry currElement = (Map.Entry) iter.next();
+ for (Iterator<Map.Entry<String, Object>> iter = returnedSet.iterator();
+ iter.hasNext(); i++) {
+ Map.Entry<String, Object> currElement = iter.next();
if (currElement == null) {
if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
@@ -642,7 +643,7 @@
int numberOfEntries = descriptorMap.size();
String[] responseFields = new String[numberOfEntries];
- Set returnedSet = descriptorMap.entrySet();
+ Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();
int i = 0;
@@ -653,8 +654,9 @@
"Returning " + numberOfEntries + " fields");
}
- for (Iterator iter = returnedSet.iterator(); iter.hasNext(); i++) {
- Map.Entry currElement = (Map.Entry) iter.next();
+ for (Iterator<Map.Entry<String, Object>> iter = returnedSet.iterator();
+ iter.hasNext(); i++) {
+ Map.Entry<String, Object> currElement = iter.next();
if (( currElement == null ) || (currElement.getKey() == null)) {
if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
@@ -700,9 +702,8 @@
}
if (fieldNames == null) {
- for (Iterator iter = descriptorMap.values().iterator();
- iter.hasNext(); i++)
- responseFields[i] = iter.next();
+ for (Object value : descriptorMap.values())
+ responseFields[i++] = value;
} else {
for (i=0; i < fieldNames.length; i++) {
if ((fieldNames[i] == null) || (fieldNames[i].equals(""))) {
@@ -883,9 +884,9 @@
* not a String with value "t", "f", "true", "false". These String
* values must not be case sensitive.
* <LI> visibility fieldName, if defined, is null, or not a
- * Numeric String or a not Numeric Value >= 1 and <= 4
+ * Numeric String or a not Numeric Value >= 1 and <= 4
* <LI> severity fieldName, if defined, is null, or not a Numeric
- * String or not a Numeric Value >= 0 and <= 6<br>
+ * String or not a Numeric Value >= 0 and <= 6<br>
* <LI> persistPolicy fieldName, if defined, is null, or not one of
* the following strings:<br>
* "OnUpdate", "OnTimer", "NoMoreOftenThan", "OnUnregister", "Always",
@@ -904,7 +905,7 @@
}
// verify that the descriptor is valid, by iterating over each field...
- Set returnedSet = descriptorMap.entrySet();
+ Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();
if (returnedSet == null) { // null descriptor, not valid
if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
@@ -925,9 +926,7 @@
// According to the descriptor type we validate the fields contained
- for (Iterator iter = returnedSet.iterator(); iter.hasNext();) {
- Map.Entry currElement = (Map.Entry) iter.next();
-
+ for (Map.Entry<String, Object> currElement : returnedSet) {
if (currElement != null) {
if (currElement.getValue() != null) {
// validate the field valued...
@@ -1083,10 +1082,9 @@
*/
public synchronized String toXMLString() {
final StringBuilder buf = new StringBuilder("<Descriptor>");
- Set returnedSet = descriptorMap.entrySet();
- for (Iterator iter = returnedSet.iterator(); iter.hasNext(); ) {
- final Map.Entry currElement = (Map.Entry) iter.next();
- final String name = currElement.getKey().toString();
+ Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();
+ for (Map.Entry<String, Object> currElement : returnedSet) {
+ final String name = currElement.getKey();
Object value = currElement.getValue();
String valueString = null;
/* Set valueString to non-null if and only if this is a string that
@@ -1256,7 +1254,7 @@
}
final Class<?> c =
Class.forName(className, false, contextClassLoader);
- constr = c.getConstructor(new Class[] {String.class});
+ constr = c.getConstructor(new Class<?>[] {String.class});
} catch (Exception e) {
throw new XMLParseException(e,
"Cannot parse value: <" + s + ">");
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -39,7 +39,6 @@
import java.io.ObjectStreamField;
import java.lang.reflect.Method;
import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.logging.Level;
import javax.management.Descriptor;
@@ -49,32 +48,56 @@
import javax.management.RuntimeOperationsException;
/**
- * The ModelMBeanAttributeInfo object describes an attribute of the ModelMBean.
+ * <p>The ModelMBeanAttributeInfo object describes an attribute of the ModelMBean.
* It is a subclass of MBeanAttributeInfo with the addition of an associated Descriptor
- * and an implementation of the DescriptorAccess interface.
- * <P>
- * The fields in the descriptor are defined, but not limited to, the following: <P>
- * <PRE>
- * name : attribute name
- * descriptorType : must be "attribute"
- * value : current value for attribute
- * default : default value for attribute
- * displayName : name of attribute to be used in displays
- * getMethod : name of operation descriptor for get method
- * setMethod : name of operation descriptor for set method
- * protocolMap : object which implements the Descriptor interface: mappings
- * must be appropriate for the attribute
- * and entries can be updated or augmented at runtime.
- * persistPolicy : OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never
- * persistPeriod : seconds - frequency of persist cycle. Used when persistPolicy
- * is "OnTimer" or "NoMoreOftenThan".
- * currencyTimeLimit : how long value is valid, <0 never, =0 always, >0 seconds
- * lastUpdatedTimeStamp : when value was set
- * visibility : 1-4 where 1: always visible, 4: rarely visible
- * presentationString : xml formatted string to allow presentation of data
- * </PRE>
- * The default descriptor contains the name, descriptorType and displayName fields.
- * The default value of the name and displayName fields is the name of the attribute.
+ * and an implementation of the DescriptorAccess interface.</p>
+ *
+ * <P id="descriptor">
+ * The fields in the descriptor are defined, but not limited to, the following.
+ * Note that when the Type in this table is Number, a String that is the decimal
+ * representation of a Long can also be used.</P>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr><th>Name</th><th>Type</th><th>Meaning</th></tr>
+ * <tr><td>name</td><td>String</td>
+ * <td>Attribute name.</td></tr>
+ * <tr><td>descriptorType</td><td>String</td>
+ * <td>Must be "attribute".</td></tr>
+ * <tr id="value-field"><td>value</td><td>Object</td>
+ * <td>Current (cached) value for attribute.</td></tr>
+ * <tr><td>default</td><td>Object</td>
+ * <td>Default value for attribute.</td></tr>
+ * <tr><td>displayName</td><td>String</td>
+ * <td>Name of attribute to be used in displays.</td></tr>
+ * <tr><td>getMethod</td><td>String</td>
+ * <td>Name of operation descriptor for get method.</td></tr>
+ * <tr><td>setMethod</td><td>String</td>
+ * <td>Name of operation descriptor for set method.</td></tr>
+ * <tr><td>protocolMap</td><td>Descriptor</td>
+ * <td>See the section "Protocol Map Support" in the JMX specification
+ * document. Mappings must be appropriate for the attribute and entries
+ * can be updated or augmented at runtime.</td></tr>
+ * <tr><td>persistPolicy</td><td>String</td>
+ * <td>One of: OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never.
+ * See the section "MBean Descriptor Fields" in the JMX specification
+ * document.</td></tr>
+ * <tr><td>persistPeriod</td><td>Number</td>
+ * <td>Frequency of persist cycle in seconds. Used when persistPolicy is
+ * "OnTimer" or "NoMoreOftenThan".</td></tr>
+ * <tr><td>currencyTimeLimit</td><td>Number</td>
+ * <td>How long <a href="#value=field">value</a> is valid: <0 never,
+ * =0 always, >0 seconds.</td></tr>
+ * <tr><td>lastUpdatedTimeStamp</td><td>Number</td>
+ * <td>When <a href="#value-field">value</a> was set.</td></tr>
+ * <tr><td>visibility</td><td>Number</td>
+ * <td>1-4 where 1: always visible, 4: rarely visible.</td></tr>
+ * <tr><td>presentationString</td><td>String</td>
+ * <td>XML formatted string to allow presentation of data.</td></tr>
+ * </table>
+ *
+ * <p>The default descriptor contains the name, descriptorType and displayName
+ * fields. The default value of the name and displayName fields is the name of
+ * the attribute.</p>
*
* <p><b>Note:</b> because of inconsistencies in previous versions of
* this specification, it is recommended not to use negative or zero
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanConstructorInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanConstructorInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -49,22 +49,33 @@
import javax.management.RuntimeOperationsException;
/**
- * The ModelMBeanConstructorInfo object describes a constructor of the ModelMBean.
+ * <p>The ModelMBeanConstructorInfo object describes a constructor of the ModelMBean.
* It is a subclass of MBeanConstructorInfo with the addition of an associated Descriptor
- * and an implementation of the DescriptorAccess interface.
- * <P>
- * <PRE>
- * The fields in the descriptor are defined, but not limited to, the following: <P>
- * name : constructor name
- * descriptorType : must be "operation"
- * role : must be "constructor"
- * displayName : human readable name of constructor
- * visibility : 1-4 where 1: always visible 4: rarely visible
- * presentationString : xml formatted string to describe how to present operation
- *</PRE>
+ * and an implementation of the DescriptorAccess interface.</p>
+ *
+ * <P id="descriptor">
+ * The fields in the descriptor are defined, but not limited to, the following.
+ * Note that when the Type in this table is Number, a String that is the decimal
+ * representation of a Long can also be used.</P>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr><th>Name</th><th>Type</th><th>Meaning</th></tr>
+ * <tr><td>name</td><td>String</td>
+ * <td>Constructor name.</td></tr>
+ * <tr><td>descriptorType</td><td>String</td>
+ * <td>Must be "operation".</td></tr>
+ * <tr><td>role</td><td>String</td>
+ * <td>Must be "constructor".</td></tr>
+ * <tr><td>displayName</td><td>String</td>
+ * <td>Human readable name of constructor.</td></tr>
+ * <tr><td>visibility</td><td>Number</td>
+ * <td>1-4 where 1: always visible 4: rarely visible.</td></tr>
+ * <tr><td>presentationString</td><td>String</td>
+ * <td>XML formatted string to describe how to present operation</td></tr>
+ * </table>
*
* <p>The {@code persistPolicy} and {@code currencyTimeLimit} fields
- * are meaningless for constructors, but are not considered invalid.
+ * are meaningless for constructors, but are not considered invalid.</p>
*
* <p>The default descriptor will have the {@code name}, {@code
* descriptorType}, {@code displayName} and {@code role} fields. The
@@ -152,7 +163,7 @@
* describing the MBean constructor.
*/
public ModelMBeanConstructorInfo(String description,
- Constructor constructorMethod)
+ Constructor<?> constructorMethod)
{
super(description, constructorMethod);
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
@@ -194,7 +205,7 @@
*/
public ModelMBeanConstructorInfo(String description,
- Constructor constructorMethod,
+ Constructor<?> constructorMethod,
Descriptor descriptor)
{
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -156,29 +156,55 @@
/**
- * Returns the ModelMBean's descriptor which contains MBean wide policies. This descriptor contains
- * metadata about the MBean and default policies for persistence and caching.
- * <P>
- * The fields in the descriptor are defined, but not limited to, the following:
- * <PRE>
- * name : MBean name
- * descriptorType : must be "mbean"
- * displayName : name of attribute to be used in displays
- * persistPolicy : OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never
- * persistLocation : The fully qualified directory name where the MBean should be persisted (if appropriate)
- * persistFile : File name into which the MBean should be persisted
- * persistPeriod : seconds - frequency of persist cycle for OnTime and NoMoreOftenThan PersistPolicy
- * currencyTimeLimit : how long value is valid, <0 never, =0 always, >0 seconds
- * log : where t: log all notifications f: log no notifications
- * logfile : fully qualified filename to log events to
- * visibility : 1-4 where 1: always visible 4: rarely visible
- * export : name to be used to export/expose this MBean so that it is findable by
- * other JMX Agents.
- * presentationString : xml formatted string to allow presentation of data to be associated with the MBean.
- * </PRE>
+ * <p>Returns the ModelMBean's descriptor which contains MBean wide
+ * policies. This descriptor contains metadata about the MBean and default
+ * policies for persistence and caching.</p>
+ *
+ * <P id="descriptor">
+ * The fields in the descriptor are defined, but not limited to, the
+ * following. Note that when the Type in this table is Number, a String
+ * that is the decimal representation of a Long can also be used.</P>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr><th>Name</th><th>Type</th><th>Meaning</th></tr>
+ * <tr><td>name</td><td>String</td>
+ * <td>MBean name.</td></tr>
+ * <tr><td>descriptorType</td><td>String</td>
+ * <td>Must be "mbean".</td></tr>
+ * <tr><td>displayName</td><td>String</td>
+ * <td>Name of MBean to be used in displays.</td></tr>
+ * <tr><td>persistPolicy</td><td>String</td>
+ * <td>One of: OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never.
+ * See the section "MBean Descriptor Fields" in the JMX specification
+ * document.</td></tr>
+ * <tr><td>persistLocation</td><td>String</td>
+ * <td>The fully qualified directory name where the MBean should be
+ * persisted (if appropriate).</td></tr>
+ * <tr><td>persistFile</td><td>String</td>
+ * <td>File name into which the MBean should be persisted.</td></tr>
+ * <tr><td>persistPeriod</td><td>Number</td>
+ * <td>Frequency of persist cycle in seconds, for OnTime and
+ * NoMoreOftenThan PersistPolicy</td></tr>
+ * <tr><td>currencyTimeLimit</td><td>Number</td>
+ * <td>How long cached value is valid: <0 never, =0 always,
+ * >0 seconds.</td></tr>
+ * <tr><td>log</td><td>String</td>
+ * <td>t: log all notifications, f: log no notifications.</td></tr>
+ * <tr><td>logfile</td><td>String</td>
+ * <td>Fully qualified filename to log events to.</td></tr>
+ * <tr><td>visibility</td><td>Number</td>
+ * <td>1-4 where 1: always visible 4: rarely visible.</td></tr>
+ * <tr><td>export</td><td>String</td>
+ * <td>Name to be used to export/expose this MBean so that it is
+ * findable by other JMX Agents.</td></tr>
+ * <tr><td>presentationString</td><td>String</td>
+ * <td>XML formatted string to allow presentation of data to be
+ * associated with the MBean.</td></tr>
+ * </table>
+ *
* <P>
* The default descriptor is: name=className,descriptorType="mbean", displayName=className,
- * persistPolicy="never",log="F",export="F",visibility="1"
+ * persistPolicy="never",log="F",visibility="1"
* If the descriptor does not contain all these fields, they will be added with these default values.
*
* <p><b>Note:</b> because of inconsistencies in previous versions of
@@ -207,7 +233,7 @@
* does a complete replacement of the descriptor, no merging is done. If the descriptor to
* set to is null then the default descriptor will be created.
* The default descriptor is: name=className,descriptorType="mbean", displayName=className,
- * persistPolicy="never",log="F",export="F",visibility="1"
+ * persistPolicy="never",log="F",visibility="1"
* If the descriptor does not contain all these fields, they will be added with these default values.
*
* See {@link #getMBeanDescriptor getMBeanDescriptor} method javadoc for description of valid field names.
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -46,34 +46,46 @@
import javax.management.RuntimeOperationsException;
/**
- * The ModelMBeanNotificationInfo object describes a notification emitted
+ * <p>The ModelMBeanNotificationInfo object describes a notification emitted
* by a ModelMBean.
* It is a subclass of MBeanNotificationInfo with the addition of an
- * associated Descriptor and an implementation of the Descriptor interface.
- * <P>
- * The fields in the descriptor are defined, but not limited to,
- * the following:
- * <PRE>
- * name : notification name
- * descriptorType : must be "notification"
- * severity : 0-6 where 0: unknown; 1: non-recoverable;
- * 2: critical, failure; 3: major, severe;
- * 4: minor, marginal, error; 5: warning;
- * 6: normal, cleared, informative
- * messageID : unique key for message text (to allow translation,
- * analysis)
- * messageText : text of notification
- * log : T - log message F - do not log message
- * logfile : string fully qualified file name appropriate for
- * operating system
- * visibility : 1-4 where 1: always visible 4: rarely visible
- * presentationString : xml formatted string to allow presentation of data
- * </PRE>
- * The default descriptor contains the name, descriptorType,
+ * associated Descriptor and an implementation of the Descriptor interface.</p>
+ *
+ * <P id="descriptor">
+ * The fields in the descriptor are defined, but not limited to, the following.
+ * Note that when the Type in this table is Number, a String that is the decimal
+ * representation of a Long can also be used.</P>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr><th>Name</th><th>Type</th><th>Meaning</th></tr>
+ * <tr><td>name</td><td>String</td>
+ * <td>Notification name.</td></tr>
+ * <tr><td>descriptorType</td><td>String</td>
+ * <td>Must be "notification".</td></tr>
+ * <tr><td>severity</td><td>Number</td>
+ * <td>0-6 where 0: unknown; 1: non-recoverable;
+ * 2: critical, failure; 3: major, severe;
+ * 4: minor, marginal, error; 5: warning;
+ * 6: normal, cleared, informative</td></tr>
+ * <tr><td>messageID</td><td>String</td>
+ * <td>Unique key for message text (to allow translation, analysis).</td></tr>
+ * <tr><td>messageText</td><td>String</td>
+ * <td>Text of notification.</td></tr>
+ * <tr><td>log</td><td>String</td>
+ * <td>T - log message, F - do not log message.</td></tr>
+ * <tr><td>logfile</td><td>String</td>
+ * <td>fully qualified file name appropriate for operating system.</td></tr>
+ * <tr><td>visibility</td><td>Number</td>
+ * <td>1-4 where 1: always visible 4: rarely visible.</td></tr>
+ * <tr><td>presentationString</td><td>String</td>
+ * <td>XML formatted string to allow presentation of data.</td></tr>
+ * </table>
+ *
+ * <p>The default descriptor contains the name, descriptorType,
* displayName and severity(=6) fields. The default value of the name
* and displayName fields is the name of the Notification class (as
* specified by the <code>name</code> parameter of the
- * ModelMBeanNotificationInfo constructor).
+ * ModelMBeanNotificationInfo constructor).</p>
*
* <p>The <b>serialVersionUID</b> of this class is <code>-7445681389570207141L</code>.
*
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanOperationInfo.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanOperationInfo.java Wed Jul 05 16:43:43 2017 +0200
@@ -49,27 +49,48 @@
import javax.management.RuntimeOperationsException;
/**
- * The ModelMBeanOperationInfo object describes a management operation of the ModelMBean.
- * It is a subclass of MBeanOperationInfo with the addition of an associated Descriptor
- * and an implementation of the DescriptorAccess interface.
- * <P>
- * <PRE>
- * The fields in the descriptor are defined, but not limited to, the following:
- * name : operation name
- * descriptorType : must be "operation"
- * class : class where method is defined (fully qualified)
- * role : must be "operation", "getter", or "setter
- * targetObject : object on which to execute this method
- * targetType : type of object reference for targetObject. Can be:
- * ObjectReference | Handle | EJBHandle | IOR | RMIReference.
- * value : cached value for operation
- * currencyTimeLimit : how long cached value is valid
- * lastUpdatedTimeStamp : when cached value was set
- * visibility : 1-4 where 1: always visible 4: rarely visible
- * presentationString : xml formatted string to describe how to present operation
- * </PRE>
- * The default descriptor will have name, descriptorType, displayName and role fields set.
- * The default value of the name and displayName fields is the operation name.
+ * <p>The ModelMBeanOperationInfo object describes a management operation of
+ * the ModelMBean. It is a subclass of MBeanOperationInfo with the addition
+ * of an associated Descriptor and an implementation of the DescriptorAccess
+ * interface.</p>
+ *
+ * <P id="descriptor">
+ * The fields in the descriptor are defined, but not limited to, the following.
+ * Note that when the Type in this table is Number, a String that is the decimal
+ * representation of a Long can also be used.</P>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr><th>Name</th><th>Type</th><th>Meaning</th></tr>
+ * <tr><td>name</td><td>String</td>
+ * <td>Operation name.</td></tr>
+ * <tr><td>descriptorType</td><td>String</td>
+ * <td>Must be "operation".</td></tr>
+ * <tr><td>class</td><td>String</td>
+ * <td>Class where method is defined (fully qualified).</td></tr>
+ * <tr><td>role</td><td>String</td>
+ * <td>Must be "operation", "getter", or "setter".</td></tr>
+ * <tr><td>targetObject</td><td>Object</td>
+ * <td>Object on which to execute this method.</td></tr>
+ * <tr><td>targetType</td><td>String</td>
+ * <td>type of object reference for targetObject. Can be:
+ * ObjectReference | Handle | EJBHandle | IOR | RMIReference.</td></tr>
+ * <tr><td>value</td><td>Object</td>
+ * <td>Cached value for operation.</td></tr>
+ * <tr><td>displayName</td><td>String</td>
+ * <td>Human readable display name of the operation.</td>
+ * <tr><td>currencyTimeLimit</td><td>Number</td>
+ * <td>How long cached value is valid.</td></tr>
+ * <tr><td>lastUpdatedTimeStamp</td><td>Number</td>
+ * <td>When cached value was set.</td></tr>
+ * <tr><td>visibility</td><td>Number</td>
+ * <td>1-4 where 1: always visible 4: rarely visible.</td></tr>
+ * <tr><td>presentationString</td><td>String</td>
+ * <td>XML formatted string to describe how to present operation</td></tr>
+ * </table>
+ *
+ * <p>The default descriptor will have name, descriptorType, displayName and
+ * role fields set. The default value of the name and displayName fields is
+ * the operation name.</p>
*
* <p><b>Note:</b> because of inconsistencies in previous versions of
* this specification, it is recommended not to use negative or zero
--- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Wed Jul 05 16:43:43 2017 +0200
@@ -1074,7 +1074,7 @@
}
}
- final Class targetClass;
+ final Class<?> targetClass;
if (opClassName != null) {
try {
@@ -1126,20 +1126,20 @@
"resolving " + targetClass.getName() + "." + opMethodName);
}
- final Class[] argClasses;
+ final Class<?>[] argClasses;
if (sig == null)
argClasses = null;
else {
final ClassLoader targetClassLoader = targetClass.getClassLoader();
- argClasses = new Class[sig.length];
+ argClasses = new Class<?>[sig.length];
for (int i = 0; i < sig.length; i++) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),"resolveMethod",
"resolve type " + sig[i]);
}
- argClasses[i] = (Class) primitiveClassMap.get(sig[i]);
+ argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
if (argClasses[i] == null) {
try {
argClasses[i] =
@@ -1170,7 +1170,7 @@
/* Map e.g. "int" to int.class. Goodness knows how many time this
particular wheel has been reinvented. */
- private static final Class[] primitiveClasses = {
+ private static final Class<?>[] primitiveClasses = {
int.class, long.class, boolean.class, double.class,
float.class, short.class, byte.class, char.class,
};
@@ -1178,7 +1178,7 @@
new HashMap<String,Class<?>>();
static {
for (int i = 0; i < primitiveClasses.length; i++) {
- final Class c = primitiveClasses[i];
+ final Class<?> c = primitiveClasses[i];
primitiveClassMap.put(c.getName(), c);
}
}
@@ -1645,7 +1645,7 @@
try {
ClassLoader cl =
response.getClass().getClassLoader();
- Class c = Class.forName(respType, true, cl);
+ Class<?> c = Class.forName(respType, true, cl);
subtype = c.isInstance(response);
} catch (Exception e) {
subtype = false;
@@ -1904,7 +1904,7 @@
if (attrSetMethod == null) {
if (attrValue != null) {
try {
- final Class clazz = loadClass(attrType);
+ final Class<?> clazz = loadClass(attrType);
if (! clazz.isInstance(attrValue)) throw new
InvalidAttributeValueException(clazz.getName() +
" expected, " +
@@ -2044,8 +2044,7 @@
final AttributeList responseList = new AttributeList();
// Go through the list of attributes
- for (Iterator i = attributes.iterator(); i.hasNext();) {
- final Attribute attr = (Attribute) i.next();
+ for (Attribute attr : attributes.asList()) {
try {
setAttribute(attr);
responseList.add(attr);
@@ -2799,7 +2798,7 @@
return MBeanServerFactory.getClassLoaderRepository(server);
}
- private Class loadClass(String className)
+ private Class<?> loadClass(String className)
throws ClassNotFoundException {
try {
return Class.forName(className);
--- a/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java Wed Jul 05 16:43:43 2017 +0200
@@ -457,7 +457,11 @@
* All the various flavors of {@code MBeanServer.createMBean} methods
* will eventually call this method. A subclass that wishes to
* support MBean creation through {@code createMBean} thus only
- * needs to provide an implementation for this one method.
+ * needs to provide an implementation for this one method.</p>
+ *
+ * <p>A subclass implementation of this method should respect the contract
+ * of the various {@code createMBean} methods in the {@link MBeanServer}
+ * interface, in particular as regards exception wrapping.</p>
*
* @param className The class name of the MBean to be instantiated.
* @param name The object name of the MBean. May be null.
@@ -488,6 +492,17 @@
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
+ * @exception RuntimeMBeanException If the MBean's constructor or its
+ * {@code preRegister} or {@code postRegister} method threw
+ * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
+ * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
+ * <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
+ * throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
+ * and registration succeeded. In such a case, the MBean will be actually
+ * registered even though the <CODE>createMBean</CODE> method
+ * threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
+ * also be thrown by <CODE>preRegister</CODE>, in which case the MBean
+ * will not be registered.
* @exception MBeanException The constructor of the MBean has
* thrown an exception
* @exception NotCompliantMBeanException This class is not a JMX
@@ -1096,7 +1111,7 @@
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException {
try {
- return safeCreateMBean(className, name, null, params, signature, true);
+ return createMBean(className, name, null, params, signature, true);
} catch (InstanceNotFoundException ex) {
// should not happen!
throw new MBeanException(ex, "Unexpected exception: " + ex);
@@ -1113,7 +1128,7 @@
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException {
- return safeCreateMBean(className, name, loaderName, params, signature, false);
+ return createMBean(className, name, loaderName, params, signature, false);
}
/**
@@ -1126,7 +1141,7 @@
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException {
try {
- return safeCreateMBean(className, name, null, null, null, true);
+ return createMBean(className, name, null, null, null, true);
} catch (InstanceNotFoundException ex) {
// should not happen!
throw new MBeanException(ex, "Unexpected exception: " + ex);
@@ -1143,32 +1158,7 @@
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException {
- return safeCreateMBean(className, name, loaderName, null, null, false);
- }
-
- // make sure all exceptions are correctly wrapped in a JMXException
- private ObjectInstance safeCreateMBean(String className,
- ObjectName name, ObjectName loaderName, Object[] params,
- String[] signature, boolean useRepository)
- throws ReflectionException, InstanceAlreadyExistsException,
- MBeanRegistrationException, MBeanException,
- NotCompliantMBeanException, InstanceNotFoundException {
- try {
- return createMBean(className, name, loaderName, params,
- signature, useRepository);
- } catch (ReflectionException x) { throw x;
- } catch (InstanceAlreadyExistsException x) { throw x;
- } catch (MBeanRegistrationException x) { throw x;
- } catch (MBeanException x) { throw x;
- } catch (NotCompliantMBeanException x) { throw x;
- } catch (InstanceNotFoundException x) { throw x;
- } catch (SecurityException x) { throw x;
- } catch (JMRuntimeException x) { throw x;
- } catch (RuntimeException x) {
- throw new RuntimeOperationsException(x, x.toString());
- } catch (Exception x) {
- throw new MBeanException(x, x.toString());
- }
+ return createMBean(className, name, loaderName, null, null, false);
}
--- a/jdk/src/share/classes/javax/management/openmbean/ArrayType.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/ArrayType.java Wed Jul 05 16:43:43 2017 +0200
@@ -296,7 +296,7 @@
// Check and construct state specific to ArrayType
//
if (elementType.isArray()) {
- ArrayType at = (ArrayType) elementType;
+ ArrayType<?> at = (ArrayType<?>) elementType;
this.dimension = at.getDimension() + dimension;
this.elementType = at.getElementOpenType();
this.primitiveArray = at.isPrimitiveArray();
@@ -384,7 +384,7 @@
/* Package-private constructor for callers we trust to get it right. */
ArrayType(String className, String typeName, String description,
- int dimension, OpenType elementType,
+ int dimension, OpenType<?> elementType,
boolean primitiveArray) {
super(className, typeName, description, true);
this.dimension = dimension;
@@ -397,7 +397,7 @@
throws OpenDataException {
boolean isPrimitiveArray = false;
if (elementType.isArray()) {
- isPrimitiveArray = ((ArrayType) elementType).isPrimitiveArray();
+ isPrimitiveArray = ((ArrayType<?>) elementType).isPrimitiveArray();
}
return buildArrayClassName(dimension, elementType, isPrimitiveArray);
}
@@ -443,7 +443,7 @@
throws OpenDataException {
boolean isPrimitiveArray = false;
if (elementType.isArray()) {
- isPrimitiveArray = ((ArrayType) elementType).isPrimitiveArray();
+ isPrimitiveArray = ((ArrayType<?>) elementType).isPrimitiveArray();
}
return buildArrayDescription(dimension, elementType, isPrimitiveArray);
}
@@ -453,7 +453,7 @@
boolean isPrimitiveArray)
throws OpenDataException {
if (elementType.isArray()) {
- ArrayType at = (ArrayType) elementType;
+ ArrayType<?> at = (ArrayType<?>) elementType;
dimension += at.getDimension();
elementType = at.getElementOpenType();
isPrimitiveArray = at.isPrimitiveArray();
@@ -551,7 +551,7 @@
return false;
}
- Class objClass = obj.getClass();
+ Class<?> objClass = obj.getClass();
String objClassName = objClass.getName();
// if obj is not an array, return false
@@ -636,8 +636,8 @@
}
@Override
- boolean isAssignableFrom(OpenType ot) {
- if (!(ot instanceof ArrayType))
+ boolean isAssignableFrom(OpenType<?> ot) {
+ if (!(ot instanceof ArrayType<?>))
return false;
ArrayType<?> at = (ArrayType<?>) ot;
return (at.getDimension() == getDimension() &&
@@ -675,9 +675,9 @@
// if obj is not an ArrayType, return false
//
- if (!(obj instanceof ArrayType))
+ if (!(obj instanceof ArrayType<?>))
return false;
- ArrayType other = (ArrayType) obj;
+ ArrayType<?> other = (ArrayType<?>) obj;
// if other's dimension is different than this instance's, return false
//
@@ -879,6 +879,7 @@
// Build primitive array
//
try {
+ @SuppressWarnings("rawtypes")
ArrayType at = new ArrayType(simpleType, true);
if (n > 1)
at = new ArrayType<T>(n - 1, at);
@@ -934,7 +935,7 @@
}
}
- private ArrayType convertFromWrapperToPrimitiveTypes() {
+ private <T> ArrayType<T> convertFromWrapperToPrimitiveTypes() {
String cn = getClassName();
String tn = getTypeName();
String d = getDescription();
@@ -952,8 +953,8 @@
break;
}
}
- return new ArrayType(cn, tn, d,
- dimension, elementType, primitiveArray);
+ return new ArrayType<T>(cn, tn, d,
+ dimension, elementType, primitiveArray);
}
/**
@@ -1002,7 +1003,7 @@
}
}
- private ArrayType convertFromPrimitiveToWrapperTypes() {
+ private <T> ArrayType<T> convertFromPrimitiveToWrapperTypes() {
String cn = getClassName();
String tn = getTypeName();
String d = getDescription();
@@ -1020,7 +1021,7 @@
break;
}
}
- return new ArrayType(cn, tn, d,
- dimension, elementType, primitiveArray);
+ return new ArrayType<T>(cn, tn, d,
+ dimension, elementType, primitiveArray);
}
}
--- a/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Wed Jul 05 16:43:43 2017 +0200
@@ -236,8 +236,8 @@
if (other == null)
return false;
- final Class proxyClass = proxy.getClass();
- final Class otherClass = other.getClass();
+ final Class<?> proxyClass = proxy.getClass();
+ final Class<?> otherClass = other.getClass();
if (proxyClass != otherClass)
return false;
InvocationHandler otherih = Proxy.getInvocationHandler(other);
--- a/jdk/src/share/classes/javax/management/openmbean/CompositeType.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/CompositeType.java Wed Jul 05 16:43:43 2017 +0200
@@ -329,7 +329,7 @@
* @return true if {@code ot} is assignable to this open type.
*/
@Override
- boolean isAssignableFrom(OpenType ot) {
+ boolean isAssignableFrom(OpenType<?> ot) {
if (!(ot instanceof CompositeType))
return false;
CompositeType ct = (CompositeType) ot;
@@ -420,9 +420,7 @@
if (myHashCode == null) {
int value = 0;
value += this.getTypeName().hashCode();
- String key;
- for (Iterator k = nameToDescription.keySet().iterator(); k.hasNext(); ) {
- key = (String) k.next();
+ for (String key : nameToDescription.keySet()) {
value += key.hashCode();
value += this.nameToType.get(key).hashCode();
}
@@ -457,10 +455,10 @@
result.append(getTypeName());
result.append(",items=(");
int i=0;
- Iterator k=nameToType.keySet().iterator();
+ Iterator<String> k=nameToType.keySet().iterator();
String key;
while (k.hasNext()) {
- key = (String) k.next();
+ key = k.next();
if (i > 0) result.append(",");
result.append("(itemName=");
result.append(key);
--- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java Wed Jul 05 16:43:43 2017 +0200
@@ -78,12 +78,12 @@
/**
* @serial The open mbean attribute's min value
*/
- private final Comparable minValue;
+ private final Comparable<?> minValue;
/**
* @serial The open mbean attribute's max value
*/
- private final Comparable maxValue;
+ private final Comparable<?> maxValue;
// As this instance is immutable, these two values need only
@@ -450,7 +450,7 @@
}
static void check(OpenMBeanParameterInfo info) throws OpenDataException {
- OpenType openType = info.getOpenType();
+ OpenType<?> openType = info.getOpenType();
if (openType == null)
throw new IllegalArgumentException("OpenType cannot be null");
@@ -562,7 +562,7 @@
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "rawtypes"})
static int compare(Object x, Object y) {
return ((Comparable) x).compareTo(y);
}
@@ -657,11 +657,11 @@
return result;
}
- static <T> Comparable comparableValueFrom(Descriptor d, String name,
- OpenType<T> openType) {
+ static <T> Comparable<?> comparableValueFrom(Descriptor d, String name,
+ OpenType<T> openType) {
T t = valueFrom(d, name, openType);
if (t == null || t instanceof Comparable<?>)
- return (Comparable) t;
+ return (Comparable<?>) t;
final String msg =
"Descriptor field " + name + " with value " + t +
" is not Comparable";
@@ -925,7 +925,7 @@
return isValue(this, obj);
}
- @SuppressWarnings("unchecked") // cast to Comparable
+ @SuppressWarnings({"unchecked", "rawtypes"}) // cast to Comparable
static boolean isValue(OpenMBeanParameterInfo info, Object obj) {
if (info.hasDefaultValue() && obj == null)
return true;
--- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanParameterInfoSupport.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanParameterInfoSupport.java Wed Jul 05 16:43:43 2017 +0200
@@ -74,12 +74,12 @@
/**
* @serial The open mbean parameter's min value
*/
- private Comparable minValue = null;
+ private Comparable<?> minValue = null;
/**
* @serial The open mbean parameter's max value
*/
- private Comparable maxValue = null;
+ private Comparable<?> maxValue = null;
// As this instance is immutable, these two values need only
--- a/jdk/src/share/classes/javax/management/openmbean/OpenType.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/OpenType.java Wed Jul 05 16:43:43 2017 +0200
@@ -206,7 +206,7 @@
}
}
- private static boolean overridesGetClassName(final Class<? extends OpenType> c) {
+ private static boolean overridesGetClassName(final Class<?> c) {
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
try {
--- a/jdk/src/share/classes/javax/management/openmbean/SimpleType.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/SimpleType.java Wed Jul 05 16:43:43 2017 +0200
@@ -163,7 +163,7 @@
public static final SimpleType<ObjectName> OBJECTNAME =
new SimpleType<ObjectName>(ObjectName.class);
- private static final SimpleType[] typeArray = {
+ private static final SimpleType<?>[] typeArray = {
VOID, BOOLEAN, CHARACTER, BYTE, SHORT, INTEGER, LONG, FLOAT,
DOUBLE, STRING, BIGDECIMAL, BIGINTEGER, DATE, OBJECTNAME,
};
@@ -232,10 +232,10 @@
return (this == obj);
*/
- if (!(obj instanceof SimpleType))
+ if (!(obj instanceof SimpleType<?>))
return false;
- SimpleType other = (SimpleType) obj;
+ SimpleType<?> other = (SimpleType<?>) obj;
// Test if other's className field is the same as for this instance
//
@@ -290,11 +290,11 @@
return myToString;
}
- private static final Map<SimpleType,SimpleType> canonicalTypes =
- new HashMap<SimpleType,SimpleType>();
+ private static final Map<SimpleType<?>,SimpleType<?>> canonicalTypes =
+ new HashMap<SimpleType<?>,SimpleType<?>>();
static {
for (int i = 0; i < typeArray.length; i++) {
- final SimpleType type = typeArray[i];
+ final SimpleType<?> type = typeArray[i];
canonicalTypes.put(type, type);
}
}
@@ -310,7 +310,7 @@
* resolved.
*/
public Object readResolve() throws ObjectStreamException {
- final SimpleType canonical = canonicalTypes.get(this);
+ final SimpleType<?> canonical = canonicalTypes.get(this);
if (canonical == null) {
// Should not happen
throw new InvalidObjectException("Invalid SimpleType: " + this);
--- a/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java Wed Jul 05 16:43:43 2017 +0200
@@ -30,6 +30,7 @@
// java import
//
import com.sun.jmx.mbeanserver.GetPropertyAction;
+import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
@@ -611,7 +612,7 @@
@SuppressWarnings("unchecked") // historical confusion about the return type
public Collection<Object> values() {
- return (Collection) dataMap.values() ;
+ return Util.cast(dataMap.values());
}
@@ -647,7 +648,7 @@
@SuppressWarnings("unchecked") // historical confusion about the return type
public Set<Map.Entry<Object,Object>> entrySet() {
- return (Set) dataMap.entrySet();
+ return Util.cast(dataMap.entrySet());
}
@@ -725,8 +726,7 @@
if (this.size() != other.size()) {
return false;
}
- for (Iterator iter = this.values().iterator(); iter.hasNext(); ) {
- CompositeData value = (CompositeData) iter.next();
+ for (CompositeData value : dataMap.values()) {
if ( ! other.containsValue(value) ) {
return false;
}
@@ -760,9 +760,8 @@
int result = 0;
result += this.tabularType.hashCode();
- for (Iterator iter = this.values().iterator(); iter.hasNext(); ) {
- result += ((CompositeData)iter.next()).hashCode();
- }
+ for (Object value : values())
+ result += value.hashCode();
return result;
--- a/jdk/src/share/classes/javax/management/openmbean/TabularType.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/openmbean/TabularType.java Wed Jul 05 16:43:43 2017 +0200
@@ -237,7 +237,7 @@
}
@Override
- boolean isAssignableFrom(OpenType ot) {
+ boolean isAssignableFrom(OpenType<?> ot) {
if (!(ot instanceof TabularType))
return false;
TabularType tt = (TabularType) ot;
@@ -329,9 +329,8 @@
int value = 0;
value += this.getTypeName().hashCode();
value += this.rowType.hashCode();
- for (Iterator k = indexNames.iterator(); k.hasNext(); ) {
- value += k.next().hashCode();
- }
+ for (String index : indexNames)
+ value += index.hashCode();
myHashCode = Integer.valueOf(value);
}
@@ -364,12 +363,10 @@
.append(",rowType=")
.append(rowType.toString())
.append(",indexNames=(");
- int i=0;
- Iterator k = indexNames.iterator();
- while( k.hasNext() ) {
- if (i > 0) result.append(",");
- result.append(k.next().toString());
- i++;
+ String sep = "";
+ for (String index : indexNames) {
+ result.append(sep).append(index);
+ sep = ",";
}
result.append("))");
myToString = result.toString();
--- a/jdk/src/share/classes/javax/management/relation/MBeanServerNotificationFilter.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/MBeanServerNotificationFilter.java Wed Jul 05 16:43:43 2017 +0200
@@ -354,7 +354,7 @@
// Checks the type first
String ntfType = notif.getType();
- Vector enabledTypes = getEnabledTypes();
+ Vector<String> enabledTypes = getEnabledTypes();
if (!(enabledTypes.contains(ntfType))) {
RELATION_LOGGER.logp(Level.FINER,
MBeanServerNotificationFilter.class.getName(),
@@ -464,8 +464,8 @@
// Serializes this instance in the old serial form
//
ObjectOutputStream.PutField fields = out.putFields();
- fields.put("mySelectObjNameList", (Vector)selectedNames);
- fields.put("myDeselectObjNameList", (Vector)deselectedNames);
+ fields.put("mySelectObjNameList", selectedNames);
+ fields.put("myDeselectObjNameList", deselectedNames);
out.writeFields();
}
else
--- a/jdk/src/share/classes/javax/management/relation/RelationService.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/RelationService.java Wed Jul 05 16:43:43 2017 +0200
@@ -1111,7 +1111,7 @@
throw new IllegalArgumentException(excMsg);
}
- if (!(oldValue instanceof ArrayList))
+ if (!(oldValue instanceof ArrayList<?>))
oldValue = new ArrayList<ObjectName>(oldValue);
RELATION_LOGGER.entering(RelationService.class.getName(),
@@ -1881,7 +1881,7 @@
"getRole",
params,
signature));
- if (invokeResult == null || invokeResult instanceof ArrayList)
+ if (invokeResult == null || invokeResult instanceof ArrayList<?>)
result = invokeResult;
else
result = new ArrayList<ObjectName>(invokeResult);
@@ -2786,7 +2786,7 @@
// Note that it is possible that the MBean has already been removed
// from the internal map: this is the case when the MBean is
// unregistered, the role is updated, then we arrive here.
- HashMap mbeanRefMap = (HashMap)
+ Map<String,List<String>> mbeanRefMap =
(myRefedMBeanObjName2RelIdsMap.get(objectName));
if (mbeanRefMap == null) {
@@ -2796,11 +2796,11 @@
return true;
}
- ArrayList roleNames = new ArrayList();
+ List<String> roleNames = null;
if (!allRolesFlag) {
// Now retrieves the roles of current relation where the MBean
// was referenced
- roleNames = (ArrayList)(mbeanRefMap.get(relationId));
+ roleNames = mbeanRefMap.get(relationId);
// Removes obsolete reference to role
int obsRefIdx = roleNames.indexOf(roleName);
@@ -2840,8 +2840,8 @@
//
// -exception RelationServiceNotRegisteredException if the Relation
// Service is not registered in the MBean Server.
- private void updateUnregistrationListener(List newRefList,
- List obsoleteRefList)
+ private void updateUnregistrationListener(List<ObjectName> newRefList,
+ List<ObjectName> obsoleteRefList)
throws RelationServiceNotRegisteredException {
if (newRefList != null && obsoleteRefList != null) {
@@ -2871,24 +2871,14 @@
// Enables ObjectNames in newRefList
if (newRefList != null) {
- for (Iterator newRefIter = newRefList.iterator();
- newRefIter.hasNext();) {
-
- ObjectName newObjName = (ObjectName)
- (newRefIter.next());
+ for (ObjectName newObjName : newRefList)
myUnregNtfFilter.enableObjectName(newObjName);
- }
}
if (obsoleteRefList != null) {
// Disables ObjectNames in obsoleteRefList
- for (Iterator obsRefIter = obsoleteRefList.iterator();
- obsRefIter.hasNext();) {
-
- ObjectName obsObjName = (ObjectName)
- (obsRefIter.next());
+ for (ObjectName obsObjName : obsoleteRefList)
myUnregNtfFilter.disableObjectName(obsObjName);
- }
}
// Under test
@@ -3047,18 +3037,13 @@
// to see which roles have not been initialized
// Note: no need to test if list not null before cloning, not allowed
// to have an empty relation type.
- ArrayList roleInfoList = (ArrayList)
- (((ArrayList)(relType.getRoleInfos())).clone());
+ List<RoleInfo> roleInfoList = new ArrayList<RoleInfo>(relType.getRoleInfos());
if (roleList != null) {
- for (Iterator roleIter = roleList.iterator();
- roleIter.hasNext();) {
-
- Role currRole = (Role)(roleIter.next());
+ for (Role currRole : roleList.asList()) {
String currRoleName = currRole.getRoleName();
- ArrayList currRoleValue = (ArrayList)
- (currRole.getRoleValue());
+ List<ObjectName> currRoleValue = currRole.getRoleValue();
// Retrieves corresponding role info
// Can throw a RoleInfoNotFoundException to be converted into a
// RoleNotFoundException
@@ -3137,9 +3122,7 @@
// Only role list parameter used, as default initialization of roles
// done automatically in initializeMissingRoles() sets each
// uninitialized role to an empty value.
- for (Iterator roleIter = roleList.iterator();
- roleIter.hasNext();) {
- Role currRole = (Role)(roleIter.next());
+ for (Role currRole : roleList.asList()) {
// Creates a dummy empty ArrayList of ObjectNames to be the old
// role value :)
List<ObjectName> dummyList = new ArrayList<ObjectName>();
@@ -3191,7 +3174,7 @@
// -exception IllegalArgumentException if null parameter
private Integer checkRoleInt(int chkType,
String roleName,
- List roleValue,
+ List<ObjectName> roleValue,
RoleInfo roleInfo,
boolean writeChkFlag)
throws IllegalArgumentException {
@@ -3266,9 +3249,7 @@
// registered in the same MBean Server.
String expClassName = roleInfo.getRefMBeanClassName();
- for (Iterator refMBeanIter = roleValue.iterator();
- refMBeanIter.hasNext();) {
- ObjectName currObjName = (ObjectName)(refMBeanIter.next());
+ for (ObjectName currObjName : roleValue) {
// Checks it is registered
if (currObjName == null) {
@@ -3330,7 +3311,7 @@
ObjectName relationObjName,
String relationId,
String relationTypeName,
- List roleInfoList)
+ List<RoleInfo> roleInfoList)
throws IllegalArgumentException,
RelationServiceNotRegisteredException,
InvalidRoleValueException {
@@ -3361,10 +3342,8 @@
// with an empty list of ObjectNames.
// A check is performed to verify that the role can be set to an
// empty value, according to its minimum cardinality
- for (Iterator roleInfoIter = roleInfoList.iterator();
- roleInfoIter.hasNext();) {
-
- RoleInfo currRoleInfo = (RoleInfo)(roleInfoIter.next());
+ for (RoleInfo currRoleInfo : roleInfoList) {
+
String roleName = currRoleInfo.getName();
// Creates an empty value
@@ -3663,7 +3642,7 @@
// not exist in the relation
private void handleReferenceUnregistration(String relationId,
ObjectName objectName,
- List roleNameList)
+ List<String> roleNameList)
throws IllegalArgumentException,
RelationServiceNotRegisteredException,
RelationNotFoundException,
@@ -3694,14 +3673,12 @@
// Flag to specify if the relation has to be deleted
boolean deleteRelFlag = false;
- for (Iterator roleNameIter = roleNameList.iterator();
- roleNameIter.hasNext();) {
+ for (String currRoleName : roleNameList) {
if (deleteRelFlag) {
break;
}
- String currRoleName = (String)(roleNameIter.next());
// Retrieves number of MBeans currently referenced in role
// BEWARE! Do not use getRole() as role may be not readable
//
@@ -3753,10 +3730,7 @@
// using setRole(). So the Relation Service will update the
// myRefedMBeanObjName2RelIdsMap to refelect the new role
// value!
- for (Iterator roleNameIter = roleNameList.iterator();
- roleNameIter.hasNext();) {
-
- String currRoleName = (String)(roleNameIter.next());
+ for (String currRoleName : roleNameList) {
if (relObj instanceof RelationSupport) {
// Internal relation
--- a/jdk/src/share/classes/javax/management/relation/RelationSupport.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/RelationSupport.java Wed Jul 05 16:43:43 2017 +0200
@@ -108,7 +108,7 @@
// via Relation Service setRole() and setRoles() methods
// - if the relation is internal to the Relation Service, via
// setRoleInt() and setRolesInt() methods.
- private Map<String,Role> myRoleName2ValueMap = new HashMap<String,Role>();
+ private final Map<String,Role> myRoleName2ValueMap = new HashMap<String,Role>();
// Flag to indicate if the object has been added in the Relation Service
private final AtomicBoolean myInRelServFlg = new AtomicBoolean();
@@ -424,7 +424,7 @@
}
}
- ArrayList roleValue = (ArrayList)(role.getRoleValue());
+ List<ObjectName> roleValue = role.getRoleValue();
RELATION_LOGGER.exiting(RelationSupport.class.getName(),
"getRoleCardinality");
@@ -855,8 +855,7 @@
// Note: no need to test if role value (list) not null before
// cloning, null value not allowed, empty list if
// nothing.
- result = (ArrayList)
- (((ArrayList)(role.getRoleValue())).clone());
+ result = new ArrayList<ObjectName>(role.getRoleValue());
} else {
// Role retrieved during multi-role retrieval: returns the
@@ -1492,10 +1491,7 @@
RoleList roleList = new RoleList();
RoleUnresolvedList roleUnresList = new RoleUnresolvedList();
- for (Iterator roleIter = list.iterator();
- roleIter.hasNext();) {
-
- Role currRole = (Role)(roleIter.next());
+ for (Role currRole : list.asList()) {
Object currResult = null;
// Can throw:
@@ -1617,12 +1613,10 @@
synchronized(myRoleName2ValueMap) {
- for (Iterator roleIter = list.iterator();
- roleIter.hasNext();) {
+ for (Role currRole : list.asList()) {
// No need to check if role is null, it is not allowed to store
// a null role in a RoleList :)
- Role currRole = (Role)(roleIter.next());
String currRoleName = currRole.getRoleName();
if (myRoleName2ValueMap.containsKey(currRoleName)) {
--- a/jdk/src/share/classes/javax/management/relation/Role.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/Role.java Wed Jul 05 16:43:43 2017 +0200
@@ -228,9 +228,9 @@
public String toString() {
StringBuilder result = new StringBuilder();
result.append("role name: " + name + "; role value: ");
- for (Iterator objNameIter = objectNameList.iterator();
+ for (Iterator<ObjectName> objNameIter = objectNameList.iterator();
objNameIter.hasNext();) {
- ObjectName currObjName = (ObjectName)(objNameIter.next());
+ ObjectName currObjName = objNameIter.next();
result.append(currObjName.toString());
if (objNameIter.hasNext()) {
result.append(", ");
@@ -325,7 +325,7 @@
//
ObjectOutputStream.PutField fields = out.putFields();
fields.put("myName", name);
- fields.put("myObjNameList", (ArrayList)objectNameList);
+ fields.put("myObjNameList", objectNameList);
out.writeFields();
}
else
--- a/jdk/src/share/classes/javax/management/relation/RoleList.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/RoleList.java Wed Jul 05 16:43:43 2017 +0200
@@ -25,6 +25,7 @@
package javax.management.relation;
+import com.sun.jmx.mbeanserver.Util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -140,7 +141,7 @@
checkTypeSafe(this);
typeSafe = true;
}
- return (List<Role>) (List) this;
+ return Util.cast(this);
}
//
--- a/jdk/src/share/classes/javax/management/relation/RoleResult.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/RoleResult.java Wed Jul 05 16:43:43 2017 +0200
@@ -172,7 +172,7 @@
roleList = new RoleList();
- for (Iterator roleIter = list.iterator();
+ for (Iterator<?> roleIter = list.iterator();
roleIter.hasNext();) {
Role currRole = (Role)(roleIter.next());
roleList.add((Role)(currRole.clone()));
@@ -195,7 +195,7 @@
unresolvedRoleList = new RoleUnresolvedList();
- for (Iterator roleUnresIter = unresolvedList.iterator();
+ for (Iterator<?> roleUnresIter = unresolvedList.iterator();
roleUnresIter.hasNext();) {
RoleUnresolved currRoleUnres =
(RoleUnresolved)(roleUnresIter.next());
--- a/jdk/src/share/classes/javax/management/relation/RoleUnresolved.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/RoleUnresolved.java Wed Jul 05 16:43:43 2017 +0200
@@ -285,9 +285,9 @@
result.append("role name: " + roleName);
if (roleValue != null) {
result.append("; value: ");
- for (Iterator objNameIter = roleValue.iterator();
+ for (Iterator<ObjectName> objNameIter = roleValue.iterator();
objNameIter.hasNext();) {
- ObjectName currObjName = (ObjectName)(objNameIter.next());
+ ObjectName currObjName = objNameIter.next();
result.append(currObjName.toString());
if (objNameIter.hasNext()) {
result.append(", ");
@@ -344,7 +344,7 @@
//
ObjectOutputStream.PutField fields = out.putFields();
fields.put("myRoleName", roleName);
- fields.put("myRoleValue", (ArrayList)roleValue);
+ fields.put("myRoleValue", roleValue);
fields.put("myPbType", problemType);
out.writeFields();
}
--- a/jdk/src/share/classes/javax/management/relation/RoleUnresolvedList.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/relation/RoleUnresolvedList.java Wed Jul 05 16:43:43 2017 +0200
@@ -25,6 +25,7 @@
package javax.management.relation;
+import com.sun.jmx.mbeanserver.Util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -140,7 +141,7 @@
checkTypeSafe(this);
typeSafe = true;
}
- return (List<RoleUnresolved>) (List) this;
+ return Util.cast(this);
}
//
--- a/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java Wed Jul 05 16:43:43 2017 +0200
@@ -367,7 +367,8 @@
return provider.newJMXConnector(serviceURL, fixedenv);
}
- private static String resolvePkgs(Map env) throws JMXProviderException {
+ private static String resolvePkgs(Map<String, ?> env)
+ throws JMXProviderException {
Object pkgsObject = null;
@@ -521,7 +522,7 @@
return null;
}
- static ClassLoader resolveClassLoader(Map environment) {
+ static ClassLoader resolveClassLoader(Map<String, ?> environment) {
ClassLoader loader = null;
if (environment != null) {
--- a/jdk/src/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java Wed Jul 05 16:43:43 2017 +0200
@@ -118,7 +118,8 @@
* if it is one of the classes whose byte code we have, or
* delegate the load if it is one of the referenced classes.
*/
- protected Class findClass(String name) throws ClassNotFoundException {
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
for (int i = 0; i < classNames.length; i++) {
if (name.equals(classNames[i])) {
return defineClass(classNames[i], byteCodes[i], 0,
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnection.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnection.java Wed Jul 05 16:43:43 2017 +0200
@@ -31,7 +31,6 @@
import java.rmi.Remote;
import java.util.Set;
-import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
@@ -45,11 +44,11 @@
import javax.management.MBeanServerConnection;
import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
-import javax.management.QueryExp;
import javax.management.ReflectionException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeOperationsException;
import javax.management.remote.NotificationResult;
import javax.security.auth.Subject;
@@ -89,8 +88,9 @@
* even though it would add useful information to the documentation. The
* reason is that it was only added in Mustang (Java SE 6), whereas versions
* 1.4 and 2.0 of the JMX API must be implementable on Tiger per our
- * commitments for JSR 255.
+ * commitments for JSR 255. This is also why we suppress rawtypes warnings.
*/
+@SuppressWarnings("rawtypes")
public interface RMIConnection extends Closeable, Remote {
/**
* <p>Returns the connection ID. This string is different for
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Wed Jul 05 16:43:43 2017 +0200
@@ -308,6 +308,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public ObjectInstance createMBean(String className,
ObjectName name,
MarshalledObject params,
@@ -368,6 +369,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public ObjectInstance createMBean(String className,
ObjectName name,
ObjectName loaderName,
@@ -493,6 +495,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public Set<ObjectInstance>
queryMBeans(ObjectName name,
MarshalledObject query,
@@ -527,6 +530,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public Set<ObjectName>
queryNames(ObjectName name,
MarshalledObject query,
@@ -668,6 +672,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public void setAttribute(ObjectName name,
MarshalledObject attribute,
Subject delegationSubject)
@@ -720,6 +725,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public AttributeList setAttributes(ObjectName name,
MarshalledObject attributes,
Subject delegationSubject)
@@ -765,6 +771,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public Object invoke(ObjectName name,
String operationName,
MarshalledObject params,
@@ -928,6 +935,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public Integer[] addNotificationListeners(ObjectName[] names,
MarshalledObject[] filters,
Subject[] delegationSubjects)
@@ -1013,6 +1021,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public void addNotificationListener(ObjectName name,
ObjectName listener,
MarshalledObject filter,
@@ -1148,6 +1157,7 @@
}
}
+ @SuppressWarnings("rawtypes") // MarshalledObject
public void removeNotificationListener(ObjectName name,
ObjectName listener,
MarshalledObject filter,
@@ -1809,7 +1819,7 @@
}
}
- private static <T> T unwrap(final MarshalledObject mo,
+ private static <T> T unwrap(final MarshalledObject<?> mo,
final ClassLoader cl,
final Class<T> wrappedClass)
throws IOException {
@@ -1847,7 +1857,7 @@
return null;
}
- private static <T> T unwrap(final MarshalledObject mo,
+ private static <T> T unwrap(final MarshalledObject<?> mo,
final ClassLoader cl1,
final ClassLoader cl2,
final Class<T> wrappedClass)
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Wed Jul 05 16:43:43 2017 +0200
@@ -28,6 +28,7 @@
import com.sun.jmx.event.DaemonThreadFactory;
import com.sun.jmx.event.EventConnection;
import com.sun.jmx.mbeanserver.PerThreadGroupPool;
+import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
import com.sun.jmx.remote.internal.ClientListenerInfo;
import com.sun.jmx.remote.internal.ClientNotifForwarder;
@@ -584,7 +585,7 @@
// added for re-connection
private Integer addListenerWithSubject(ObjectName name,
- MarshalledObject filter,
+ MarshalledObject<NotificationFilter> filter,
Subject delegationSubject,
boolean reconnect)
throws InstanceNotFoundException, IOException {
@@ -595,7 +596,8 @@
"(ObjectName,MarshalledObject,Subject)");
final ObjectName[] names = new ObjectName[] {name};
- final MarshalledObject[] filters = new MarshalledObject[] {filter};
+ final MarshalledObject<NotificationFilter>[] filters =
+ Util.cast(new MarshalledObject<?>[] {filter});
final Subject[] delegationSubjects = new Subject[] {
delegationSubject
};
@@ -611,7 +613,7 @@
// added for re-connection
private Integer[] addListenersWithSubjects(ObjectName[] names,
- MarshalledObject[] filters,
+ MarshalledObject<NotificationFilter>[] filters,
Subject[] delegationSubjects,
boolean reconnect)
throws InstanceNotFoundException, IOException {
@@ -1362,7 +1364,7 @@
//--------------------------------------------------------------------
private class RMINotifClient extends ClientNotifForwarder {
- public RMINotifClient(ClassLoader cl, Map env) {
+ public RMINotifClient(ClassLoader cl, Map<String, ?> env) {
super(cl, env);
}
@@ -1444,8 +1446,8 @@
Integer[] listenerIDs;
final ObjectName[] names =
new ObjectName[] {MBeanServerDelegate.DELEGATE_NAME};
- final MarshalledObject[] filters =
- new MarshalledObject[] {sFilter};
+ final MarshalledObject<NotificationFilter>[] filters =
+ Util.cast(new MarshalledObject<?>[] {sFilter});
final Subject[] subjects = new Subject[] {null};
try {
listenerIDs =
@@ -1580,7 +1582,8 @@
final ObjectName[] names = new ObjectName[len];
final NotificationListener[] listeners = new NotificationListener[len];
final NotificationFilter[] filters = new NotificationFilter[len];
- final MarshalledObject[] mFilters = new MarshalledObject[len];
+ final MarshalledObject<NotificationFilter>[] mFilters =
+ Util.cast(new MarshalledObject<?>[len]);
final Object[] handbacks = new Object[len];
for (i=0;i<len;i++) {
@@ -1742,7 +1745,7 @@
* @exception IOException if the connection to the ORB failed.
**/
static RMIServer connectStub(RMIServer rmiServer,
- Map environment)
+ Map<String, ?> environment)
throws IOException {
if (rmiServer instanceof javax.rmi.CORBA.Stub) {
javax.rmi.CORBA.Stub stub = (javax.rmi.CORBA.Stub) rmiServer;
@@ -1776,7 +1779,7 @@
* does not point to an {@link org.omg.CORBA.ORB ORB}.
* @exception IOException if the ORB initialization failed.
**/
- static ORB resolveOrb(Map environment)
+ static ORB resolveOrb(Map<String, ?> environment)
throws IOException {
if (environment != null) {
final Object orb = environment.get(EnvHelp.DEFAULT_ORB);
@@ -2004,7 +2007,7 @@
}
}
- private RMIServer findRMIServerIIOP(String ior, Map env, boolean isIiop) {
+ private RMIServer findRMIServerIIOP(String ior, Map<String, ?> env, boolean isIiop) {
// could forbid "rmi:" URL here -- but do we need to?
final ORB orb = (ORB)
env.get(EnvHelp.DEFAULT_ORB);
@@ -2012,7 +2015,7 @@
return (RMIServer) PortableRemoteObject.narrow(stub, RMIServer.class);
}
- private RMIServer findRMIServerJRMP(String base64, Map env, boolean isIiop)
+ private RMIServer findRMIServerJRMP(String base64, Map<String, ?> env, boolean isIiop)
throws IOException {
// could forbid "iiop:" URL here -- but do we need to?
final byte[] serialized;
@@ -2046,7 +2049,8 @@
this.loader = cl;
}
- protected Class resolveClass(ObjectStreamClass classDesc)
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass classDesc)
throws IOException, ClassNotFoundException {
return Class.forName(classDesc.getName(), false, loader);
}
@@ -2121,13 +2125,13 @@
private static final String rmiServerImplStubClassName =
RMIServer.class.getName() + "Impl_Stub";
- private static final Class rmiServerImplStubClass;
+ private static final Class<?> rmiServerImplStubClass;
private static final String rmiConnectionImplStubClassName =
RMIConnection.class.getName() + "Impl_Stub";
private static final Class<?> rmiConnectionImplStubClass;
private static final String pRefClassName =
"com.sun.jmx.remote.internal.PRef";
- private static final Constructor proxyRefConstructor;
+ private static final Constructor<?> proxyRefConstructor;
static {
final String pRefByteCodeString =
"\312\376\272\276\0\0\0.\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17\0"+
@@ -2162,7 +2166,7 @@
}
};
- Class serverStubClass;
+ Class<?> serverStubClass;
try {
serverStubClass = Class.forName(rmiServerImplStubClassName);
} catch (Exception e) {
@@ -2175,10 +2179,10 @@
rmiServerImplStubClass = serverStubClass;
Class<?> stubClass;
- Constructor constr;
+ Constructor<?> constr;
try {
stubClass = Class.forName(rmiConnectionImplStubClassName);
- constr = (Constructor) AccessController.doPrivileged(action);
+ constr = (Constructor<?>) AccessController.doPrivileged(action);
} catch (Exception e) {
logger.error("<clinit>",
"Failed to initialize proxy reference constructor "+
@@ -2198,9 +2202,8 @@
RemoteRef ref = stub.getRef();
RemoteRef proxyRef = (RemoteRef)
proxyRefConstructor.newInstance(new Object[] {ref});
- final Class[] constrTypes = {RemoteRef.class};
- final Constructor rmiConnectionImplStubConstructor =
- rmiConnectionImplStubClass.getConstructor(constrTypes);
+ final Constructor<?> rmiConnectionImplStubConstructor =
+ rmiConnectionImplStubClass.getConstructor(RemoteRef.class);
Object[] args = {proxyRef};
RMIConnection proxyStub = (RMIConnection)
rmiConnectionImplStubConstructor.newInstance(args);
@@ -2328,7 +2331,7 @@
"com.sun.jmx.remote.internal.ProxyStub";
private static final String pInputStreamClassName =
"com.sun.jmx.remote.internal.PInputStream";
- private static final Class proxyStubClass;
+ private static final Class<?> proxyStubClass;
static {
final String proxyStubByteCodeString =
"\312\376\272\276\0\0\0.\0)\12\0\14\0\26\7\0\27\12\0\14\0\30\12"+
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Wed Jul 05 16:43:43 2017 +0200
@@ -423,7 +423,7 @@
try {
if (tracing) logger.trace("start", "binding to " + jndiUrl);
- final Hashtable usemap = EnvHelp.mapToHashtable(attributes);
+ final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
bind(jndiUrl, usemap, objref, rebind);
@@ -555,7 +555,7 @@
logger.trace("stop",
"unbind from external directory: " + boundJndiUrl);
- final Hashtable usemap = EnvHelp.mapToHashtable(attributes);
+ final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
InitialContext ctx =
new InitialContext(usemap);
@@ -655,7 +655,7 @@
* @param rmiServer The object to bind in the registry
* @param rebind true if the object must be rebound.
**/
- void bind(String jndiUrl, Hashtable attributes,
+ void bind(String jndiUrl, Hashtable<?, ?> attributes,
RMIServer rmiServer, boolean rebind)
throws NamingException, MalformedURLException {
// if jndiURL is not null, we nust bind the stub to a
@@ -692,7 +692,8 @@
* @param attributes A Map containing environment parameters,
* built from the Map specified at this object creation.
**/
- private void encodeStubInAddress(RMIServer rmiServer, Map attributes)
+ private void encodeStubInAddress(
+ RMIServer rmiServer, Map<String, ?> attributes)
throws IOException {
final String protocol, host;
@@ -735,14 +736,16 @@
/**
* Returns the IOR of the given rmiServer.
**/
- static String encodeStub(RMIServer rmiServer, Map env) throws IOException {
+ static String encodeStub(
+ RMIServer rmiServer, Map<String, ?> env) throws IOException {
if (rmiServer instanceof javax.rmi.CORBA.Stub)
return "/ior/" + encodeIIOPStub(rmiServer, env);
else
return "/stub/" + encodeJRMPStub(rmiServer, env);
}
- static String encodeJRMPStub(RMIServer rmiServer, Map env)
+ static String encodeJRMPStub(
+ RMIServer rmiServer, Map<String, ?> env)
throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
@@ -752,7 +755,8 @@
return byteArrayToBase64(bytes);
}
- static String encodeIIOPStub(RMIServer rmiServer, Map env)
+ static String encodeIIOPStub(
+ RMIServer rmiServer, Map<String, ?> env)
throws IOException {
try {
javax.rmi.CORBA.Stub stub =
@@ -767,7 +771,8 @@
* Object that we will bind to the registry.
* This object is a stub connected to our RMIServerImpl.
**/
- private static RMIServer objectToBind(RMIServerImpl rmiServer, Map env)
+ private static RMIServer objectToBind(
+ RMIServerImpl rmiServer, Map<String, ?> env)
throws IOException {
return RMIConnector.
connectStub((RMIServer)rmiServer.toStub(),env);
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java Wed Jul 05 16:43:43 2017 +0200
@@ -75,7 +75,7 @@
* to an empty Map.
*/
public RMIServerImpl(Map<String,?> env) {
- this.env = (env == null) ? Collections.EMPTY_MAP : env;
+ this.env = (env == null) ? Collections.<String,Object>emptyMap() : env;
}
void setRMIConnectorServer(RMIConnectorServer connServer)
@@ -337,8 +337,9 @@
synchronized (clientList) {
dropDeadReferences();
- for (Iterator it = clientList.iterator(); it.hasNext(); ) {
- WeakReference wr = (WeakReference) it.next();
+ for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
+ it.hasNext(); ) {
+ WeakReference<RMIConnection> wr = it.next();
if (wr.get() == client) {
it.remove();
break;
@@ -417,9 +418,10 @@
dropDeadReferences(), this will usually be the first
element of the list, but a garbage collection could have
happened in between. */
- for (Iterator it = clientList.iterator(); it.hasNext(); ) {
- WeakReference wr = (WeakReference) it.next();
- RMIConnection client = (RMIConnection) wr.get();
+ for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
+ it.hasNext(); ) {
+ WeakReference<RMIConnection> wr = it.next();
+ RMIConnection client = wr.get();
it.remove();
if (client != null) {
try {
@@ -475,10 +477,10 @@
buf.append("//").append(clientHost);
buf.append(" ");
if (subject != null) {
- Set principals = subject.getPrincipals();
+ Set<Principal> principals = subject.getPrincipals();
String sep = "";
- for (Iterator it = principals.iterator(); it.hasNext(); ) {
- Principal p = (Principal) it.next();
+ for (Iterator<Principal> it = principals.iterator(); it.hasNext(); ) {
+ Principal p = it.next();
String name = p.getName().replace(' ', '_').replace(';', ':');
buf.append(sep).append(name);
sep = ";";
@@ -492,8 +494,9 @@
private void dropDeadReferences() {
synchronized (clientList) {
- for (Iterator it = clientList.iterator(); it.hasNext(); ) {
- WeakReference wr = (WeakReference) it.next();
+ for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
+ it.hasNext(); ) {
+ WeakReference<RMIConnection> wr = it.next();
if (wr.get() == null)
it.remove();
}
@@ -522,7 +525,7 @@
private MBeanServer mbeanServer;
- private final Map env;
+ private final Map<String, ?> env;
private RMIConnectorServer connServer;
--- a/jdk/src/share/classes/javax/management/timer/Timer.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/javax/management/timer/Timer.java Wed Jul 05 16:43:43 2017 +0200
@@ -248,8 +248,7 @@
*/
public synchronized MBeanNotificationInfo[] getNotificationInfo() {
Set<String> notifTypes = new TreeSet<String>();
- for (Iterator it = timerTable.values().iterator(); it.hasNext(); ) {
- Object[] entry = (Object[]) it.next();
+ for (Object[] entry : timerTable.values()) {
TimerNotification notif = (TimerNotification)
entry[TIMER_NOTIF_INDEX];
notifTypes.add(notif.getType());
--- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Wed Jul 05 16:43:43 2017 +0200
@@ -43,7 +43,7 @@
String method;
URI uri;
HttpConnection connection;
- int reqContentLen;
+ long reqContentLen;
long rspContentLen;
/* raw streams which access the socket directly */
InputStream ris;
@@ -79,7 +79,7 @@
ServerImpl server;
ExchangeImpl (
- String m, URI u, Request req, int len, HttpConnection connection
+ String m, URI u, Request req, long len, HttpConnection connection
) throws IOException {
this.req = req;
this.reqHdrs = req.headers();
@@ -148,7 +148,7 @@
if (uis != null) {
return uis;
}
- if (reqContentLen == -1) {
+ if (reqContentLen == -1L) {
uis_orig = new ChunkedInputStream (this, ris);
uis = uis_orig;
} else {
--- a/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Wed Jul 05 16:43:43 2017 +0200
@@ -37,21 +37,21 @@
*/
class FixedLengthInputStream extends LeftOverInputStream {
- private int remaining;
+ private long remaining;
- FixedLengthInputStream (ExchangeImpl t, InputStream src, int len) {
+ FixedLengthInputStream (ExchangeImpl t, InputStream src, long len) {
super (t, src);
this.remaining = len;
}
protected int readImpl (byte[]b, int off, int len) throws IOException {
- eof = (remaining == 0);
+ eof = (remaining == 0L);
if (eof) {
return -1;
}
if (len > remaining) {
- len = remaining;
+ len = (int)remaining;
}
int n = in.read(b, off, len);
if (n > -1) {
@@ -65,7 +65,7 @@
return 0;
}
int n = in.available();
- return n < remaining? n: remaining;
+ return n < remaining? n: (int)remaining;
}
public boolean markSupported () {return false;}
--- a/jdk/src/share/classes/sun/net/httpserver/Request.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/sun/net/httpserver/Request.java Wed Jul 05 16:43:43 2017 +0200
@@ -53,7 +53,7 @@
do {
startLine = readLine();
/* skip blank lines */
- } while (startLine.equals (""));
+ } while (startLine == null ? false : startLine.equals (""));
}
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Wed Jul 05 16:43:43 2017 +0200
@@ -470,13 +470,13 @@
String version = requestLine.substring (start);
Headers headers = req.headers();
String s = headers.getFirst ("Transfer-encoding");
- int clen = 0;
+ long clen = 0L;
if (s !=null && s.equalsIgnoreCase ("chunked")) {
- clen = -1;
+ clen = -1L;
} else {
s = headers.getFirst ("Content-Length");
if (s != null) {
- clen = Integer.parseInt (s);
+ clen = Long.parseLong(s);
}
}
ctx = contexts.findContext (protocol, uri.getPath());
--- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Wed Jul 05 16:43:43 2017 +0200
@@ -272,14 +272,14 @@
*/
private Method[] getMemberMethods() {
if (memberMethods == null) {
- final Method[] mm = type.getDeclaredMethods();
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- AccessibleObject.setAccessible(mm, true);
- return null;
- }
- });
- memberMethods = mm;
+ memberMethods = AccessController.doPrivileged(
+ new PrivilegedAction<Method[]>() {
+ public Method[] run() {
+ final Method[] mm = type.getDeclaredMethods();
+ AccessibleObject.setAccessible(mm, true);
+ return mm;
+ }
+ });
}
return memberMethods;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/net/httpserver/bugs/FixedLengthInputStream.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6756771
+ * @summary com.sun.net.httpserver.HttpServer should handle POSTs larger than 2Gig
+ */
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetSocketAddress;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.Socket;
+import java.util.logging.*;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+public class FixedLengthInputStream
+{
+ static final long POST_SIZE = 4L * 1024L * 1024L * 1024L; // 4Gig
+
+ /* Remove when CR 6755625 is fixed */
+ static final String requestHeaders = ((new StringBuilder())
+ .append("POST /flis/ HTTP/1.1\r\n")
+ .append("User-Agent: Java/1.7.0\r\n")
+ .append("Host: localhost\r\n")
+ .append("Accept: text/html, image/gif, image/jpeg,")
+ .append( " *; q=.2, */*; q=.2\r\n")
+ .append("Content-Length: 4294967296\r\n\r\n")).toString();
+
+ void test(String[] args) throws IOException {
+ HttpServer httpServer = startHttpServer();
+ int port = httpServer.getAddress().getPort();
+ try {
+ /* Uncomment & when CR 6755625 is fixed, remove socket code
+ URL url = new URL("http://localhost:" + port + "/flis/");
+ HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+ uc.setDoOutput(true);
+ uc.setRequestMethod("POST");
+ uc.setFixedLengthStreamingMode(POST_SIZE);
+ OutputStream os = uc.getOutputStream();
+ */
+
+ Socket socket = new Socket("localhost", port);
+ OutputStream os = socket.getOutputStream();
+ PrintStream ps = new PrintStream(os);
+ debug("Request: " + requestHeaders);
+ ps.print(requestHeaders);
+ ps.flush();
+
+ /* create a 32K byte array with data to POST */
+ int thirtyTwoK = 32 * 1024;
+ byte[] ba = new byte[thirtyTwoK];
+ for (int i =0; i<thirtyTwoK; i++)
+ ba[i] = (byte)i;
+
+ long times = POST_SIZE / thirtyTwoK;
+ for (int i=0; i<times; i++) {
+ os.write(ba);
+ }
+
+ /* Uncomment & when CR 6755625 is fixed, remove socket code
+ os.close();
+ InputStream is = uc.getInputStream();
+ while(is.read(ba) != -1);
+ is.close();
+ */
+
+ InputStream is = socket.getInputStream();
+ is.read();
+ socket.close();
+
+ pass();
+ } finally {
+ httpServer.stop(0);
+ }
+ }
+
+ /**
+ * Http Server
+ */
+ HttpServer startHttpServer() throws IOException {
+ if (debug) {
+ Logger logger =
+ Logger.getLogger("com.sun.net.httpserver");
+ Handler outHandler = new StreamHandler(System.out,
+ new SimpleFormatter());
+ outHandler.setLevel(Level.FINEST);
+ logger.setLevel(Level.FINEST);
+ logger.addHandler(outHandler);
+ }
+ HttpServer httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+ httpServer.createContext("/flis/", new MyHandler(POST_SIZE));
+ httpServer.start();
+ return httpServer;
+ }
+
+ class MyHandler implements HttpHandler {
+ static final int BUFFER_SIZE = 32 * 1024;
+ long expected;
+
+ MyHandler(long expected){
+ this.expected = expected;
+ }
+
+ @Override
+ public void handle(HttpExchange t) throws IOException {
+ InputStream is = t.getRequestBody();
+ byte[] ba = new byte[BUFFER_SIZE];
+ int read;
+ long count = 0L;
+ while((read = is.read(ba)) != -1) {
+ count += read;
+ }
+ is.close();
+
+ check(count == expected, "Expected: " + expected + ", received "
+ + count);
+
+ debug("Received " + count + " bytes");
+
+ t.sendResponseHeaders(200, -1);
+ t.close();
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ boolean debug = true;
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}
+ void debug(String message) {if(debug) { System.out.println(message); } }
+ public static void main(String[] args) throws Throwable {
+ Class<?> k = new Object(){}.getClass().getEnclosingClass();
+ try {k.getMethod("instanceMain",String[].class)
+ .invoke( k.newInstance(), (Object) args);}
+ catch (Throwable e) {throw e.getCause();}}
+ public void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/ParameterAnnotations.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6761678
+ * @summary Check properties of Annotations returned from
+ * getParameterAnnotations, including freedom from security
+ * exceptions.
+ * @author Martin Buchholz
+ */
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.security.Permission;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.FIELD, ElementType.PARAMETER })
+@interface Named {
+ String value();
+}
+
+public class ParameterAnnotations {
+
+ // A security policy that differs from the default only in that it
+ // allows a security manager to be uninstalled.
+ static class MyPolicy extends Policy {
+ final Policy defaultPolicy;
+ MyPolicy(Policy defaultPolicy) {
+ this.defaultPolicy = defaultPolicy;
+ }
+ public boolean implies(ProtectionDomain pd, Permission p) {
+ return p.getName().equals("setSecurityManager") ||
+ defaultPolicy.implies(pd, p);
+ }
+ }
+
+ public void nop(@Named("foo") Object foo,
+ @Named("bar") Object bar) {
+ }
+
+ void test(String[] args) throws Throwable {
+ // Test without a security manager
+ test1();
+
+ // Test with a security manager
+ Policy defaultPolicy = Policy.getPolicy();
+ Policy.setPolicy(new MyPolicy(defaultPolicy));
+ System.setSecurityManager(new SecurityManager());
+ try {
+ test1();
+ } finally {
+ System.setSecurityManager(null);
+ Policy.setPolicy(defaultPolicy);
+ }
+ }
+
+ void test1() throws Throwable {
+ for (Method m : thisClass.getMethods()) {
+ if (m.getName().equals("nop")) {
+ Annotation[][] ann = m.getParameterAnnotations();
+ equal(ann.length, 2);
+ Annotation foo = ann[0][0];
+ Annotation bar = ann[1][0];
+ equal(foo.toString(), "@Named(value=foo)");
+ equal(bar.toString(), "@Named(value=bar)");
+ check(foo.equals(foo));
+ check(! foo.equals(bar));
+ }
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ static Class<?> thisClass = new Object(){}.getClass().getEnclosingClass();
+ public static void main(String[] args) throws Throwable {
+ try {thisClass.getMethod("instanceMain",String[].class)
+ .invoke(thisClass.newInstance(), (Object) args);}
+ catch (Throwable e) {throw e.getCause();}}
+ public void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- a/jdk/test/javax/management/MBeanServer/MBeanExceptionTest.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/test/javax/management/MBeanServer/MBeanExceptionTest.java Wed Jul 05 16:43:43 2017 +0200
@@ -23,16 +23,19 @@
/*
* @test
- * @bug 5035217
+ * @bug 5035217 6766173
* @summary Test that MBean's RuntimeException is wrapped in
* RuntimeMBeanException and (for Standard MBeans) that checked exceptions
* are wrapped in MBeanException
* @author Eamonn McManus
- * @compile -source 1.4 MBeanExceptionTest.java
+ * @compile MBeanExceptionTest.java
* @run main MBeanExceptionTest
*/
+import java.util.Collections;
+import java.util.Set;
import javax.management.*;
+import javax.management.namespace.MBeanServerSupport;
public class MBeanExceptionTest {
public static void main(String[] args) throws Exception {
@@ -56,6 +59,53 @@
failures += test(mbs, standardName, true);
failures += test(mbs, standardMBeanName, true);
failures += test(mbs, dynamicName, false);
+
+ final boolean[] booleans = {false, true};
+
+ for (boolean mbss : booleans) {
+ for (boolean runtimeX : booleans) {
+ Class<? extends Exception> excC =
+ runtimeX ? RuntimeMBeanException.class : MBeanException.class;
+ String excS =
+ runtimeX ? "a RuntimeMBeanException" : "an MBeanException";
+ String mbsS =
+ mbss ? "a conformant MBeanServerSupport" : "a plain MBeanServer";
+ MBeanServer xmbs =
+ mbss ? new CreateExceptionMBS() : mbs;
+ System.out.println(
+ "Test that, with " + mbsS + ", " + excS + " is wrapped " +
+ "in " + excS);
+ // E.g. "Test that, with a plain MBeanServer, an MBeanException
+ // is wrapped in an MBeanException".
+ try {
+ mbs.createMBean(
+ Except.class.getName(), new ObjectName(":name=Oops"),
+ new Object[] {runtimeX},
+ new String[] {boolean.class.getName()});
+ System.out.println(
+ "FAIL: createMBean succeeded but should not have");
+ failures++;
+ } catch (Exception e) {
+ if (!excC.isInstance(e)) {
+ System.out.println(
+ "FAIL: expected " + excC.getName() + " from " +
+ "createMBean, got " + e);
+ failures++;
+ } else {
+ Throwable cause = e.getCause();
+ if (!excC.isInstance(cause)) {
+ System.out.println(
+ "FAIL: expected " + excC.getName() +
+ " as cause of " + excC.getName() +
+ ", got " + e);
+ failures++;
+ } else
+ System.out.println("...ok");
+ }
+ }
+ }
+ }
+
if (failures == 0)
System.out.println("Test passed");
else {
@@ -153,6 +203,15 @@
}
public static class Except implements ExceptMBean {
+ public Except() {}
+
+ public Except(boolean runtimeX) throws MBeanException {
+ if (runtimeX)
+ throw new RuntimeMBeanException(new RuntimeException(), "Bang");
+ else
+ throw new MBeanException(new Exception(), "Bang");
+ }
+
public String getUncheckedException() {
throw theUncheckedException;
}
@@ -221,4 +280,28 @@
private static final RuntimeException theUncheckedException =
new UnsupportedOperationException("The unchecked exception " +
"that should be seen");
+
+ private static class CreateExceptionMBS extends MBeanServerSupport {
+ @Override
+ protected Set<ObjectName> getNames() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public DynamicMBean getDynamicMBeanFor(ObjectName name)
+ throws InstanceNotFoundException {
+ throw new InstanceNotFoundException(name);
+ }
+
+ @Override
+ public ObjectInstance createMBean(String className,
+ ObjectName name, ObjectName loaderName, Object[] params,
+ String[] signature, boolean useCLR)
+ throws ReflectionException, InstanceAlreadyExistsException,
+ MBeanRegistrationException, MBeanException,
+ NotCompliantMBeanException, InstanceNotFoundException {
+ Exception wrapped = new MBeanException(new Exception(), "Bang");
+ throw new MBeanException(wrapped, "Bang");
+ }
+ }
}
--- a/jdk/test/javax/management/eventService/CustomForwarderTest.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/test/javax/management/eventService/CustomForwarderTest.java Wed Jul 05 16:43:43 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test CustomForwarderTest
- * @bug 5108776
+ * @bug 5108776 6759619
* @summary Test that a custom EventForwarder can be added
* @author Eamonn McManus
*/
@@ -45,6 +45,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import javax.management.MBeanNotificationInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerInvocationHandler;
import javax.management.Notification;
@@ -107,6 +108,14 @@
socket.close();
}
+ void simulateNonFatal() {
+ receiver.nonFatal(new Exception("NonFatal"));
+ }
+
+ void simulateFailed() {
+ receiver.failed(new Error("Failed"));
+ }
+
private class Receiver implements Runnable {
public void run() {
byte[] buf = new byte[1024];
@@ -216,16 +225,26 @@
EventClientDelegateMBean.OBJECT_NAME,
EventClientDelegateMBean.class,
false);
- EventRelay relay = new UdpEventRelay(delegate);
+ UdpEventRelay relay = new UdpEventRelay(delegate);
EventClient client = new EventClient(delegate, relay, null, null, 0L);
final Semaphore lostCountSema = new Semaphore(0);
+ final BlockingQueue<Notification> nonFatalNotifs =
+ new ArrayBlockingQueue<Notification>(1);
+ final BlockingQueue<Notification> failedNotifs =
+ new ArrayBlockingQueue<Notification>(1);
NotificationListener lostListener = new NotificationListener() {
public void handleNotification(Notification notification, Object handback) {
if (notification.getType().equals(EventClient.NOTIFS_LOST)) {
System.out.println("Got lost-notifs notif: count=" +
notification.getUserData());
lostCountSema.release(((Long) notification.getUserData()).intValue());
+ } else if (notification.getType().equals(EventClient.NONFATAL)) {
+ System.out.println("Got nonFatal notif");
+ nonFatalNotifs.add(notification);
+ } else if (notification.getType().equals(EventClient.FAILED)) {
+ System.out.println("Got failed notif");
+ failedNotifs.add(notification);
} else
System.out.println("Mysterious EventClient notif: " + notification);
}
@@ -300,6 +319,35 @@
Thread.sleep(10);
assertEquals("Further lost-notifs", 0, lostCountSema.availablePermits());
+ System.out.println("Testing error notifs");
+ relay.simulateNonFatal();
+ n = nonFatalNotifs.poll(10, TimeUnit.SECONDS);
+ assertEquals("Exception message for non-fatal exception", "NonFatal",
+ ((Throwable) n.getSource()).getMessage());
+ relay.simulateFailed();
+ n = failedNotifs.poll(10, TimeUnit.SECONDS);
+ assertEquals("Exception message for failed exception", "Failed",
+ ((Throwable) n.getSource()).getMessage());
+
+ // 6759619
+ System.out.println("Test EventClient.getEventClientNotificationInfo");
+ MBeanNotificationInfo[] mbnis = client.getEventClientNotificationInfo();
+ final String[] expectedTypes = {
+ EventClient.NOTIFS_LOST, EventClient.NONFATAL, EventClient.FAILED
+ };
+ check:
+ for (String type : expectedTypes) {
+ for (MBeanNotificationInfo mbni : mbnis) {
+ for (String t : mbni.getNotifTypes()) {
+ if (type.equals(t)) {
+ System.out.println("...found " + type);
+ continue check;
+ }
+ }
+ }
+ throw new Exception("TEST FAILED: Did not find notif type " + type);
+ }
+
client.close();
System.out.println("TEST PASSED");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,237 @@
+/*
+ * @test
+ * @bug 6713777
+ * @summary Test that exception messages include all relevant information
+ * @author Eamonn McManus
+ */
+
+import java.beans.ConstructorProperties;
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+public class ExceptionDiagnosisTest {
+ private static volatile String failure;
+
+ // ------ Illegal MXBeans ------
+
+ // Test that all of BdelloidMXBean, Rotifer, and File appear in the
+ // exception messages. File is not an allowed type because of recursive
+ // getters like "File getParentFile()".
+ public static interface BdelloidMXBean {
+ public Rotifer getRotifer();
+ }
+
+ public static class Bdelloid implements BdelloidMXBean {
+ public Rotifer getRotifer() {
+ return null;
+ }
+ }
+
+ public static class Rotifer {
+ public File getFile() {
+ return null;
+ }
+ }
+
+ // Test that all of IndirectHashMapMXBean, HashMapContainer, and
+ // HashMap<String,String> appear in the exception messages.
+ // HashMap<String,String> is not an allowed type because only the
+ // java.util interface such as Map are allowed with generic parameters,
+ // not their concrete implementations like HashMap.
+ public static interface IndirectHashMapMXBean {
+ public HashMapContainer getContainer();
+ }
+
+ public static class IndirectHashMap implements IndirectHashMapMXBean {
+ public HashMapContainer getContainer() {
+ return null;
+ }
+ }
+
+ public static class HashMapContainer {
+ public HashMap<String, String> getHashMap() {return null;}
+ }
+
+ // ------ MXBeans that are legal but where proxies are not ------
+
+ // Test that all of BlimMXBean, BlimContainer, Blim, and Blam appear
+ // in the exception messages for a proxy for this MXBean. Blam is
+ // legal in MXBeans but is not reconstructible so you cannot make
+ // a proxy for BlimMXBean.
+ public static interface BlimMXBean {
+ public BlimContainer getBlimContainer();
+ }
+
+ public static class BlimImpl implements BlimMXBean {
+ public BlimContainer getBlimContainer() {
+ return null;
+ }
+ }
+
+ public static class BlimContainer {
+ public Blim getBlim() {return null;}
+ public void setBlim(Blim blim) {}
+ }
+
+ public static class Blim {
+ public Blam getBlam() {return null;}
+ public void setBlam(Blam blam) {}
+ }
+
+ public static class Blam {
+ public Blam(int x) {}
+
+ public int getX() {return 0;}
+ }
+
+
+ // ------ Property name differing only in case ------
+
+ public static interface CaseProbMXBean {
+ public CaseProb getCaseProb();
+ }
+
+ public static class CaseProbImpl implements CaseProbMXBean {
+ public CaseProb getCaseProb() {return null;}
+ }
+
+ public static class CaseProb {
+ @ConstructorProperties({"urlPath"})
+ public CaseProb(String urlPath) {}
+
+ public String getURLPath() {return null;}
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ testMXBeans(new Bdelloid(), BdelloidMXBean.class, Rotifer.class, File.class);
+ testMXBeans(new IndirectHashMap(),
+ IndirectHashMapMXBean.class, HashMapContainer.class,
+ HashMapContainer.class.getMethod("getHashMap").getGenericReturnType());
+
+ testProxies(new BlimImpl(), BlimMXBean.class, BlimMXBean.class,
+ BlimContainer.class, Blim.class, Blam.class);
+
+ testCaseProb();
+
+ if (failure == null)
+ System.out.println("TEST PASSED");
+ else
+ throw new Exception("TEST FAILED: " + failure);
+ }
+
+ private static void testMXBeans(Object mbean, Type... expectedTypes)
+ throws Exception {
+ try {
+ MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ ObjectName name = new ObjectName("a:b=c");
+ mbs.registerMBean(mbean, name);
+ fail("No exception from registerMBean for " + mbean);
+ } catch (NotCompliantMBeanException e) {
+ checkExceptionChain("MBean " + mbean, e, expectedTypes);
+ }
+ }
+
+ private static <T> void testProxies(
+ Object mbean, Class<T> mxbeanClass, Type... expectedTypes)
+ throws Exception {
+ MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ ObjectName name = new ObjectName("a:b=c");
+ mbs.registerMBean(mbean, name);
+ T proxy = JMX.newMXBeanProxy(mbs, name, mxbeanClass);
+ List<Method> methods = new ArrayList<Method>();
+ for (Method m : mxbeanClass.getMethods()) {
+ if (m.getDeclaringClass() == mxbeanClass)
+ methods.add(m);
+ }
+ if (methods.size() != 1) {
+ fail("TEST BUG: expected to find exactly one method in " +
+ mxbeanClass.getName() + ": " + methods);
+ }
+ Method getter = methods.get(0);
+ try {
+ try {
+ getter.invoke(proxy);
+ fail("No exception from proxy method " + getter.getName() +
+ " in " + mxbeanClass.getName());
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof Exception)
+ throw (Exception) cause;
+ else
+ throw (Error) cause;
+ }
+ } catch (IllegalArgumentException e) {
+ checkExceptionChain(
+ "Proxy for " + mxbeanClass.getName(), e, expectedTypes);
+ }
+ }
+
+ private static void testCaseProb() throws Exception {
+ MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ ObjectName name = new ObjectName("a:b=c");
+ Object mbean = new CaseProbImpl();
+ mbs.registerMBean(new CaseProbImpl(), name);
+ CaseProbMXBean proxy = JMX.newMXBeanProxy(mbs, name, CaseProbMXBean.class);
+ try {
+ CaseProb prob = proxy.getCaseProb();
+ fail("No exception from proxy method getCaseProb");
+ } catch (IllegalArgumentException e) {
+ String messageChain = messageChain(e);
+ if (messageChain.contains("URLPath")) {
+ System.out.println("Message chain contains URLPath as required: "
+ + messageChain);
+ } else {
+ fail("Exception chain for CaseProb does not mention property" +
+ " URLPath differing only in case");
+ System.out.println("Full stack trace:");
+ e.printStackTrace(System.out);
+ }
+ }
+ }
+
+ private static void checkExceptionChain(
+ String what, Throwable e, Type[] expectedTypes) {
+ System.out.println("Exceptions in chain for " + what + ":");
+ for (Throwable t = e; t != null; t = t.getCause())
+ System.out.println(".." + t);
+
+ String messageChain = messageChain(e);
+
+ // Now check that each of the classes is mentioned in those messages
+ for (Type type : expectedTypes) {
+ String name = (type instanceof Class) ?
+ ((Class<?>) type).getName() : type.toString();
+ if (!messageChain.contains(name)) {
+ fail("Exception chain for " + what + " does not mention " +
+ name);
+ System.out.println("Full stack trace:");
+ e.printStackTrace(System.out);
+ }
+ }
+
+ System.out.println();
+ }
+
+ private static String messageChain(Throwable t) {
+ String msg = "//";
+ for ( ; t != null; t = t.getCause())
+ msg += " " + t.getMessage() + " //";
+ return msg;
+ }
+
+ private static void fail(String why) {
+ failure = why;
+ System.out.println("FAIL: " + why);
+ }
+}
--- a/jdk/test/javax/management/mxbean/TypeNameTest.java Wed Jul 05 16:43:18 2017 +0200
+++ b/jdk/test/javax/management/mxbean/TypeNameTest.java Wed Jul 05 16:43:43 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6757225
+ * @bug 6757225 6763051
* @summary Test that type names in MXBeans match their spec.
* @author Eamonn McManus
*/
@@ -40,6 +40,8 @@
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.StandardMBean;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularType;
public class TypeNameTest {
public static interface TestMXBean {
@@ -63,7 +65,7 @@
}
};
- static String failure;
+ static volatile String failure;
public static void main(String[] args) throws Exception {
TestMXBean testImpl = (TestMXBean) Proxy.newProxyInstance(
@@ -74,24 +76,46 @@
mbs.registerMBean(mxbean, name);
MBeanInfo mbi = mbs.getMBeanInfo(name);
MBeanAttributeInfo[] mbais = mbi.getAttributes();
+ boolean sawTabular = false;
for (MBeanAttributeInfo mbai : mbais) {
String attrName = mbai.getName();
String attrTypeName = (String) mbai.getDescriptor().getFieldValue("originalType");
String fieldName = attrName + "Name";
Field nameField = TestMXBean.class.getField(fieldName);
String expectedTypeName = (String) nameField.get(null);
+
if (expectedTypeName.equals(attrTypeName)) {
System.out.println("OK: " + attrName + ": " + attrTypeName);
} else {
- failure = "For attribute " + attrName + " expected type name \"" +
+ fail("For attribute " + attrName + " expected type name \"" +
expectedTypeName + "\", found type name \"" + attrTypeName +
- "\"";
- System.out.println("FAIL: " + failure);
+ "\"");
+ }
+
+ if (mbai.getType().equals(TabularData.class.getName())) {
+ sawTabular = true;
+ TabularType tt = (TabularType) mbai.getDescriptor().getFieldValue("openType");
+ if (tt.getTypeName().equals(attrTypeName)) {
+ System.out.println("OK: TabularType name for " + attrName);
+ } else {
+ fail("For attribute " + attrName + " expected TabularType " +
+ "name \"" + attrTypeName + "\", found \"" +
+ tt.getTypeName());
+ }
}
}
+
+ if (!sawTabular)
+ fail("Test bug: did not test TabularType name");
+
if (failure == null)
System.out.println("TEST PASSED");
else
throw new Exception("TEST FAILED: " + failure);
}
+
+ private static void fail(String why) {
+ System.out.println("FAIL: " + why);
+ failure = why;
+ }
}
--- a/langtools/.hgtags Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/.hgtags Wed Jul 05 16:43:43 2017 +0200
@@ -13,3 +13,4 @@
258af9b67b7cb4262ab1b5424160c9ad22d52e8f jdk7-b36
24a47c3062fe8869fcfb533ce0ff770c8ceb550d jdk7-b37
3fd42dfa6f27f2767a241fb82bc01a613f0c2096 jdk7-b38
+3fb51e47622bb771571680bc6a7b64c6172b482d jdk7-b39
--- a/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java Wed Jul 05 16:43:43 2017 +0200
@@ -49,4 +49,23 @@
* @return a string representing the object's kind
*/
String getKind();
+
+ static class LocalizedString implements Formattable {
+ String key;
+
+ public LocalizedString(String key) {
+ this.key = key;
+ }
+
+ public String toString(java.util.Locale l, Messages messages) {
+ return messages.getLocalizedString(l, key);
+ }
+ public String getKind() {
+ return "LocalizedString";
+ }
+
+ public String toString() {
+ return key;
+ }
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jul 05 16:43:43 2017 +0200
@@ -361,6 +361,8 @@
for (Symbol sup = clazz;
sup != null && sup != this.owner;
sup = types.supertype(sup.type).tsym) {
+ while (sup.type.tag == TYPEVAR)
+ sup = sup.type.getUpperBound().tsym;
if (sup.type.isErroneous())
return true; // error recovery
if ((sup.flags() & COMPOUND) != 0)
@@ -1183,7 +1185,9 @@
* as possible implementations.
*/
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
- for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) {
+ for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
+ while (t.tag == TYPEVAR)
+ t = t.getUpperBound();
TypeSymbol c = t.tsym;
for (Scope.Entry e = c.members().lookup(name);
e.scope != null;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Wed Jul 05 16:43:43 2017 +0200
@@ -360,17 +360,6 @@
public boolean isUnbound() { return false; }
public Type withTypeVar(Type t) { return this; }
- public static List<Type> removeBounds(List<Type> ts) {
- ListBuffer<Type> result = new ListBuffer<Type>();
- for(;ts.nonEmpty(); ts = ts.tail) {
- result.append(ts.head.removeBounds());
- }
- return result.toList();
- }
- public Type removeBounds() {
- return this;
- }
-
/** The underlying method type of this type.
*/
public MethodType asMethodType() { throw new AssertionError(); }
@@ -489,10 +478,6 @@
return new WildcardType(t, kind, tsym, bound);
}
- public Type removeBounds() {
- return isUnbound() ? this : type;
- }
-
public Type getExtendsBound() {
if (kind == EXTENDS)
return type;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jul 05 16:43:43 2017 +0200
@@ -709,16 +709,13 @@
case UNDETVAR:
if (s.tag == WILDCARD) {
UndetVar undetvar = (UndetVar)t;
-
- // Because of wildcard capture, s must be on the left
- // hand side of an assignment. Furthermore, t is an
- // underconstrained type variable, for example, one
- // that is only used in the return type of a method.
- // If the type variable is truly underconstrained, it
- // cannot have any low bounds:
- assert undetvar.lobounds.isEmpty() : undetvar;
-
undetvar.inst = glb(upperBound(s), undetvar.inst);
+ // We should check instantiated type against any of the
+ // undetvar's lower bounds.
+ for (Type t2 : undetvar.lobounds) {
+ if (!isSubtype(t2, undetvar.inst))
+ return false;
+ }
return true;
} else {
return isSameType(t, s);
@@ -3367,33 +3364,67 @@
* quantifiers) only
*/
private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
- ListBuffer<Type> from = new ListBuffer<Type>();
- ListBuffer<Type> to = new ListBuffer<Type>();
- adaptSelf(t, from, to);
- ListBuffer<Type> rewritten = new ListBuffer<Type>();
- List<Type> formals = from.toList();
- boolean changed = false;
- for (Type arg : to.toList()) {
- Type bound;
- if (rewriteTypeVars && arg.tag == TYPEVAR) {
- TypeVar tv = (TypeVar)arg;
- bound = high ? tv.bound : syms.botType;
- } else {
- bound = high ? upperBound(arg) : lowerBound(arg);
+ return new Rewriter(high, rewriteTypeVars).rewrite(t);
+ }
+
+ class Rewriter extends UnaryVisitor<Type> {
+
+ boolean high;
+ boolean rewriteTypeVars;
+
+ Rewriter(boolean high, boolean rewriteTypeVars) {
+ this.high = high;
+ this.rewriteTypeVars = rewriteTypeVars;
+ }
+
+ Type rewrite(Type t) {
+ ListBuffer<Type> from = new ListBuffer<Type>();
+ ListBuffer<Type> to = new ListBuffer<Type>();
+ adaptSelf(t, from, to);
+ ListBuffer<Type> rewritten = new ListBuffer<Type>();
+ List<Type> formals = from.toList();
+ boolean changed = false;
+ for (Type arg : to.toList()) {
+ Type bound = visit(arg);
+ if (arg != bound) {
+ changed = true;
+ bound = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
+ : makeSuperWildcard(bound, (TypeVar)formals.head);
+ }
+ rewritten.append(bound);
+ formals = formals.tail;
}
- Type newarg = bound;
- if (arg != bound) {
- changed = true;
- newarg = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
- : makeSuperWildcard(bound, (TypeVar)formals.head);
- }
- rewritten.append(newarg);
- formals = formals.tail;
+ if (changed)
+ return subst(t.tsym.type, from.toList(), rewritten.toList());
+ else
+ return t;
+ }
+
+ public Type visitType(Type t, Void s) {
+ return high ? upperBound(t) : lowerBound(t);
+ }
+
+ @Override
+ public Type visitCapturedType(CapturedType t, Void s) {
+ return visitWildcardType(t.wildcard, null);
}
- if (changed)
- return subst(t.tsym.type, from.toList(), rewritten.toList());
- else
- return t;
+
+ @Override
+ public Type visitTypeVar(TypeVar t, Void s) {
+ if (rewriteTypeVars)
+ return high ? t.bound : syms.botType;
+ else
+ return t;
+ }
+
+ @Override
+ public Type visitWildcardType(WildcardType t, Void s) {
+ Type bound = high ? t.getExtendsBound() :
+ t.getSuperBound();
+ if (bound == null)
+ bound = high ? syms.objectType : syms.botType;
+ return bound;
+ }
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 05 16:43:43 2017 +0200
@@ -706,13 +706,13 @@
}
}
- // Check that the variable's declared type is well-formed.
- chk.validate(tree.vartype, env);
-
VarSymbol v = tree.sym;
Lint lint = env.info.lint.augment(v.attributes_field, v.flags());
Lint prevLint = chk.setLint(lint);
+ // Check that the variable's declared type is well-formed.
+ chk.validate(tree.vartype, env);
+
try {
chk.checkDeprecatedAnnotation(tree.pos(), v);
@@ -2007,6 +2007,10 @@
log.error(pos, "type.var.cant.be.deref");
return syms.errSymbol;
} else {
+ Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ?
+ rs.new AccessError(env, site, sym) :
+ sym;
+ rs.access(sym2, pos, site, name, true);
return sym;
}
case ERROR:
@@ -2374,16 +2378,14 @@
}
if (warned && sym.type.tag == FORALL) {
- String typeargs = "";
- if (typeargtypes != null && typeargtypes.nonEmpty()) {
- typeargs = "<" + Type.toString(typeargtypes) + ">";
- }
chk.warnUnchecked(env.tree.pos(),
"unchecked.meth.invocation.applied",
- sym,
- sym.location(),
- typeargs,
- Type.toString(argtypes));
+ kindName(sym),
+ sym.name,
+ rs.methodArguments(sym.type.getParameterTypes()),
+ rs.methodArguments(argtypes),
+ kindName(sym.location()),
+ sym.location());
owntype = new MethodType(owntype.getParameterTypes(),
types.erasure(owntype.getReturnType()),
owntype.getThrownTypes(),
@@ -2516,7 +2518,10 @@
// accept class or interface or typevar as first bound.
Type b = checkBase(bs.head, tree.bounds.head, env, false, false, false);
boundSet.add(types.erasure(b));
- if (b.tag == TYPEVAR) {
+ if (b.isErroneous()) {
+ a.bound = b;
+ }
+ else if (b.tag == TYPEVAR) {
// if first bound was a typevar, do not accept further bounds.
if (tree.bounds.tail.nonEmpty()) {
log.error(tree.bounds.tail.head.pos(),
@@ -2530,7 +2535,9 @@
for (JCExpression bound : tree.bounds.tail) {
bs = bs.tail;
Type i = checkBase(bs.head, bound, env, false, true, false);
- if (i.tag == CLASS)
+ if (i.isErroneous())
+ a.bound = i;
+ else if (i.tag == CLASS)
chk.checkNotRepeated(bound.pos(), types.erasure(i), boundSet);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jul 05 16:43:43 2017 +0200
@@ -424,43 +424,43 @@
* @param bs The bound.
*/
private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
- if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) {
- CapturedType ct = (CapturedType)a;
- boolean ok;
- if (ct.bound.isErroneous()) {//capture doesn't exist
- ok = false;
+ if (a.isUnbound()) {
+ return;
+ } else if (a.tag != WILDCARD) {
+ a = types.upperBound(a);
+ for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
+ if (!types.isSubtype(a, l.head)) {
+ log.error(pos, "not.within.bounds", a);
+ return;
+ }
+ }
+ } else if (a.isExtendsBound()) {
+ if (!types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings))
+ log.error(pos, "not.within.bounds", a);
+ } else if (a.isSuperBound()) {
+ if (types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound()))
+ log.error(pos, "not.within.bounds", a);
+ }
+ }
+
+ /** Check that a type is within some bounds.
+ *
+ * Used in TypeApply to verify that, e.g., X in V<X> is a valid
+ * type argument.
+ * @param pos Position to be used for error reporting.
+ * @param a The type that should be bounded by bs.
+ * @param bs The bound.
+ */
+ private void checkCapture(JCTypeApply tree) {
+ List<JCExpression> args = tree.getTypeArguments();
+ for (Type arg : types.capture(tree.type).getTypeArguments()) {
+ if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous()) {
+ log.error(args.head.pos, "not.within.bounds", args.head.type);
+ break;
}
- else {
- switch (ct.wildcard.kind) {
- case EXTENDS:
- ok = types.isCastable(bs.getUpperBound(),
- types.upperBound(a),
- Warner.noWarnings);
- break;
- case SUPER:
- ok = !types.notSoftSubtype(types.lowerBound(a),
- bs.getUpperBound());
- break;
- case UNBOUND:
- ok = true;
- break;
- default:
- throw new AssertionError("Invalid bound kind");
- }
- }
- if (!ok)
- log.error(pos, "not.within.bounds", a);
+ args = args.tail;
}
- else {
- a = types.upperBound(a);
- for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
- if (!types.isSubtype(a, l.head)) {
- log.error(pos, "not.within.bounds", a);
- return;
- }
- }
- }
- }
+ }
/** Check that type is different from 'void'.
* @param pos Position to be used for error reporting.
@@ -802,10 +802,10 @@
public void visitTypeApply(JCTypeApply tree) {
if (tree.type.tag == CLASS) {
- List<Type> formals = tree.type.tsym.type.getTypeArguments();
- List<Type> actuals = types.capture(tree.type).getTypeArguments();
+ List<Type> formals = tree.type.tsym.type.allparams();
+ List<Type> actuals = tree.type.allparams();
List<JCExpression> args = tree.arguments;
- List<Type> forms = formals;
+ List<Type> forms = tree.type.tsym.type.getTypeArguments();
ListBuffer<TypeVar> tvars_buf = new ListBuffer<TypeVar>();
// For matching pairs of actual argument types `a' and
@@ -826,24 +826,28 @@
}
args = tree.arguments;
+ List<Type> tvars_cap = types.substBounds(formals,
+ formals,
+ types.capture(tree.type).allparams());
+ while (args.nonEmpty() && tvars_cap.nonEmpty()) {
+ // Let the actual arguments know their bound
+ args.head.type.withTypeVar((TypeVar)tvars_cap.head);
+ args = args.tail;
+ tvars_cap = tvars_cap.tail;
+ }
+
+ args = tree.arguments;
List<TypeVar> tvars = tvars_buf.toList();
+
while (args.nonEmpty() && tvars.nonEmpty()) {
- // Let the actual arguments know their bound
- args.head.type.withTypeVar(tvars.head);
+ checkExtends(args.head.pos(),
+ args.head.type,
+ tvars.head);
args = args.tail;
tvars = tvars.tail;
}
- args = tree.arguments;
- tvars = tvars_buf.toList();
- while (args.nonEmpty() && tvars.nonEmpty()) {
- checkExtends(args.head.pos(),
- actuals.head,
- tvars.head);
- args = args.tail;
- tvars = tvars.tail;
- actuals = actuals.tail;
- }
+ checkCapture(tree);
// Check that this type is either fully parameterized, or
// not parameterized at all.
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 05 16:43:43 2017 +0200
@@ -30,6 +30,8 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.tree.*;
+import com.sun.tools.javac.api.Formattable.LocalizedString;
+import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Symbol.*;
@@ -40,6 +42,9 @@
import static com.sun.tools.javac.code.TypeTags.*;
import javax.lang.model.element.ElementVisitor;
+import java.util.Map;
+import java.util.HashMap;
+
/** Helper class for name resolution, used mostly by the attribution phase.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
@@ -554,7 +559,6 @@
boolean useVarargs,
boolean operator) {
if (sym.kind == ERR) return bestSoFar;
- if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
assert sym.kind < AMBIGUOUS;
try {
if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
@@ -651,8 +655,9 @@
// both abstract or both concrete
if (!m1Abstract && !m2Abstract)
return new AmbiguityError(m1, m2);
- // check for same erasure
- if (!types.isSameType(m1.erasure(types), m2.erasure(types)))
+ // check that both signatures have the same erasure
+ if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
+ m2.erasure(types).getParameterTypes()))
return new AmbiguityError(m1, m2);
// both abstract, neither overridden; merge throws clause and result type
Symbol result;
@@ -1192,15 +1197,23 @@
Name name,
List<Type> argtypes,
List<Type> typeargtypes) {
- Symbol sym = findFun(env, name, argtypes, typeargtypes, false, env.info.varArgs=false);
- if (varargsEnabled && sym.kind >= WRONG_MTHS) {
- sym = findFun(env, name, argtypes, typeargtypes, true, false);
- if (sym.kind >= WRONG_MTHS)
- sym = findFun(env, name, argtypes, typeargtypes, true, env.info.varArgs=true);
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= ERRONEOUS) {
+ sym = findFun(env, name, argtypes, typeargtypes,
+ steps.head.isBoxingRequired,
+ env.info.varArgs = steps.head.isVarargsRequired);
+ methodResolutionCache.put(steps.head, sym);
+ steps = steps.tail;
}
- if (sym.kind >= AMBIGUOUS) {
- sym = access(
- sym, pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
+ if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+ MethodResolutionPhase errPhase =
+ firstErroneousResolutionPhase();
+ sym = access(methodResolutionCache.get(errPhase),
+ pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
+ env.info.varArgs = errPhase.isVarargsRequired;
}
return sym;
}
@@ -1217,17 +1230,23 @@
Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
Type site, Name name, List<Type> argtypes,
List<Type> typeargtypes) {
- Symbol sym = findMethod(env, site, name, argtypes, typeargtypes, false,
- env.info.varArgs=false, false);
- if (varargsEnabled && sym.kind >= WRONG_MTHS) {
- sym = findMethod(env, site, name, argtypes, typeargtypes, true,
- false, false);
- if (sym.kind >= WRONG_MTHS)
- sym = findMethod(env, site, name, argtypes, typeargtypes, true,
- env.info.varArgs=true, false);
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= ERRONEOUS) {
+ sym = findMethod(env, site, name, argtypes, typeargtypes,
+ steps.head.isBoxingRequired(),
+ env.info.varArgs = steps.head.isVarargsRequired(), false);
+ methodResolutionCache.put(steps.head, sym);
+ steps = steps.tail;
}
- if (sym.kind >= AMBIGUOUS) {
- sym = access(sym, pos, site, name, true, argtypes, typeargtypes);
+ if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+ MethodResolutionPhase errPhase =
+ firstErroneousResolutionPhase();
+ sym = access(methodResolutionCache.get(errPhase),
+ pos, site, name, true, argtypes, typeargtypes);
+ env.info.varArgs = errPhase.isVarargsRequired;
}
return sym;
}
@@ -1268,14 +1287,22 @@
Type site,
List<Type> argtypes,
List<Type> typeargtypes) {
- Symbol sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, false, env.info.varArgs=false);
- if (varargsEnabled && sym.kind >= WRONG_MTHS) {
- sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, false);
- if (sym.kind >= WRONG_MTHS)
- sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, env.info.varArgs=true);
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= ERRONEOUS) {
+ sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
+ steps.head.isBoxingRequired(),
+ env.info.varArgs = steps.head.isVarargsRequired());
+ methodResolutionCache.put(steps.head, sym);
+ steps = steps.tail;
}
- if (sym.kind >= AMBIGUOUS) {
- sym = access(sym, pos, site, names.init, true, argtypes, typeargtypes);
+ if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+ MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
+ sym = access(methodResolutionCache.get(errPhase),
+ pos, site, names.init, true, argtypes, typeargtypes);
+ env.info.varArgs = errPhase.isVarargsRequired();
}
return sym;
}
@@ -1452,6 +1479,12 @@
error.report(log, tree.pos(), type.getEnclosingType(), null, null, null);
}
+ private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
+
+ public Object methodArguments(List<Type> argtypes) {
+ return argtypes.isEmpty() ? noArgs : argtypes;
+ }
+
/** Root class for resolve errors.
* Instances of this class indicate "Symbol not found".
* Instances of subclass indicate other errors.
@@ -1558,8 +1591,8 @@
"cant.apply.symbol" + (explanation != null ? ".1" : ""),
kindname,
ws.name == names.init ? ws.owner.name : ws.name,
- ws.type.getParameterTypes(),
- argtypes,
+ methodArguments(ws.type.getParameterTypes()),
+ methodArguments(argtypes),
kindName(ws.owner),
ws.owner.type,
explanation);
@@ -1733,4 +1766,50 @@
pair.sym2.location(site, types));
}
}
+
+ enum MethodResolutionPhase {
+ BASIC(false, false),
+ BOX(true, false),
+ VARARITY(true, true);
+
+ boolean isBoxingRequired;
+ boolean isVarargsRequired;
+
+ MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
+ this.isBoxingRequired = isBoxingRequired;
+ this.isVarargsRequired = isVarargsRequired;
+ }
+
+ public boolean isBoxingRequired() {
+ return isBoxingRequired;
+ }
+
+ public boolean isVarargsRequired() {
+ return isVarargsRequired;
+ }
+
+ public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
+ return (varargsEnabled || !isVarargsRequired) &&
+ (boxingEnabled || !isBoxingRequired);
+ }
+ }
+
+ private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
+ new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
+
+ final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
+
+ private MethodResolutionPhase firstErroneousResolutionPhase() {
+ MethodResolutionPhase bestSoFar = BASIC;
+ Symbol sym = methodNotFound;
+ List<MethodResolutionPhase> steps = methodResolutionSteps;
+ while (steps.nonEmpty() &&
+ steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+ sym.kind >= WRONG_MTHS) {
+ sym = methodResolutionCache.get(steps.head);
+ bestSoFar = steps.head;
+ steps = steps.tail;
+ }
+ return bestSoFar;
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jul 05 16:43:43 2017 +0200
@@ -745,7 +745,10 @@
compiler.warn.unchecked.cast.to.type=\
[unchecked] unchecked cast to type {0}
compiler.warn.unchecked.meth.invocation.applied=\
- [unchecked] unchecked method invocation: {0} in {1} is applied to {2}({3})
+ [unchecked] unchecked method invocation: {0} {1} in {4} {5} is applied to given types\n\
+ required: {2}\n\
+ found: {3}
+
compiler.warn.unchecked.generic.array.creation=\
[unchecked] unchecked generic array creation of type {0} for varargs parameter
@@ -771,7 +774,7 @@
Cannot find annotation method ''{1}()'' in type ''{0}'': {2}
compiler.warn.raw.class.use=\
- [raw-type] found raw type: {0}\n\
+ [rawtypes] found raw type: {0}\n\
missing type parameters for generic class {1}
#####
@@ -1062,6 +1065,9 @@
package
#####
+compiler.misc.no.args=\
+ no arguments
+
compiler.err.override.static=\
{0}; overriding method is static
compiler.err.override.meth=\
--- a/langtools/test/tools/javac/6304921/T6304921.out Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/test/tools/javac/6304921/T6304921.out Wed Jul 05 16:43:43 2017 +0200
@@ -1,4 +1,4 @@
-T6304921.java:671/671/680: warning: [raw-type] found raw type: java.util.ArrayList
+T6304921.java:671/671/680: warning: [rawtypes] found raw type: java.util.ArrayList
missing type parameters for generic class java.util.ArrayList<E>
List<Integer> list = new ArrayList();
^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6758789/T6758789a.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6758789
+ * @summary 6758789: Some method resolution diagnostic should be improved
+ * @author Maurizio Cimadamore
+ *
+ * @compile/fail/ref=T6758789a.out -XDrawDiagnostics T6758789a.java
+ */
+
+class T6758789a {
+ void m1() {}
+ void m2(int i) {}
+ void test() {
+ m1(1);
+ m2();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6758789/T6758789a.out Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,3 @@
+T6758789a.java:37:9: compiler.err.cant.apply.symbol: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, null
+T6758789a.java:38:9: compiler.err.cant.apply.symbol: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, null
+2 errors
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6758789/T6758789b.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6758789
+ * @summary 6758789: Some method resolution diagnostic should be improved
+ * @author Maurizio Cimadamore
+ *
+ * @compile/fail/ref=T6758789b.out -Werror -XDrawDiagnostics -Xlint:unchecked T6758789b.java
+ */
+
+class T6758789a {
+ class Foo<T> {}
+
+ <X> void m(Foo<X> foo) {}
+
+ void test() {
+ m(new Foo());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6758789/T6758789b.out Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,3 @@
+T6758789b.java:39:11: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
+T6758789b.java:39:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/6548436/T6548436a.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6548436
+ * @summary Incorrect inconvertible types error
+ * @author Maurizio Cimadamore
+ *
+ * @compile T6548436a.java
+ */
+
+public class T6548436a {
+
+ static class Base<E extends Comparable<E>> {}
+
+ static void test(Base<?> je) {
+ Object o = (Base<Integer>)je;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/6548436/T6548436b.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6548436
+ * @summary Incorrect inconvertible types error
+ * @author Maurizio Cimadamore
+ *
+ * @compile T6548436b.java
+ */
+
+public class T6548436b {
+
+ enum E { }
+
+ static void test(Enum<?> o) {
+ Object e = (E)o;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/6548436/T6548436c.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6548436
+ * @summary Incorrect inconvertible types error
+ * @author Maurizio Cimadamore
+ *
+ * @compile T6548436c.java
+ */
+
+public class T6548436c {
+
+ interface A<T extends A<? super T>> { }
+
+ interface B extends A<B> { }
+
+ static void test(A<?> a) {
+ Object o = (B)a;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/6548436/T6548436d.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6548436
+ * @summary Incorrect inconvertible types error
+ * @author Maurizio Cimadamore
+ *
+ * @compile/fail T6548436d.java
+ */
+
+public class T6548436d {
+
+ static class Base<E extends Comparable<E>> {}
+
+ static void test(Base<? extends Double> je) {
+ Object o = (Base<Integer>)je;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6487370/T6487370.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6487370
+ * @author Maurizio Cimadamore
+ * @summary javac incorrectly gives ambiguity warning with override-equivalent abstract inherited methods
+ */
+
+public class T6487370 {
+
+ interface I1 {
+ String m(Number n);
+ }
+
+ interface I2 {
+ Object m(Number n);
+ }
+
+ static abstract class X implements I1, I2 {
+ String test() {
+ return m(0.0f);
+ }
+ }
+
+ static class W extends X {
+ public String m(Number n) {
+ return "Hello!";
+ }
+ }
+
+ public static void main(String args[]) {
+ System.out.println(new W().test());
+ }
+}
--- a/langtools/test/tools/javac/generics/6531090/T6531090b.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/test/tools/javac/generics/6531090/T6531090b.java Wed Jul 05 16:43:43 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6531090
+ * @bug 6531090 6711619
*
* @summary Cannot access methods/fields of a captured type belonging to an intersection type
* @author Maurizio Cimadamore
@@ -32,12 +32,20 @@
public class T6531090b {
static class A {
- public void a() {}
- public A a;
+ public void a1() {}
+ protected void a2() {}
+ void a3() {}
+ public A a1;
+ protected A a2;
+ A a3;
}
static class B extends A {
- public void b(){}
- public B b;
+ public void b1() {}
+ protected void b2() {}
+ void b3() {}
+ public B b1;
+ protected B b2;
+ B b3;
}
static interface I{
void i();
@@ -65,18 +73,35 @@
}
static void testMemberMethods(C<? extends A, ? extends I> arg) {
- arg.t.a();
- arg.t.b();
+ arg.t.a1();
+ arg.t.a2();
+ arg.t.a3();
+ arg.t.b1();
+ arg.t.b2();
+ arg.t.b3();
arg.t.i1();
- arg.w.a();
- arg.w.b();
+ arg.w.a1();
+ arg.w.a2();
+ arg.w.a3();
+ arg.w.b1();
+ arg.w.b2();
+ arg.w.b3();
arg.w.i1();
}
static void testMemberFields(C<? extends A, ? extends I> arg) {
- A ta = arg.t.a;
- B tb = arg.t.b;
- A wa = arg.w.a;
- B wb = arg.w.b;
+ A ta; B tb;
+ ta = arg.t.a1;
+ ta = arg.t.a2;
+ ta = arg.t.a3;
+ tb = arg.t.b1;
+ tb = arg.t.b2;
+ tb = arg.t.b3;
+ ta = arg.w.a1;
+ ta = arg.w.a2;
+ ta = arg.w.a3;
+ tb = arg.w.b1;
+ tb = arg.w.b2;
+ tb = arg.w.b3;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6711619/T6711619a.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6711619
+ *
+ * @summary javac doesn't allow access to protected members in intersection types
+ * @author Maurizio Cimadamore
+ *
+ * @compile/fail/ref=T6711619a.out -XDrawDiagnostics T6711619a.java
+ */
+class T6711619a {
+
+ static class A {
+ private void a() {}
+ private A a;
+ }
+ static class B extends A {
+ private B b() {}
+ private B b;
+ }
+ static interface I{
+ void i();
+ }
+ static interface I1{
+ void i1();
+ }
+ static class E extends B implements I, I1{
+ public void i() {}
+ public void i1() {}
+ }
+ static class C<W extends B & I1, T extends W>{
+ T t;
+ W w;
+ C(W w, T t) {
+ this.w = w;
+ this.t = t;
+ }
+ }
+
+ static void testMemberMethods(C<? extends A, ? extends I> arg) {
+ arg.t.a();
+ arg.t.b();
+ }
+
+ static void testMemberFields(C<? extends A, ? extends I> arg) {
+ A ta; B tb;
+ ta = arg.t.a;
+ tb = arg.t.b;
+ ta = arg.w.a;
+ tb = arg.w.b;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6711619/T6711619a.out Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,7 @@
+T6711619a.java:63:14: compiler.err.report.access: a(), private, T6711619a.A
+T6711619a.java:64:14: compiler.err.report.access: b(), private, T6711619a.B
+T6711619a.java:69:19: compiler.err.report.access: a, private, T6711619a.A
+T6711619a.java:70:19: compiler.err.report.access: b, private, T6711619a.B
+T6711619a.java:71:19: compiler.err.report.access: a, private, T6711619a.A
+T6711619a.java:72:19: compiler.err.report.access: b, private, T6711619a.B
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6711619/T6711619b.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6711619
+ *
+ * @summary javac doesn't allow access to protected members in intersection types
+ * @author Maurizio Cimadamore
+ *
+ * @compile/fail/ref=T6711619b.out -XDrawDiagnostics T6711619b.java
+ */
+
+class T6711619b {
+ static class X1<E extends X1<E>> {
+ private int i;
+ E e;
+ int f() {
+ return e.i;
+ }
+ }
+
+ static class X2<E extends X2<E>> {
+ static private int i;
+ int f() {
+ return E.i;
+ }
+ }
+
+ static class X3<E extends X3<E> & java.io.Serializable> {
+ private int i;
+ E e;
+ int f() {
+ return e.i;
+ }
+ }
+
+ static class X4<E extends X4<E> & java.io.Serializable> {
+ static private int i;
+ int f() {
+ return E.i;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6711619/T6711619b.out Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,5 @@
+T6711619b.java:39:22: compiler.err.report.access: i, private, T6711619b.X1
+T6711619b.java:46:22: compiler.err.report.access: i, private, T6711619b.X2
+T6711619b.java:54:22: compiler.err.report.access: i, private, T6711619b.X3
+T6711619b.java:61:22: compiler.err.report.access: i, private, T6711619b.X4
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/T6557954.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6557954
+ * @summary Inner class type parameters doesn't get substituted when checking type well-formedness
+ * @author Maurizio Cimadamore
+ *
+ * @compile T6557954.java
+ */
+
+class T6557954<T> {
+ class Foo<U extends T> {}
+ T6557954<Number>.Foo<Integer> f;
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out Wed Jul 05 16:43:43 2017 +0200
@@ -1,3 +1,3 @@
T6718364.java:36:32: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6718364.X, T6718364.X<java.lang.Integer>
-T6718364.java:36:10: compiler.warn.unchecked.meth.invocation.applied: <T>m(T6718364.X<T>,T), T6718364, , T6718364.X<T6718364.X<java.lang.Integer>>,T6718364.X
+T6718364.java:36:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6718364.X<T>,T, T6718364.X<T6718364.X<java.lang.Integer>>,T6718364.X, kindname.class, T6718364
2 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/typevars/6680106/T6680106.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6680106
+ * @summary StackOverFlowError for Cyclic inheritance in TypeParameters with ArrayType Bounds
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=T6680106.out -XDrawDiagnostics T6680106.java
+ */
+
+class T6680106 {
+ class A0 {}
+ class A1<T extends T[]> {}
+ class A2<T extends S[], S extends T[]> {}
+ class A3<T extends S[], S extends U[], U extends T[]> {}
+ class A5<T extends A0 & T[]> {}
+ class A6<T extends A0 & S[], S extends A0 & T[]> {}
+ class A7<T extends A0 & S[], S extends A0 & U[], U extends A0 & T[]> {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,13 @@
+T6680106.java:34:25: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+T6680106.java:35:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
+T6680106.java:35:40: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+T6680106.java:36:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
+T6680106.java:36:40: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class)
+T6680106.java:36:55: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+T6680106.java:37:30: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+T6680106.java:38:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
+T6680106.java:38:50: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+T6680106.java:39:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
+T6680106.java:39:50: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class)
+T6680106.java:39:70: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+12 errors
\ No newline at end of file
--- a/langtools/test/tools/javac/generics/wildcards/6651719/T6651719b.java Wed Jul 05 16:43:18 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/*
- * @test
- * @bug 6651719
- * @summary Compiler crashes possibly during forward reference of TypeParameter
- * @compile T6651719b.java
- */
-import java.util.*;
-
-public class T6651719b {
- <T> void m(T t, List<? super List<T>> list) {}
- void test(List<? super List<?>> list) {
- m("", list);
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/wildcards/6762569/T6762569a.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6762569
+ * @summary Javac crashes with AssertionError in Types.containedBy
+ * @compile T6762569a.java
+ */
+import java.util.*;
+
+class T6762569a {
+ <T> void m(T t, List<? super List<T>> list) {}
+
+ void test(List<? super List<?>> list) {
+ m("", list);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/wildcards/6762569/T6762569b.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6762569
+ * @summary Javac crashes with AssertionError in Types.containedBy
+ * @compile/fail T6762569b.java
+ */
+import java.util.*;
+
+class T6762569b {
+ <T> void m(T t, List<? super List<T>> list) {}
+
+ void test(List<? super List<? extends Number>> list) {
+ m("", list);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/wildcards/T6732484.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6732484
+ * @summary Bound error on wildcard code
+ * @author Maurizio Cimadamore
+ * @compile T6732484.java
+ */
+
+class T6732484 {
+ class A<T extends A<T>> {}
+ class B extends A<B> {}
+
+ A<? super B> f;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/varargs/T6746184.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6746184
+ * @summary javac fails to compile call to public varargs method
+ */
+
+public class T6746184 {
+ public static void main(String[] args) {
+ A.m(new Object());
+ }
+}
+
+class A {
+ public static void m(final Object... varargs) {}
+ private static void m(final Object singleArg) {}
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/T6763518.java Wed Jul 05 16:43:43 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6763518
+ * @summary Impossible to suppress raw-type warnings
+ * @compile -Werror -Xlint:rawtypes T6763518.java
+ */
+
+import java.util.List;
+
+class T6763518 {
+ @SuppressWarnings("rawtypes")
+ List l1;
+
+ void m(@SuppressWarnings("rawtypes") List l2) {
+ @SuppressWarnings("rawtypes")
+ List l3;
+ };
+}
--- a/langtools/test/tools/javap/ListTest.java Wed Jul 05 16:43:18 2017 +0200
+++ b/langtools/test/tools/javap/ListTest.java Wed Jul 05 16:43:43 2017 +0200
@@ -82,16 +82,16 @@
String[] args = new String[options.size() + 1];
options.toArray(args);
args[args.length - 1] = testClassName;
- String oldOut = runOldJavap(args);
- String newOut = runNewJavap(args);
- boolean ok = oldOut.equals(newOut);
+ byte[] oldOut = runOldJavap(args);
+ byte[] newOut = runNewJavap(args);
+ boolean ok = equal(oldOut, newOut);
System.err.println((ok ? "pass" : "FAIL") + ": " + testClassName);
if (!ok && viewResults)
view(oldOut, newOut);
return ok;
}
- String runOldJavap(String[] args) {
+ byte[] runOldJavap(String[] args) {
//System.err.println("OLD: " + Arrays.asList(args));
PrintStream oldOut = System.out;
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -101,29 +101,34 @@
} finally {
System.setOut(oldOut);
}
- return out.toString();
+ return out.toByteArray();
}
- String runNewJavap(String[] args) {
+ byte[] runNewJavap(String[] args) {
String[] nArgs = new String[args.length + 2];
nArgs[0] = "-XDcompat";
nArgs[1] = "-XDignore.symbol.file";
System.arraycopy(args, 0, nArgs, 2, args.length);
//System.err.println("NEW: " + Arrays.asList(nArgs));
- StringWriter out = new StringWriter();
- com.sun.tools.javap.Main.run(nArgs, new PrintWriter(out, true));
- return out.toString();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ com.sun.tools.javap.Main.run(nArgs,
+ new PrintWriter(new OutputStreamWriter(out), true));
+ return out.toByteArray();
}
- File write(String text, String suffix) throws IOException {
- File f = File.createTempFile("ListTest", suffix);
- FileWriter out = new FileWriter(f);
+ File write(byte[] text, String suffix) throws IOException {
+ File f = new File("ListTest." + suffix);
+ FileOutputStream out = new FileOutputStream(f);
out.write(text);
out.close();
return f;
}
- void view(String oldOut, String newOut) throws Exception {
+ boolean equal(byte[] a1, byte[] a2) {
+ return Arrays.equals(a1, a2);
+ }
+
+ void view(byte[] oldOut, byte[] newOut) throws Exception {
File oldFile = write(oldOut, "old");
File newFile = write(newOut, "new");
List<String> cmd = new ArrayList<String>();