--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad Fri May 06 18:20:50 2016 +0300
@@ -3572,6 +3572,8 @@
return FP_REG_mask();
}
+const bool Matcher::convi2l_type_required = false;
+
// helper for encoding java_to_runtime calls on sim
//
// this is needed to compute the extra arguments required when
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Fri May 06 18:20:50 2016 +0300
@@ -1030,6 +1030,14 @@
}
}
+void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
+ Unimplemented();
+}
+
+void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
+ fatal("vectorizedMismatch intrinsic is not implemented on this platform");
+}
+
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
// _i2b, _i2c, _i2s
void LIRGenerator::do_Convert(Convert* x) {
--- a/hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp Fri May 06 18:20:50 2016 +0300
@@ -71,7 +71,7 @@
define_pd_global(bool, OptoScheduling, false);
define_pd_global(bool, OptoBundling, false);
define_pd_global(bool, OptoRegScheduling, false);
-define_pd_global(bool, SuperWordLoopUnrollAnalysis, false);
+define_pd_global(bool, SuperWordLoopUnrollAnalysis, true);
define_pd_global(intx, ReservedCodeCacheSize, 48*M);
define_pd_global(intx, NonProfiledCodeHeapSize, 21*M);
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Fri May 06 18:20:50 2016 +0300
@@ -4787,15 +4787,15 @@
br(rscratch2);
bind(loop);
+ add(base, base, unroll * 16);
for (int i = -unroll; i < 0; i++)
stp(value, value, Address(base, i * 16));
bind(entry);
subs(cnt, cnt, unroll * 2);
- add(base, base, unroll * 16);
br(Assembler::GE, loop);
tbz(cnt, 0, fini);
- str(value, Address(base, -unroll * 16));
+ str(value, Address(post(base, 8)));
bind(fini);
}
@@ -4810,6 +4810,7 @@
Label base_aligned;
assert_different_registers(base, cnt, rscratch1);
+ guarantee(base == r10 && cnt == r11, "fix register usage");
Register tmp = rscratch1;
Register tmp2 = rscratch2;
@@ -4848,15 +4849,15 @@
br(tmp2);
bind(small_loop);
+ add(base, base, unroll * 16);
for (int i = -unroll; i < 0; i++)
stp(zr, zr, Address(base, i * 16));
bind(small_table_end);
subs(cnt, cnt, unroll * 2);
- add(base, base, unroll * 16);
br(Assembler::GE, small_loop);
tbz(cnt, 0, done);
- str(zr, Address(base, -unroll * 16));
+ str(zr, Address(post(base, 8)));
bind(done);
}
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Fri May 06 18:20:50 2016 +0300
@@ -724,11 +724,15 @@
Register tmp2 = rscratch2;
int zva_length = VM_Version::zva_length();
Label initial_table_end, loop_zva;
+ Label fini;
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "zero_longs");
address start = __ pc();
+ // Base must be 16 byte aligned. If not just return and let caller handle it
+ __ tst(base, 0x0f);
+ __ br(Assembler::NE, fini);
// Align base with ZVA length.
__ neg(tmp, base);
__ andr(tmp, tmp, zva_length - 1);
@@ -751,6 +755,7 @@
__ add(base, base, zva_length);
__ br(Assembler::GE, loop_zva);
__ add(cnt, cnt, zva_length >> 3); // count not zeroed by DC ZVA
+ __ bind(fini);
__ ret(lr);
return start;
@@ -2077,7 +2082,9 @@
const Register to = c_rarg0; // source array address
const Register value = c_rarg1; // value
const Register count = c_rarg2; // elements count
- const Register cnt_words = c_rarg3; // temp register
+
+ const Register bz_base = r10; // base for block_zero routine
+ const Register cnt_words = r11; // temp register
__ enter();
@@ -2147,7 +2154,9 @@
__ cmp(cnt_words, BlockZeroingLowLimit >> 3);
__ ccmp(value, 0 /* comparing value */, 0 /* NZCV */, Assembler::GE);
__ br(Assembler::NE, non_block_zeroing);
- __ block_zero(to, cnt_words, true);
+ __ mov(bz_base, to);
+ __ block_zero(bz_base, cnt_words, true);
+ __ mov(to, bz_base);
__ b(rest);
__ bind(non_block_zeroing);
__ fill_words(to, cnt_words, value);
--- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp Fri May 06 18:20:50 2016 +0300
@@ -1427,4 +1427,12 @@
ShouldNotReachHere();
}
}
+
+ void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
+ fatal("vectorizedMismatch intrinsic is not implemented on this platform");
+ }
}
+
+void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
+ Unimplemented();
+}
--- a/hotspot/src/cpu/ppc/vm/ppc.ad Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad Fri May 06 18:20:50 2016 +0300
@@ -1380,6 +1380,8 @@
// Save return pc.
___(std) std(return_pc, _abi(lr), callers_sp);
}
+
+ C->set_frame_complete(cbuf.insts_size());
}
#undef ___
#undef ___stop
@@ -2311,6 +2313,8 @@
return RegMask();
}
+const bool Matcher::convi2l_type_required = true;
+
%}
//----------ENCODING BLOCK-----------------------------------------------------
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Fri May 06 18:20:50 2016 +0300
@@ -869,6 +869,94 @@
}
}
+void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
+ // Make all state_for calls early since they can emit code
+ LIR_Opr result = rlock_result(x);
+ int flags = 0;
+ switch (x->id()) {
+ case vmIntrinsics::_updateBytesCRC32C:
+ case vmIntrinsics::_updateDirectByteBufferCRC32C: {
+
+ bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C);
+ int array_offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;
+
+ LIRItem crc(x->argument_at(0), this);
+ LIRItem buf(x->argument_at(1), this);
+ LIRItem off(x->argument_at(2), this);
+ LIRItem end(x->argument_at(3), this);
+
+ buf.load_item();
+ off.load_nonconstant();
+ end.load_nonconstant();
+
+ // len = end - off
+ LIR_Opr len = end.result();
+ LIR_Opr tmpA = new_register(T_INT);
+ LIR_Opr tmpB = new_register(T_INT);
+ __ move(end.result(), tmpA);
+ __ move(off.result(), tmpB);
+ __ sub(tmpA, tmpB, tmpA);
+ len = tmpA;
+
+ LIR_Opr index = off.result();
+
+ if(off.result()->is_constant()) {
+ index = LIR_OprFact::illegalOpr;
+ array_offset += off.result()->as_jint();
+ }
+
+ LIR_Opr base_op = buf.result();
+
+ if (index->is_valid()) {
+ LIR_Opr tmp = new_register(T_LONG);
+ __ convert(Bytecodes::_i2l, index, tmp);
+ index = tmp;
+ if (index->is_constant()) {
+ array_offset += index->as_constant_ptr()->as_jint();
+ index = LIR_OprFact::illegalOpr;
+ } else if (index->is_register()) {
+ LIR_Opr tmp2 = new_register(T_LONG);
+ LIR_Opr tmp3 = new_register(T_LONG);
+ __ move(base_op, tmp2);
+ __ move(index, tmp3);
+ __ add(tmp2, tmp3, tmp2);
+ base_op = tmp2;
+ } else {
+ ShouldNotReachHere();
+ }
+ }
+
+ LIR_Address* a = new LIR_Address(base_op, array_offset, T_BYTE);
+
+ BasicTypeList signature(3);
+ signature.append(T_INT);
+ signature.append(T_ADDRESS);
+ signature.append(T_INT);
+ CallingConvention* cc = frame_map()->c_calling_convention(&signature);
+ const LIR_Opr result_reg = result_register_for(x->type());
+
+ LIR_Opr addr = new_pointer_register();
+ __ leal(LIR_OprFact::address(a), addr);
+
+ crc.load_item_force(cc->at(0));
+ __ move(addr, cc->at(1));
+ __ move(len, cc->at(2));
+
+ __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), getThreadTemp(), result_reg, cc->args());
+ __ move(result_reg, result);
+
+ break;
+ }
+ default: {
+ ShouldNotReachHere();
+ }
+ }
+}
+
+void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
+ fatal("vectorizedMismatch intrinsic is not implemented on this platform");
+}
+
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
// _i2b, _i2c, _i2s
void LIRGenerator::do_Convert(Convert* x) {
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Fri May 06 18:20:50 2016 +0300
@@ -4845,21 +4845,21 @@
// Reverse byte order of lower 32 bits, assuming upper 32 bits all zeros
void MacroAssembler::reverse_bytes_32(Register src, Register dst, Register tmp) {
- srlx(src, 24, dst);
-
- sllx(src, 32+8, tmp);
- srlx(tmp, 32+24, tmp);
- sllx(tmp, 8, tmp);
- or3(dst, tmp, dst);
-
- sllx(src, 32+16, tmp);
- srlx(tmp, 32+24, tmp);
- sllx(tmp, 16, tmp);
- or3(dst, tmp, dst);
-
- sllx(src, 32+24, tmp);
- srlx(tmp, 32, tmp);
- or3(dst, tmp, dst);
+ srlx(src, 24, dst);
+
+ sllx(src, 32+8, tmp);
+ srlx(tmp, 32+24, tmp);
+ sllx(tmp, 8, tmp);
+ or3(dst, tmp, dst);
+
+ sllx(src, 32+16, tmp);
+ srlx(tmp, 32+24, tmp);
+ sllx(tmp, 16, tmp);
+ or3(dst, tmp, dst);
+
+ sllx(src, 32+24, tmp);
+ srlx(tmp, 32, tmp);
+ or3(dst, tmp, dst);
}
void MacroAssembler::movitof_revbytes(Register src, FloatRegister dst, Register tmp1, Register tmp2) {
@@ -5111,3 +5111,176 @@
not1(crc);
}
+#define CHUNK_LEN 128 /* 128 x 8B = 1KB */
+#define CHUNK_K1 0x1307a0206 /* reverseBits(pow(x, CHUNK_LEN*8*8*3 - 32) mod P(x)) << 1 */
+#define CHUNK_K2 0x1a0f717c4 /* reverseBits(pow(x, CHUNK_LEN*8*8*2 - 32) mod P(x)) << 1 */
+#define CHUNK_K3 0x0170076fa /* reverseBits(pow(x, CHUNK_LEN*8*8*1 - 32) mod P(x)) << 1 */
+
+void MacroAssembler::kernel_crc32c(Register crc, Register buf, Register len, Register table) {
+
+ Label L_crc32c_head, L_crc32c_aligned;
+ Label L_crc32c_parallel, L_crc32c_parallel_loop;
+ Label L_crc32c_serial, L_crc32c_x32_loop, L_crc32c_x8, L_crc32c_x8_loop;
+ Label L_crc32c_done, L_crc32c_tail, L_crc32c_return;
+
+ set(ExternalAddress(StubRoutines::crc32c_table_addr()), table);
+
+ cmp_and_br_short(len, 0, Assembler::lessEqual, Assembler::pn, L_crc32c_return);
+
+ // clear upper 32 bits of crc
+ clruwu(crc);
+
+ and3(buf, 7, G4);
+ cmp_and_brx_short(G4, 0, Assembler::equal, Assembler::pt, L_crc32c_aligned);
+
+ mov(8, G1);
+ sub(G1, G4, G4);
+
+ // ------ process the misaligned head (7 bytes or less) ------
+ bind(L_crc32c_head);
+
+ // crc = (crc >>> 8) ^ byteTable[(crc ^ b) & 0xFF];
+ ldub(buf, 0, G1);
+ update_byte_crc32(crc, G1, table);
+
+ inc(buf);
+ dec(len);
+ cmp_and_br_short(len, 0, Assembler::equal, Assembler::pn, L_crc32c_return);
+ dec(G4);
+ cmp_and_br_short(G4, 0, Assembler::greater, Assembler::pt, L_crc32c_head);
+
+ // ------ process the 8-byte-aligned body ------
+ bind(L_crc32c_aligned);
+ nop();
+ cmp_and_br_short(len, 8, Assembler::less, Assembler::pn, L_crc32c_tail);
+
+ // reverse the byte order of lower 32 bits to big endian, and move to FP side
+ movitof_revbytes(crc, F0, G1, G3);
+
+ set(CHUNK_LEN*8*4, G4);
+ cmp_and_br_short(len, G4, Assembler::less, Assembler::pt, L_crc32c_serial);
+
+ // ------ process four 1KB chunks in parallel ------
+ bind(L_crc32c_parallel);
+
+ fzero(FloatRegisterImpl::D, F2);
+ fzero(FloatRegisterImpl::D, F4);
+ fzero(FloatRegisterImpl::D, F6);
+
+ mov(CHUNK_LEN - 1, G4);
+ bind(L_crc32c_parallel_loop);
+ // schedule ldf's ahead of crc32c's to hide the load-use latency
+ ldf(FloatRegisterImpl::D, buf, 0, F8);
+ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*8, F10);
+ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*16, F12);
+ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*24, F14);
+ crc32c(F0, F8, F0);
+ crc32c(F2, F10, F2);
+ crc32c(F4, F12, F4);
+ crc32c(F6, F14, F6);
+ inc(buf, 8);
+ dec(G4);
+ cmp_and_br_short(G4, 0, Assembler::greater, Assembler::pt, L_crc32c_parallel_loop);
+
+ ldf(FloatRegisterImpl::D, buf, 0, F8);
+ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*8, F10);
+ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*16, F12);
+ crc32c(F0, F8, F0);
+ crc32c(F2, F10, F2);
+ crc32c(F4, F12, F4);
+
+ inc(buf, CHUNK_LEN*24);
+ ldfl(FloatRegisterImpl::D, buf, G0, F14); // load in little endian
+ inc(buf, 8);
+
+ prefetch(buf, 0, Assembler::severalReads);
+ prefetch(buf, CHUNK_LEN*8, Assembler::severalReads);
+ prefetch(buf, CHUNK_LEN*16, Assembler::severalReads);
+ prefetch(buf, CHUNK_LEN*24, Assembler::severalReads);
+
+ // move to INT side, and reverse the byte order of lower 32 bits to little endian
+ movftoi_revbytes(F0, O4, G1, G4);
+ movftoi_revbytes(F2, O5, G1, G4);
+ movftoi_revbytes(F4, G5, G1, G4);
+
+ // combine the results of 4 chunks
+ set64(CHUNK_K1, G3, G1);
+ xmulx(O4, G3, O4);
+ set64(CHUNK_K2, G3, G1);
+ xmulx(O5, G3, O5);
+ set64(CHUNK_K3, G3, G1);
+ xmulx(G5, G3, G5);
+
+ movdtox(F14, G4);
+ xor3(O4, O5, O5);
+ xor3(G5, O5, O5);
+ xor3(G4, O5, O5);
+
+ // reverse the byte order to big endian, via stack, and move to FP side
+ // TODO: use new revb instruction
+ add(SP, -8, G1);
+ srlx(G1, 3, G1);
+ sllx(G1, 3, G1);
+ stx(O5, G1, G0);
+ ldfl(FloatRegisterImpl::D, G1, G0, F2); // load in little endian
+
+ crc32c(F6, F2, F0);
+
+ set(CHUNK_LEN*8*4, G4);
+ sub(len, G4, len);
+ cmp_and_br_short(len, G4, Assembler::greaterEqual, Assembler::pt, L_crc32c_parallel);
+ nop();
+ cmp_and_br_short(len, 0, Assembler::equal, Assembler::pt, L_crc32c_done);
+
+ bind(L_crc32c_serial);
+
+ mov(32, G4);
+ cmp_and_br_short(len, G4, Assembler::less, Assembler::pn, L_crc32c_x8);
+
+ // ------ process 32B chunks ------
+ bind(L_crc32c_x32_loop);
+ ldf(FloatRegisterImpl::D, buf, 0, F2);
+ crc32c(F0, F2, F0);
+ ldf(FloatRegisterImpl::D, buf, 8, F2);
+ crc32c(F0, F2, F0);
+ ldf(FloatRegisterImpl::D, buf, 16, F2);
+ crc32c(F0, F2, F0);
+ ldf(FloatRegisterImpl::D, buf, 24, F2);
+ inc(buf, 32);
+ crc32c(F0, F2, F0);
+ dec(len, 32);
+ cmp_and_br_short(len, G4, Assembler::greaterEqual, Assembler::pt, L_crc32c_x32_loop);
+
+ bind(L_crc32c_x8);
+ nop();
+ cmp_and_br_short(len, 8, Assembler::less, Assembler::pt, L_crc32c_done);
+
+ // ------ process 8B chunks ------
+ bind(L_crc32c_x8_loop);
+ ldf(FloatRegisterImpl::D, buf, 0, F2);
+ inc(buf, 8);
+ crc32c(F0, F2, F0);
+ dec(len, 8);
+ cmp_and_br_short(len, 8, Assembler::greaterEqual, Assembler::pt, L_crc32c_x8_loop);
+
+ bind(L_crc32c_done);
+
+ // move to INT side, and reverse the byte order of lower 32 bits to little endian
+ movftoi_revbytes(F0, crc, G1, G3);
+
+ cmp_and_br_short(len, 0, Assembler::equal, Assembler::pt, L_crc32c_return);
+
+ // ------ process the misaligned tail (7 bytes or less) ------
+ bind(L_crc32c_tail);
+
+ // crc = (crc >>> 8) ^ byteTable[(crc ^ b) & 0xFF];
+ ldub(buf, 0, G1);
+ update_byte_crc32(crc, G1, table);
+
+ inc(buf);
+ dec(len);
+ cmp_and_br_short(len, 0, Assembler::greater, Assembler::pt, L_crc32c_tail);
+
+ bind(L_crc32c_return);
+ nop();
+}
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Fri May 06 18:20:50 2016 +0300
@@ -1420,6 +1420,8 @@
// Fold 8-bit data
void fold_8bit_crc32(Register xcrc, Register table, Register xtmp, Register tmp);
void fold_8bit_crc32(Register crc, Register table, Register tmp);
+ // CRC32C code for java.util.zip.CRC32C::updateBytes/updateDirectByteBuffer instrinsic.
+ void kernel_crc32c(Register crc, Register buf, Register len, Register table);
};
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Fri May 06 18:20:50 2016 +0300
@@ -2133,6 +2133,8 @@
return L7_REGP_mask();
}
+const bool Matcher::convi2l_type_required = true;
+
%}
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -4909,11 +4909,6 @@
return start;
}
-#define CHUNK_LEN 128 /* 128 x 8B = 1KB */
-#define CHUNK_K1 0x1307a0206 /* reverseBits(pow(x, CHUNK_LEN*8*8*3 - 32) mod P(x)) << 1 */
-#define CHUNK_K2 0x1a0f717c4 /* reverseBits(pow(x, CHUNK_LEN*8*8*2 - 32) mod P(x)) << 1 */
-#define CHUNK_K3 0x0170076fa /* reverseBits(pow(x, CHUNK_LEN*8*8*1 - 32) mod P(x)) << 1 */
-
/**
* Arguments:
*
@@ -4938,171 +4933,8 @@
const Register len = O2; // number of bytes
const Register table = O3; // byteTable
- Label L_crc32c_head, L_crc32c_aligned;
- Label L_crc32c_parallel, L_crc32c_parallel_loop;
- Label L_crc32c_serial, L_crc32c_x32_loop, L_crc32c_x8, L_crc32c_x8_loop;
- Label L_crc32c_done, L_crc32c_tail, L_crc32c_return;
-
- __ cmp_and_br_short(len, 0, Assembler::lessEqual, Assembler::pn, L_crc32c_return);
-
- // clear upper 32 bits of crc
- __ clruwu(crc);
-
- __ and3(buf, 7, G4);
- __ cmp_and_brx_short(G4, 0, Assembler::equal, Assembler::pt, L_crc32c_aligned);
-
- __ mov(8, G1);
- __ sub(G1, G4, G4);
-
- // ------ process the misaligned head (7 bytes or less) ------
- __ BIND(L_crc32c_head);
-
- // crc = (crc >>> 8) ^ byteTable[(crc ^ b) & 0xFF];
- __ ldub(buf, 0, G1);
- __ update_byte_crc32(crc, G1, table);
-
- __ inc(buf);
- __ dec(len);
- __ cmp_and_br_short(len, 0, Assembler::equal, Assembler::pn, L_crc32c_return);
- __ dec(G4);
- __ cmp_and_br_short(G4, 0, Assembler::greater, Assembler::pt, L_crc32c_head);
-
- // ------ process the 8-byte-aligned body ------
- __ BIND(L_crc32c_aligned);
- __ nop();
- __ cmp_and_br_short(len, 8, Assembler::less, Assembler::pn, L_crc32c_tail);
-
- // reverse the byte order of lower 32 bits to big endian, and move to FP side
- __ movitof_revbytes(crc, F0, G1, G3);
-
- __ set(CHUNK_LEN*8*4, G4);
- __ cmp_and_br_short(len, G4, Assembler::less, Assembler::pt, L_crc32c_serial);
-
- // ------ process four 1KB chunks in parallel ------
- __ BIND(L_crc32c_parallel);
-
- __ fzero(FloatRegisterImpl::D, F2);
- __ fzero(FloatRegisterImpl::D, F4);
- __ fzero(FloatRegisterImpl::D, F6);
-
- __ mov(CHUNK_LEN - 1, G4);
- __ BIND(L_crc32c_parallel_loop);
- // schedule ldf's ahead of crc32c's to hide the load-use latency
- __ ldf(FloatRegisterImpl::D, buf, 0, F8);
- __ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*8, F10);
- __ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*16, F12);
- __ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*24, F14);
- __ crc32c(F0, F8, F0);
- __ crc32c(F2, F10, F2);
- __ crc32c(F4, F12, F4);
- __ crc32c(F6, F14, F6);
- __ inc(buf, 8);
- __ dec(G4);
- __ cmp_and_br_short(G4, 0, Assembler::greater, Assembler::pt, L_crc32c_parallel_loop);
-
- __ ldf(FloatRegisterImpl::D, buf, 0, F8);
- __ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*8, F10);
- __ ldf(FloatRegisterImpl::D, buf, CHUNK_LEN*16, F12);
- __ crc32c(F0, F8, F0);
- __ crc32c(F2, F10, F2);
- __ crc32c(F4, F12, F4);
-
- __ inc(buf, CHUNK_LEN*24);
- __ ldfl(FloatRegisterImpl::D, buf, G0, F14); // load in little endian
- __ inc(buf, 8);
-
- __ prefetch(buf, 0, Assembler::severalReads);
- __ prefetch(buf, CHUNK_LEN*8, Assembler::severalReads);
- __ prefetch(buf, CHUNK_LEN*16, Assembler::severalReads);
- __ prefetch(buf, CHUNK_LEN*24, Assembler::severalReads);
-
- // move to INT side, and reverse the byte order of lower 32 bits to little endian
- __ movftoi_revbytes(F0, O4, G1, G4);
- __ movftoi_revbytes(F2, O5, G1, G4);
- __ movftoi_revbytes(F4, G5, G1, G4);
-
- // combine the results of 4 chunks
- __ set64(CHUNK_K1, G3, G1);
- __ xmulx(O4, G3, O4);
- __ set64(CHUNK_K2, G3, G1);
- __ xmulx(O5, G3, O5);
- __ set64(CHUNK_K3, G3, G1);
- __ xmulx(G5, G3, G5);
-
- __ movdtox(F14, G4);
- __ xor3(O4, O5, O5);
- __ xor3(G5, O5, O5);
- __ xor3(G4, O5, O5);
-
- // reverse the byte order to big endian, via stack, and move to FP side
- __ add(SP, -8, G1);
- __ srlx(G1, 3, G1);
- __ sllx(G1, 3, G1);
- __ stx(O5, G1, G0);
- __ ldfl(FloatRegisterImpl::D, G1, G0, F2); // load in little endian
-
- __ crc32c(F6, F2, F0);
-
- __ set(CHUNK_LEN*8*4, G4);
- __ sub(len, G4, len);
- __ cmp_and_br_short(len, G4, Assembler::greaterEqual, Assembler::pt, L_crc32c_parallel);
- __ nop();
- __ cmp_and_br_short(len, 0, Assembler::equal, Assembler::pt, L_crc32c_done);
-
- __ BIND(L_crc32c_serial);
-
- __ mov(32, G4);
- __ cmp_and_br_short(len, G4, Assembler::less, Assembler::pn, L_crc32c_x8);
-
- // ------ process 32B chunks ------
- __ BIND(L_crc32c_x32_loop);
- __ ldf(FloatRegisterImpl::D, buf, 0, F2);
- __ inc(buf, 8);
- __ crc32c(F0, F2, F0);
- __ ldf(FloatRegisterImpl::D, buf, 0, F2);
- __ inc(buf, 8);
- __ crc32c(F0, F2, F0);
- __ ldf(FloatRegisterImpl::D, buf, 0, F2);
- __ inc(buf, 8);
- __ crc32c(F0, F2, F0);
- __ ldf(FloatRegisterImpl::D, buf, 0, F2);
- __ inc(buf, 8);
- __ crc32c(F0, F2, F0);
- __ dec(len, 32);
- __ cmp_and_br_short(len, G4, Assembler::greaterEqual, Assembler::pt, L_crc32c_x32_loop);
-
- __ BIND(L_crc32c_x8);
- __ nop();
- __ cmp_and_br_short(len, 8, Assembler::less, Assembler::pt, L_crc32c_done);
-
- // ------ process 8B chunks ------
- __ BIND(L_crc32c_x8_loop);
- __ ldf(FloatRegisterImpl::D, buf, 0, F2);
- __ inc(buf, 8);
- __ crc32c(F0, F2, F0);
- __ dec(len, 8);
- __ cmp_and_br_short(len, 8, Assembler::greaterEqual, Assembler::pt, L_crc32c_x8_loop);
-
- __ BIND(L_crc32c_done);
-
- // move to INT side, and reverse the byte order of lower 32 bits to little endian
- __ movftoi_revbytes(F0, crc, G1, G3);
-
- __ cmp_and_br_short(len, 0, Assembler::equal, Assembler::pt, L_crc32c_return);
-
- // ------ process the misaligned tail (7 bytes or less) ------
- __ BIND(L_crc32c_tail);
-
- // crc = (crc >>> 8) ^ byteTable[(crc ^ b) & 0xFF];
- __ ldub(buf, 0, G1);
- __ update_byte_crc32(crc, G1, table);
-
- __ inc(buf);
- __ dec(len);
- __ cmp_and_br_short(len, 0, Assembler::greater, Assembler::pt, L_crc32c_tail);
-
- __ BIND(L_crc32c_return);
- __ nop();
+ __ kernel_crc32c(crc, buf, len, table);
+
__ retl();
__ delayed()->nop();
@@ -5366,6 +5198,12 @@
StubRoutines::_crc_table_adr = (address)StubRoutines::Sparc::_crc_table;
StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
}
+
+ if (UseCRC32CIntrinsics) {
+ // set table address before stub generation which use it
+ StubRoutines::_crc32c_table_addr = (address)StubRoutines::Sparc::_crc32c_table;
+ StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
+ }
}
@@ -5425,12 +5263,6 @@
StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress");
StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB");
}
-
- // generate CRC32C intrinsic code
- if (UseCRC32CIntrinsics) {
- StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
- }
-
// generate Adler32 intrinsics code
if (UseAdler32Intrinsics) {
StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
--- a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -147,3 +147,62 @@
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
};
+
+/**
+ * CRC32C constants lookup table
+ */
+juint StubRoutines::Sparc::_crc32c_table[] =
+{
+ 0x00000000UL, 0xF26B8303UL, 0xE13B70F7UL, 0x1350F3F4UL, 0xC79A971FUL,
+ 0x35F1141CUL, 0x26A1E7E8UL, 0xD4CA64EBUL, 0x8AD958CFUL, 0x78B2DBCCUL,
+ 0x6BE22838UL, 0x9989AB3BUL, 0x4D43CFD0UL, 0xBF284CD3UL, 0xAC78BF27UL,
+ 0x5E133C24UL, 0x105EC76FUL, 0xE235446CUL, 0xF165B798UL, 0x030E349BUL,
+ 0xD7C45070UL, 0x25AFD373UL, 0x36FF2087UL, 0xC494A384UL, 0x9A879FA0UL,
+ 0x68EC1CA3UL, 0x7BBCEF57UL, 0x89D76C54UL, 0x5D1D08BFUL, 0xAF768BBCUL,
+ 0xBC267848UL, 0x4E4DFB4BUL, 0x20BD8EDEUL, 0xD2D60DDDUL, 0xC186FE29UL,
+ 0x33ED7D2AUL, 0xE72719C1UL, 0x154C9AC2UL, 0x061C6936UL, 0xF477EA35UL,
+ 0xAA64D611UL, 0x580F5512UL, 0x4B5FA6E6UL, 0xB93425E5UL, 0x6DFE410EUL,
+ 0x9F95C20DUL, 0x8CC531F9UL, 0x7EAEB2FAUL, 0x30E349B1UL, 0xC288CAB2UL,
+ 0xD1D83946UL, 0x23B3BA45UL, 0xF779DEAEUL, 0x05125DADUL, 0x1642AE59UL,
+ 0xE4292D5AUL, 0xBA3A117EUL, 0x4851927DUL, 0x5B016189UL, 0xA96AE28AUL,
+ 0x7DA08661UL, 0x8FCB0562UL, 0x9C9BF696UL, 0x6EF07595UL, 0x417B1DBCUL,
+ 0xB3109EBFUL, 0xA0406D4BUL, 0x522BEE48UL, 0x86E18AA3UL, 0x748A09A0UL,
+ 0x67DAFA54UL, 0x95B17957UL, 0xCBA24573UL, 0x39C9C670UL, 0x2A993584UL,
+ 0xD8F2B687UL, 0x0C38D26CUL, 0xFE53516FUL, 0xED03A29BUL, 0x1F682198UL,
+ 0x5125DAD3UL, 0xA34E59D0UL, 0xB01EAA24UL, 0x42752927UL, 0x96BF4DCCUL,
+ 0x64D4CECFUL, 0x77843D3BUL, 0x85EFBE38UL, 0xDBFC821CUL, 0x2997011FUL,
+ 0x3AC7F2EBUL, 0xC8AC71E8UL, 0x1C661503UL, 0xEE0D9600UL, 0xFD5D65F4UL,
+ 0x0F36E6F7UL, 0x61C69362UL, 0x93AD1061UL, 0x80FDE395UL, 0x72966096UL,
+ 0xA65C047DUL, 0x5437877EUL, 0x4767748AUL, 0xB50CF789UL, 0xEB1FCBADUL,
+ 0x197448AEUL, 0x0A24BB5AUL, 0xF84F3859UL, 0x2C855CB2UL, 0xDEEEDFB1UL,
+ 0xCDBE2C45UL, 0x3FD5AF46UL, 0x7198540DUL, 0x83F3D70EUL, 0x90A324FAUL,
+ 0x62C8A7F9UL, 0xB602C312UL, 0x44694011UL, 0x5739B3E5UL, 0xA55230E6UL,
+ 0xFB410CC2UL, 0x092A8FC1UL, 0x1A7A7C35UL, 0xE811FF36UL, 0x3CDB9BDDUL,
+ 0xCEB018DEUL, 0xDDE0EB2AUL, 0x2F8B6829UL, 0x82F63B78UL, 0x709DB87BUL,
+ 0x63CD4B8FUL, 0x91A6C88CUL, 0x456CAC67UL, 0xB7072F64UL, 0xA457DC90UL,
+ 0x563C5F93UL, 0x082F63B7UL, 0xFA44E0B4UL, 0xE9141340UL, 0x1B7F9043UL,
+ 0xCFB5F4A8UL, 0x3DDE77ABUL, 0x2E8E845FUL, 0xDCE5075CUL, 0x92A8FC17UL,
+ 0x60C37F14UL, 0x73938CE0UL, 0x81F80FE3UL, 0x55326B08UL, 0xA759E80BUL,
+ 0xB4091BFFUL, 0x466298FCUL, 0x1871A4D8UL, 0xEA1A27DBUL, 0xF94AD42FUL,
+ 0x0B21572CUL, 0xDFEB33C7UL, 0x2D80B0C4UL, 0x3ED04330UL, 0xCCBBC033UL,
+ 0xA24BB5A6UL, 0x502036A5UL, 0x4370C551UL, 0xB11B4652UL, 0x65D122B9UL,
+ 0x97BAA1BAUL, 0x84EA524EUL, 0x7681D14DUL, 0x2892ED69UL, 0xDAF96E6AUL,
+ 0xC9A99D9EUL, 0x3BC21E9DUL, 0xEF087A76UL, 0x1D63F975UL, 0x0E330A81UL,
+ 0xFC588982UL, 0xB21572C9UL, 0x407EF1CAUL, 0x532E023EUL, 0xA145813DUL,
+ 0x758FE5D6UL, 0x87E466D5UL, 0x94B49521UL, 0x66DF1622UL, 0x38CC2A06UL,
+ 0xCAA7A905UL, 0xD9F75AF1UL, 0x2B9CD9F2UL, 0xFF56BD19UL, 0x0D3D3E1AUL,
+ 0x1E6DCDEEUL, 0xEC064EEDUL, 0xC38D26C4UL, 0x31E6A5C7UL, 0x22B65633UL,
+ 0xD0DDD530UL, 0x0417B1DBUL, 0xF67C32D8UL, 0xE52CC12CUL, 0x1747422FUL,
+ 0x49547E0BUL, 0xBB3FFD08UL, 0xA86F0EFCUL, 0x5A048DFFUL, 0x8ECEE914UL,
+ 0x7CA56A17UL, 0x6FF599E3UL, 0x9D9E1AE0UL, 0xD3D3E1ABUL, 0x21B862A8UL,
+ 0x32E8915CUL, 0xC083125FUL, 0x144976B4UL, 0xE622F5B7UL, 0xF5720643UL,
+ 0x07198540UL, 0x590AB964UL, 0xAB613A67UL, 0xB831C993UL, 0x4A5A4A90UL,
+ 0x9E902E7BUL, 0x6CFBAD78UL, 0x7FAB5E8CUL, 0x8DC0DD8FUL, 0xE330A81AUL,
+ 0x115B2B19UL, 0x020BD8EDUL, 0xF0605BEEUL, 0x24AA3F05UL, 0xD6C1BC06UL,
+ 0xC5914FF2UL, 0x37FACCF1UL, 0x69E9F0D5UL, 0x9B8273D6UL, 0x88D28022UL,
+ 0x7AB90321UL, 0xAE7367CAUL, 0x5C18E4C9UL, 0x4F48173DUL, 0xBD23943EUL,
+ 0xF36E6F75UL, 0x0105EC76UL, 0x12551F82UL, 0xE03E9C81UL, 0x34F4F86AUL,
+ 0xC69F7B69UL, 0xD5CF889DUL, 0x27A40B9EUL, 0x79B737BAUL, 0x8BDCB4B9UL,
+ 0x988C474DUL, 0x6AE7C44EUL, 0xBE2DA0A5UL, 0x4C4623A6UL, 0x5F16D052UL,
+ 0xAD7D5351UL
+};
--- a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,7 @@
// masks and table for CRC32
static uint64_t _crc_by128_masks[];
static juint _crc_table[];
+ static juint _crc32c_table[];
public:
// test assembler stop routine by setting registers
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Fri May 06 18:20:50 2016 +0300
@@ -1081,8 +1081,56 @@
return NULL;
}
-// Not supported
+/**
+ * Method entry for intrinsic-candidate (non-native) methods:
+ * int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
+ * int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long buf, int off, int end)
+ * Unlike CRC32, CRC32C does not have any methods marked as native
+ * CRC32C also uses an "end" variable instead of the length variable CRC32 uses
+ */
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
+
+ if (UseCRC32CIntrinsics) {
+ address entry = __ pc();
+
+ // Load parameters from the stack
+ const Register crc = O0; // initial crc
+ const Register buf = O1; // source java byte array address
+ const Register offset = O2; // offset
+ const Register end = O3; // index of last element to process
+ const Register len = O2; // len argument to the kernel
+ const Register table = O3; // crc32c lookup table address
+
+ // Arguments are reversed on java expression stack
+ // Calculate address of start element
+ if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
+ __ lduw(Gargs, 0, end);
+ __ lduw(Gargs, 8, offset);
+ __ ldx( Gargs, 16, buf);
+ __ lduw(Gargs, 32, crc);
+ __ add(buf, offset, buf);
+ __ sub(end, offset, len);
+ } else {
+ __ lduw(Gargs, 0, end);
+ __ lduw(Gargs, 8, offset);
+ __ ldx( Gargs, 16, buf);
+ __ lduw(Gargs, 24, crc);
+ __ add(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE), buf); // account for the header size
+ __ add(buf, offset, buf);
+ __ sub(end, offset, len);
+ }
+
+ // Call the crc32c kernel
+ __ MacroAssembler::save_thread(L7_thread_cache);
+ __ kernel_crc32c(crc, buf, len, table);
+ __ MacroAssembler::restore_thread(L7_thread_cache);
+
+ // result in O0
+ __ retl();
+ __ delayed()->nop();
+
+ return entry;
+ }
return NULL;
}
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Fri May 06 18:20:50 2016 +0300
@@ -49,9 +49,11 @@
AllocatePrefetchDistance = allocate_prefetch_distance();
AllocatePrefetchStyle = allocate_prefetch_style();
- if (AllocatePrefetchStyle == 3 && !has_blk_init()) {
- warning("BIS instructions are not available on this CPU");
- FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
+ if (!has_blk_init()) {
+ if (AllocatePrefetchInstr == 1) {
+ warning("BIS instructions required for AllocatePrefetchInstr 1 unavailable");
+ FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
+ }
}
UseSSE = 0; // Only on x86 and x64
@@ -88,11 +90,13 @@
if (has_blk_init() && UseTLAB &&
FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
// Use BIS instruction for TLAB allocation prefetch.
- FLAG_SET_ERGO(intx, AllocatePrefetchInstr, 1);
- if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
- FLAG_SET_ERGO(intx, AllocatePrefetchStyle, 3);
- }
- if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
+ FLAG_SET_DEFAULT(AllocatePrefetchInstr, 1);
+ }
+ if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
+ if (AllocatePrefetchInstr == 0) {
+ // Use different prefetch distance without BIS
+ FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
+ } else {
// Use smaller prefetch distance with BIS
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
}
@@ -107,25 +111,14 @@
FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, AllocateInstancePrefetchLines*2);
}
}
- if (AllocatePrefetchStyle != 3 && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
- // Use different prefetch distance without BIS
- FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
- }
- if (AllocatePrefetchInstr == 1) {
- // Need extra space at the end of TLAB for BIS, otherwise prefetching
- // instructions will fault (due to accessing memory outside of heap).
- // The amount of space is the max of the number of lines to
- // prefetch for array and for instance allocations. (Extra space must be
- // reserved to accomodate both types of allocations.)
+ }
- // +1 for rounding up to next cache line, +1 to be safe
- int lines = MAX2(AllocatePrefetchLines, AllocateInstancePrefetchLines) + 2;
- int step_size = AllocatePrefetchStepSize;
- int distance = AllocatePrefetchDistance;
- _reserve_for_allocation_prefetch = (distance + step_size*lines)/(int)HeapWordSize;
- }
+ if (AllocatePrefetchInstr == 1) {
+ // Use allocation prefetch style 3 because BIS instructions
+ // require aligned memory addresses.
+ FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
}
-#endif
+#endif /* COMPILER2 */
}
// Use hardware population count instruction if available.
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Fri May 06 18:20:50 2016 +0300
@@ -2332,6 +2332,22 @@
emit_int8((unsigned char)(0xC0 | encode));
}
+void Assembler::ktestq(KRegister src1, KRegister src2) {
+ assert(VM_Version::supports_avx512bw(), "");
+ InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
+ int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
+ emit_int8((unsigned char)0x99);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::ktestd(KRegister src1, KRegister src2) {
+ assert(VM_Version::supports_avx512bw(), "");
+ InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
+ int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
+ emit_int8((unsigned char)0x99);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
void Assembler::movb(Address dst, int imm8) {
InstructionMark im(this);
prefix(dst);
@@ -2500,7 +2516,7 @@
emit_operand(src, dst);
}
-void Assembler::evmovdqub(KRegister mask, XMMRegister dst, Address src, int vector_len) {
+void Assembler::evmovdqub(XMMRegister dst, KRegister mask, Address src, int vector_len) {
assert(VM_Version::supports_avx512vlbw(), "");
assert(is_vector_masking(), ""); // For stub code use only
InstructionMark im(this);
@@ -2513,16 +2529,6 @@
emit_operand(dst, src);
}
-void Assembler::evmovdquw(XMMRegister dst, XMMRegister src, int vector_len) {
- assert(VM_Version::supports_evex(), "");
- InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
- attributes.set_is_evex_instruction();
- int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
- int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
- emit_int8(0x6F);
- emit_int8((unsigned char)(0xC0 | encode));
-}
-
void Assembler::evmovdquw(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_evex(), "");
InstructionMark im(this);
@@ -2535,6 +2541,19 @@
emit_operand(dst, src);
}
+void Assembler::evmovdquw(XMMRegister dst, KRegister mask, Address src, int vector_len) {
+ assert(is_vector_masking(), "");
+ assert(VM_Version::supports_avx512vlbw(), "");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_embedded_opmask_register_specifier(mask);
+ attributes.set_is_evex_instruction();
+ vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
+ emit_int8(0x6F);
+ emit_operand(dst, src);
+}
+
void Assembler::evmovdquw(Address dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
assert(src != xnoreg, "sanity");
@@ -2548,6 +2567,19 @@
emit_operand(src, dst);
}
+void Assembler::evmovdquw(Address dst, KRegister mask, XMMRegister src, int vector_len) {
+ assert(VM_Version::supports_avx512vlbw(), "");
+ assert(src != xnoreg, "sanity");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_embedded_opmask_register_specifier(mask);
+ attributes.set_is_evex_instruction();
+ vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
+ emit_int8(0x7F);
+ emit_operand(src, dst);
+}
+
void Assembler::evmovdqul(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
@@ -3295,10 +3327,71 @@
emit_int8((unsigned char)(0xC0 | encode));
}
+void Assembler::evpcmpgtb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
+ assert(VM_Version::supports_avx512vlbw(), "");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_is_evex_instruction();
+ int dst_enc = kdst->encoding();
+ vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
+ emit_int8(0x64);
+ emit_operand(as_Register(dst_enc), src);
+}
+
+void Assembler::evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
+ assert(is_vector_masking(), "");
+ assert(VM_Version::supports_avx512vlbw(), "");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_embedded_opmask_register_specifier(mask);
+ attributes.set_is_evex_instruction();
+ int dst_enc = kdst->encoding();
+ vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
+ emit_int8(0x64);
+ emit_operand(as_Register(dst_enc), src);
+}
+
+void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
+ assert(VM_Version::supports_avx512vlbw(), "");
+ InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
+ attributes.set_is_evex_instruction();
+ int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+ emit_int8(0x3E);
+ emit_int8((unsigned char)(0xC0 | encode));
+ emit_int8(vcc);
+}
+
+void Assembler::evpcmpuw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
+ assert(is_vector_masking(), "");
+ assert(VM_Version::supports_avx512vlbw(), "");
+ InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+ attributes.set_embedded_opmask_register_specifier(mask);
+ attributes.set_is_evex_instruction();
+ int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+ emit_int8(0x3E);
+ emit_int8((unsigned char)(0xC0 | encode));
+ emit_int8(vcc);
+}
+
+void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len) {
+ assert(VM_Version::supports_avx512vlbw(), "");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_is_evex_instruction();
+ int dst_enc = kdst->encoding();
+ vex_prefix(src, nds->encoding(), kdst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+ emit_int8(0x3E);
+ emit_operand(as_Register(dst_enc), src);
+ emit_int8(vcc);
+}
+
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
assert(VM_Version::supports_avx512bw(), "");
InstructionMark im(this);
- InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_is_evex_instruction();
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
int dst_enc = kdst->encoding();
@@ -3307,7 +3400,7 @@
emit_operand(as_Register(dst_enc), src);
}
-void Assembler::evpcmpeqb(KRegister mask, KRegister kdst, XMMRegister nds, Address src, int vector_len) {
+void Assembler::evpcmpeqb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
assert(VM_Version::supports_avx512vlbw(), "");
assert(is_vector_masking(), ""); // For stub code use only
InstructionMark im(this);
@@ -3620,6 +3713,46 @@
emit_operand(dst, src);
}
+void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len) {
+ assert(is_vector_masking(), "");
+ assert(VM_Version::supports_avx512vlbw(), "");
+ assert(dst != xnoreg, "sanity");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_embedded_opmask_register_specifier(mask);
+ attributes.set_is_evex_instruction();
+ vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x30);
+ emit_operand(dst, src);
+}
+
+void Assembler::evpmovwb(Address dst, XMMRegister src, int vector_len) {
+ assert(VM_Version::supports_avx512vlbw(), "");
+ assert(src != xnoreg, "sanity");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_is_evex_instruction();
+ vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x30);
+ emit_operand(src, dst);
+}
+
+void Assembler::evpmovwb(Address dst, KRegister mask, XMMRegister src, int vector_len) {
+ assert(is_vector_masking(), "");
+ assert(VM_Version::supports_avx512vlbw(), "");
+ assert(src != xnoreg, "sanity");
+ InstructionMark im(this);
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+ attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.set_embedded_opmask_register_specifier(mask);
+ attributes.set_is_evex_instruction();
+ vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x30);
+ emit_operand(src, dst);
+}
+
// generic
void Assembler::pop(Register dst) {
int encode = prefix_and_encode(dst->encoding());
@@ -6406,7 +6539,6 @@
emit_int8(0x77);
}
-
#ifndef _LP64
// 32bit only pieces of the assembler
@@ -6973,7 +7105,10 @@
emit_int8(byte3);
// P2: byte 4 as zL'Lbv'aaa
- int byte4 = (_attributes->is_no_reg_mask()) ? 0 : _attributes->get_embedded_opmask_register_specifier(); // kregs are implemented in the low 3 bits as aaa (hard code k1, it will be initialized for now)
+ // kregs are implemented in the low 3 bits as aaa (hard code k1, it will be initialized for now)
+ int byte4 = (_attributes->is_no_reg_mask()) ?
+ 0 :
+ _attributes->get_embedded_opmask_register_specifier();
// EVEX.v` for extending EVEX.vvvv or VIDX
byte4 |= (evex_v ? 0: EVEX_V);
// third EXEC.b for broadcast actions
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Fri May 06 18:20:50 2016 +0300
@@ -587,6 +587,16 @@
#endif
};
+ enum ComparisonPredicate {
+ eq = 0,
+ lt = 1,
+ le = 2,
+ _false = 3,
+ neq = 4,
+ nlt = 5,
+ nle = 6,
+ _true = 7
+ };
// NOTE: The general philopsophy of the declarations here is that 64bit versions
@@ -830,7 +840,6 @@
void clear_vector_masking(void) { _vector_masking = false; }
bool is_vector_masking(void) { return _vector_masking; }
-
void lea(Register dst, Address src);
void mov(Register dst, Register src);
@@ -1362,6 +1371,9 @@
void kortestdl(KRegister dst, KRegister src);
void kortestql(KRegister dst, KRegister src);
+ void ktestq(KRegister src1, KRegister src2);
+ void ktestd(KRegister src1, KRegister src2);
+
void ktestql(KRegister dst, KRegister src);
void movdl(XMMRegister dst, Register src);
@@ -1391,10 +1403,11 @@
void evmovdqub(Address dst, XMMRegister src, int vector_len);
void evmovdqub(XMMRegister dst, Address src, int vector_len);
void evmovdqub(XMMRegister dst, XMMRegister src, int vector_len);
- void evmovdqub(KRegister mask, XMMRegister dst, Address src, int vector_len);
+ void evmovdqub(XMMRegister dst, KRegister mask, Address src, int vector_len);
void evmovdquw(Address dst, XMMRegister src, int vector_len);
+ void evmovdquw(Address dst, KRegister mask, XMMRegister src, int vector_len);
void evmovdquw(XMMRegister dst, Address src, int vector_len);
- void evmovdquw(XMMRegister dst, XMMRegister src, int vector_len);
+ void evmovdquw(XMMRegister dst, KRegister mask, Address src, int vector_len);
void evmovdqul(Address dst, XMMRegister src, int vector_len);
void evmovdqul(XMMRegister dst, Address src, int vector_len);
void evmovdqul(XMMRegister dst, XMMRegister src, int vector_len);
@@ -1545,7 +1558,14 @@
void vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len);
void evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vector_len);
- void evpcmpeqb(KRegister mask, KRegister kdst, XMMRegister nds, Address src, int vector_len);
+ void evpcmpeqb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len);
+
+ void evpcmpgtb(KRegister kdst, XMMRegister nds, Address src, int vector_len);
+ void evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len);
+
+ void evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len);
+ void evpcmpuw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, ComparisonPredicate of, int vector_len);
+ void evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len);
void pcmpeqw(XMMRegister dst, XMMRegister src);
void vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
@@ -1589,7 +1609,11 @@
void pmovzxbw(XMMRegister dst, XMMRegister src);
void pmovzxbw(XMMRegister dst, Address src);
- void vpmovzxbw(XMMRegister dst, Address src, int vector_len);
+ void vpmovzxbw( XMMRegister dst, Address src, int vector_len);
+ void evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len);
+
+ void evpmovwb(Address dst, XMMRegister src, int vector_len);
+ void evpmovwb(Address dst, KRegister mask, XMMRegister src, int vector_len);
#ifndef _LP64 // no 32bit push/pop on amd64
void popl(Address dst);
@@ -1839,6 +1863,8 @@
void vsubss(XMMRegister dst, XMMRegister nds, Address src);
void vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src);
+ void shlxl(Register dst, Register src1, Register src2);
+ void shlxq(Register dst, Register src1, Register src2);
//====================VECTOR ARITHMETIC=====================================
@@ -2073,9 +2099,6 @@
void cmppd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len);
void vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len);
- void shlxl(Register dst, Register src1, Register src2);
- void shlxq(Register dst, Register src1, Register src2);
-
protected:
// Next instructions require address alignment 16 bytes SSE mode.
// They should be called only from corresponding MacroAssembler instructions.
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Fri May 06 18:20:50 2016 +0300
@@ -1109,6 +1109,87 @@
}
}
+void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
+ Unimplemented();
+}
+
+void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
+ assert(UseVectorizedMismatchIntrinsic, "need AVX instruction support");
+
+ // Make all state_for calls early since they can emit code
+ LIR_Opr result = rlock_result(x);
+
+ LIRItem a(x->argument_at(0), this); // Object
+ LIRItem aOffset(x->argument_at(1), this); // long
+ LIRItem b(x->argument_at(2), this); // Object
+ LIRItem bOffset(x->argument_at(3), this); // long
+ LIRItem length(x->argument_at(4), this); // int
+ LIRItem log2ArrayIndexScale(x->argument_at(5), this); // int
+
+ a.load_item();
+ aOffset.load_nonconstant();
+ b.load_item();
+ bOffset.load_nonconstant();
+
+ long constant_aOffset = 0;
+ LIR_Opr result_aOffset = aOffset.result();
+ if (result_aOffset->is_constant()) {
+ constant_aOffset = result_aOffset->as_jlong();
+ result_aOffset = LIR_OprFact::illegalOpr;
+ }
+ LIR_Opr result_a = a.result();
+
+ long constant_bOffset = 0;
+ LIR_Opr result_bOffset = bOffset.result();
+ if (result_bOffset->is_constant()) {
+ constant_bOffset = result_bOffset->as_jlong();
+ result_bOffset = LIR_OprFact::illegalOpr;
+ }
+ LIR_Opr result_b = b.result();
+
+#ifndef _LP64
+ result_a = new_register(T_INT);
+ __ convert(Bytecodes::_l2i, a.result(), result_a);
+ result_b = new_register(T_INT);
+ __ convert(Bytecodes::_l2i, b.result(), result_b);
+#endif
+
+
+ LIR_Address* addr_a = new LIR_Address(result_a,
+ result_aOffset,
+ LIR_Address::times_1,
+ constant_aOffset,
+ T_BYTE);
+
+ LIR_Address* addr_b = new LIR_Address(result_b,
+ result_bOffset,
+ LIR_Address::times_1,
+ constant_bOffset,
+ T_BYTE);
+
+ BasicTypeList signature(4);
+ signature.append(T_ADDRESS);
+ signature.append(T_ADDRESS);
+ signature.append(T_INT);
+ signature.append(T_INT);
+ CallingConvention* cc = frame_map()->c_calling_convention(&signature);
+ const LIR_Opr result_reg = result_register_for(x->type());
+
+ LIR_Opr ptr_addr_a = new_pointer_register();
+ __ leal(LIR_OprFact::address(addr_a), ptr_addr_a);
+
+ LIR_Opr ptr_addr_b = new_pointer_register();
+ __ leal(LIR_OprFact::address(addr_b), ptr_addr_b);
+
+ __ move(ptr_addr_a, cc->at(0));
+ __ move(ptr_addr_b, cc->at(1));
+ length.load_item_force(cc->at(2));
+ log2ArrayIndexScale.load_item_force(cc->at(3));
+
+ __ call_runtime_leaf(StubRoutines::vectorizedMismatch(), getThreadTemp(), result_reg, cc->args());
+ __ move(result_reg, result);
+}
+
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
// _i2b, _i2c, _i2s
LIR_Opr fixed_register_for(BasicType type) {
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Fri May 06 18:20:50 2016 +0300
@@ -8259,10 +8259,19 @@
// Search for Non-ASCII character (Negative byte value) in a byte array,
// return true if it has any and false otherwise.
+// ..\jdk\src\java.base\share\classes\java\lang\StringCoding.java
+// @HotSpotIntrinsicCandidate
+// private static boolean hasNegatives(byte[] ba, int off, int len) {
+// for (int i = off; i < off + len; i++) {
+// if (ba[i] < 0) {
+// return true;
+// }
+// }
+// return false;
+// }
void MacroAssembler::has_negatives(Register ary1, Register len,
- Register result, Register tmp1,
- XMMRegister vec1, XMMRegister vec2) {
-
+ Register result, Register tmp1,
+ XMMRegister vec1, XMMRegister vec2) {
// rsi: byte array
// rcx: len
// rax: result
@@ -8275,79 +8284,161 @@
testl(len, len);
jcc(Assembler::zero, FALSE_LABEL);
- movl(result, len); // copy
-
- if (UseAVX >= 2 && UseSSE >= 2) {
- // With AVX2, use 32-byte vector compare
- Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
-
- // Compare 32-byte vectors
- andl(result, 0x0000001f); // tail count (in bytes)
- andl(len, 0xffffffe0); // vector count (in bytes)
- jcc(Assembler::zero, COMPARE_TAIL);
+ if ((UseAVX > 2) && // AVX512
+ VM_Version::supports_avx512vlbw() &&
+ VM_Version::supports_bmi2()) {
+
+ set_vector_masking(); // opening of the stub context for programming mask registers
+
+ Label test_64_loop, test_tail;
+ Register tmp3_aliased = len;
+
+ movl(tmp1, len);
+ vpxor(vec2, vec2, vec2, Assembler::AVX_512bit);
+
+ andl(tmp1, 64 - 1); // tail count (in chars) 0x3F
+ andl(len, ~(64 - 1)); // vector count (in chars)
+ jccb(Assembler::zero, test_tail);
lea(ary1, Address(ary1, len, Address::times_1));
negptr(len);
- movl(tmp1, 0x80808080); // create mask to test for Unicode chars in vector
- movdl(vec2, tmp1);
- vpbroadcastd(vec2, vec2);
-
- bind(COMPARE_WIDE_VECTORS);
- vmovdqu(vec1, Address(ary1, len, Address::times_1));
- vptest(vec1, vec2);
+ bind(test_64_loop);
+ // Check whether our 64 elements of size byte contain negatives
+ evpcmpgtb(k2, vec2, Address(ary1, len, Address::times_1), Assembler::AVX_512bit);
+ kortestql(k2, k2);
jcc(Assembler::notZero, TRUE_LABEL);
- addptr(len, 32);
- jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
-
- testl(result, result);
+
+ addptr(len, 64);
+ jccb(Assembler::notZero, test_64_loop);
+
+
+ bind(test_tail);
+ // bail out when there is nothing to be done
+ testl(tmp1, -1);
jcc(Assembler::zero, FALSE_LABEL);
- vmovdqu(vec1, Address(ary1, result, Address::times_1, -32));
- vptest(vec1, vec2);
+ // Save k1
+ kmovql(k3, k1);
+
+ // ~(~0 << len) applied up to two times (for 32-bit scenario)
+#ifdef _LP64
+ mov64(tmp3_aliased, 0xFFFFFFFFFFFFFFFF);
+ shlxq(tmp3_aliased, tmp3_aliased, tmp1);
+ notq(tmp3_aliased);
+ kmovql(k1, tmp3_aliased);
+#else
+ Label k_init;
+ jmp(k_init);
+
+ // We could not read 64-bits from a general purpose register thus we move
+ // data required to compose 64 1's to the instruction stream
+ // We emit 64 byte wide series of elements from 0..63 which later on would
+ // be used as a compare targets with tail count contained in tmp1 register.
+ // Result would be a k1 register having tmp1 consecutive number or 1
+ // counting from least significant bit.
+ address tmp = pc();
+ emit_int64(0x0706050403020100);
+ emit_int64(0x0F0E0D0C0B0A0908);
+ emit_int64(0x1716151413121110);
+ emit_int64(0x1F1E1D1C1B1A1918);
+ emit_int64(0x2726252423222120);
+ emit_int64(0x2F2E2D2C2B2A2928);
+ emit_int64(0x3736353433323130);
+ emit_int64(0x3F3E3D3C3B3A3938);
+
+ bind(k_init);
+ lea(len, InternalAddress(tmp));
+ // create mask to test for negative byte inside a vector
+ evpbroadcastb(vec1, tmp1, Assembler::AVX_512bit);
+ evpcmpgtb(k1, vec1, Address(len, 0), Assembler::AVX_512bit);
+
+#endif
+ evpcmpgtb(k2, k1, vec2, Address(ary1, 0), Assembler::AVX_512bit);
+ ktestq(k2, k1);
+ // Restore k1
+ kmovql(k1, k3);
jcc(Assembler::notZero, TRUE_LABEL);
+
jmp(FALSE_LABEL);
- bind(COMPARE_TAIL); // len is zero
- movl(len, result);
- // Fallthru to tail compare
- } else if (UseSSE42Intrinsics) {
- assert(UseSSE >= 4, "SSE4 must be for SSE4.2 intrinsics to be available");
- // With SSE4.2, use double quad vector compare
- Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
-
- // Compare 16-byte vectors
- andl(result, 0x0000000f); // tail count (in bytes)
- andl(len, 0xfffffff0); // vector count (in bytes)
- jccb(Assembler::zero, COMPARE_TAIL);
-
- lea(ary1, Address(ary1, len, Address::times_1));
- negptr(len);
-
- movl(tmp1, 0x80808080);
- movdl(vec2, tmp1);
- pshufd(vec2, vec2, 0);
-
- bind(COMPARE_WIDE_VECTORS);
- movdqu(vec1, Address(ary1, len, Address::times_1));
- ptest(vec1, vec2);
- jcc(Assembler::notZero, TRUE_LABEL);
- addptr(len, 16);
- jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
-
- testl(result, result);
- jcc(Assembler::zero, FALSE_LABEL);
-
- movdqu(vec1, Address(ary1, result, Address::times_1, -16));
- ptest(vec1, vec2);
- jccb(Assembler::notZero, TRUE_LABEL);
- jmpb(FALSE_LABEL);
-
- bind(COMPARE_TAIL); // len is zero
- movl(len, result);
- // Fallthru to tail compare
- }
-
+ clear_vector_masking(); // closing of the stub context for programming mask registers
+ }
+ else {
+ movl(result, len); // copy
+
+ if (UseAVX == 2 && UseSSE >= 2) {
+ // With AVX2, use 32-byte vector compare
+ Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
+
+ // Compare 32-byte vectors
+ andl(result, 0x0000001f); // tail count (in bytes)
+ andl(len, 0xffffffe0); // vector count (in bytes)
+ jccb(Assembler::zero, COMPARE_TAIL);
+
+ lea(ary1, Address(ary1, len, Address::times_1));
+ negptr(len);
+
+ movl(tmp1, 0x80808080); // create mask to test for Unicode chars in vector
+ movdl(vec2, tmp1);
+ vpbroadcastd(vec2, vec2);
+
+ bind(COMPARE_WIDE_VECTORS);
+ vmovdqu(vec1, Address(ary1, len, Address::times_1));
+ vptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ addptr(len, 32);
+ jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
+
+ testl(result, result);
+ jccb(Assembler::zero, FALSE_LABEL);
+
+ vmovdqu(vec1, Address(ary1, result, Address::times_1, -32));
+ vptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ jmpb(FALSE_LABEL);
+
+ bind(COMPARE_TAIL); // len is zero
+ movl(len, result);
+ // Fallthru to tail compare
+ }
+ else if (UseSSE42Intrinsics) {
+ assert(UseSSE >= 4, "SSE4 must be for SSE4.2 intrinsics to be available");
+ // With SSE4.2, use double quad vector compare
+ Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
+
+ // Compare 16-byte vectors
+ andl(result, 0x0000000f); // tail count (in bytes)
+ andl(len, 0xfffffff0); // vector count (in bytes)
+ jccb(Assembler::zero, COMPARE_TAIL);
+
+ lea(ary1, Address(ary1, len, Address::times_1));
+ negptr(len);
+
+ movl(tmp1, 0x80808080);
+ movdl(vec2, tmp1);
+ pshufd(vec2, vec2, 0);
+
+ bind(COMPARE_WIDE_VECTORS);
+ movdqu(vec1, Address(ary1, len, Address::times_1));
+ ptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ addptr(len, 16);
+ jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
+
+ testl(result, result);
+ jccb(Assembler::zero, FALSE_LABEL);
+
+ movdqu(vec1, Address(ary1, result, Address::times_1, -16));
+ ptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ jmpb(FALSE_LABEL);
+
+ bind(COMPARE_TAIL); // len is zero
+ movl(len, result);
+ // Fallthru to tail compare
+ }
+ }
// Compare 4-byte vectors
andl(len, 0xfffffffc); // vector count (in bytes)
jccb(Assembler::zero, COMPARE_CHAR);
@@ -8395,7 +8486,6 @@
vpxor(vec2, vec2);
}
}
-
// Compare char[] or byte[] arrays aligned to 4 bytes or substrings.
void MacroAssembler::arrays_equals(bool is_array_equ, Register ary1, Register ary2,
Register limit, Register result, Register chr,
@@ -8841,10 +8931,23 @@
}
// encode char[] to byte[] in ISO_8859_1
+ //@HotSpotIntrinsicCandidate
+ //private static int implEncodeISOArray(byte[] sa, int sp,
+ //byte[] da, int dp, int len) {
+ // int i = 0;
+ // for (; i < len; i++) {
+ // char c = StringUTF16.getChar(sa, sp++);
+ // if (c > '\u00FF')
+ // break;
+ // da[dp++] = (byte)c;
+ // }
+ // return i;
+ //}
void MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
- XMMRegister tmp1Reg, XMMRegister tmp2Reg,
- XMMRegister tmp3Reg, XMMRegister tmp4Reg,
- Register tmp5, Register result) {
+ XMMRegister tmp1Reg, XMMRegister tmp2Reg,
+ XMMRegister tmp3Reg, XMMRegister tmp4Reg,
+ Register tmp5, Register result) {
+
// rsi: src
// rdi: dst
// rdx: len
@@ -8859,6 +8962,7 @@
// check for zero length
testl(len, len);
jcc(Assembler::zero, L_done);
+
movl(result, len);
// Setup pointers
@@ -8967,6 +9071,7 @@
bind(L_copy_1_char_exit);
addptr(result, len); // len is negative count of not processed elements
+
bind(L_done);
}
@@ -9478,8 +9583,8 @@
notq(tmp2);
kmovql(k1, tmp2);
- evmovdqub(k1, rymm0, Address(obja, result), Assembler::AVX_512bit);
- evpcmpeqb(k1, k7, rymm0, Address(objb, result), Assembler::AVX_512bit);
+ evmovdqub(rymm0, k1, Address(obja, result), Assembler::AVX_512bit);
+ evpcmpeqb(k7, k1, rymm0, Address(objb, result), Assembler::AVX_512bit);
ktestql(k7, k1);
// Restore k1
@@ -10838,13 +10943,24 @@
#undef BIND
#undef BLOCK_COMMENT
-
// Compress char[] array to byte[].
+// ..\jdk\src\java.base\share\classes\java\lang\StringUTF16.java
+// @HotSpotIntrinsicCandidate
+// private static int compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) {
+// for (int i = 0; i < len; i++) {
+// int c = src[srcOff++];
+// if (c >>> 8 != 0) {
+// return 0;
+// }
+// dst[dstOff++] = (byte)c;
+// }
+// return len;
+// }
void MacroAssembler::char_array_compress(Register src, Register dst, Register len,
- XMMRegister tmp1Reg, XMMRegister tmp2Reg,
- XMMRegister tmp3Reg, XMMRegister tmp4Reg,
- Register tmp5, Register result) {
- Label copy_chars_loop, return_length, return_zero, done;
+ XMMRegister tmp1Reg, XMMRegister tmp2Reg,
+ XMMRegister tmp3Reg, XMMRegister tmp4Reg,
+ Register tmp5, Register result) {
+ Label copy_chars_loop, return_length, return_zero, done, below_threshold;
// rsi: src
// rdi: dst
@@ -10861,11 +10977,141 @@
// save length for return
push(len);
+ if ((UseAVX > 2) && // AVX512
+ VM_Version::supports_avx512vlbw() &&
+ VM_Version::supports_bmi2()) {
+
+ set_vector_masking(); // opening of the stub context for programming mask registers
+
+ Label copy_32_loop, copy_loop_tail, copy_just_portion_of_candidates;
+
+ // alignement
+ Label post_alignement;
+
+ // if length of the string is less than 16, handle it in an old fashioned
+ // way
+ testl(len, -32);
+ jcc(Assembler::zero, below_threshold);
+
+ // First check whether a character is compressable ( <= 0xFF).
+ // Create mask to test for Unicode chars inside zmm vector
+ movl(result, 0x00FF);
+ evpbroadcastw(tmp2Reg, result, Assembler::AVX_512bit);
+
+ testl(len, -64);
+ jcc(Assembler::zero, post_alignement);
+
+ // Save k1
+ kmovql(k3, k1);
+
+ movl(tmp5, dst);
+ andl(tmp5, (64 - 1));
+ negl(tmp5);
+ andl(tmp5, (64 - 1));
+
+ // bail out when there is nothing to be done
+ testl(tmp5, 0xFFFFFFFF);
+ jcc(Assembler::zero, post_alignement);
+
+ // ~(~0 << len), where len is the # of remaining elements to process
+ movl(result, 0xFFFFFFFF);
+ shlxl(result, result, tmp5);
+ notl(result);
+
+ kmovdl(k1, result);
+
+ evmovdquw(tmp1Reg, k1, Address(src, 0), Assembler::AVX_512bit);
+ evpcmpuw(k2, k1, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit);
+ ktestd(k2, k1);
+ jcc(Assembler::carryClear, copy_just_portion_of_candidates);
+
+ evpmovwb(Address(dst, 0), k1, tmp1Reg, Assembler::AVX_512bit);
+
+ addptr(src, tmp5);
+ addptr(src, tmp5);
+ addptr(dst, tmp5);
+ subl(len, tmp5);
+
+ bind(post_alignement);
+ // end of alignement
+
+ movl(tmp5, len);
+ andl(tmp5, (32 - 1)); // tail count (in chars)
+ andl(len, ~(32 - 1)); // vector count (in chars)
+ jcc(Assembler::zero, copy_loop_tail);
+
+ lea(src, Address(src, len, Address::times_2));
+ lea(dst, Address(dst, len, Address::times_1));
+ negptr(len);
+
+ bind(copy_32_loop);
+ evmovdquw(tmp1Reg, Address(src, len, Address::times_2), Assembler::AVX_512bit);
+ evpcmpuw(k2, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit);
+ kortestdl(k2, k2);
+ jcc(Assembler::carryClear, copy_just_portion_of_candidates);
+
+ // All elements in current processed chunk are valid candidates for
+ // compression. Write a truncated byte elements to the memory.
+ evpmovwb(Address(dst, len, Address::times_1), tmp1Reg, Assembler::AVX_512bit);
+ addptr(len, 32);
+ jcc(Assembler::notZero, copy_32_loop);
+
+ bind(copy_loop_tail);
+ // bail out when there is nothing to be done
+ testl(tmp5, 0xFFFFFFFF);
+ jcc(Assembler::zero, return_length);
+
+ // Save k1
+ kmovql(k3, k1);
+
+ movl(len, tmp5);
+
+ // ~(~0 << len), where len is the # of remaining elements to process
+ movl(result, 0xFFFFFFFF);
+ shlxl(result, result, len);
+ notl(result);
+
+ kmovdl(k1, result);
+
+ evmovdquw(tmp1Reg, k1, Address(src, 0), Assembler::AVX_512bit);
+ evpcmpuw(k2, k1, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit);
+ ktestd(k2, k1);
+ jcc(Assembler::carryClear, copy_just_portion_of_candidates);
+
+ evpmovwb(Address(dst, 0), k1, tmp1Reg, Assembler::AVX_512bit);
+ // Restore k1
+ kmovql(k1, k3);
+
+ jmp(return_length);
+
+ bind(copy_just_portion_of_candidates);
+ kmovdl(tmp5, k2);
+ tzcntl(tmp5, tmp5);
+
+ // ~(~0 << tmp5), where tmp5 is a number of elements in an array from the
+ // result to the first element larger than 0xFF
+ movl(result, 0xFFFFFFFF);
+ shlxl(result, result, tmp5);
+ notl(result);
+
+ kmovdl(k1, result);
+
+ evpmovwb(Address(dst, 0), k1, tmp1Reg, Assembler::AVX_512bit);
+ // Restore k1
+ kmovql(k1, k3);
+
+ jmp(return_zero);
+
+ clear_vector_masking(); // closing of the stub context for programming mask registers
+ }
if (UseSSE42Intrinsics) {
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
Label copy_32_loop, copy_16, copy_tail;
+ bind(below_threshold);
+
movl(result, len);
+
movl(tmp5, 0xff00ff00); // create mask to test for Unicode chars in vectors
// vectored compression
@@ -10947,10 +11193,16 @@
}
// Inflate byte[] array to char[].
+// ..\jdk\src\java.base\share\classes\java\lang\StringLatin1.java
+// @HotSpotIntrinsicCandidate
+// private static void inflate(byte[] src, int srcOff, char[] dst, int dstOff, int len) {
+// for (int i = 0; i < len; i++) {
+// dst[dstOff++] = (char)(src[srcOff++] & 0xff);
+// }
+// }
void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len,
- XMMRegister tmp1, Register tmp2) {
- Label copy_chars_loop, done;
-
+ XMMRegister tmp1, Register tmp2) {
+ Label copy_chars_loop, done, below_threshold;
// rsi: src
// rdi: dst
// rdx: len
@@ -10961,20 +11213,109 @@
// rdx holds length
assert_different_registers(src, dst, len, tmp2);
+ if ((UseAVX > 2) && // AVX512
+ VM_Version::supports_avx512vlbw() &&
+ VM_Version::supports_bmi2()) {
+
+ set_vector_masking(); // opening of the stub context for programming mask registers
+
+ Label copy_32_loop, copy_tail;
+ Register tmp3_aliased = len;
+
+ // if length of the string is less than 16, handle it in an old fashioned
+ // way
+ testl(len, -16);
+ jcc(Assembler::zero, below_threshold);
+
+ // In order to use only one arithmetic operation for the main loop we use
+ // this pre-calculation
+ movl(tmp2, len);
+ andl(tmp2, (32 - 1)); // tail count (in chars), 32 element wide loop
+ andl(len, -32); // vector count
+ jccb(Assembler::zero, copy_tail);
+
+ lea(src, Address(src, len, Address::times_1));
+ lea(dst, Address(dst, len, Address::times_2));
+ negptr(len);
+
+
+ // inflate 32 chars per iter
+ bind(copy_32_loop);
+ vpmovzxbw(tmp1, Address(src, len, Address::times_1), Assembler::AVX_512bit);
+ evmovdquw(Address(dst, len, Address::times_2), tmp1, Assembler::AVX_512bit);
+ addptr(len, 32);
+ jcc(Assembler::notZero, copy_32_loop);
+
+ bind(copy_tail);
+ // bail out when there is nothing to be done
+ testl(tmp2, -1); // we don't destroy the contents of tmp2 here
+ jcc(Assembler::zero, done);
+
+ // Save k1
+ kmovql(k2, k1);
+
+ // ~(~0 << length), where length is the # of remaining elements to process
+ movl(tmp3_aliased, -1);
+ shlxl(tmp3_aliased, tmp3_aliased, tmp2);
+ notl(tmp3_aliased);
+ kmovdl(k1, tmp3_aliased);
+ evpmovzxbw(tmp1, k1, Address(src, 0), Assembler::AVX_512bit);
+ evmovdquw(Address(dst, 0), k1, tmp1, Assembler::AVX_512bit);
+
+ // Restore k1
+ kmovql(k1, k2);
+ jmp(done);
+
+ clear_vector_masking(); // closing of the stub context for programming mask registers
+ }
if (UseSSE42Intrinsics) {
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
- Label copy_8_loop, copy_bytes, copy_tail;
+ Label copy_16_loop, copy_8_loop, copy_bytes, copy_new_tail, copy_tail;
movl(tmp2, len);
- andl(tmp2, 0x00000007); // tail count (in chars)
- andl(len, 0xfffffff8); // vector count (in chars)
- jccb(Assembler::zero, copy_tail);
+
+ if (UseAVX > 1) {
+ andl(tmp2, (16 - 1));
+ andl(len, -16);
+ jccb(Assembler::zero, copy_new_tail);
+ } else {
+ andl(tmp2, 0x00000007); // tail count (in chars)
+ andl(len, 0xfffffff8); // vector count (in chars)
+ jccb(Assembler::zero, copy_tail);
+ }
// vectored inflation
lea(src, Address(src, len, Address::times_1));
lea(dst, Address(dst, len, Address::times_2));
negptr(len);
+ if (UseAVX > 1) {
+ bind(copy_16_loop);
+ vpmovzxbw(tmp1, Address(src, len, Address::times_1), Assembler::AVX_256bit);
+ vmovdqu(Address(dst, len, Address::times_2), tmp1);
+ addptr(len, 16);
+ jcc(Assembler::notZero, copy_16_loop);
+
+ bind(below_threshold);
+ bind(copy_new_tail);
+ if (UseAVX > 2) {
+ movl(tmp2, len);
+ }
+ else {
+ movl(len, tmp2);
+ }
+ andl(tmp2, 0x00000007);
+ andl(len, 0xFFFFFFF8);
+ jccb(Assembler::zero, copy_tail);
+
+ pmovzxbw(tmp1, Address(src, 0));
+ movdqu(Address(dst, 0), tmp1);
+ addptr(src, 8);
+ addptr(dst, 2 * 8);
+
+ jmp(copy_tail, true);
+ }
+
// inflate 8 chars per iter
bind(copy_8_loop);
pmovzxbw(tmp1, Address(src, len, Address::times_1)); // unpack to 8 words
@@ -11013,7 +11354,6 @@
bind(done);
}
-
Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
switch (cond) {
// Note some conditions are synonyms for others
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Fri May 06 18:20:50 2016 +0300
@@ -847,7 +847,7 @@
void call(Label& L, relocInfo::relocType rtype);
void call(Register entry);
- // NOTE: this call tranfers to the effective address of entry NOT
+ // NOTE: this call transfers to the effective address of entry NOT
// the address contained by entry. This is because this is more natural
// for jumps/calls.
void call(AddressLiteral entry);
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri May 06 18:20:50 2016 +0300
@@ -4409,7 +4409,7 @@
* c_rarg0 - int crc
* c_rarg1 - byte* buf
* c_rarg2 - long length
- * c_rarg3 - table_start - optional (present only when doing a library_calll,
+ * c_rarg3 - table_start - optional (present only when doing a library_call,
* not used by x86 algorithm)
*
* Ouput:
@@ -4532,6 +4532,9 @@
* c_rarg1 - objb address
* c_rarg3 - length length
* c_rarg4 - scale log2_array_indxscale
+ *
+ * Output:
+ * rax - int >= mismatched index, < 0 bitwise complement of tail
*/
address generate_vectorizedMismatch() {
__ align(CodeEntryAlignment);
@@ -5291,9 +5294,6 @@
if (UseMulAddIntrinsic) {
StubRoutines::_mulAdd = generate_mulAdd();
}
- if (UseVectorizedMismatchIntrinsic) {
- StubRoutines::_vectorizedMismatch = generate_vectorizedMismatch();
- }
#ifndef _WINDOWS
if (UseMontgomeryMultiplyIntrinsic) {
StubRoutines::_montgomeryMultiply
@@ -5305,6 +5305,10 @@
}
#endif // WINDOWS
#endif // COMPILER2
+
+ if (UseVectorizedMismatchIntrinsic) {
+ StubRoutines::_vectorizedMismatch = generate_vectorizedMismatch();
+ }
}
public:
--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp Fri May 06 18:20:50 2016 +0300
@@ -289,9 +289,9 @@
}
/**
-* Method entry for static native methods:
+* Method entry for static (non-native) methods:
* int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
-* int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
+* int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long address, int off, int end)
*/
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
if (UseCRC32CIntrinsics) {
@@ -306,7 +306,7 @@
// Arguments are reversed on java expression stack
// Calculate address of start element
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
- __ movptr(buf, Address(rsp, 3 * wordSize)); // long buf
+ __ movptr(buf, Address(rsp, 3 * wordSize)); // long address
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
__ addq(buf, off); // + offset
__ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC
--- a/hotspot/src/cpu/x86/vm/x86.ad Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/x86.ad Fri May 06 18:20:50 2016 +0300
@@ -1861,6 +1861,8 @@
return false;
}
+const bool Matcher::convi2l_type_required = true;
+
// Helper methods for MachSpillCopyNode::implementation().
static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, uint ireg, outputStream* st) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java Fri May 06 18:20:50 2016 +0300
@@ -326,8 +326,9 @@
Address vmInternalInfoAddr = vmVersion.getAddressField("_s_internal_vm_info_string").getValue();
vmInternalInfo = CStringUtilities.getString(vmInternalInfoAddr);
+ Type threadLocalAllocBuffer = db.lookupType("ThreadLocalAllocBuffer");
CIntegerType intType = (CIntegerType) db.lookupType("int");
- CIntegerField reserveForAllocationPrefetchField = vmVersion.getCIntegerField("_reserve_for_allocation_prefetch");
+ CIntegerField reserveForAllocationPrefetchField = threadLocalAllocBuffer.getCIntegerField("_reserve_for_allocation_prefetch");
reserveForAllocationPrefetch = (int)reserveForAllocationPrefetchField.getCInteger(intType);
} catch (Exception exp) {
throw new RuntimeException("can't determine target's VM version : " + exp.getMessage());
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Fri May 06 18:20:50 2016 +0300
@@ -146,6 +146,9 @@
@Override
public JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant baseConstant, long displacement) {
+ if (kind == null) {
+ throw new IllegalArgumentException("null JavaKind");
+ }
if (kind == JavaKind.Object) {
Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops);
return HotSpotObjectConstantImpl.forObject(o);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java Fri May 06 18:20:50 2016 +0300
@@ -130,7 +130,7 @@
/* Load non-public field: LambdaForm MethodHandle.form */
JavaConstant lambdaForm = constantReflection.readFieldValue(LazyInitialization.methodHandleFormField, methodHandle);
- if (lambdaForm.isNull()) {
+ if (lambdaForm == null || lambdaForm.isNull()) {
return null;
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Fri May 06 18:20:50 2016 +0300
@@ -882,4 +882,9 @@
public boolean isTrustedInterfaceType() {
return TrustedInterface.class.isAssignableFrom(mirror());
}
+
+ @Override
+ public boolean isCloneableWithAllocation() {
+ return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0;
+ }
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java Fri May 06 18:20:50 2016 +0300
@@ -267,4 +267,9 @@
public boolean isTrustedInterfaceType() {
return false;
}
+
+ @Override
+ public boolean isCloneableWithAllocation() {
+ return false;
+ }
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Fri May 06 18:20:50 2016 +0300
@@ -1077,6 +1077,7 @@
@HotSpotVMConstant(name = "JVM_ACC_FIELD_STABLE") @Stable public int jvmAccFieldStable;
@HotSpotVMConstant(name = "JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE") @Stable public int jvmAccFieldHasGenericSignature;
@HotSpotVMConstant(name = "JVM_ACC_WRITTEN_FLAGS") @Stable public int jvmAccWrittenFlags;
+ @HotSpotVMConstant(name = "JVM_ACC_IS_CLONEABLE_FAST") @Stable public int jvmAccIsCloneableFast;
// Modifier.SYNTHETIC is not public so we get it via vmStructs.
@HotSpotVMConstant(name = "JVM_ACC_SYNTHETIC") @Stable public int jvmAccSynthetic;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java Fri May 06 18:20:50 2016 +0300
@@ -35,8 +35,8 @@
* @param displacement the displacement within the object in bytes
* @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
* value cannot be read.
- * @throws IllegalArgumentException if {@code kind} is {@link JavaKind#Void} or not
- * {@linkplain JavaKind#isPrimitive() primitive} kind
+ * @throws IllegalArgumentException if {@code kind} is {@code null}, {@link JavaKind#Void} or
+ * not {@linkplain JavaKind#isPrimitive() primitive} kind
*/
JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant base, long displacement) throws IllegalArgumentException;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Fri May 06 18:20:50 2016 +0300
@@ -359,4 +359,12 @@
}
return null;
}
+
+ /**
+ * Returns true if this type is {@link Cloneable} and can be safely cloned by creating a normal
+ * Java allocation and populating it from the fields returned by
+ * {@link #getInstanceFields(boolean)}. Some types may require special handling by the platform
+ * so they would to go through the normal {@link Object#clone} path.
+ */
+ boolean isCloneableWithAllocation();
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,13 @@
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.util.PropertiesSheet;
import java.awt.Image;
import java.util.List;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
+import org.openide.nodes.Sheet;
import org.openide.util.ImageUtilities;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
@@ -75,6 +77,16 @@
}
@Override
+ protected Sheet createSheet() {
+ Sheet s = super.createSheet();
+ if (children.folder instanceof Properties.Entity) {
+ Properties.Entity p = (Properties.Entity) children.folder;
+ PropertiesSheet.initializeSheet(p.getProperties(), s);
+ }
+ return s;
+ }
+
+ @Override
public Image getIcon(int i) {
return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png");
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -124,6 +124,8 @@
public void clear() {
document.clear();
+ root = new FolderNode(document);
+ manager.setRootContext(root);
}
@Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,31 +31,47 @@
import com.sun.hotspot.igv.data.serialization.ParseMonitor;
import com.sun.hotspot.igv.data.serialization.Parser;
import com.sun.hotspot.igv.settings.Settings;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
-import javax.swing.Action;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.JFileChooser;
-import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.util.Exceptions;
+import org.openide.util.RequestProcessor;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
-import org.openide.util.RequestProcessor;
-import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.SystemAction;
/**
*
* @author Thomas Wuerthinger
*/
-public final class ImportAction extends CallableSystemAction {
+
+@ActionID(
+ category = "File",
+ id = "com.sun.hotspot.igv.coordinator.actions.ImportAction"
+)
+@ActionRegistration(
+ iconBase = "com/sun/hotspot/igv/coordinator/images/import.png",
+ displayName = "#CTL_ImportAction"
+)
+@ActionReferences({
+ @ActionReference(path = "Menu/File", position = 0),
+ @ActionReference(path = "Shortcuts", name = "C-O")
+})
+public final class ImportAction extends SystemAction {
private static final int WORKUNITS = 10000;
public static FileFilter getFileFilter() {
@@ -74,74 +90,77 @@
}
@Override
- public void performAction() {
-
+ public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser();
fc.setFileFilter(ImportAction.getFileFilter());
fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+ fc.setMultiSelectionEnabled(true);
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
- File file = fc.getSelectedFile();
-
- File dir = file;
- if (!dir.isDirectory()) {
- dir = dir.getParentFile();
- }
+ for (final File file : fc.getSelectedFiles()) {
+ File dir = file;
+ if (!dir.isDirectory()) {
+ dir = dir.getParentFile();
+ }
- Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
- try {
- final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
- final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
- handle.start(WORKUNITS);
- final long start = channel.size();
- ParseMonitor monitor = new ParseMonitor() {
- @Override
- public void updateProgress() {
- try {
- int prog = (int) (WORKUNITS * (double) channel.position() / (double) start);
- handle.progress(prog);
- } catch (IOException ex) {
- }
- }
- @Override
- public void setState(String state) {
- updateProgress();
- handle.progress(state);
+ Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
+ try {
+ final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
+ final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
+ handle.start(WORKUNITS);
+ final long startTime = System.currentTimeMillis();
+ final long start = channel.size();
+ ParseMonitor monitor = new ParseMonitor() {
+ @Override
+ public void updateProgress() {
+ try {
+ int prog = (int) (WORKUNITS * (double) channel.position() / (double) start);
+ handle.progress(prog);
+ } catch (IOException ex) {
+ }
+ }
+ @Override
+ public void setState(String state) {
+ updateProgress();
+ handle.progress(state);
+ }
+ };
+ final GraphParser parser;
+ final OutlineTopComponent component = OutlineTopComponent.findInstance();
+ if (file.getName().endsWith(".xml")) {
+ parser = new Parser(channel, monitor, null);
+ } else if (file.getName().endsWith(".bgv")) {
+ parser = new BinaryParser(channel, monitor, component.getDocument(), null);
+ } else {
+ parser = null;
}
- };
- final GraphParser parser;
- final OutlineTopComponent component = OutlineTopComponent.findInstance();
- if (file.getName().endsWith(".xml")) {
- parser = new Parser(channel, monitor, null);
- } else if (file.getName().endsWith(".bgv")) {
- parser = new BinaryParser(channel, monitor, component.getDocument(), null);
- } else {
- parser = null;
+ RequestProcessor.getDefault().post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final GraphDocument document = parser.parse();
+ if (document != null) {
+ SwingUtilities.invokeLater(new Runnable(){
+ @Override
+ public void run() {
+ component.requestActive();
+ component.getDocument().addGraphDocument(document);
+ }
+ });
+ }
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ handle.finish();
+ long stop = System.currentTimeMillis();
+ Logger.getLogger(getClass().getName()).log(Level.INFO, "Loaded in " + file + " in " + ((stop - startTime) / 1000.0) + " seconds");
+ }
+ });
+ } catch (FileNotFoundException ex) {
+ Exceptions.printStackTrace(ex);
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
}
- RequestProcessor.getDefault().post(new Runnable() {
- @Override
- public void run() {
- try {
- final GraphDocument document = parser.parse();
- if (document != null) {
- SwingUtilities.invokeLater(new Runnable(){
- @Override
- public void run() {
- component.requestActive();
- component.getDocument().addGraphDocument(document);
- }
- });
- }
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- handle.finish();
- }
- });
- } catch (FileNotFoundException ex) {
- Exceptions.printStackTrace(ex);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
}
}
}
@@ -151,11 +170,6 @@
return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction");
}
- public ImportAction() {
- putValue(Action.SHORT_DESCRIPTION, "Open XML graph document...");
- putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
- }
-
@Override
protected String iconResource() {
return "com/sun/hotspot/igv/coordinator/images/import.png";
@@ -165,9 +179,4 @@
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
-
- @Override
- protected boolean asynchronous() {
- return false;
- }
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,14 +29,30 @@
import java.awt.event.KeyEvent;
import javax.swing.Action;
import javax.swing.KeyStroke;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
/**
*
* @author Thomas Wuerthinger
*/
+@ActionID(
+ category = "File",
+ id = "com.sun.hotspot.igv.coordinator.actions.SaveAllAction"
+)
+@ActionRegistration(
+ displayName = "#CTL_SaveAllAction"
+)
+@ActionReferences({
+ @ActionReference(path = "Menu/File", position = 0),
+ @ActionReference(path = "Shortcuts", name = "C-S")
+})
public final class SaveAllAction extends CallableSystemAction {
@Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml Fri May 06 18:20:50 2016 +0300
@@ -18,6 +18,8 @@
<folder name="Menu">
<folder name="File">
+ <file name="Export_hidden"/>
+ <file name="Import_hidden"/>
<file name="Separator2.instance_hidden"/>
<file name="Separator3.instance_hidden"/>
<file name="SeparatorOpen.instance_hidden"/>
@@ -43,11 +45,11 @@
</file>
<file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
- <attr name="position" intvalue="400" />
+ <attr name="position" intvalue="400"/>
</file>
<file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
- <attr name="position" intvalue="500" />
+ <attr name="position" intvalue="500"/>
</file>
<!-- Hidden menu entries from other modules -->
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,11 +51,13 @@
}
public void addGraphDocument(GraphDocument document) {
- for (FolderElement e : document.elements) {
- e.setParent(this);
- this.addElement(e);
+ if (document != this) {
+ for (FolderElement e : document.elements) {
+ e.setParent(this);
+ this.addElement(e);
+ }
+ document.clear();
}
- document.clear();
getChangedEvent().fire();
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,7 +90,9 @@
public void addNode(int id) {
InputNode node = graph.getNode(id);
assert node != null;
- assert !nodes.contains(node) : "duplicate : " + node;
+ // nodes.contains(node) is too expensive for large graphs so
+ // just make sure the Graph doesn't know it yet.
+ assert graph.getBlock(id) == null : "duplicate : " + node;
graph.setBlock(node, this);
nodes.add(node);
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,9 @@
package com.sun.hotspot.igv.data;
import java.io.Serializable;
+import java.lang.ref.WeakReference;
import java.util.*;
+import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -36,7 +38,7 @@
public class Properties implements Serializable, Iterable<Property> {
public static final long serialVersionUID = 1L;
- private String[] map = new String[4];
+ protected String[] map = new String[4];
public Properties() {
}
@@ -102,6 +104,59 @@
System.arraycopy(p.map, 0, map, 0, p.map.length);
}
+ protected Properties(String[] map) {
+ this.map = map;
+ }
+
+ static class SharedProperties extends Properties {
+ int hashCode;
+
+ SharedProperties(String[] map) {
+ super(map);
+ this.hashCode = Arrays.hashCode(map);
+ }
+
+ @Override
+ protected void setPropertyInternal(String name, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof SharedProperties)) {
+ return super.equals(other);
+ }
+ SharedProperties props2 = (SharedProperties) other;
+ return Arrays.equals(map, props2.map);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+ }
+
+ private static class PropertyCache {
+ static WeakHashMap<SharedProperties, WeakReference<SharedProperties>> immutableCache = new WeakHashMap<>();
+
+ static synchronized SharedProperties intern(Properties properties) {
+ String[] map = properties.map;
+ SharedProperties key = new SharedProperties(map);
+ WeakReference<SharedProperties> entry = immutableCache.get(key);
+ if (entry != null) {
+ SharedProperties props = entry.get();
+ if (props != null) {
+ return props;
+ }
+ }
+ immutableCache.put(key, new WeakReference<>(key));
+ return key;
+ }
+ }
+
public static class Entity implements Provider {
private Properties properties;
@@ -118,6 +173,10 @@
public Properties getProperties() {
return properties;
}
+
+ public void internProperties() {
+ properties = PropertyCache.intern(properties);
+ }
}
public interface PropertyMatcher {
@@ -322,8 +381,8 @@
public void setProperty(String name, String value) {
setPropertyInternal(name.intern(), value != null ? value.intern() : null);
}
- private void setPropertyInternal(String name, String value) {
+ protected void setPropertyInternal(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];
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -68,6 +69,8 @@
private static final String NO_BLOCK = "noBlock";
+ private static final Charset utf8 = Charset.forName("UTF-8");
+
private final GroupCallback callback;
private final List<Object> constantPool;
private final ByteBuffer buffer;
@@ -275,28 +278,36 @@
hashStack = new LinkedList<>();
this.monitor = monitor;
try {
- this.digest = MessageDigest.getInstance("SHA-256");
+ this.digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
}
}
private void fill() throws IOException {
+ // All the data between lastPosition and position has been
+ // used so add it to the digest.
+ int position = buffer.position();
+ buffer.position(lastPosition);
+ byte[] remaining = new byte[position - buffer.position()];
+ buffer.get(remaining);
+ digest.update(remaining);
+ assert position == buffer.position();
+
buffer.compact();
if (channel.read(buffer) < 0) {
throw new EOFException();
}
buffer.flip();
+ lastPosition = buffer.position();
}
private void ensureAvailable(int i) throws IOException {
+ if (i > buffer.capacity()) {
+ throw new IllegalArgumentException(String.format("Can not request %d bytes: buffer capacity is %d", i, buffer.capacity()));
+ }
while (buffer.remaining() < i) {
fill();
}
- buffer.mark();
- byte[] result = new byte[i];
- buffer.get(result);
- digest.update(result);
- buffer.reset();
}
private int readByte() throws IOException {
@@ -330,12 +341,7 @@
}
private String readString() throws IOException {
- int len = readInt();
- ensureAvailable(len * 2);
- char[] chars = new char[len];
- buffer.asCharBuffer().get(chars);
- buffer.position(buffer.position() + len * 2);
- return new String(chars).intern();
+ return new String(readBytes(), utf8).intern();
}
private byte[] readBytes() throws IOException {
@@ -343,10 +349,15 @@
if (len < 0) {
return null;
}
- ensureAvailable(len);
- byte[] data = new byte[len];
- buffer.get(data);
- return data;
+ byte[] b = new byte[len];
+ int bytesRead = 0;
+ while (bytesRead < b.length) {
+ int toRead = Math.min(b.length - bytesRead, buffer.capacity());
+ ensureAvailable(toRead);
+ buffer.get(b, bytesRead, toRead);
+ bytesRead += toRead;
+ }
+ return b;
}
private String readIntsToString() throws IOException {
@@ -643,6 +654,7 @@
int bci = readInt();
Group group = new Group(parent);
group.getProperties().setProperty("name", name);
+ parseProperties(group.getProperties());
if (method != null) {
InputMethod inMethod = new InputMethod(group, method.name, shortName, bci);
inMethod.setBytecodes("TODO");
@@ -651,13 +663,25 @@
return group;
}
+ int lastPosition = 0;
+
private InputGraph parseGraph() throws IOException {
if (monitor != null) {
monitor.updateProgress();
}
String title = readPoolObject(String.class);
digest.reset();
+ lastPosition = buffer.position();
InputGraph graph = parseGraph(title);
+
+ int position = buffer.position();
+ buffer.position(lastPosition);
+ byte[] remaining = new byte[position - buffer.position()];
+ buffer.get(remaining);
+ digest.update(remaining);
+ assert position == buffer.position();
+ lastPosition = buffer.position();
+
byte[] d = digest.digest();
byte[] hash = hashStack.peek();
if (hash != null && Arrays.equals(hash, d)) {
@@ -669,11 +693,24 @@
return graph;
}
+ private void parseProperties(Properties properties) throws IOException {
+ int propCount = readShort();
+ for (int j = 0; j < propCount; j++) {
+ String key = readPoolObject(String.class);
+ Object value = readPropertyObject();
+ properties.setProperty(key, value != null ? value.toString() : "null");
+ }
+ }
+
private InputGraph parseGraph(String title) throws IOException {
InputGraph graph = new InputGraph(title);
+ parseProperties(graph.getProperties());
parseNodes(graph);
parseBlocks(graph);
graph.ensureNodesInBlocks();
+ for (InputNode node : graph.getNodes()) {
+ node.internProperties();
+ }
return graph;
}
@@ -822,9 +859,10 @@
}
}
+ static final Pattern templatePattern = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}");
+
private String createName(List<Edge> edges, Map<String, Object> properties, String template) {
- Pattern p = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}");
- Matcher m = p.matcher(template);
+ Matcher m = templatePattern.matcher(template);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String name = m.group(2);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,4 +37,14 @@
InputGraph getGraph();
void setSelectedNodes(Set<InputNode> nodes);
+
+ /**
+ * @return an iterator walking forward through the {@link InputGraph}s following the {@link #getGraph()}
+ */
+ Iterable<InputGraph> searchForward();
+
+ /**
+ * @return an iterator walking backward through the {@link InputGraph}s preceeding the {@link #getGraph()}
+ */
+ Iterable<InputGraph> searchBackward();
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml Fri May 06 18:20:50 2016 +0300
@@ -22,6 +22,14 @@
<specification-version>1.0</specification-version>
</run-dependency>
</dependency>
+ <dependency>
+ <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.0</specification-version>
+ </run-dependency>
+ </dependency>
</module-dependencies>
<public-packages>
<package>com.sun.hotspot.igv.graph</package>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
import com.sun.hotspot.igv.data.Source;
import com.sun.hotspot.igv.layout.Port;
import com.sun.hotspot.igv.layout.Vertex;
+import com.sun.hotspot.igv.util.StringUtils;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
@@ -141,7 +142,7 @@
sb.append(text);
for (InputNode n : getSource().getSourceNodes()) {
- sb.append("Node (ID=" + n.getId() + "): " + n.getProperties().get("name"));
+ sb.append(StringUtils.escapeHTML("Node (ID=" + n.getId() + "): " + n.getProperties().get("name")));
sb.append("<br>");
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -445,5 +445,48 @@
void close() {
filterChain.getChangedEvent().removeListener(filterChainChangedListener);
sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
+ }
+
+ Iterable<InputGraph> getGraphsForward() {
+ return new Iterable<InputGraph>() {
+
+ @Override
+ public Iterator<InputGraph> iterator() {
+ return new Iterator<InputGraph>() {
+ int index = getFirstPosition();
+
+ @Override
+ public boolean hasNext() {
+ return index + 1 < graphs.size();
+ }
+
+ @Override
+ public InputGraph next() {
+ return graphs.get(++index);
+ }
+ };
+ }
+ };
+ }
+
+ Iterable<InputGraph> getGraphsBackward() {
+ return new Iterable<InputGraph>() {
+ @Override
+ public Iterator<InputGraph> iterator() {
+ return new Iterator<InputGraph>() {
+ int index = getFirstPosition();
+
+ @Override
+ public boolean hasNext() {
+ return index - 1 > 0;
+ }
+
+ @Override
+ public InputGraph next() {
+ return graphs.get(--index);
+ }
+ };
+ }
+ };
+ }
}
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,4 +50,14 @@
public void setSelectedNodes(Set<InputNode> nodes) {
editor.setSelectedNodes(nodes);
}
+
+ @Override
+ public Iterable<InputGraph> searchBackward() {
+ return editor.getDiagramModel().getGraphsBackward();
+ }
+
+ @Override
+ public Iterable<InputGraph> searchForward() {
+ return editor.getDiagramModel().getGraphsForward();
+ }
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -289,7 +289,10 @@
quicksearch = (Component) quicksearch.getClass().getConstructor(KeyStroke.class).newInstance(new Object[]{null});
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
}
- quicksearch.setMinimumSize(quicksearch.getPreferredSize()); // necessary for GTK LAF
+ Dimension preferredSize = quicksearch.getPreferredSize();
+ preferredSize = new Dimension((int) preferredSize.getWidth() * 2, (int) preferredSize.getHeight());
+ quicksearch.setMinimumSize(preferredSize); // necessary for GTK LAF
+ quicksearch.setPreferredSize(preferredSize);
toolBar.add(quicksearch);
centerPanel = new JPanel();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
package com.sun.hotspot.igv.view;
+import com.sun.hotspot.igv.data.InputGraph;
import com.sun.hotspot.igv.data.InputNode;
import com.sun.hotspot.igv.data.Properties;
import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
@@ -81,57 +82,67 @@
final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
if (p != null && p.getGraph() != null) {
- List<InputNode> matches = null;
- try {
- RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE);
- Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(p.getGraph().getNodes());
-
- matches = selector.selectMultiple(matcher);
- } catch (Exception e) {
- final String msg = e.getMessage();
- response.addResult(new Runnable() {
- @Override
- public void run() {
- Message desc = new NotifyDescriptor.Message("An exception occurred during the search, "
- + "perhaps due to a malformed query string:\n" + msg,
- NotifyDescriptor.WARNING_MESSAGE);
- DialogDisplayer.getDefault().notify(desc);
- }
- },
- "(Error during search)"
- );
+ InputGraph matchGraph = p.getGraph();
+ // Search the current graph
+ List<InputNode> matches = findMatches(name, value, p.getGraph(), response);
+ if (matches == null) {
+ // See if the it hits in a later graph
+ for (InputGraph graph : p.searchForward()) {
+ matches = findMatches(name, value, graph, response);
+ if (matches != null) {
+ matchGraph = graph;
+ break;
+ }
+ }
+ }
+ if (matches == null) {
+ // See if it hits in a earlier graph
+ for (InputGraph graph : p.searchBackward()) {
+ matches = findMatches(name, value, graph, response);
+ if (matches != null) {
+ matchGraph = graph;
+ break;
+ }
+ }
}
if (matches != null) {
final Set<InputNode> set = new HashSet<>(matches);
+ final InputGraph theGraph = p.getGraph() != matchGraph ? matchGraph : null;
response.addResult(new Runnable() {
@Override
- public void run() {
- final EditorTopComponent comp = EditorTopComponent.getActive();
- if (comp != null) {
- comp.setSelectedNodes(set);
- comp.requestActive();
+ public void run() {
+ final EditorTopComponent comp = EditorTopComponent.getActive();
+ if (comp != null) {
+ if (theGraph != null) {
+ comp.getDiagramModel().selectGraph(theGraph);
}
+ comp.setSelectedNodes(set);
+ comp.requestActive();
}
- },
- "All " + matches.size() + " matching nodes (" + name + "=" + value + ")"
+ }
+ },
+ "All " + matches.size() + " matching nodes (" + name + "=" + value + ")" + (theGraph != null ? " in " + theGraph.getName() : "")
);
// Single matches
for (final InputNode n : matches) {
response.addResult(new Runnable() {
@Override
- public void run() {
- final EditorTopComponent comp = EditorTopComponent.getActive();
- if (comp != null) {
- final Set<InputNode> tmpSet = new HashSet<>();
- tmpSet.add(n);
- comp.setSelectedNodes(tmpSet);
- comp.requestActive();
+ public void run() {
+ final EditorTopComponent comp = EditorTopComponent.getActive();
+ if (comp != null) {
+ final Set<InputNode> tmpSet = new HashSet<>();
+ tmpSet.add(n);
+ if (theGraph != null) {
+ comp.getDiagramModel().selectGraph(theGraph);
}
+ comp.setSelectedNodes(tmpSet);
+ comp.requestActive();
}
- },
- n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")"
+ }
+ },
+ n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")" + (theGraph != null ? " in " + theGraph.getName() : "")
);
}
}
@@ -139,4 +150,27 @@
System.out.println("no input graph provider!");
}
}
+
+ private List<InputNode> findMatches(String name, String value, InputGraph inputGraph, SearchResponse response) {
+ try {
+ RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE);
+ Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(inputGraph.getNodes());
+ List<InputNode> matches = selector.selectMultiple(matcher);
+ return matches.size() == 0 ? null : matches;
+ } catch (Exception e) {
+ final String msg = e.getMessage();
+ response.addResult(new Runnable() {
+ @Override
+ public void run() {
+ Message desc = new NotifyDescriptor.Message("An exception occurred during the search, "
+ + "perhaps due to a malformed query string:\n" + msg,
+ NotifyDescriptor.WARNING_MESSAGE);
+ DialogDisplayer.getDefault().notify(desc);
+ }
+ },
+ "(Error during search)"
+ );
+ }
+ return null;
+ }
}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml Fri May 06 18:20:50 2016 +0300
@@ -61,14 +61,26 @@
<attr name="position" intvalue="710"/>
</file>
</folder>
+ <folder name="Window">
+ <file name="Tools_hidden"/>
+ <file name="Web_hidden"/>
+ <file name="org-netbeans-modules-tasks-ui-DashboardTopComponent.shadow_hidden"/>
+ </folder>
</folder>
<folder name="QuickSearch">
+ <file name="Actions_hidden"/>
+ <file name="GoToOption_hidden"/>
+ <file name="GoToSymbol_hidden"/>
+ <file name="GoToType_hidden"/>
+ <file name="Help_hidden"/>
+ <file name="Hudson_hidden"/>
<folder name="Nodes">
<attr name="command" stringvalue="n"/>
<attr name="position" intvalue="0"/>
<file name="com-sun-hotspot-igv-view-NodeQuickSearch.instance"/>
</folder>
+ <file name="Projects_hidden"/>
</folder>
<folder name="QuickSearchShadow">
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
import com.sun.hotspot.igv.graph.Figure;
import com.sun.hotspot.igv.graph.InputSlot;
import com.sun.hotspot.igv.graph.OutputSlot;
+import com.sun.hotspot.igv.util.StringUtils;
import com.sun.hotspot.igv.view.DiagramScene;
import java.awt.*;
import java.awt.geom.Line2D;
@@ -148,7 +149,7 @@
private String generateToolTipText(List<Connection> conn) {
StringBuilder sb = new StringBuilder();
for (Connection c : conn) {
- sb.append(c.getToolTipText());
+ sb.append(StringUtils.escapeHTML(c.getToolTipText()));
sb.append("<br>");
}
return sb.toString();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Fri May 06 18:20:50 2016 +0300
@@ -48,5 +48,5 @@
# Disable assertions for RequestProcessor to prevent annoying messages in case
# of multiple SceneAnimator update tasks in the default RequestProcessor.
-run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx8g -J-Djava.lang.Integer.IntegerCache.high=20000
+run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx8g -J-Djava.lang.Integer.IntegerCache.high=200000
debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -224,6 +224,11 @@
case vmIntrinsics::_updateCRC32:
case vmIntrinsics::_updateBytesCRC32:
case vmIntrinsics::_updateByteBufferCRC32:
+#ifdef SPARC
+ case vmIntrinsics::_updateBytesCRC32C:
+ case vmIntrinsics::_updateDirectByteBufferCRC32C:
+#endif
+ case vmIntrinsics::_vectorizedMismatch:
case vmIntrinsics::_compareAndSwapInt:
case vmIntrinsics::_compareAndSwapObject:
case vmIntrinsics::_getCharStringU:
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri May 06 18:20:50 2016 +0300
@@ -3174,6 +3174,15 @@
do_update_CRC32(x);
break;
+ case vmIntrinsics::_updateBytesCRC32C:
+ case vmIntrinsics::_updateDirectByteBufferCRC32C:
+ do_update_CRC32C(x);
+ break;
+
+ case vmIntrinsics::_vectorizedMismatch:
+ do_vectorizedMismatch(x);
+ break;
+
default: ShouldNotReachHere(); break;
}
}
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Fri May 06 18:20:50 2016 +0300
@@ -253,6 +253,8 @@
void do_FPIntrinsics(Intrinsic* x);
void do_Reference_get(Intrinsic* x);
void do_update_CRC32(Intrinsic* x);
+ void do_update_CRC32C(Intrinsic* x);
+ void do_vectorizedMismatch(Intrinsic* x);
LIR_Opr call_runtime(BasicTypeArray* signature, LIRItemList* args, address entry, ValueType* result_type, CodeEmitInfo* info);
LIR_Opr call_runtime(BasicTypeArray* signature, LIR_OprList* args, address entry, ValueType* result_type, CodeEmitInfo* info);
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri May 06 18:20:50 2016 +0300
@@ -318,6 +318,8 @@
FUNCTION_CASE(entry, TRACE_TIME_METHOD);
#endif
FUNCTION_CASE(entry, StubRoutines::updateBytesCRC32());
+ FUNCTION_CASE(entry, StubRoutines::updateBytesCRC32C());
+ FUNCTION_CASE(entry, StubRoutines::vectorizedMismatch());
FUNCTION_CASE(entry, StubRoutines::dexp());
FUNCTION_CASE(entry, StubRoutines::dlog());
FUNCTION_CASE(entry, StubRoutines::dlog10());
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Fri May 06 18:20:50 2016 +0300
@@ -552,7 +552,7 @@
}
replay_state = this;
CompileBroker::compile_method(method, entry_bci, comp_level,
- methodHandle(), 0, "replay", THREAD);
+ methodHandle(), 0, CompileTask::Reason_Replay, THREAD);
replay_state = NULL;
reset();
}
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Fri May 06 18:20:50 2016 +0300
@@ -1647,7 +1647,7 @@
}
// Force compilation
CompileBroker::compile_method(m, InvocationEntryBci, comp_level,
- methodHandle(), 0, "CTW", THREAD);
+ methodHandle(), 0, CompileTask::Reason_CTW, THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
@@ -1663,7 +1663,7 @@
m->clear_code();
}
CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization,
- methodHandle(), 0, "CTW", THREAD);
+ methodHandle(), 0, CompileTask::Reason_CTW, THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Fri May 06 18:20:50 2016 +0300
@@ -353,6 +353,7 @@
case vmIntrinsics::_updateCRC32:
case vmIntrinsics::_updateBytesCRC32:
case vmIntrinsics::_updateByteBufferCRC32:
+ case vmIntrinsics::_vectorizedMismatch:
return true;
default:
return false;
@@ -384,6 +385,7 @@
case vmIntrinsics::_updateCRC32:
case vmIntrinsics::_updateBytesCRC32:
case vmIntrinsics::_updateByteBufferCRC32:
+ case vmIntrinsics::_vectorizedMismatch:
return false;
default:
return true;
@@ -669,6 +671,9 @@
case vmIntrinsics::_updateDirectByteBufferCRC32C:
if (!UseCRC32CIntrinsics) return true;
break;
+ case vmIntrinsics::_vectorizedMismatch:
+ if (!UseVectorizedMismatchIntrinsic) return true;
+ break;
case vmIntrinsics::_updateBytesAdler32:
case vmIntrinsics::_updateByteBufferAdler32:
if (!UseAdler32Intrinsics) return true;
@@ -734,9 +739,6 @@
case vmIntrinsics::_montgomerySquare:
if (!UseMontgomerySquareIntrinsic) return true;
break;
- case vmIntrinsics::_vectorizedMismatch:
- if (!UseVectorizedMismatchIntrinsic) return true;
- break;
case vmIntrinsics::_addExactI:
case vmIntrinsics::_addExactL:
case vmIntrinsics::_decrementExactI:
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri May 06 18:20:50 2016 +0300
@@ -117,6 +117,7 @@
template(java_util_Hashtable, "java/util/Hashtable") \
template(java_lang_Compiler, "java/lang/Compiler") \
template(jdk_internal_misc_Signal, "jdk/internal/misc/Signal") \
+ template(jdk_internal_util_Preconditions, "jdk/internal/util/Preconditions") \
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
template(jdk_internal_vm_PostVMInitHook, "jdk/internal/vm/PostVMInitHook") \
@@ -934,8 +935,8 @@
do_intrinsic(_equalsL, java_lang_StringLatin1,equals_name, equalsB_signature, F_S) \
do_intrinsic(_equalsU, java_lang_StringUTF16, equals_name, equalsB_signature, F_S) \
\
- do_intrinsic(_Objects_checkIndex, java_util_Objects, checkIndex_name, Objects_checkIndex_signature, F_S) \
- do_signature(Objects_checkIndex_signature, "(IILjava/util/function/BiFunction;)I") \
+ do_intrinsic(_Preconditions_checkIndex, jdk_internal_util_Preconditions, checkIndex_name, Preconditions_checkIndex_signature, F_S) \
+ do_signature(Preconditions_checkIndex_signature, "(IILjava/util/function/BiFunction;)I") \
\
do_class(java_nio_Buffer, "java/nio/Buffer") \
do_intrinsic(_checkIndex, java_nio_Buffer, checkIndex_name, int_int_signature, F_R) \
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri May 06 18:20:50 2016 +0300
@@ -169,6 +169,8 @@
CompileQueue* CompileBroker::_c2_compile_queue = NULL;
CompileQueue* CompileBroker::_c1_compile_queue = NULL;
+
+
class CompilationLog : public StringEventLog {
public:
CompilationLog() : StringEventLog("Compilation events") {
@@ -844,7 +846,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking,
Thread* thread) {
guarantee(!method->is_abstract(), "cannot compile abstract methods");
@@ -860,7 +862,7 @@
if (osr_bci != InvocationEntryBci) {
tty->print(" osr_bci: %d", osr_bci);
}
- tty->print(" level: %d comment: %s count: %d", comp_level, comment, hot_count);
+ tty->print(" level: %d comment: %s count: %d", comp_level, CompileTask::reason_name(compile_reason), hot_count);
if (!hot_method.is_null()) {
tty->print(" hot: ");
if (hot_method() != method()) {
@@ -1024,7 +1026,7 @@
task = create_compile_task(queue,
compile_id, method,
osr_bci, comp_level,
- hot_method, hot_count, comment,
+ hot_method, hot_count, compile_reason,
blocking);
}
@@ -1036,15 +1038,18 @@
nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
int comp_level,
const methodHandle& hot_method, int hot_count,
- const char* comment, Thread* THREAD) {
- // do nothing if compilebroker is not available
- if (!_initialized) {
+ CompileTask::CompileReason compile_reason,
+ Thread* THREAD) {
+ // Do nothing if compilebroker is not initalized or compiles are submitted on level none
+ if (!_initialized || comp_level == CompLevel_none) {
return NULL;
}
+
AbstractCompiler *comp = CompileBroker::compiler(comp_level);
- assert(comp != NULL, "Ensure we don't compile before compilebroker init");
+ assert(comp != NULL, "Ensure we have a compiler");
+
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp);
- nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_method, hot_count, comment, directive, THREAD);
+ nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, directive, THREAD);
DirectivesStack::release(directive);
return nm;
}
@@ -1052,7 +1057,8 @@
nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
int comp_level,
const methodHandle& hot_method, int hot_count,
- const char* comment, DirectiveSet* directive,
+ CompileTask::CompileReason compile_reason,
+ DirectiveSet* directive,
Thread* THREAD) {
// make sure arguments make sense
@@ -1178,7 +1184,7 @@
return NULL;
}
bool is_blocking = !directive->BackgroundCompilationOption || CompileTheWorld || ReplayCompiles;
- compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, is_blocking, THREAD);
+ compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, is_blocking, THREAD);
}
// return requested nmethod
@@ -1342,11 +1348,11 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking) {
CompileTask* new_task = CompileTask::allocate();
new_task->initialize(compile_id, method, osr_bci, comp_level,
- hot_method, hot_count, comment,
+ hot_method, hot_count, compile_reason,
blocking);
queue->add(new_task);
return new_task;
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Fri May 06 18:20:50 2016 +0300
@@ -232,7 +232,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking);
static void wait_for_completion(CompileTask* task);
#if INCLUDE_JVMCI
@@ -251,7 +251,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking,
Thread* thread);
@@ -289,14 +289,15 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment, Thread* thread);
+ CompileTask::CompileReason compile_reason,
+ Thread* thread);
static nmethod* compile_method(const methodHandle& method,
int osr_bci,
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
DirectiveSet* directive,
Thread* thread);
--- a/hotspot/src/share/vm/compiler/compileTask.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/compiler/compileTask.cpp Fri May 06 18:20:50 2016 +0300
@@ -82,7 +82,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool is_blocking) {
assert(!_lock->is_locked(), "bad locking");
@@ -104,7 +104,7 @@
_hot_method_holder = NULL;
_hot_count = hot_count;
_time_queued = 0; // tidy
- _comment = comment;
+ _compile_reason = compile_reason;
_failure_reason = NULL;
if (LogCompilation) {
@@ -309,9 +309,9 @@
xtty->begin_elem("task_queued");
log_task(xtty);
- if (_comment != NULL) {
- xtty->print(" comment='%s'", _comment);
- }
+ assert(_compile_reason > CompileTask::Reason_None && _compile_reason < CompileTask::Reason_Count, "Valid values");
+ xtty->print(" comment='%s'", reason_name(_compile_reason));
+
if (_hot_method != NULL) {
methodHandle hot(thread, _hot_method);
methodHandle method(thread, _method);
@@ -440,3 +440,5 @@
}
st->cr();
}
+
+
--- a/hotspot/src/share/vm/compiler/compileTask.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/compiler/compileTask.hpp Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,39 @@
friend class VMStructs;
friend class JVMCIVMStructs;
+ public:
+ // Different reasons for a compilation
+ // The order is important - Reason_Whitebox and higher can not become
+ // stale, see CompileTask::can_become_stale()
+ // Also mapped to reason_names[]
+ enum CompileReason {
+ Reason_None,
+ Reason_InvocationCount, // Simple/StackWalk-policy
+ Reason_BackedgeCount, // Simple/StackWalk-policy
+ Reason_Tiered, // Tiered-policy
+ Reason_CTW, // Compile the world
+ Reason_Replay, // ciReplay
+ Reason_Whitebox, // Whitebox API
+ Reason_MustBeCompiled, // Java callHelper, LinkResolver
+ Reason_Bootstrap, // JVMCI bootstrap
+ Reason_Count
+ };
+
+ static const char* reason_name(CompileTask::CompileReason compile_reason) {
+ static const char* reason_names[] = {
+ "no_reason",
+ "count",
+ "backedge_count",
+ "tiered",
+ "CTW",
+ "replay",
+ "whitebox",
+ "must_be_compiled",
+ "bootstrap"
+ };
+ return reason_names[compile_reason];
+ }
+
private:
static CompileTask* _task_free_list;
#ifdef ASSERT
@@ -69,7 +102,7 @@
Method* _hot_method; // which method actually triggered this task
jobject _hot_method_holder;
int _hot_count; // information about its invocation counter
- const char* _comment; // more info about the task
+ CompileReason _compile_reason; // more info about the task
const char* _failure_reason;
public:
@@ -78,8 +111,8 @@
}
void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level,
- const methodHandle& hot_method, int hot_count, const char* comment,
- bool is_blocking);
+ const methodHandle& hot_method, int hot_count,
+ CompileTask::CompileReason compile_reason, bool is_blocking);
static CompileTask* allocate();
static void free(CompileTask* task);
@@ -91,6 +124,15 @@
bool is_complete() const { return _is_complete; }
bool is_blocking() const { return _is_blocking; }
bool is_success() const { return _is_success; }
+ bool can_become_stale() const {
+ switch (_compile_reason) {
+ case Reason_BackedgeCount:
+ case Reason_InvocationCount:
+ case Reason_Tiered:
+ return !_is_blocking;
+ }
+ return false;
+ }
#if INCLUDE_JVMCI
bool has_waiter() const { return _has_waiter; }
void clear_waiter() { _has_waiter = false; }
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.cpp Fri May 06 18:20:50 2016 +0300
@@ -36,6 +36,7 @@
// static member initialization
size_t ThreadLocalAllocBuffer::_max_size = 0;
+int ThreadLocalAllocBuffer::_reserve_for_allocation_prefetch = 0;
unsigned ThreadLocalAllocBuffer::_target_refills = 0;
GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL;
@@ -215,6 +216,23 @@
_global_stats = new GlobalTLABStats();
+ // Need extra space at the end of TLAB, otherwise prefetching
+ // instructions will fault (due to accessing memory outside of heap).
+ // The amount of space is the max of the number of lines to
+ // prefetch for array and for instance allocations. (Extra space must be
+ // reserved to accommodate both types of allocations.)
+ //
+ // Only SPARC-specific BIS instructions are known to fault. (Those
+ // instructions are generated if AllocatePrefetchStyle==3 and
+ // AllocatePrefetchInstr==1). To be on the safe side, however,
+ // extra space is reserved for all combinations of
+ // AllocatePrefetchStyle and AllocatePrefetchInstr.
+
+ // +1 for rounding up to next cache line, +1 to be safe
+ int lines = MAX2(AllocatePrefetchLines, AllocateInstancePrefetchLines) + 2;
+ _reserve_for_allocation_prefetch = (AllocatePrefetchDistance + AllocatePrefetchStepSize * lines) /
+ (int)HeapWordSize;
+
// During jvm startup, the main (primordial) thread is initialized
// before the heap is initialized. So reinitialize it now.
guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread");
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.hpp Fri May 06 18:20:50 2016 +0300
@@ -49,8 +49,9 @@
size_t _refill_waste_limit; // hold onto tlab if free() is larger than this
size_t _allocated_before_last_gc; // total bytes allocated up until the last gc
- static size_t _max_size; // maximum size of any TLAB
- static unsigned _target_refills; // expected number of refills between GCs
+ static size_t _max_size; // maximum size of any TLAB
+ static int _reserve_for_allocation_prefetch; // Reserve at the end of the TLAB
+ static unsigned _target_refills; // expected number of refills between GCs
unsigned _number_of_refills;
unsigned _fast_refill_waste;
@@ -129,7 +130,7 @@
// Reserve space at the end of TLAB
static size_t end_reserve() {
int reserve_size = typeArrayOopDesc::header_size(T_INT);
- return MAX2(reserve_size, VM_Version::reserve_for_allocation_prefetch());
+ return MAX2(reserve_size, _reserve_for_allocation_prefetch);
}
static size_t alignment_reserve() { return align_object_size(end_reserve()); }
static size_t alignment_reserve_in_bytes() { return alignment_reserve() * HeapWordSize; }
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Fri May 06 18:20:50 2016 +0300
@@ -85,7 +85,7 @@
if (!mh->is_native() && !mh->is_static() && !mh->is_initializer()) {
ResourceMark rm;
int hot_count = 10; // TODO: what's the appropriate value?
- CompileBroker::compile_method(mh, InvocationEntryBci, CompLevel_full_optimization, mh, hot_count, "bootstrap", THREAD);
+ CompileBroker::compile_method(mh, InvocationEntryBci, CompLevel_full_optimization, mh, hot_count, CompileTask::Reason_Bootstrap, THREAD);
}
}
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Fri May 06 18:20:50 2016 +0300
@@ -425,19 +425,22 @@
}
JRT_END
-JRT_ENTRY(void, JVMCIRuntime::throw_and_post_jvmti_exception(JavaThread* thread, Symbol* name, const char* message))
- SharedRuntime::throw_and_post_jvmti_exception(thread, name, message);
+JRT_ENTRY(void, JVMCIRuntime::throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message))
+ TempNewSymbol symbol = SymbolTable::new_symbol(exception, CHECK);
+ SharedRuntime::throw_and_post_jvmti_exception(thread, symbol, message);
JRT_END
-JRT_ENTRY(void, JVMCIRuntime::throw_klass_external_name_exception(JavaThread* thread, Symbol* exception, Klass* klass))
+JRT_ENTRY(void, JVMCIRuntime::throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass))
ResourceMark rm(thread);
- SharedRuntime::throw_and_post_jvmti_exception(thread, exception, klass->external_name());
+ TempNewSymbol symbol = SymbolTable::new_symbol(exception, CHECK);
+ SharedRuntime::throw_and_post_jvmti_exception(thread, symbol, klass->external_name());
JRT_END
-JRT_ENTRY(void, JVMCIRuntime::throw_class_cast_exception(JavaThread* thread, Symbol* exception, Klass* caster_klass, Klass* target_klass))
+JRT_ENTRY(void, JVMCIRuntime::throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass))
ResourceMark rm(thread);
const char* message = SharedRuntime::generate_class_cast_message(caster_klass, target_klass);
- SharedRuntime::throw_and_post_jvmti_exception(thread, exception, message);
+ TempNewSymbol symbol = SymbolTable::new_symbol(exception, CHECK);
+ SharedRuntime::throw_and_post_jvmti_exception(thread, symbol, message);
JRT_END
JRT_LEAF(void, JVMCIRuntime::log_object(JavaThread* thread, oopDesc* obj, bool as_string, bool newline))
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Fri May 06 18:20:50 2016 +0300
@@ -156,10 +156,10 @@
static void new_store_pre_barrier(JavaThread* thread);
// used to throw exceptions from compiled JVMCI code
- static void throw_and_post_jvmti_exception(JavaThread* thread, Symbol* exception, const char* message);
+ static void throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message);
// helper methods to throw exception with complex messages
- static void throw_klass_external_name_exception(JavaThread* thread, Symbol* exception, Klass* klass);
- static void throw_class_cast_exception(JavaThread* thread, Symbol* exception, Klass* caster_klass, Klass* target_klass);
+ static void throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass);
+ static void throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass);
// Test only function
static int test_deoptimize_call_int(JavaThread* thread, int value);
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Fri May 06 18:20:50 2016 +0300
@@ -309,6 +309,7 @@
declare_constant(JVM_ACC_MONITOR_MATCH) \
declare_constant(JVM_ACC_HAS_MONITOR_BYTECODES) \
declare_constant(JVM_ACC_HAS_FINALIZER) \
+ declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \
declare_constant(JVM_ACC_FIELD_INTERNAL) \
declare_constant(JVM_ACC_FIELD_STABLE) \
declare_constant(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) \
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Fri May 06 18:20:50 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -545,7 +545,7 @@
case vmIntrinsics::_updateByteBufferAdler32:
case vmIntrinsics::_profileBoolean:
case vmIntrinsics::_isCompileConstant:
- case vmIntrinsics::_Objects_checkIndex:
+ case vmIntrinsics::_Preconditions_checkIndex:
break;
default:
return false;
--- a/hotspot/src/share/vm/opto/compile.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/compile.cpp Fri May 06 18:20:50 2016 +0300
@@ -3263,6 +3263,43 @@
frc._tests.push(iff);
break;
}
+ case Op_ConvI2L: {
+ if (!Matcher::convi2l_type_required) {
+ // Code generation on some platforms doesn't need accurate
+ // ConvI2L types. Widening the type can help remove redundant
+ // address computations.
+ n->as_Type()->set_type(TypeLong::INT);
+ ResourceMark rm;
+ Node_List wq;
+ wq.push(n);
+ for (uint next = 0; next < wq.size(); next++) {
+ Node *m = wq.at(next);
+
+ for(;;) {
+ // Loop over all nodes with identical inputs edges as m
+ Node* k = m->find_similar(m->Opcode());
+ if (k == NULL) {
+ break;
+ }
+ // Push their uses so we get a chance to remove node made
+ // redundant
+ for (DUIterator_Fast imax, i = k->fast_outs(imax); i < imax; i++) {
+ Node* u = k->fast_out(i);
+ assert(!wq.contains(u), "shouldn't process one node several times");
+ if (u->Opcode() == Op_LShiftL ||
+ u->Opcode() == Op_AddL ||
+ u->Opcode() == Op_SubL ||
+ u->Opcode() == Op_AddP) {
+ wq.push(u);
+ }
+ }
+ // Replace all nodes with identical edges as m with m
+ k->subsume_by(m, this);
+ }
+ }
+ }
+ break;
+ }
default:
assert( !n->is_Call(), "" );
assert( !n->is_Mem(), "" );
--- a/hotspot/src/share/vm/opto/compile.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/compile.hpp Fri May 06 18:20:50 2016 +0300
@@ -1101,7 +1101,7 @@
int code_size() { return _method_size; }
CodeBuffer* code_buffer() { return &_code_buffer; }
int first_block_size() { return _first_block_size; }
- void set_frame_complete(int off) { _code_offsets.set_value(CodeOffsets::Frame_Complete, off); }
+ void set_frame_complete(int off) { if (!in_scratch_emit_size()) { _code_offsets.set_value(CodeOffsets::Frame_Complete, off); } }
ExceptionHandlerTable* handler_table() { return &_handler_table; }
ImplicitExceptionTable* inc_table() { return &_inc_table; }
OopMapSet* oop_map_set() { return _oop_map_set; }
--- a/hotspot/src/share/vm/opto/library_call.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/library_call.cpp Fri May 06 18:20:50 2016 +0300
@@ -261,7 +261,7 @@
bool inline_native_getLength();
bool inline_array_copyOf(bool is_copyOfRange);
bool inline_array_equals(StrIntrinsicNode::ArgEnc ae);
- bool inline_objects_checkIndex();
+ bool inline_preconditions_checkIndex();
void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark);
bool inline_native_clone(bool is_virtual);
bool inline_native_Reflection_getCallerClass();
@@ -714,7 +714,7 @@
case vmIntrinsics::_copyOfRange: return inline_array_copyOf(true);
case vmIntrinsics::_equalsB: return inline_array_equals(StrIntrinsicNode::LL);
case vmIntrinsics::_equalsC: return inline_array_equals(StrIntrinsicNode::UU);
- case vmIntrinsics::_Objects_checkIndex: return inline_objects_checkIndex();
+ case vmIntrinsics::_Preconditions_checkIndex: return inline_preconditions_checkIndex();
case vmIntrinsics::_clone: return inline_native_clone(intrinsic()->is_virtual());
case vmIntrinsics::_allocateUninitializedArray: return inline_unsafe_newArray(true);
@@ -1141,7 +1141,7 @@
return true;
}
-bool LibraryCallKit::inline_objects_checkIndex() {
+bool LibraryCallKit::inline_preconditions_checkIndex() {
Node* index = argument(0);
Node* length = argument(1);
if (too_many_traps(Deoptimization::Reason_intrinsic) || too_many_traps(Deoptimization::Reason_range_check)) {
--- a/hotspot/src/share/vm/opto/macro.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/macro.cpp Fri May 06 18:20:50 2016 +0300
@@ -1897,7 +1897,7 @@
Node *prefetch_adr;
Node *prefetch;
- uint lines = AllocatePrefetchDistance / AllocatePrefetchStepSize;
+ uint lines = (length != NULL) ? AllocatePrefetchLines : AllocateInstancePrefetchLines;
uint step_size = AllocatePrefetchStepSize;
uint distance = 0;
@@ -1926,12 +1926,8 @@
contended_phi_rawmem = pf_phi_rawmem;
i_o = pf_phi_abio;
} else if( UseTLAB && AllocatePrefetchStyle == 3 ) {
- // Insert a prefetch for each allocation.
- // This code is used for Sparc with BIS.
- Node *pf_region = new RegionNode(3);
- Node *pf_phi_rawmem = new PhiNode( pf_region, Type::MEMORY,
- TypeRawPtr::BOTTOM );
- transform_later(pf_region);
+ // Insert a prefetch instruction for each allocation.
+ // This code is used for SPARC with BIS.
// Generate several prefetch instructions.
uint lines = (length != NULL) ? AllocatePrefetchLines : AllocateInstancePrefetchLines;
@@ -1940,10 +1936,15 @@
// Next cache address.
Node *cache_adr = new AddPNode(old_eden_top, old_eden_top,
- _igvn.MakeConX(distance));
+ _igvn.MakeConX(step_size + distance));
transform_later(cache_adr);
cache_adr = new CastP2XNode(needgc_false, cache_adr);
transform_later(cache_adr);
+ // For BIS instructions to be emitted, the address must be aligned at cache line size.
+ // (The VM sets AllocatePrefetchStepSize to the cache line size, unless a value is
+ // specified at the command line.) If the address is not aligned at cache line size
+ // boundary, a standard store instruction is triggered (instead of the BIS). For the
+ // latter, 8-byte alignment is necessary.
Node* mask = _igvn.MakeConX(~(intptr_t)(step_size-1));
cache_adr = new AndXNode(cache_adr, mask);
transform_later(cache_adr);
--- a/hotspot/src/share/vm/opto/matcher.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/matcher.hpp Fri May 06 18:20:50 2016 +0300
@@ -488,6 +488,9 @@
// ourselves.
static const bool need_masked_shift_count;
+ // Whether code generation need accurate ConvI2L types.
+ static const bool convi2l_type_required;
+
// This routine is run whenever a graph fails to match.
// If it returns, the compiler should bailout to interpreter without error.
// In non-product mode, SoftMatchFailure is false to detect non-canonical
--- a/hotspot/src/share/vm/opto/node.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/node.cpp Fri May 06 18:20:50 2016 +0300
@@ -2297,7 +2297,8 @@
if (def && def->outcnt() >= 2) {
for (DUIterator_Fast dmax, i = def->fast_outs(dmax); i < dmax; i++) {
Node* use = def->fast_out(i);
- if (use->Opcode() == opc &&
+ if (use != this &&
+ use->Opcode() == opc &&
use->req() == req()) {
uint j;
for (j = 0; j < use->req(); j++) {
--- a/hotspot/src/share/vm/opto/output.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/output.cpp Fri May 06 18:20:50 2016 +0300
@@ -1548,6 +1548,10 @@
}
dump_asm(node_offsets, node_offset_limit);
if (xtty != NULL) {
+ // print_metadata and dump_asm above may safepoint which makes us loose the ttylock.
+ // Retake lock too make sure the end tag is coherent, and that xmlStream->pop_tag is done
+ // thread safe
+ ttyLocker ttyl2;
xtty->tail("opto_assembly");
}
}
--- a/hotspot/src/share/vm/opto/superword.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/opto/superword.cpp Fri May 06 18:20:50 2016 +0300
@@ -198,7 +198,7 @@
ignored_loop_nodes[i] = -1;
}
- int max_vector = Matcher::max_vector_size(T_INT);
+ int max_vector = Matcher::max_vector_size(T_BYTE);
bool post_loop_allowed = (PostLoopMultiversioning && Matcher::has_predicated_vectors() && cl->is_post_loop());
// Process the loop, some/all of the stack entries will not be in order, ergo
--- a/hotspot/src/share/vm/prims/whitebox.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Fri May 06 18:20:50 2016 +0300
@@ -709,7 +709,7 @@
return false;
}
methodHandle mh(THREAD, method);
- nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
+ nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), CompileTask::Reason_Whitebox, THREAD);
MutexLockerEx mu(Compile_lock);
return (mh->queued_for_compilation() || nm != NULL);
}
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri May 06 18:20:50 2016 +0300
@@ -191,8 +191,8 @@
max_method = method;
} else {
// If a method has been stale for some time, remove it from the queue.
- // Blocking tasks don't become stale
- if (!task->is_blocking() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
+ // Blocking tasks and tasks submitted from whitebox API don't become stale
+ if (task->can_become_stale() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
if (PrintTieredEvents) {
print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level());
}
@@ -491,7 +491,7 @@
void AdvancedThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
update_rate(os::javaTimeMillis(), mh());
- CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
}
// Handle the invocation event.
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp Fri May 06 18:20:50 2016 +0300
@@ -90,16 +90,29 @@
}
Flag::Error AllocatePrefetchDistanceConstraintFunc(intx value, bool verbose) {
- if (value < 0) {
+ if (value < 0 || value > 512) {
CommandLineError::print(verbose,
- "Unable to determine system-specific value for AllocatePrefetchDistance. "
- "Please provide appropriate value, if unsure, use 0 to disable prefetching\n");
+ "AllocatePrefetchDistance (" INTX_FORMAT ") must be "
+ "between 0 and " INTX_FORMAT "\n",
+ AllocatePrefetchDistance, 512);
return Flag::VIOLATES_CONSTRAINT;
}
return Flag::SUCCESS;
}
+Flag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose) {
+ if (AllocatePrefetchStyle == 3) {
+ if (value % wordSize != 0) {
+ CommandLineError::print(verbose,
+ "AllocatePrefetchStepSize (" INTX_FORMAT ") must be multiple of %d\n",
+ value, wordSize);
+ return Flag::VIOLATES_CONSTRAINT;
+ }
+ }
+ return Flag::SUCCESS;
+}
+
Flag::Error AllocatePrefetchInstrConstraintFunc(intx value, bool verbose) {
intx max_value = max_intx;
#if defined(SPARC)
@@ -117,49 +130,6 @@
return Flag::SUCCESS;
}
-Flag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose) {
- intx max_value = 512;
- if (value < 1 || value > max_value) {
- CommandLineError::print(verbose,
- "AllocatePrefetchStepSize (" INTX_FORMAT ") "
- "must be between 1 and %d\n",
- AllocatePrefetchStepSize,
- max_value);
- return Flag::VIOLATES_CONSTRAINT;
- }
-
- if (AllocatePrefetchDistance % AllocatePrefetchStepSize != 0) {
- CommandLineError::print(verbose,
- "AllocatePrefetchDistance (" INTX_FORMAT ") "
- "%% AllocatePrefetchStepSize (" INTX_FORMAT ") "
- "= " INTX_FORMAT " "
- "must be 0\n",
- AllocatePrefetchDistance, AllocatePrefetchStepSize,
- AllocatePrefetchDistance % AllocatePrefetchStepSize);
- return Flag::VIOLATES_CONSTRAINT;
- }
-
- /* The limit of 64 for the quotient of AllocatePrefetchDistance and AllocatePrefetchSize
- * originates from the limit of 64 for AllocatePrefetchLines/AllocateInstancePrefetchLines.
- * If AllocatePrefetchStyle == 2, the quotient from above is used in PhaseMacroExpand::prefetch_allocation()
- * to determine the number of lines to prefetch. For other values of AllocatePrefetchStyle,
- * AllocatePrefetchDistance and AllocatePrefetchSize is used. For consistency, all these
- * quantities must have the same limit (64 in this case).
- */
- if (AllocatePrefetchDistance / AllocatePrefetchStepSize > 64) {
- CommandLineError::print(verbose,
- "AllocatePrefetchDistance (" INTX_FORMAT ") too large or "
- "AllocatePrefetchStepSize (" INTX_FORMAT ") too small; "
- "try decreasing/increasing values so that "
- "AllocatePrefetchDistance / AllocatePrefetchStepSize <= 64\n",
- AllocatePrefetchDistance, AllocatePrefetchStepSize,
- AllocatePrefetchDistance % AllocatePrefetchStepSize);
- return Flag::VIOLATES_CONSTRAINT;
- }
-
- return Flag::SUCCESS;
-}
-
Flag::Error CompileThresholdConstraintFunc(intx value, bool verbose) {
if (value < 0 || value > INT_MAX >> InvocationCounter::count_shift) {
CommandLineError::print(verbose,
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri May 06 18:20:50 2016 +0300
@@ -130,7 +130,7 @@
}
CompileBroker::compile_method(selected_method, InvocationEntryBci,
CompilationPolicy::policy()->initial_compile_level(),
- methodHandle(), 0, "must_be_compiled", CHECK);
+ methodHandle(), 0, CompileTask::Reason_MustBeCompiled, CHECK);
}
}
@@ -508,12 +508,11 @@
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
- const char* comment = "count";
if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
CompiledMethod* nm = m->code();
if (nm == NULL ) {
- CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
+ CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, CompileTask::Reason_InvocationCount, thread);
}
}
}
@@ -521,10 +520,9 @@
void SimpleCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->backedge_count();
- const char* comment = "backedge_count";
if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
- CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
+ CompileBroker::compile_method(m, bci, comp_level, m, hot_count, CompileTask::Reason_BackedgeCount, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
}
@@ -539,7 +537,6 @@
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
- const char* comment = "count";
if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m, comp_level)) {
ResourceMark rm(thread);
@@ -569,7 +566,7 @@
assert(top != NULL, "findTopInlinableFrame returned null");
if (TraceCompilationPolicy) top->print();
CompileBroker::compile_method(top->top_method(), InvocationEntryBci, comp_level,
- m, hot_count, comment, thread);
+ m, hot_count, CompileTask::Reason_InvocationCount, thread);
}
}
}
@@ -577,10 +574,9 @@
void StackWalkCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->backedge_count();
- const char* comment = "backedge_count";
if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
- CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
+ CompileBroker::compile_method(m, bci, comp_level, m, hot_count, CompileTask::Reason_BackedgeCount, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri May 06 18:20:50 2016 +0300
@@ -2901,9 +2901,9 @@
\
product(intx, AllocatePrefetchStyle, 1, \
"0 = no prefetch, " \
- "1 = prefetch instructions for each allocation, " \
+ "1 = generate prefetch instructions for each allocation, " \
"2 = use TLAB watermark to gate allocation prefetch, " \
- "3 = use BIS instruction on Sparc for allocation prefetch") \
+ "3 = generate one prefetch instruction per cache line") \
range(0, 3) \
\
product(intx, AllocatePrefetchDistance, -1, \
@@ -2926,8 +2926,8 @@
constraint(AllocatePrefetchStepSizeConstraintFunc,AfterMemoryInit)\
\
product(intx, AllocatePrefetchInstr, 0, \
- "Prefetch instruction to prefetch ahead of allocation pointer") \
- constraint(AllocatePrefetchInstrConstraintFunc, AfterErgo) \
+ "Select instruction to prefetch ahead of allocation pointer") \
+ constraint(AllocatePrefetchInstrConstraintFunc, AfterMemoryInit) \
\
/* deoptimization */ \
develop(bool, TraceDeoptimization, false, \
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Fri May 06 18:20:50 2016 +0300
@@ -265,7 +265,7 @@
// Tell the broker to compile the method
void SimpleThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
- CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
}
// Call and loop predicates determine whether a transition to a higher
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri May 06 18:20:50 2016 +0300
@@ -600,6 +600,7 @@
nonstatic_field(ThreadLocalAllocBuffer, _pf_top, HeapWord*) \
nonstatic_field(ThreadLocalAllocBuffer, _desired_size, size_t) \
nonstatic_field(ThreadLocalAllocBuffer, _refill_waste_limit, size_t) \
+ static_field(ThreadLocalAllocBuffer, _reserve_for_allocation_prefetch, int) \
static_field(ThreadLocalAllocBuffer, _target_refills, unsigned) \
nonstatic_field(ThreadLocalAllocBuffer, _number_of_refills, unsigned) \
nonstatic_field(ThreadLocalAllocBuffer, _fast_refill_waste, unsigned) \
@@ -1324,7 +1325,6 @@
static_field(Abstract_VM_Version, _vm_minor_version, int) \
static_field(Abstract_VM_Version, _vm_security_version, int) \
static_field(Abstract_VM_Version, _vm_build_number, int) \
- static_field(Abstract_VM_Version, _reserve_for_allocation_prefetch, int) \
\
static_field(JDK_Version, _current, JDK_Version) \
nonstatic_field(JDK_Version, _major, unsigned char) \
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Fri May 06 18:20:50 2016 +0300
@@ -43,7 +43,6 @@
bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0;
-int Abstract_VM_Version::_reserve_for_allocation_prefetch = 0;
#ifndef HOTSPOT_VERSION_STRING
#error HOTSPOT_VERSION_STRING must be defined
--- a/hotspot/src/share/vm/runtime/vm_version.hpp Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/src/share/vm/runtime/vm_version.hpp Fri May 06 18:20:50 2016 +0300
@@ -57,7 +57,6 @@
static int _vm_build_number;
static unsigned int _parallel_worker_threads;
static bool _parallel_worker_threads_initialized;
- static int _reserve_for_allocation_prefetch;
static unsigned int nof_parallel_worker_threads(unsigned int num,
unsigned int dem,
@@ -139,12 +138,6 @@
return _L1_data_cache_line_size;
}
- // Need a space at the end of TLAB for prefetch instructions
- // which may fault when accessing memory outside of heap.
- static int reserve_for_allocation_prefetch() {
- return _reserve_for_allocation_prefetch;
- }
-
// ARCH specific policy for the BiasedLocking
static bool use_biased_locking() { return true; }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Fri May 06 18:20:50 2016 +0300
@@ -868,6 +868,31 @@
}
}
+ static class TrivialCloneable implements Cloneable {
+ @Override
+ protected Object clone() {
+ return new TrivialCloneable();
+ }
+ }
+
+ @Test
+ public void isCloneableWithAllocationTest() {
+ ResolvedJavaType cloneable = metaAccess.lookupJavaType(Cloneable.class);
+ for (Class<?> c : classes) {
+ ResolvedJavaType type = metaAccess.lookupJavaType(c);
+ if (type.isCloneableWithAllocation()) {
+ // Only Cloneable types should be allocation cloneable
+ assertTrue(c.toString(), cloneable.isAssignableFrom(type));
+ }
+ }
+ /*
+ * We can't know for sure which types should be allocation cloneable on a particular
+ * platform but assume that at least totally trivial objects should be.
+ */
+ ResolvedJavaType trivialCloneable = metaAccess.lookupJavaType(TrivialCloneable.class);
+ assertTrue(trivialCloneable.toString(), trivialCloneable.isCloneableWithAllocation());
+ }
+
@Test
public void findMethodTest() {
try {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/startup/TieredStopAtLevel0SanityTest.java Fri May 06 18:20:50 2016 +0300
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8154151
+ * @summary Sanity test flag combo that force compiles on level 0
+ * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:TieredStopAtLevel=0 TieredStopAtLevel0SanityTest
+ */
+
+public class TieredStopAtLevel0SanityTest {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello world!");
+ }
+}
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestBoolean {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -148,4 +149,3 @@
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestByte {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -185,4 +186,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestChar {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -203,4 +204,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestDouble {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -185,4 +186,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestFloat {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -185,4 +186,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestInt {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -251,22 +252,31 @@
}
{
- boolean r = UNSAFE.weakCompareAndSwapInt(base, offset, 1, 2);
- assertEquals(r, true, "weakCompareAndSwap int");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapInt(base, offset, 1, 2);
+ }
+ assertEquals(success, true, "weakCompareAndSwap int");
int x = UNSAFE.getInt(base, offset);
assertEquals(x, 2, "weakCompareAndSwap int value");
}
{
- boolean r = UNSAFE.weakCompareAndSwapIntAcquire(base, offset, 2, 1);
- assertEquals(r, true, "weakCompareAndSwapAcquire int");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapIntAcquire(base, offset, 2, 1);
+ }
+ assertEquals(success, true, "weakCompareAndSwapAcquire int");
int x = UNSAFE.getInt(base, offset);
assertEquals(x, 1, "weakCompareAndSwapAcquire int");
}
{
- boolean r = UNSAFE.weakCompareAndSwapIntRelease(base, offset, 1, 2);
- assertEquals(r, true, "weakCompareAndSwapRelease int");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapIntRelease(base, offset, 1, 2);
+ }
+ assertEquals(success, true, "weakCompareAndSwapRelease int");
int x = UNSAFE.getInt(base, offset);
assertEquals(x, 2, "weakCompareAndSwapRelease int");
}
@@ -286,7 +296,7 @@
int o = UNSAFE.getAndAddInt(base, offset, 2);
assertEquals(o, 1, "getAndAdd int");
int x = UNSAFE.getInt(base, offset);
- assertEquals(x, 1 + 2, "weakCompareAndSwapRelease int");
+ assertEquals(x, 1 + 2, "getAndAdd int");
}
}
@@ -300,4 +310,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestLong {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -251,22 +252,31 @@
}
{
- boolean r = UNSAFE.weakCompareAndSwapLong(base, offset, 1L, 2L);
- assertEquals(r, true, "weakCompareAndSwap long");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapLong(base, offset, 1L, 2L);
+ }
+ assertEquals(success, true, "weakCompareAndSwap long");
long x = UNSAFE.getLong(base, offset);
assertEquals(x, 2L, "weakCompareAndSwap long value");
}
{
- boolean r = UNSAFE.weakCompareAndSwapLongAcquire(base, offset, 2L, 1L);
- assertEquals(r, true, "weakCompareAndSwapAcquire long");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapLongAcquire(base, offset, 2L, 1L);
+ }
+ assertEquals(success, true, "weakCompareAndSwapAcquire long");
long x = UNSAFE.getLong(base, offset);
assertEquals(x, 1L, "weakCompareAndSwapAcquire long");
}
{
- boolean r = UNSAFE.weakCompareAndSwapLongRelease(base, offset, 1L, 2L);
- assertEquals(r, true, "weakCompareAndSwapRelease long");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapLongRelease(base, offset, 1L, 2L);
+ }
+ assertEquals(success, true, "weakCompareAndSwapRelease long");
long x = UNSAFE.getLong(base, offset);
assertEquals(x, 2L, "weakCompareAndSwapRelease long");
}
@@ -286,7 +296,7 @@
long o = UNSAFE.getAndAddLong(base, offset, 2L);
assertEquals(o, 1L, "getAndAdd long");
long x = UNSAFE.getLong(base, offset);
- assertEquals(x, 1L + 2L, "weakCompareAndSwapRelease long");
+ assertEquals(x, 1L + 2L, "getAndAdd long");
}
}
@@ -300,4 +310,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestObject {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -204,22 +205,31 @@
}
{
- boolean r = UNSAFE.weakCompareAndSwapObject(base, offset, "foo", "bar");
- assertEquals(r, true, "weakCompareAndSwap Object");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapObject(base, offset, "foo", "bar");
+ }
+ assertEquals(success, true, "weakCompareAndSwap Object");
Object x = UNSAFE.getObject(base, offset);
assertEquals(x, "bar", "weakCompareAndSwap Object value");
}
{
- boolean r = UNSAFE.weakCompareAndSwapObjectAcquire(base, offset, "bar", "foo");
- assertEquals(r, true, "weakCompareAndSwapAcquire Object");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapObjectAcquire(base, offset, "bar", "foo");
+ }
+ assertEquals(success, true, "weakCompareAndSwapAcquire Object");
Object x = UNSAFE.getObject(base, offset);
assertEquals(x, "foo", "weakCompareAndSwapAcquire Object");
}
{
- boolean r = UNSAFE.weakCompareAndSwapObjectRelease(base, offset, "foo", "bar");
- assertEquals(r, true, "weakCompareAndSwapRelease Object");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapObjectRelease(base, offset, "foo", "bar");
+ }
+ assertEquals(success, true, "weakCompareAndSwapRelease Object");
Object x = UNSAFE.getObject(base, offset);
assertEquals(x, "bar", "weakCompareAndSwapRelease Object");
}
@@ -236,4 +246,3 @@
}
-
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class JdkInternalMiscUnsafeAccessTestShort {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final jdk.internal.misc.Unsafe UNSAFE;
@@ -203,4 +204,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestBoolean {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -131,9 +132,7 @@
-
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestByte {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -160,7 +161,6 @@
-
}
static void testAccess(long address) {
@@ -173,4 +173,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestChar {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -160,7 +161,6 @@
-
}
static void testAccess(long address) {
@@ -173,4 +173,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestDouble {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -160,7 +161,6 @@
-
}
static void testAccess(long address) {
@@ -173,4 +173,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestFloat {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -160,7 +161,6 @@
-
}
static void testAccess(long address) {
@@ -173,4 +173,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestInt {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -165,7 +166,6 @@
-
UNSAFE.putInt(base, offset, 1);
// Compare
@@ -184,7 +184,6 @@
}
-
// Compare set and get
{
int o = UNSAFE.getAndSetInt(base, offset, 1);
@@ -200,7 +199,7 @@
int o = UNSAFE.getAndAddInt(base, offset, 2);
assertEquals(o, 1, "getAndAdd int");
int x = UNSAFE.getInt(base, offset);
- assertEquals(x, 1 + 2, "weakCompareAndSwapRelease int");
+ assertEquals(x, 1 + 2, "getAndAdd int");
}
}
@@ -214,4 +213,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestLong {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -165,7 +166,6 @@
-
UNSAFE.putLong(base, offset, 1L);
// Compare
@@ -184,7 +184,6 @@
}
-
// Compare set and get
{
long o = UNSAFE.getAndSetLong(base, offset, 1L);
@@ -200,7 +199,7 @@
long o = UNSAFE.getAndAddLong(base, offset, 2L);
assertEquals(o, 1L, "getAndAdd long");
long x = UNSAFE.getLong(base, offset);
- assertEquals(x, 1L + 2L, "weakCompareAndSwapRelease long");
+ assertEquals(x, 1L + 2L, "getAndAdd long");
}
}
@@ -214,4 +213,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestObject {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -136,7 +137,6 @@
-
UNSAFE.putObject(base, offset, "foo");
// Compare
@@ -155,7 +155,6 @@
}
-
// Compare set and get
{
Object o = UNSAFE.getAndSetObject(base, offset, "foo");
@@ -168,4 +167,3 @@
}
-
--- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class SunMiscUnsafeAccessTestShort {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final sun.misc.Unsafe UNSAFE;
@@ -160,7 +161,6 @@
-
}
static void testAccess(long address) {
@@ -173,4 +173,3 @@
}
}
-
--- a/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template Fri May 06 18:20:50 2016 +0300
@@ -40,6 +40,7 @@
public class $Qualifier$UnsafeAccessTest$Type$ {
static final int ITERS = Integer.getInteger("iters", 1);
+ static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10);
static final $package$.Unsafe UNSAFE;
@@ -273,22 +274,31 @@
}
{
- boolean r = UNSAFE.weakCompareAndSwap$Type$(base, offset, $value1$, $value2$);
- assertEquals(r, true, "weakCompareAndSwap $type$");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwap$Type$(base, offset, $value1$, $value2$);
+ }
+ assertEquals(success, true, "weakCompareAndSwap $type$");
$type$ x = UNSAFE.get$Type$(base, offset);
assertEquals(x, $value2$, "weakCompareAndSwap $type$ value");
}
{
- boolean r = UNSAFE.weakCompareAndSwap$Type$Acquire(base, offset, $value2$, $value1$);
- assertEquals(r, true, "weakCompareAndSwapAcquire $type$");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwap$Type$Acquire(base, offset, $value2$, $value1$);
+ }
+ assertEquals(success, true, "weakCompareAndSwapAcquire $type$");
$type$ x = UNSAFE.get$Type$(base, offset);
assertEquals(x, $value1$, "weakCompareAndSwapAcquire $type$");
}
{
- boolean r = UNSAFE.weakCompareAndSwap$Type$Release(base, offset, $value1$, $value2$);
- assertEquals(r, true, "weakCompareAndSwapRelease $type$");
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwap$Type$Release(base, offset, $value1$, $value2$);
+ }
+ assertEquals(success, true, "weakCompareAndSwapRelease $type$");
$type$ x = UNSAFE.get$Type$(base, offset);
assertEquals(x, $value2$, "weakCompareAndSwapRelease $type$");
}
@@ -311,7 +321,7 @@
$type$ o = UNSAFE.getAndAdd$Type$(base, offset, $value2$);
assertEquals(o, $value1$, "getAndAdd $type$");
$type$ x = UNSAFE.get$Type$(base, offset);
- assertEquals(x, $value1$ + $value2$, "weakCompareAndSwapRelease $type$");
+ assertEquals(x, $value1$ + $value2$, "getAndAdd $type$");
}
#end[AtomicAdd]
}
--- a/hotspot/test/compiler/unsafe/generate-unsafe-tests.sh Fri May 06 09:54:58 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-#!/bin/bash
-
-javac -d . ../../../../jdk/make/src/classes/build/tools/spp/Spp.java
-
-SPP=build.tools.spp.Spp
-
-# Generates unsafe access tests for objects and all primitive types
-# $1 = package name to Unsafe, sun.misc | jdk.internal.misc
-# $2 = test class qualifier name, SunMisc | JdkInternalMisc
-function generate {
- package=$1
- Qualifier=$2
-
- for type in boolean byte short char int long float double Object
- do
- Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}"
- args="-K$type -Dtype=$type -DType=$Type"
-
- case $type in
- Object|int|long)
- args="$args -KCAS -KOrdered"
- ;;
- esac
-
- case $type in
- int|long)
- args="$args -KAtomicAdd"
- ;;
- esac
-
- case $type in
- short|char|int|long)
- args="$args -KUnaligned"
- ;;
- esac
-
- case $type in
- boolean)
- value1=true
- value2=false
- value3=false
- ;;
- byte)
- value1=(byte)1
- value2=(byte)2
- value3=(byte)3
- ;;
- short)
- value1=(short)1
- value2=(short)2
- value3=(short)3
- ;;
- char)
- value1=\'a\'
- value2=\'b\'
- value3=\'c\'
- ;;
- int)
- value1=1
- value2=2
- value3=3
- ;;
- long)
- value1=1L
- value2=2L
- value3=3L
- ;;
- float)
- value1=1.0f
- value2=2.0f
- value3=3.0f
- ;;
- double)
- value1=1.0d
- value2=2.0d
- value3=3.0d
- ;;
- Object)
- value1=\"foo\"
- value2=\"bar\"
- value3=\"baz\"
- ;;
- esac
-
- args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3"
-
- echo $args
-
- java $SPP -nel -K$Qualifier -Dpackage=$package -DQualifier=$Qualifier \
- $args < X-UnsafeAccessTest.java.template > ${Qualifier}UnsafeAccessTest${Type}.java
- done
-}
-
-generate sun.misc SunMisc
-generate jdk.internal.misc JdkInternalMisc
-
-rm -fr build
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/vectorization/TestVectorUnalignedOffset.java Fri May 06 18:20:50 2016 +0300
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016, Red Hat, 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8155612
+ * @summary Aarch64: vector nodes need to support misaligned offset
+ * @run main/othervm -XX:-BackgroundCompilation TestVectorUnalignedOffset
+ *
+ */
+
+
+public class TestVectorUnalignedOffset {
+
+ static void test1(int[] src_array, int[] dst_array, int l) {
+ for (int i = 0; i < l; i++) {
+ dst_array[i + 250] = src_array[i + 250];
+ }
+ }
+
+ static void test2(byte[] src_array, byte[] dst_array, int l) {
+ for (int i = 0; i < l; i++) {
+ dst_array[i + 250] = src_array[i + 250];
+ }
+ }
+
+ static public void main(String[] args) {
+ int[] int_array = new int[1000];
+ byte[] byte_array = new byte[1000];
+ for (int i = 0; i < 20000; i++) {
+ test1(int_array, int_array, int_array.length - 250);
+ test2(byte_array, byte_array, byte_array.length - 250);
+ }
+ }
+}
--- a/hotspot/test/compiler/whitebox/BlockingCompilation.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/compiler/whitebox/BlockingCompilation.java Fri May 06 18:20:50 2016 +0300
@@ -23,15 +23,14 @@
/*
* @test
- * @bug 8150646
+ * @bug 8150646 8153013
* @summary Add support for blocking compiles through whitebox API
* @modules java.base/jdk.internal.misc
* @library /testlibrary /test/lib /
* @build sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * sun.hotspot.WhiteBox$WhiteBoxPermission
- *
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm/timeout=60
* -Xbootclasspath/a:.
* -Xmixed
@@ -41,11 +40,10 @@
* BlockingCompilation
*/
+import compiler.testlibrary.CompilerUtils;
import java.lang.reflect.Method;
import java.util.Random;
-
import sun.hotspot.WhiteBox;
-import compiler.testlibrary.CompilerUtils;
public class BlockingCompilation {
private static final WhiteBox WB = WhiteBox.getWhiteBox();
@@ -78,7 +76,13 @@
// If the compiles are blocking, this call will block until the test time out,
// Progress == success
// (Don't run with -Xcomp since that can cause long timeouts due to many compiles)
- WB.enqueueMethodForCompilation(m, highest_level);
+ if (!WB.enqueueMethodForCompilation(m, highest_level)) {
+ throw new Exception("Failed to enqueue method on level: " + highest_level);
+ }
+
+ if (!WB.isMethodQueuedForCompilation(m)) {
+ throw new Exception("Must be enqueued because of locked compilation");
+ }
// restore state
WB.unlockCompilation();
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java Fri May 06 09:54:58 2016 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java Fri May 06 18:20:50 2016 +0300
@@ -90,13 +90,6 @@
excludeTestMaxRange("CICompilerCount");
/*
- * JDK-8153340
- * Temporary exclude AllocatePrefetchDistance option from testing
- */
- excludeTestRange("AllocatePrefetchDistance");
-
-
- /*
* JDK-8136766
* Temporarily remove ThreadStackSize from testing because Windows can set it to 0
* (for default OS size) but other platforms insist it must be greater than 0