This commit is contained in:
Jesper Wilhelmsson 2016-02-11 21:07:38 +01:00
commit c6d81e192d
117 changed files with 1100 additions and 464 deletions

View file

@ -1,5 +1,5 @@
suite = {
"mxversion" : "5.6.11",
"mxversion" : "5.6.16",
"name" : "jvmci",
"url" : "http://openjdk.java.net/projects/graal",
"developer" : {

View file

@ -14928,7 +14928,22 @@ instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
ins_pipe(pipe_class_memory);
%}
instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
iRegP_R10 tmp, rFlagsReg cr)
%{
predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (AryEq ary1 ary2));
effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr);
format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %}
ins_encode %{
__ byte_arrays_equals($ary1$$Register, $ary2$$Register,
$result$$Register, $tmp$$Register);
%}
ins_pipe(pipe_class_memory);
%}
instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
iRegP_R10 tmp, rFlagsReg cr)
%{
predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);

View file

@ -40,11 +40,7 @@ define_pd_global(bool, ImplicitNullChecks, true); // Generate code for im
define_pd_global(bool, TrapBasedNullChecks, false);
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
#if defined(COMPILER2) || INCLUDE_JVMCI
define_pd_global(intx, CodeEntryAlignment, 64);
#else
define_pd_global(intx, CodeEntryAlignment, 16);
#endif // COMPILER2
define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(intx, InlineFrequencyCount, 100);

View file

@ -127,7 +127,10 @@ int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
Instruction_aarch64::extract(insn2, 4, 0)) {
// movk #imm16<<32
Instruction_aarch64::patch(branch + 4, 20, 5, (uint64_t)target >> 32);
offset &= (1<<20)-1;
long dest = ((long)target & 0xffffffffL) | ((long)branch & 0xffff00000000L);
long pc_page = (long)branch >> 12;
long adr_page = (long)dest >> 12;
offset = adr_page - pc_page;
instructions = 2;
}
}
@ -3993,11 +3996,12 @@ void MacroAssembler::adrp(Register reg1, const Address &dest, unsigned long &byt
if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
_adrp(reg1, dest.target());
} else {
unsigned long pc_page = (unsigned long)pc() >> 12;
long offset = dest_page - pc_page;
offset = (offset & ((1<<20)-1)) << 12;
_adrp(reg1, pc()+offset);
movk(reg1, (unsigned long)dest.target() >> 32, 32);
unsigned long target = (unsigned long)dest.target();
unsigned long adrp_target
= (target & 0xffffffffUL) | ((unsigned long)pc() & 0xffff00000000UL);
_adrp(reg1, (address)adrp_target);
movk(reg1, target >> 32, 32);
}
byte_offset = (unsigned long)dest.target() & 0xfff;
}
@ -4552,6 +4556,82 @@ void MacroAssembler::string_equals(Register str1, Register str2,
BLOCK_COMMENT("} string_equals");
}
void MacroAssembler::byte_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1)
{
Register cnt1 = rscratch1;
Register cnt2 = rscratch2;
Register tmp2 = rscratch2;
Label SAME, DIFFER, NEXT, TAIL07, TAIL03, TAIL01;
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE);
BLOCK_COMMENT("byte_arrays_equals {");
// different until proven equal
mov(result, false);
// same array?
cmp(ary1, ary2);
br(Assembler::EQ, SAME);
// ne if either null
cbz(ary1, DIFFER);
cbz(ary2, DIFFER);
// lengths ne?
ldrw(cnt1, Address(ary1, length_offset));
ldrw(cnt2, Address(ary2, length_offset));
cmp(cnt1, cnt2);
br(Assembler::NE, DIFFER);
lea(ary1, Address(ary1, base_offset));
lea(ary2, Address(ary2, base_offset));
subs(cnt1, cnt1, 8);
br(LT, TAIL07);
BIND(NEXT);
ldr(tmp1, Address(post(ary1, 8)));
ldr(tmp2, Address(post(ary2, 8)));
subs(cnt1, cnt1, 8);
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DIFFER);
br(GE, NEXT);
BIND(TAIL07); // 0-7 bytes left, cnt1 = #bytes left - 4
tst(cnt1, 0b100);
br(EQ, TAIL03);
ldrw(tmp1, Address(post(ary1, 4)));
ldrw(tmp2, Address(post(ary2, 4)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL03); // 0-3 bytes left, cnt1 = #bytes left - 4
tst(cnt1, 0b10);
br(EQ, TAIL01);
ldrh(tmp1, Address(post(ary1, 2)));
ldrh(tmp2, Address(post(ary2, 2)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL01); // 0-1 byte left
tst(cnt1, 0b01);
br(EQ, SAME);
ldrb(tmp1, ary1);
ldrb(tmp2, ary2);
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(SAME);
mov(result, true);
BIND(DIFFER); // result already set
BLOCK_COMMENT("} byte_arrays_equals");
}
// Compare char[] arrays aligned to 4 bytes
void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1)

View file

@ -1191,6 +1191,8 @@ public:
Register tmp1);
void char_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1);
void byte_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1);
void encode_iso_array(Register src, Register dst,
Register len, Register result,
FloatRegister Vtmp1, FloatRegister Vtmp2,

View file

@ -786,12 +786,19 @@ class StubGenerator: public StubCodeGenerator {
int offset;
const Register t0 = r3, t1 = r4, t2 = r5, t3 = r6,
t4 = r7, t5 = r10, t6 = r11, t7 = r12;
const Register stride = r13;
assert_different_registers(rscratch1, t0, t1, t2, t3, t4, t5, t6, t7);
assert_different_registers(s, d, count, rscratch1);
Label again, large, small;
__ align(6);
const char *stub_name;
if (direction == copy_forwards)
stub_name = "foward_copy_longs";
else
stub_name = "backward_copy_longs";
StubCodeMark mark(this, "StubRoutines", stub_name);
__ align(CodeEntryAlignment);
__ bind(start);
__ cmp(count, 8);
__ br(Assembler::LO, small);
@ -836,7 +843,7 @@ class StubGenerator: public StubCodeGenerator {
__ ret(lr);
__ align(6);
__ align(CodeEntryAlignment);
__ bind(large);
// Fill 8 registers
@ -845,10 +852,18 @@ class StubGenerator: public StubCodeGenerator {
__ ldp(t4, t5, Address(s, 6 * unit));
__ ldp(t6, t7, Address(__ pre(s, 8 * unit)));
int prefetch = PrefetchCopyIntervalInBytes;
bool use_stride = false;
if (direction == copy_backwards) {
use_stride = prefetch > 256;
prefetch = -prefetch;
if (use_stride) __ mov(stride, prefetch);
}
__ bind(again);
if (direction == copy_forwards && PrefetchCopyIntervalInBytes > 0)
__ prfm(Address(s, PrefetchCopyIntervalInBytes), PLDL1KEEP);
if (PrefetchCopyIntervalInBytes > 0)
__ prfm(use_stride ? Address(s, stride) : Address(s, prefetch), PLDL1KEEP);
__ stp(t0, t1, Address(d, 2 * unit));
__ ldp(t0, t1, Address(s, 2 * unit));
@ -962,7 +977,7 @@ class StubGenerator: public StubCodeGenerator {
__ lea(d, Address(d, count, Address::lsl(exact_log2(-step))));
}
Label done, tail;
Label tail;
__ cmp(count, 16/granularity);
__ br(Assembler::LO, tail);
@ -987,7 +1002,8 @@ class StubGenerator: public StubCodeGenerator {
}
// rscratch2 is the byte adjustment needed to align s.
__ cbz(rscratch2, aligned);
__ lsr(rscratch2, rscratch2, exact_log2(granularity));
int shift = exact_log2(granularity);
if (shift) __ lsr(rscratch2, rscratch2, shift);
__ sub(count, count, rscratch2);
#if 0
@ -1150,8 +1166,11 @@ class StubGenerator: public StubCodeGenerator {
// caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
BLOCK_COMMENT("Entry:");
}
__ cmp(d, s);
__ br(Assembler::LS, nooverlap_target);
// use fwd copy when (d-s) above_equal (count*size)
__ sub(rscratch1, d, s);
__ cmp(rscratch1, count, Assembler::LSL, exact_log2(size));
__ br(Assembler::HS, nooverlap_target);
if (is_oop) {
__ push(RegSet::of(d, count), sp);

View file

@ -120,7 +120,14 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(AllocatePrefetchStepSize, 64);
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 256);
FLAG_SET_DEFAULT(PrefetchFieldsAhead, 256);
if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes))
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 256);
if ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768)) {
warning("PrefetchCopyIntervalInBytes must be a multiple of 8 and < 32768");
PrefetchCopyIntervalInBytes &= ~7;
if (PrefetchCopyIntervalInBytes >= 32768)
PrefetchCopyIntervalInBytes = 32760;
}
unsigned long auxv = getauxval(AT_HWCAP);

View file

@ -45,13 +45,6 @@ void VM_Version::initialize() {
if( cache_line_size > AllocatePrefetchStepSize )
AllocatePrefetchStepSize = cache_line_size;
assert(AllocatePrefetchLines > 0, "invalid value");
if( AllocatePrefetchLines < 1 ) // set valid value in product VM
AllocatePrefetchLines = 3;
assert(AllocateInstancePrefetchLines > 0, "invalid value");
if( AllocateInstancePrefetchLines < 1 ) // set valid value in product VM
AllocateInstancePrefetchLines = 1;
AllocatePrefetchDistance = allocate_prefetch_distance();
AllocatePrefetchStyle = allocate_prefetch_style();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -114,15 +114,20 @@ class RegisterSaver {
OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
int* total_frame_words, bool verify_fpu, bool save_vectors) {
int vect_words = 0;
int num_xmm_regs = XMMRegisterImpl::number_of_registers;
int ymm_bytes = num_xmm_regs * 16;
int zmm_bytes = num_xmm_regs * 32;
#ifdef COMPILER2
if (save_vectors) {
assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
// Save upper half of ZMM/YMM registers :
vect_words = 8 * 16 / wordSize;
additional_frame_words += vect_words;
assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX");
assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now");
// Save upper half of YMM registers
int vect_bytes = ymm_bytes;
if (UseAVX > 2) {
// Save upper half of ZMM registers as well
vect_bytes += zmm_bytes;
}
additional_frame_words += vect_bytes / wordSize;
}
#else
assert(!save_vectors, "vectors are generated only by C2");
@ -185,13 +190,14 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
off = xmm0_off;
delta = xmm1_off - off;
if(UseSSE == 1) { // Save the XMM state
if(UseSSE == 1) {
// Save the XMM state
for (int n = 0; n < num_xmm_regs; n++) {
__ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
off += delta;
}
} else if(UseSSE >= 2) {
// Save whole 128bit (16 bytes) XMM regiters
// Save whole 128bit (16 bytes) XMM registers
for (int n = 0; n < num_xmm_regs; n++) {
__ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
off += delta;
@ -199,13 +205,14 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
}
if (save_vectors) {
assert(vect_words*wordSize == 128, "");
__ subptr(rsp, 128); // Save upper half of YMM registes
__ subptr(rsp, ymm_bytes);
// Save upper half of YMM registers
for (int n = 0; n < num_xmm_regs; n++) {
__ vextractf128h(Address(rsp, n*16), as_XMMRegister(n));
}
if (UseAVX > 2) {
__ subptr(rsp, 256); // Save upper half of ZMM registes
__ subptr(rsp, zmm_bytes);
// Save upper half of ZMM registers
for (int n = 0; n < num_xmm_regs; n++) {
__ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1);
}
@ -255,50 +262,59 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
int num_xmm_regs = XMMRegisterImpl::number_of_registers;
int ymm_bytes = num_xmm_regs * 16;
int zmm_bytes = num_xmm_regs * 32;
// Recover XMM & FPU state
int additional_frame_bytes = 0;
#ifdef COMPILER2
if (restore_vectors) {
assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
additional_frame_bytes = 128;
assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX");
assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now");
// Save upper half of YMM registers
additional_frame_bytes = ymm_bytes;
if (UseAVX > 2) {
// Save upper half of ZMM registers as well
additional_frame_bytes += zmm_bytes;
}
}
#else
assert(!restore_vectors, "vectors are generated only by C2");
#endif
if (restore_vectors) {
assert(additional_frame_bytes == 128, "");
if (UseAVX > 2) {
// Restore upper half of ZMM registers.
for (int n = 0; n < num_xmm_regs; n++) {
__ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1);
}
__ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes
}
// Restore upper half of YMM registes.
for (int n = 0; n < num_xmm_regs; n++) {
__ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16));
}
__ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes
}
int off = xmm0_off;
int delta = xmm1_off - off;
if (UseSSE == 1) {
// Restore XMM registers
assert(additional_frame_bytes == 0, "");
for (int n = 0; n < num_xmm_regs; n++) {
__ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
off += delta;
}
} else if (UseSSE >= 2) {
// additional_frame_bytes only populated for the restore_vector case, else it is 0
// Restore whole 128bit (16 bytes) XMM registers. Do this before restoring YMM and
// ZMM because the movdqu instruction zeros the upper part of the XMM register.
for (int n = 0; n < num_xmm_regs; n++) {
__ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
off += delta;
}
}
if (restore_vectors) {
if (UseAVX > 2) {
// Restore upper half of ZMM registers.
for (int n = 0; n < num_xmm_regs; n++) {
__ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1);
}
__ addptr(rsp, zmm_bytes);
}
// Restore upper half of YMM registers.
for (int n = 0; n < num_xmm_regs; n++) {
__ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16));
}
__ addptr(rsp, ymm_bytes);
}
__ pop_FPU_state();
__ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
@ -306,7 +322,6 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
__ popa();
// Get the rbp, described implicitly by the frame sender code (no oopMap)
__ pop(rbp);
}
void RegisterSaver::restore_result_registers(MacroAssembler* masm) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -150,8 +150,8 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
}
#if defined(COMPILER2) || INCLUDE_JVMCI
if (save_vectors) {
assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX");
assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now");
}
#else
assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
@ -176,18 +176,18 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
// push cpu state handles this on EVEX enabled targets
if (save_vectors) {
// Save upper half of YMM registes(0..15)
// Save upper half of YMM registers(0..15)
int base_addr = XSAVE_AREA_YMM_BEGIN;
for (int n = 0; n < 16; n++) {
__ vextractf128h(Address(rsp, base_addr+n*16), as_XMMRegister(n));
}
if (VM_Version::supports_evex()) {
// Save upper half of ZMM registes(0..15)
// Save upper half of ZMM registers(0..15)
base_addr = XSAVE_AREA_ZMM_BEGIN;
for (int n = 0; n < 16; n++) {
__ vextractf64x4h(Address(rsp, base_addr+n*32), as_XMMRegister(n), 1);
}
// Save full ZMM registes(16..num_xmm_regs)
// Save full ZMM registers(16..num_xmm_regs)
base_addr = XSAVE_AREA_UPPERBANK;
off = 0;
int vector_len = Assembler::AVX_512bit;
@ -321,8 +321,8 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
#if defined(COMPILER2) || INCLUDE_JVMCI
if (restore_vectors) {
assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX");
assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now");
}
#else
assert(!restore_vectors, "vectors are generated only by C2");
@ -330,18 +330,18 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
// On EVEX enabled targets everything is handled in pop fpu state
if (restore_vectors) {
// Restore upper half of YMM registes (0..15)
// Restore upper half of YMM registers (0..15)
int base_addr = XSAVE_AREA_YMM_BEGIN;
for (int n = 0; n < 16; n++) {
__ vinsertf128h(as_XMMRegister(n), Address(rsp, base_addr+n*16));
}
if (VM_Version::supports_evex()) {
// Restore upper half of ZMM registes (0..15)
// Restore upper half of ZMM registers (0..15)
base_addr = XSAVE_AREA_ZMM_BEGIN;
for (int n = 0; n < 16; n++) {
__ vinsertf64x4h(as_XMMRegister(n), Address(rsp, base_addr+n*32), 1);
}
// Restore full ZMM registes(16..num_xmm_regs)
// Restore full ZMM registers(16..num_xmm_regs)
base_addr = XSAVE_AREA_UPPERBANK;
int vector_len = Assembler::AVX_512bit;
int off = 0;
@ -351,7 +351,7 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
}
} else {
if (VM_Version::supports_evex()) {
// Restore upper bank of ZMM registes(16..31) for double/float usage
// Restore upper bank of ZMM registers(16..31) for double/float usage
int base_addr = XSAVE_AREA_UPPERBANK;
int off = 0;
for (int n = 16; n < num_xmm_regs; n++) {

View file

@ -1163,13 +1163,6 @@ void VM_Version::get_processor_features() {
if( cache_line_size > AllocatePrefetchStepSize )
AllocatePrefetchStepSize = cache_line_size;
assert(AllocatePrefetchLines > 0, "invalid value");
if( AllocatePrefetchLines < 1 ) // set valid value in product VM
AllocatePrefetchLines = 3;
assert(AllocateInstancePrefetchLines > 0, "invalid value");
if( AllocateInstancePrefetchLines < 1 ) // set valid value in product VM
AllocateInstancePrefetchLines = 1;
AllocatePrefetchDistance = allocate_prefetch_distance();
AllocatePrefetchStyle = allocate_prefetch_style();
@ -1183,7 +1176,9 @@ void VM_Version::get_processor_features() {
}
if (supports_sse4_2() && supports_ht()) { // Nehalem based cpus
AllocatePrefetchDistance = 192;
AllocatePrefetchLines = 4;
if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
FLAG_SET_DEFAULT(AllocatePrefetchLines, 4);
}
}
#ifdef COMPILER2
if (supports_sse4_2()) {

View file

@ -76,14 +76,14 @@ public class AArch64 extends Architecture {
public static final Register zr = r31;
public static final Register sp = r31;
public static final Register[] cpuRegisters = {
// @formatter:off
public static final Register[] cpuRegisters = {
r0, r1, r2, r3, r4, r5, r6, r7,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
r24, r25, r26, r27, r28, r29, r30, r31
// @formatter:on
};
// @formatter:on
public static final RegisterCategory SIMD = new RegisterCategory("SIMD");
@ -121,17 +121,17 @@ public class AArch64 extends Architecture {
public static final Register v30 = new Register(62, 30, "v30", SIMD);
public static final Register v31 = new Register(63, 31, "v31", SIMD);
public static final Register[] simdRegisters = {
// @formatter:off
public static final Register[] simdRegisters = {
v0, v1, v2, v3, v4, v5, v6, v7,
v8, v9, v10, v11, v12, v13, v14, v15,
v16, v17, v18, v19, v20, v21, v22, v23,
v24, v25, v26, v27, v28, v29, v30, v31
// @formatter:on
};
// @formatter:on
public static final Register[] allRegisters = {
// @formatter:off
public static final Register[] allRegisters = {
r0, r1, r2, r3, r4, r5, r6, r7,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
@ -141,14 +141,14 @@ public class AArch64 extends Architecture {
v8, v9, v10, v11, v12, v13, v14, v15,
v16, v17, v18, v19, v20, v21, v22, v23,
v24, v25, v26, v27, v28, v29, v30, v31
// @formatter:on
};
// @formatter:on
/**
* Basic set of CPU features mirroring what is returned from the cpuid instruction. See:
* {@code VM_Version::cpuFeatureFlags}.
*/
public static enum CPUFeature {
public enum CPUFeature {
FP,
ASIMD,
EVTSTRM,
@ -166,7 +166,7 @@ public class AArch64 extends Architecture {
/**
* Set of flags to control code emission.
*/
public static enum Flag {
public enum Flag {
UseBarriersForVolatile,
UseCRC32,
UseNeon

View file

@ -58,13 +58,13 @@ public enum AArch64Kind implements PlatformKind {
private final AArch64Kind scalar;
private final EnumKey<AArch64Kind> key = new EnumKey<>(this);
private AArch64Kind(int size) {
AArch64Kind(int size) {
this.size = size;
this.scalar = this;
this.vectorLength = 1;
}
private AArch64Kind(int size, AArch64Kind scalar) {
AArch64Kind(int size, AArch64Kind scalar) {
this.size = size;
this.scalar = scalar;

View file

@ -169,7 +169,7 @@ public class AMD64 extends Architecture {
* Basic set of CPU features mirroring what is returned from the cpuid instruction. See:
* {@code VM_Version::cpuFeatureFlags}.
*/
public static enum CPUFeature {
public enum CPUFeature {
CX8,
CMOV,
FXSR,
@ -210,7 +210,7 @@ public class AMD64 extends Architecture {
/**
* Set of flags to control code emission.
*/
public static enum Flag {
public enum Flag {
UseCountLeadingZerosInstruction,
UseCountTrailingZerosInstruction
}

View file

@ -74,13 +74,13 @@ public enum AMD64Kind implements PlatformKind {
private final AMD64Kind scalar;
private final EnumKey<AMD64Kind> key = new EnumKey<>(this);
private AMD64Kind(int size) {
AMD64Kind(int size) {
this.size = size;
this.scalar = this;
this.vectorLength = 1;
}
private AMD64Kind(int size, AMD64Kind scalar) {
AMD64Kind(int size, AMD64Kind scalar) {
this.size = size;
this.scalar = scalar;

View file

@ -23,7 +23,7 @@
package jdk.vm.ci.code;
/**
* Class representing a exception with a stack trace of the currently processed position in the
* Class representing an exception with a stack trace of the currently processed position in the
* compiled Java program instead of the stack trace of the compiler. The exception of the compiler
* is saved as the cause of this exception.
*/
@ -36,7 +36,7 @@ public abstract class SourceStackTrace extends BailoutException {
private static final long serialVersionUID = 6279381376051787907L;
@Override
public final synchronized Throwable fillInStackTrace() {
public synchronized Throwable fillInStackTrace() {
assert elements != null;
setStackTrace(elements);
return this;

View file

@ -49,7 +49,7 @@ public enum HotSpotCallingConventionType implements CallingConvention.Type {
public static final Type[] VALUES = values();
private HotSpotCallingConventionType(boolean out) {
HotSpotCallingConventionType(boolean out) {
this.out = out;
}
}

View file

@ -24,6 +24,7 @@ package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Infopoint;
import jdk.vm.ci.code.site.Site;
@ -99,9 +100,9 @@ public class HotSpotCompiledCode implements CompiledCode {
protected final int totalFrameSize;
/**
* Offset in bytes for the custom stack area (relative to sp).
* The deopt rescue slot. Must be non-null if there is a safepoint in the method.
*/
protected final int customStackAreaOffset;
protected final StackSlot deoptRescueSlot;
public static class Comment {
@ -115,7 +116,7 @@ public class HotSpotCompiledCode implements CompiledCode {
}
public HotSpotCompiledCode(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection,
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, int customStackAreaOffset) {
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot) {
this.name = name;
this.targetCode = targetCode;
this.targetCodeSize = targetCodeSize;
@ -129,7 +130,7 @@ public class HotSpotCompiledCode implements CompiledCode {
this.dataSectionPatches = dataSectionPatches;
this.isImmutablePIC = isImmutablePIC;
this.totalFrameSize = totalFrameSize;
this.customStackAreaOffset = customStackAreaOffset;
this.deoptRescueSlot = deoptRescueSlot;
assert validateFrames();
}

View file

@ -22,6 +22,7 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Site;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
@ -55,9 +56,9 @@ public final class HotSpotCompiledNmethod extends HotSpotCompiledCode {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage;
public HotSpotCompiledNmethod(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection,
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, int customStackAreaOffset, HotSpotResolvedJavaMethod method, int entryBCI,
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot, HotSpotResolvedJavaMethod method, int entryBCI,
int id, long jvmciEnv, boolean hasUnsafeAccess) {
super(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC, totalFrameSize, customStackAreaOffset);
super(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC, totalFrameSize, deoptRescueSlot);
this.method = method;
this.entryBCI = entryBCI;
this.id = id;

View file

@ -126,7 +126,7 @@ final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, Metas
private static final int InternalMin = config().jvmConstantInternalMin;
private static final int InternalMax = config().jvmConstantInternalMax;
private JVM_CONSTANT(int tag) {
JVM_CONSTANT(int tag) {
this.tag = tag;
}
@ -171,7 +171,7 @@ final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, Metas
int lastCpi = Integer.MIN_VALUE;
JavaType javaType;
public LookupTypeCacheElement(int lastCpi, JavaType javaType) {
LookupTypeCacheElement(int lastCpi, JavaType javaType) {
super();
this.lastCpi = lastCpi;
this.javaType = javaType;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,9 @@
*/
package jdk.vm.ci.hotspot;
public class HotSpotForeignCallTarget {
import jdk.vm.ci.meta.InvokeTarget;
public class HotSpotForeignCallTarget implements InvokeTarget {
/**
* The entry point address of this call's target.

View file

@ -43,6 +43,7 @@ import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
@ -115,7 +116,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
private boolean isDefault;
private final String help;
private Option(Class<?> type, Object defaultValue, String help) {
Option(Class<?> type, Object defaultValue, String help) {
assert Character.isUpperCase(name().charAt(0)) : "Option name must start with upper-case letter: " + name();
this.type = type;
this.value = UNINITIALIZED;
@ -123,6 +124,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
this.help = help;
}
@SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum")
private Object getValue() {
if (value == UNINITIALIZED) {
String propertyValue = VM.getSavedProperty(JVMCI_OPTION_PROPERTY_PREFIX + name());

View file

@ -38,7 +38,7 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho
protected final HotSpotJVMCIRuntimeProvider runtime;
public HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntimeProvider runtime) {
HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntimeProvider runtime) {
this.runtime = runtime;
}

View file

@ -413,7 +413,7 @@ public final class HotSpotMethodData {
private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(config.methodDataCountOffset);
public CounterData() {
CounterData() {
super(Tag.CounterData, COUNTER_DATA_SIZE);
}
@ -442,7 +442,7 @@ public final class HotSpotMethodData {
protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(config.jumpDataTakenOffset);
protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(config.jumpDataDisplacementOffset);
public JumpData() {
JumpData() {
super(Tag.JumpData, JUMP_DATA_SIZE);
}
@ -476,7 +476,7 @@ public final class HotSpotMethodData {
final long[] counts;
final long totalCount;
public RawItemProfile(int entries, T[] items, long[] counts, long totalCount) {
RawItemProfile(int entries, T[] items, long[] counts, long totalCount) {
this.entries = entries;
this.items = items;
this.counts = counts;
@ -587,7 +587,7 @@ public final class HotSpotMethodData {
private static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
public ReceiverTypeData() {
ReceiverTypeData() {
super(Tag.ReceiverTypeData, TYPE_CHECK_DATA_SIZE);
}
@ -612,7 +612,7 @@ public final class HotSpotMethodData {
private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET = TYPE_DATA_FIRST_TYPE_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET = TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
public VirtualCallData() {
VirtualCallData() {
super(Tag.VirtualCallData, VIRTUAL_CALL_DATA_SIZE);
}
@ -714,7 +714,7 @@ public final class HotSpotMethodData {
private static class VirtualCallTypeData extends VirtualCallData {
public VirtualCallTypeData() {
VirtualCallTypeData() {
super(Tag.VirtualCallTypeData, 0);
}
@ -730,7 +730,7 @@ public final class HotSpotMethodData {
private static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
private static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth;
public RetData() {
RetData() {
super(Tag.RetData, RET_DATA_SIZE);
}
}
@ -740,7 +740,7 @@ public final class HotSpotMethodData {
private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(config.branchDataNotTakenOffset);
public BranchData() {
BranchData() {
super(Tag.BranchData, BRANCH_DATA_SIZE);
}
@ -773,7 +773,7 @@ public final class HotSpotMethodData {
private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(config.arrayDataArrayLenOffset);
protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(config.arrayDataArrayStartOffset);
public ArrayData(Tag tag, int staticSize) {
ArrayData(Tag tag, int staticSize) {
super(tag, staticSize);
}
@ -800,7 +800,7 @@ public final class HotSpotMethodData {
private static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
public MultiBranchData() {
MultiBranchData() {
super(Tag.MultiBranchData, MULTI_BRANCH_DATA_SIZE);
}
@ -882,13 +882,13 @@ public final class HotSpotMethodData {
private static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1);
public ArgInfoData() {
ArgInfoData() {
super(Tag.ArgInfoData, ARG_INFO_DATA_SIZE);
}
}
private static class UnknownProfileData extends AbstractMethodData {
public UnknownProfileData(Tag tag) {
UnknownProfileData(Tag tag) {
super(tag, 0);
}

View file

@ -56,7 +56,7 @@ public interface HotSpotMethodDataAccessor {
private final int value;
private Tag(int value) {
Tag(int value) {
this.value = value;
}

View file

@ -34,7 +34,7 @@ final class HotSpotMethodUnresolved extends HotSpotMethod {
private final Signature signature;
protected JavaType holder;
public HotSpotMethodUnresolved(String name, Signature signature, JavaType holder) {
HotSpotMethodUnresolved(String name, Signature signature, JavaType holder) {
super(name);
this.holder = holder;
this.signature = signature;

View file

@ -56,7 +56,7 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
public static class FieldLocationIdentity extends LocationIdentity {
HotSpotResolvedJavaField inner;
public FieldLocationIdentity(HotSpotResolvedJavaFieldImpl inner) {
FieldLocationIdentity(HotSpotResolvedJavaFieldImpl inner) {
this.inner = inner;
}

View file

@ -33,7 +33,6 @@ import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
@ -49,7 +48,6 @@ import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ModifiersProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@ -555,7 +553,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
*
* @param index index to the fields array
*/
public FieldInfo(int index) {
FieldInfo(int index) {
HotSpotVMConfig config = config();
// Get Klass::_fields
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
@ -838,12 +836,6 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
return null;
}
@Override
public URL getClassFilePath() {
Class<?> cls = mirror();
return cls.getResource(MetaUtil.getSimpleName(cls, true).replace('.', '$') + ".class");
}
@Override
public boolean isLocal() {
return mirror().isLocalClass();

View file

@ -27,7 +27,6 @@ import static java.util.Objects.requireNonNull;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.net.URL;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
@ -239,11 +238,6 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
return kind.toJavaClass();
}
@Override
public URL getClassFilePath() {
return null;
}
@Override
public boolean isLocal() {
return false;

View file

@ -360,7 +360,7 @@ public class HotSpotVMConfig {
private final long address;
public VMFields(long address) {
VMFields(long address) {
this.address = address;
}
@ -477,7 +477,7 @@ public class HotSpotVMConfig {
private final long address;
public VMTypes(long address) {
VMTypes(long address) {
this.address = address;
}
@ -580,7 +580,7 @@ public class HotSpotVMConfig {
private final long address;
public VMIntConstants(long address) {
VMIntConstants(long address) {
this.address = address;
}
@ -639,7 +639,7 @@ public class HotSpotVMConfig {
private final long address;
public VMLongConstants(long address) {
VMLongConstants(long address) {
this.address = address;
}
@ -698,7 +698,7 @@ public class HotSpotVMConfig {
private final long address;
public VMAddresses(long address) {
VMAddresses(long address) {
this.address = address;
}
@ -753,7 +753,7 @@ public class HotSpotVMConfig {
private final long nameOffset;
private final long addrOffset;
public Flags(HashMap<String, VMFields.Field> vmStructs, HashMap<String, VMTypes.Type> vmTypes) {
Flags(HashMap<String, VMFields.Field> vmStructs, HashMap<String, VMTypes.Type> vmTypes) {
address = vmStructs.get("Flag::flags").getValue();
entrySize = vmTypes.get("Flag").getSize();
typeOffset = vmStructs.get("Flag::_type").getOffset();

View file

@ -59,7 +59,7 @@ public enum DeoptimizationAction {
private final boolean invalidatesCompilation;
private DeoptimizationAction(boolean invalidatesCompilation) {
DeoptimizationAction(boolean invalidatesCompilation) {
this.invalidatesCompilation = invalidatesCompilation;
}

View file

@ -72,7 +72,7 @@ public enum JavaKind {
private final Class<?> boxedJavaClass;
private final int slotCount;
private JavaKind(char typeChar, String javaName, int slotCount, boolean isStackInt, Class<?> primitiveJavaClass, Class<?> boxedJavaClass) {
JavaKind(char typeChar, String javaName, int slotCount, boolean isStackInt, Class<?> primitiveJavaClass, Class<?> boxedJavaClass) {
this.typeChar = typeChar;
this.javaName = javaName;
this.slotCount = slotCount;

View file

@ -57,7 +57,7 @@ import java.util.ArrayList;
*/
public final class LIRKind {
private static enum IllegalKind implements PlatformKind {
private enum IllegalKind implements PlatformKind {
ILLEGAL;
private final EnumKey<IllegalKind> key = new EnumKey<>(this);

View file

@ -35,7 +35,7 @@ public interface MethodHandleAccessProvider {
* Identification for methods defined on the class {@link MethodHandle} that are processed by
* the {@link MethodHandleAccessProvider}.
*/
public enum IntrinsicMethod {
enum IntrinsicMethod {
/** The method {@code MethodHandle.invokeBasic}. */
INVOKE_BASIC,
/** The method {@code MethodHandle.linkToStatic}. */

View file

@ -33,7 +33,7 @@ public interface PlatformKind {
}
public class EnumKey<E extends Enum<E>> implements Key {
class EnumKey<E extends Enum<E>> implements Key {
private final Enum<E> e;
public EnumKey(Enum<E> e) {

View file

@ -23,7 +23,6 @@
package jdk.vm.ci.meta;
import java.lang.annotation.Annotation;
import java.net.URL;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
@ -307,11 +306,6 @@ public interface ResolvedJavaType extends JavaType, ModifiersProvider {
*/
String getSourceFileName();
/**
* Returns the class file path - if available - of this type, or {@code null}.
*/
URL getClassFilePath();
/**
* Returns {@code true} if the type is a local type.
*/

View file

@ -47,13 +47,13 @@ public enum SPARCKind implements PlatformKind {
private final SPARCKind scalar;
private final EnumKey<SPARCKind> key = new EnumKey<>(this);
private SPARCKind(int size) {
SPARCKind(int size) {
this.size = size;
this.scalar = this;
this.vectorLength = 1;
}
private SPARCKind(int size, SPARCKind scalar) {
SPARCKind(int size, SPARCKind scalar) {
this.size = size;
this.scalar = scalar;

View file

@ -72,7 +72,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
assert(ciObjectFactory::is_initialized(), "not a shared field");
assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool");
assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constant-pool");
constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants());
@ -106,10 +106,31 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
// even though we may not need to.
int holder_index = cpool->klass_ref_index_at(index);
bool holder_is_accessible;
ciInstanceKlass* declared_holder =
ciEnv::current(thread)->get_klass_by_index(cpool, holder_index,
ciKlass* generic_declared_holder = ciEnv::current(thread)->get_klass_by_index(cpool, holder_index,
holder_is_accessible,
klass)->as_instance_klass();
klass);
if (generic_declared_holder->is_array_klass()) {
// If the declared holder of the field is an array class, assume that
// the canonical holder of that field is java.lang.Object. Arrays
// do not have fields; java.lang.Object is the only supertype of an
// array type that can declare fields and is therefore the canonical
// holder of the array type.
//
// Furthermore, the compilers assume that java.lang.Object does not
// have any fields. Therefore, the field is not looked up. Instead,
// the method returns partial information that will trigger special
// handling in ciField::will_link and will result in a
// java.lang.NoSuchFieldError exception being thrown by the compiled
// code (the expected behavior in this case).
_holder = ciEnv::current(thread)->Object_klass();
_offset = -1;
_is_constant = false;
return;
}
ciInstanceKlass* declared_holder = generic_declared_holder->as_instance_klass();
// The declared holder of this field may not have been loaded.
// Bail out with partial field information.

View file

@ -1494,7 +1494,7 @@ void CodeCache::print_summary(outputStream* st, bool detailed) {
}
void CodeCache::print_codelist(outputStream* st) {
assert_locked_or_safepoint(CodeCache_lock);
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
NMethodIterator iter;
while(iter.next_alive()) {
@ -1508,9 +1508,8 @@ void CodeCache::print_codelist(outputStream* st) {
}
void CodeCache::print_layout(outputStream* st) {
assert_locked_or_safepoint(CodeCache_lock);
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
ResourceMark rm;
print_summary(st, true);
}

View file

@ -322,9 +322,12 @@ address ExceptionCache::test_address(address addr) {
bool ExceptionCache::add_address_and_handler(address addr, address handler) {
if (test_address(addr) == handler) return true;
if (count() < cache_size) {
set_pc_at(count(),addr);
set_handler_at(count(), handler);
int index = count();
if (index < cache_size) {
set_pc_at(index, addr);
set_handler_at(index, handler);
OrderAccess::storestore();
increment_count();
return true;
}

View file

@ -466,9 +466,16 @@ CompileQueue* CompileBroker::compile_queue(int comp_level) {
return NULL;
}
void CompileBroker::print_compile_queues(outputStream* st) {
st->print_cr("Current compiles: ");
MutexLocker locker(MethodCompileQueue_lock);
MutexLocker locker2(Threads_lock);
char buf[2000];
int buflen = sizeof(buf);
Threads::print_threads_compiling(st, buf, buflen);
st->cr();
if (_c1_compile_queue != NULL) {
_c1_compile_queue->print(st);
}
@ -479,8 +486,7 @@ void CompileBroker::print_compile_queues(outputStream* st) {
void CompileQueue::print(outputStream* st) {
assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
st->print_cr("Contents of %s", name());
st->print_cr("----------------------------");
st->print_cr("%s:", name());
CompileTask* task = _first;
if (task == NULL) {
st->print_cr("Empty");
@ -490,7 +496,7 @@ void CompileQueue::print(outputStream* st) {
task = task->next();
}
}
st->print_cr("----------------------------");
st->cr();
}
void CompileQueue::print_tty() {
@ -539,7 +545,7 @@ void CompileBroker::compilation_init(TRAPS) {
c1_count = JVMCIHostThreads;
}
if (!UseInterpreter) {
if (!UseInterpreter || !BackgroundCompilation) {
// Force initialization of JVMCI compiler otherwise JVMCI
// compilations will not block until JVMCI is initialized
ResourceMark rm;
@ -1340,49 +1346,55 @@ CompileTask* CompileBroker::create_compile_task(CompileQueue* queue,
}
#if INCLUDE_JVMCI
// The number of milliseconds to wait before checking if the
// JVMCI compiler thread is blocked.
static const long BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE = 500;
// The number of milliseconds to wait before checking if
// JVMCI compilation has made progress.
static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 500;
// The number of successive times the above check is allowed to
// see a blocked JVMCI compiler thread before unblocking the
// thread waiting for the compilation to finish.
static const int BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS = 5;
// The number of JVMCI compilation progress checks that must fail
// before unblocking a thread waiting for a blocking compilation.
static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 5;
/**
* Waits for a JVMCI compiler to complete a given task. This thread
* waits until either the task completes or it sees the JVMCI compiler
* thread is blocked for N consecutive milliseconds where N is
* BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE *
* BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS.
* waits until either the task completes or it sees no JVMCI compilation
* progress for N consecutive milliseconds where N is
* JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE *
* JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS.
*
* @return true if this thread needs to free/recycle the task
*/
bool CompileBroker::wait_for_jvmci_completion(CompileTask* task, JavaThread* thread) {
bool CompileBroker::wait_for_jvmci_completion(JVMCICompiler* jvmci, CompileTask* task, JavaThread* thread) {
MutexLocker waiter(task->lock(), thread);
int consecutively_blocked = 0;
while (task->lock()->wait(!Mutex::_no_safepoint_check_flag, BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE)) {
int progress_wait_attempts = 0;
int methods_compiled = jvmci->methods_compiled();
while (!task->is_complete() && !is_compilation_disabled_forever() &&
task->lock()->wait(!Mutex::_no_safepoint_check_flag, JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE)) {
CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread();
bool progress;
if (jvmci_compiler_thread != NULL) {
JavaThreadState state;
{
// A JVMCI compiler thread should not disappear at this point
// but let's be extra safe.
MutexLocker mu(Threads_lock, thread);
state = jvmci_compiler_thread->thread_state();
// If the JVMCI compiler thread is not blocked, we deem it to be making progress.
progress = jvmci_compiler_thread->thread_state() != _thread_blocked;
} else {
// Still waiting on JVMCI compiler queue. This thread may be holding a lock
// that all JVMCI compiler threads are blocked on. We use the counter for
// successful JVMCI compilations to determine whether JVMCI compilation
// is still making progress through the JVMCI compiler queue.
progress = jvmci->methods_compiled() != methods_compiled;
}
if (state == _thread_blocked) {
if (++consecutively_blocked == BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS) {
if (!progress) {
if (++progress_wait_attempts == JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS) {
if (PrintCompilation) {
task->print(tty, "wait for blocking compilation timed out");
}
break;
}
} else {
consecutively_blocked = 0;
progress_wait_attempts = 0;
if (jvmci_compiler_thread == NULL) {
methods_compiled = jvmci->methods_compiled();
}
} else {
// Still waiting on JVMCI compiler queue
}
}
task->clear_waiter();
@ -1407,8 +1419,9 @@ void CompileBroker::wait_for_completion(CompileTask* task) {
methodHandle method(thread, task->method());
bool free_task;
#if INCLUDE_JVMCI
if (compiler(task->comp_level())->is_jvmci()) {
free_task = wait_for_jvmci_completion(task, thread);
AbstractCompiler* comp = compiler(task->comp_level());
if (comp->is_jvmci()) {
free_task = wait_for_jvmci_completion((JVMCICompiler*) comp, task, thread);
} else
#endif
{
@ -2355,10 +2368,3 @@ void CompileBroker::print_last_compile() {
}
}
void CompileBroker::print_compiler_threads_on(outputStream* st) {
#ifndef PRODUCT
st->print_cr("Compiler thread printing unimplemented.");
st->cr();
#endif
}

View file

@ -32,6 +32,9 @@
#include "runtime/perfData.hpp"
#include "trace/tracing.hpp"
#include "utilities/stack.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciCompiler.hpp"
#endif
class nmethod;
class nmethodLocker;
@ -234,7 +237,7 @@ class CompileBroker: AllStatic {
bool blocking);
static void wait_for_completion(CompileTask* task);
#if INCLUDE_JVMCI
static bool wait_for_jvmci_completion(CompileTask* task, JavaThread* thread);
static bool wait_for_jvmci_completion(JVMCICompiler* comp, CompileTask* task, JavaThread* thread);
#endif
static void invoke_compiler_on_method(CompileTask* task);
@ -350,8 +353,6 @@ public:
// Debugging output for failure
static void print_last_compile();
static void print_compiler_threads_on(outputStream* st);
// compiler name for debugging
static const char* compiler_name(int comp_level);

View file

@ -85,6 +85,7 @@ class Disassembler {
public:
static bool can_decode() {
ttyLocker tl;
return (_decode_instructions_virtual != NULL) ||
(_decode_instructions != NULL) ||
load_library();

View file

@ -546,7 +546,7 @@ JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Hand
// Make sure a valid compile_id is associated with every compile
id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
}
result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer,
result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,
stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
compiler, _debug_recorder, _dependencies, env, id,
has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log);
@ -576,7 +576,19 @@ void CodeInstaller::initialize_fields(oop target, oop compiled_code, TRAPS) {
_code_handle = JNIHandles::make_local(HotSpotCompiledCode::targetCode(compiled_code));
_code_size = HotSpotCompiledCode::targetCodeSize(compiled_code);
_total_frame_size = HotSpotCompiledCode::totalFrameSize(compiled_code);
_custom_stack_area_offset = HotSpotCompiledCode::customStackAreaOffset(compiled_code);
oop deoptRescueSlot = HotSpotCompiledCode::deoptRescueSlot(compiled_code);
if (deoptRescueSlot == NULL) {
_orig_pc_offset = -1;
} else {
_orig_pc_offset = StackSlot::offset(deoptRescueSlot);
if (StackSlot::addFrameSize(deoptRescueSlot)) {
_orig_pc_offset += _total_frame_size;
}
if (_orig_pc_offset < 0) {
JVMCI_ERROR("invalid deopt rescue slot: %d", _orig_pc_offset);
}
}
// Pre-calculate the constants section size. This is required for PC-relative addressing.
_data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code));
@ -724,6 +736,9 @@ JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer,
if (site_InfopointReason::SAFEPOINT() == reason || site_InfopointReason::CALL() == reason || site_InfopointReason::IMPLICIT_EXCEPTION() == reason) {
TRACE_jvmci_4("safepoint at %i", pc_offset);
site_Safepoint(buffer, pc_offset, site, CHECK_OK);
if (_orig_pc_offset < 0) {
JVMCI_ERROR_OK("method contains safepoint, but has no deopt rescue slot");
}
} else {
TRACE_jvmci_4("infopoint at %i", pc_offset);
site_Infopoint(buffer, pc_offset, site, CHECK_OK);

View file

@ -125,7 +125,7 @@ private:
jobject _code_handle;
jint _code_size;
jint _total_frame_size;
jint _custom_stack_area_offset;
jint _orig_pc_offset;
jint _parameter_count;
jint _constants_size;
#ifndef PRODUCT

View file

@ -38,7 +38,7 @@ elapsedTimer JVMCICompiler::_codeInstallTimer;
JVMCICompiler::JVMCICompiler() : AbstractCompiler(jvmci) {
_bootstrapping = false;
_methodsCompiled = 0;
_methods_compiled = 0;
assert(_instance == NULL, "only one instance allowed");
_instance = this;
}
@ -99,7 +99,7 @@ void JVMCICompiler::bootstrap() {
} while (first_round && qsize == 0);
first_round = false;
if (PrintBootstrap) {
while (z < (_methodsCompiled / 100)) {
while (z < (_methods_compiled / 100)) {
++z;
tty->print_raw(".");
}
@ -107,7 +107,7 @@ void JVMCICompiler::bootstrap() {
} while (qsize != 0);
if (PrintBootstrap) {
tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methodsCompiled);
tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methods_compiled);
}
_bootstrapping = false;
}
@ -176,7 +176,7 @@ void JVMCICompiler::compile_method(const methodHandle& method, int entry_bci, JV
env->set_failure("no nmethod produced", true);
} else {
env->task()->set_num_inlined_bytecodes(CompilationRequestResult::inlinedBytecodes(result_object));
_methodsCompiled++;
Atomic::inc(&_methods_compiled);
}
}
} else {

View file

@ -33,10 +33,10 @@ private:
bool _bootstrapping;
/**
* Number of methods compiled by JVMCI. This is not synchronized
* so may not be 100% accurate.
* Number of methods successfully compiled by a call to
* JVMCICompiler::compile_method().
*/
volatile int _methodsCompiled;
volatile int _methods_compiled;
static JVMCICompiler* _instance;
@ -80,8 +80,11 @@ public:
// Print compilation timers and statistics
virtual void print_timers();
// Print compilation statistics
void reset_compilation_stats();
/**
* Gets the number of methods that have been successfully compiled by
* a call to JVMCICompiler::compile_method().
*/
int methods_compiled() { return _methods_compiled; }
// Print compilation timers and statistics
static void print_compilation_timers();

View file

@ -91,7 +91,7 @@ class JVMCIJavaClasses : AllStatic {
objArrayOop_field(HotSpotCompiledCode, dataSectionPatches, "[Ljdk/vm/ci/code/site/DataPatch;") \
boolean_field(HotSpotCompiledCode, isImmutablePIC) \
int_field(HotSpotCompiledCode, totalFrameSize) \
int_field(HotSpotCompiledCode, customStackAreaOffset) \
oop_field(HotSpotCompiledCode, deoptRescueSlot, "Ljdk/vm/ci/code/StackSlot;") \
end_class \
start_class(HotSpotCompiledCode_Comment) \
oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \

View file

@ -634,6 +634,7 @@ Handle JVMCIRuntime::callStatic(const char* className, const char* methodName, c
void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
if (JNIHandles::resolve(_HotSpotJVMCIRuntime_instance) == NULL) {
ResourceMark rm;
#ifdef ASSERT
// This should only be called in the context of the JVMCI class being initialized
TempNewSymbol name = SymbolTable::new_symbol("jdk/vm/ci/runtime/JVMCI", CHECK);

View file

@ -61,7 +61,7 @@ Node* AddNode::Identity(PhaseGVN* phase) {
//------------------------------commute----------------------------------------
// Commute operands to move loads and constants to the right.
static bool commute( Node *add, int con_left, int con_right ) {
static bool commute(Node *add, bool con_left, bool con_right) {
Node *in1 = add->in(1);
Node *in2 = add->in(2);
@ -110,8 +110,8 @@ static bool commute( Node *add, int con_left, int con_right ) {
Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
const Type *t1 = phase->type( in(1) );
const Type *t2 = phase->type( in(2) );
int con_left = t1->singleton();
int con_right = t2->singleton();
bool con_left = t1->singleton();
bool con_right = t2->singleton();
// Check for commutative operation desired
if( commute(this,con_left,con_right) ) return this;

View file

@ -867,17 +867,18 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
}
}
// Cast reference arguments to its type.
for (int i = 0; i < signature->count(); i++) {
for (int i = 0, j = 0; i < signature->count(); i++) {
ciType* t = signature->type_at(i);
if (t->is_klass()) {
Node* arg = kit.argument(receiver_skip + i);
Node* arg = kit.argument(receiver_skip + j);
const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr();
const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass());
if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, sig_type));
kit.set_argument(receiver_skip + i, cast_obj);
kit.set_argument(receiver_skip + j, cast_obj);
}
}
j += t->size(); // long and double take two slots
}
// Try to get the most accurate receiver type

View file

@ -2404,20 +2404,30 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
if (needs_guard) {
// Check for an obvious zero trip guard.
Node* inctrl = PhaseIdealLoop::skip_loop_predicates(cl->in(LoopNode::EntryControl));
if (inctrl->Opcode() == Op_IfTrue) {
if (inctrl->Opcode() == Op_IfTrue || inctrl->Opcode() == Op_IfFalse) {
bool maybe_swapped = (inctrl->Opcode() == Op_IfFalse);
// The test should look like just the backedge of a CountedLoop
Node* iff = inctrl->in(0);
if (iff->is_If()) {
Node* bol = iff->in(1);
if (bol->is_Bool() && bol->as_Bool()->_test._test == cl->loopexit()->test_trip()) {
if (bol->is_Bool()) {
BoolTest test = bol->as_Bool()->_test;
if (maybe_swapped) {
test._test = test.commute();
test._test = test.negate();
}
if (test._test == cl->loopexit()->test_trip()) {
Node* cmp = bol->in(1);
if (cmp->is_Cmp() && cmp->in(1) == cl->init_trip() && cmp->in(2) == cl->limit()) {
int init_idx = maybe_swapped ? 2 : 1;
int limit_idx = maybe_swapped ? 1 : 2;
if (cmp->is_Cmp() && cmp->in(init_idx) == cl->init_trip() && cmp->in(limit_idx) == cl->limit()) {
needs_guard = false;
}
}
}
}
}
}
#ifndef PRODUCT
if (PrintOpto) {
@ -3048,7 +3058,7 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
// state of the loop. It's safe in this case to replace it with the
// result_mem.
_igvn.replace_node(store->in(MemNode::Memory), result_mem);
_igvn.replace_node(exit, result_ctrl);
lazy_replace(exit, result_ctrl);
_igvn.replace_node(store, result_mem);
// Any uses the increment outside of the loop become the loop limit.
_igvn.replace_node(head->incr(), head->limit());

View file

@ -755,8 +755,8 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
set_loop(iff2, get_loop(iffalse));
// Lazy update of 'get_ctrl' mechanism.
lazy_replace_proj( iffalse, iff2 );
lazy_replace_proj( iftrue, ift2 );
lazy_replace(iffalse, iff2);
lazy_replace(iftrue, ift2);
// Swap names
iffalse = iff2;

View file

@ -693,13 +693,18 @@ public:
}
private:
Node *get_ctrl_no_update( Node *i ) const {
Node *get_ctrl_no_update_helper(Node *i) const {
assert(has_ctrl(i), "should be control, not loop");
return (Node*)(((intptr_t)_nodes[i->_idx]) & ~1);
}
Node *get_ctrl_no_update(Node *i) const {
assert( has_ctrl(i), "" );
Node *n = (Node*)(((intptr_t)_nodes[i->_idx]) & ~1);
Node *n = get_ctrl_no_update_helper(i);
if (!n->in(0)) {
// Skip dead CFG nodes
do {
n = (Node*)(((intptr_t)_nodes[n->_idx]) & ~1);
n = get_ctrl_no_update_helper(n);
} while (!n->in(0));
n = find_non_split_ctrl(n);
}
@ -721,22 +726,15 @@ private:
// from old_node to new_node to support the lazy update. Reference
// replaces loop reference, since that is not needed for dead node.
public:
void lazy_update( Node *old_node, Node *new_node ) {
assert( old_node != new_node, "no cycles please" );
//old_node->set_req( 1, new_node /*NO DU INFO*/ );
// Nodes always have DU info now, so re-use the side array slot
// for this node to provide the forwarding pointer.
_nodes.map( old_node->_idx, (Node*)((intptr_t)new_node + 1) );
void lazy_update(Node *old_node, Node *new_node) {
assert(old_node != new_node, "no cycles please");
// Re-use the side array slot for this node to provide the
// forwarding pointer.
_nodes.map(old_node->_idx, (Node*)((intptr_t)new_node + 1));
}
void lazy_replace( Node *old_node, Node *new_node ) {
_igvn.replace_node( old_node, new_node );
lazy_update( old_node, new_node );
}
void lazy_replace_proj( Node *old_node, Node *new_node ) {
assert( old_node->req() == 1, "use this for Projs" );
_igvn.hash_delete(old_node); // Must hash-delete before hacking edges
old_node->add_req( NULL );
lazy_replace( old_node, new_node );
void lazy_replace(Node *old_node, Node *new_node) {
_igvn.replace_node(old_node, new_node);
lazy_update(old_node, new_node);
}
private:

View file

@ -2654,9 +2654,9 @@ bool PhaseMacroExpand::expand_macro_nodes() {
eliminate_macro_nodes();
// Make sure expansion will not cause node limit to be exceeded.
// Worst case is a macro node gets expanded into about 50 nodes.
// Worst case is a macro node gets expanded into about 200 nodes.
// Allow 50% more for optimization.
if (C->check_node_count(C->macro_count() * 75, "out of nodes before macro expansion" ) )
if (C->check_node_count(C->macro_count() * 300, "out of nodes before macro expansion" ) )
return true;
// Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations.

View file

@ -472,7 +472,7 @@ void PhaseIdealLoop::do_split_if( Node *iff ) {
// Replace in the graph with lazy-update mechanism
new_iff->set_req(0, new_iff); // hook self so it does not go dead
lazy_replace_proj( ifp, ifpx );
lazy_replace(ifp, ifpx);
new_iff->set_req(0, region);
// Record bits for later xforms

View file

@ -1334,6 +1334,65 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
return new BoolNode( ncmp, _test.negate() );
}
// Change ((x & m) u<= m) or ((m & x) u<= m) to always true
// Same with ((x & m) u< m+1) and ((m & x) u< m+1)
if (cop == Op_CmpU &&
cmp1->Opcode() == Op_AndI) {
Node* bound = NULL;
if (_test._test == BoolTest::le) {
bound = cmp2;
} else if (_test._test == BoolTest::lt &&
cmp2->Opcode() == Op_AddI &&
cmp2->in(2)->find_int_con(0) == 1) {
bound = cmp2->in(1);
}
if (cmp1->in(2) == bound || cmp1->in(1) == bound) {
return ConINode::make(1);
}
}
// Change ((x & (m - 1)) u< m) into (m > 0)
// This is the off-by-one variant of the above
if (cop == Op_CmpU &&
_test._test == BoolTest::lt &&
cmp1->Opcode() == Op_AndI) {
Node* l = cmp1->in(1);
Node* r = cmp1->in(2);
for (int repeat = 0; repeat < 2; repeat++) {
bool match = r->Opcode() == Op_AddI && r->in(2)->find_int_con(0) == -1 &&
r->in(1) == cmp2;
if (match) {
// arraylength known to be non-negative, so a (arraylength != 0) is sufficient,
// but to be compatible with the array range check pattern, use (arraylength u> 0)
Node* ncmp = cmp2->Opcode() == Op_LoadRange
? phase->transform(new CmpUNode(cmp2, phase->intcon(0)))
: phase->transform(new CmpINode(cmp2, phase->intcon(0)));
return new BoolNode(ncmp, BoolTest::gt);
} else {
// commute and try again
l = cmp1->in(2);
r = cmp1->in(1);
}
}
}
// Change (arraylength <= 0) or (arraylength == 0)
// into (arraylength u<= 0)
// Also change (arraylength != 0) into (arraylength u> 0)
// The latter version matches the code pattern generated for
// array range checks, which will more likely be optimized later.
if (cop == Op_CmpI &&
cmp1->Opcode() == Op_LoadRange &&
cmp2->find_int_con(-1) == 0) {
if (_test._test == BoolTest::le || _test._test == BoolTest::eq) {
Node* ncmp = phase->transform(new CmpUNode(cmp1, cmp2));
return new BoolNode(ncmp, BoolTest::le);
} else if (_test._test == BoolTest::ne) {
Node* ncmp = phase->transform(new CmpUNode(cmp1, cmp2));
return new BoolNode(ncmp, BoolTest::gt);
}
}
// Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)".
// This is a standard idiom for branching on a boolean value.
Node *c2b = cmp1;
@ -1496,4 +1555,3 @@ const Type* Log10DNode::Value(PhaseGVN* phase) const {
double d = t1->getd();
return TypeD::make( StubRoutines::intrinsic_log10( d ) );
}

View file

@ -118,12 +118,13 @@ Flag::Error AllocatePrefetchInstrConstraintFunc(intx value, bool verbose) {
}
Flag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose) {
if (value < 1 || value > max_jint) {
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_jint);
max_value);
return Flag::VIOLATES_CONSTRAINT;
}
@ -138,6 +139,24 @@ Flag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose) {
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;
}

View file

@ -2965,16 +2965,16 @@ public:
\
product(intx, AllocatePrefetchLines, 3, \
"Number of lines to prefetch ahead of array allocation pointer") \
range(1, max_jint / 2) \
range(1, 64) \
\
product(intx, AllocateInstancePrefetchLines, 1, \
"Number of lines to prefetch ahead of instance allocation " \
"pointer") \
range(1, max_jint / 2) \
range(1, 64) \
\
product(intx, AllocatePrefetchStepSize, 16, \
"Step size in bytes of sequential prefetch instructions") \
range(1, max_jint) \
range(1, 512) \
constraint(AllocatePrefetchStepSizeConstraintFunc,AfterMemoryInit)\
\
product(intx, AllocatePrefetchInstr, 0, \

View file

@ -31,6 +31,7 @@
#include "code/codeCacheExtensions.hpp"
#include "code/scopeDesc.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compileTask.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/workgroup.hpp"
@ -2884,6 +2885,20 @@ void JavaThread::print_on(outputStream *st) const {
print_thread_state_on(st);
_safepoint_state->print_on(st);
#endif // PRODUCT
if (is_Compiler_thread()) {
CompilerThread* ct = (CompilerThread*)this;
if (ct->task() != NULL) {
st->print(" Compiling: ");
ct->task()->print(st, NULL, true, false);
} else {
st->print(" No compile task");
}
st->cr();
}
}
void JavaThread::print_name_on_error(outputStream* st, char *buf, int buflen) const {
st->print("%s", get_thread_name_string(buf, buflen));
}
// Called by fatal error handler. The difference between this and
@ -4386,7 +4401,6 @@ void Threads::print_on(outputStream* st, bool print_stacks,
wt->print_on(st);
st->cr();
}
CompileBroker::print_compiler_threads_on(st);
st->flush();
}
@ -4439,8 +4453,24 @@ void Threads::print_on_error(outputStream* st, Thread* current, char* buf,
current->print_on_error(st, buf, buflen);
st->cr();
}
st->cr();
st->print_cr("Threads with active compile tasks:");
print_threads_compiling(st, buf, buflen);
}
void Threads::print_threads_compiling(outputStream* st, char* buf, int buflen) {
ALL_JAVA_THREADS(thread) {
if (thread->is_Compiler_thread()) {
CompilerThread* ct = (CompilerThread*) thread;
if (ct->task() != NULL) {
thread->print_name_on_error(st, buf, buflen);
ct->task()->print(st, NULL, true, true);
}
}
}
}
// Internal SpinLock and Mutex
// Based on ParkEvent

View file

@ -1660,6 +1660,7 @@ class JavaThread: public Thread {
void print_thread_state_on(outputStream*) const PRODUCT_RETURN;
void print_thread_state() const PRODUCT_RETURN;
void print_on_error(outputStream* st, char* buf, int buflen) const;
void print_name_on_error(outputStream* st, char* buf, int buflen) const;
void verify();
const char* get_thread_name() const;
private:
@ -2158,6 +2159,7 @@ class Threads: AllStatic {
print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);
}
static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen);
static void print_threads_compiling(outputStream* st, char* buf, int buflen);
// Get Java threads that are waiting to enter a monitor. If doLock
// is true, then Threads_lock is grabbed as needed. Otherwise, the

View file

@ -485,18 +485,6 @@ void VM_Exit::wait_if_vm_exited() {
}
}
void VM_PrintCompileQueue::doit() {
CompileBroker::print_compile_queues(_out);
}
void VM_PrintCodeList::doit() {
CodeCache::print_codelist(_out);
}
void VM_PrintCodeCache::doit() {
CodeCache::print_layout(_out);
}
#if INCLUDE_SERVICES
void VM_PrintClassHierarchy::doit() {
KlassHierarchy::print_class_hierarchy(_out, _print_interfaces, _print_subclasses, _classname);

View file

@ -105,9 +105,6 @@
template(DumpHashtable) \
template(DumpTouchedMethods) \
template(MarkActiveNMethods) \
template(PrintCompileQueue) \
template(PrintCodeList) \
template(PrintCodeCache) \
template(PrintClassHierarchy) \
class VM_Operation: public CHeapObj<mtInternal> {
@ -424,37 +421,6 @@ class VM_Exit: public VM_Operation {
void doit();
};
class VM_PrintCompileQueue: public VM_Operation {
private:
outputStream* _out;
public:
VM_PrintCompileQueue(outputStream* st) : _out(st) {}
VMOp_Type type() const { return VMOp_PrintCompileQueue; }
Mode evaluation_mode() const { return _no_safepoint; }
void doit();
};
class VM_PrintCodeList: public VM_Operation {
private:
outputStream* _out;
public:
VM_PrintCodeList(outputStream* st) : _out(st) {}
VMOp_Type type() const { return VMOp_PrintCodeList; }
void doit();
};
class VM_PrintCodeCache: public VM_Operation {
private:
outputStream* _out;
public:
VM_PrintCodeCache(outputStream* st) : _out(st) {}
VMOp_Type type() const { return VMOp_PrintCodeCache; }
void doit();
};
#if INCLUDE_SERVICES
class VM_PrintClassHierarchy: public VM_Operation {
private:

View file

@ -832,18 +832,15 @@ void VMDynamicLibrariesDCmd::execute(DCmdSource source, TRAPS) {
}
void CompileQueueDCmd::execute(DCmdSource source, TRAPS) {
VM_PrintCompileQueue printCompileQueueOp(output());
VMThread::execute(&printCompileQueueOp);
CompileBroker::print_compile_queues(output());
}
void CodeListDCmd::execute(DCmdSource source, TRAPS) {
VM_PrintCodeList printCodeListOp(output());
VMThread::execute(&printCodeListOp);
CodeCache::print_codelist(output());
}
void CodeCacheDCmd::execute(DCmdSource source, TRAPS) {
VM_PrintCodeCache printCodeCacheOp(output());
VMThread::execute(&printCodeCacheOp);
CodeCache::print_layout(output());
}
void CompilerDirectivesPrintDCmd::execute(DCmdSource source, TRAPS) {

View file

@ -24,7 +24,7 @@
/*
* @test TestCompilerDirectivesCompatibilityBase
* @bug 8137167
* @library /testlibrary /../../test/lib
* @library /testlibrary /test/lib
* @modules java.base/sun.misc
* java.compiler
* java.management

View file

@ -24,7 +24,7 @@
/*
* @test TestCompilerDirectivesCompatibilityCommandOff
* @bug 8137167
* @library /testlibrary /../../test/lib
* @library /testlibrary /test/lib
* @modules java.base/sun.misc
* java.compiler
* java.management

View file

@ -24,7 +24,7 @@
/*
* @test TestCompilerDirectivesCompatibilityCommandOn
* @bug 8137167
* @library /testlibrary /../../test/lib
* @library /testlibrary /test/lib
* @modules java.base/sun.misc
* java.compiler
* java.management

View file

@ -24,7 +24,7 @@
/*
* @test TestCompilerDirectivesCompatibilityFlag
* @bug 8137167
* @library /testlibrary /../../test/lib
* @library /testlibrary /test/lib
* @modules java.base/sun.misc
* java.compiler
* java.management

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=compileonly
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.commandfile.CompileOnlyTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=exclude
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.commandfile.ExcludeTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=log
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.commandfile.LogTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,8 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=print
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @ignore 8140354
* @build compiler.compilercontrol.commandfile.PrintTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=compileonly
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.commands.CompileOnlyTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=exclude
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.commands.ExcludeTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=log
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.commands.LogTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,8 @@
* @test
* @bug 8137167
* @summary Tests CompileCommand=print
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @ignore 8140354
* @build compiler.compilercontrol.commands.PrintTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests directives to be able to compile only specified methods
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.directives.CompileOnlyTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests directives to be able to exclude methods from compilation
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.directives.ExcludeTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests directives to be able to turn on LogCompilation
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.directives.LogTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,8 @@
* @test
* @bug 8137167
* @summary Tests directives to be able to turn on print_assembly
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @ignore 8140354
* @build compiler.compilercontrol.directives.PrintTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests directives to be able to add and remove directives
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.jcmd.AddAndRemoveTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests jcmd to be able to add a directive to compile only specified methods
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.jcmd.AddCompileOnlyTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests jcmd to be able to add a directive to exclude only specified methods
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.jcmd.AddExcludeTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Tests jcmd to be able to add a directive to log only specified methods
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.jcmd.AddLogTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -26,7 +26,7 @@
* @bug 8137167
* @summary Tests jcmd to be able to add a directive to print assembly
* only for specified methods
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.jcmd.AddPrintAssemblyTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -26,6 +26,7 @@
* @bug 8137167
* @summary Tests jcmd to be able to add a directive to compile only specified methods
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @ignore 8140354
* @build compiler.compilercontrol.jcmd.PrintDirectivesTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -27,6 +27,7 @@
* @summary Tests jcmd to be able to add a lot of huge directive files with
* parallel executed jcmds until timeout has reached
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @ignore 8148563
* @build compiler.compilercontrol.jcmd.StressAddMultiThreadedTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils

View file

@ -25,7 +25,7 @@
* @test
* @bug 8137167
* @summary Randomly generates commands with random types
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @build compiler.compilercontrol.mixed.RandomCommandsTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -25,7 +25,8 @@
* @test
* @bug 8137167
* @summary Randomly generates valid commands with random types
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @library /testlibrary /test/lib /compiler/testlibrary ../share /
* @ignore 8140354
* @build compiler.compilercontrol.mixed.RandomValidCommandsTest
* pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*

View file

@ -32,8 +32,8 @@ import java.util.Arrays;
public enum Command {
COMPILEONLY("compileonly", ".*", "-Xbatch"),
EXCLUDE("exclude", "", "-Xbatch"),
INLINE("inline", ".*"),
DONTINLINE("dontinline", ""),
INLINE("inline", ".*", "-Xbatch"),
DONTINLINE("dontinline", "", "-Xbatch"),
LOG("log", "", "-XX:+UnlockDiagnosticVMOptions",
"-XX:+LogCompilation", "-XX:LogFile=" + LogProcessor.LOG_FILE),
PRINT("print", ""),

View file

@ -27,7 +27,7 @@ import jdk.test.lib.ProcessTools;
/*
* @test
* @library /testlibrary /../../test/lib /compiler/whitebox
* @library /testlibrary /test/lib /compiler/whitebox
* /compiler/testlibrary /compiler/codegen/7184394
* @modules java.base/sun.misc
* java.management

View file

@ -28,7 +28,7 @@ import jdk.test.lib.ProcessTools;
/*
* @test
* @library /testlibrary /../../test/lib /compiler/whitebox
* @library /testlibrary /test/lib /compiler/whitebox
* /compiler/testlibrary /compiler/codegen/7184394
* @modules java.base/sun.misc
* java.management

View file

@ -24,7 +24,7 @@
/*
* @test
* @bug 8138651
* @library /testlibrary /../../test/lib
* @library /testlibrary /test/lib
* @build IntrinsicDisabledTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission

View file

@ -42,7 +42,7 @@ import jdk.test.lib.Platform;
* @test
* @bug 8130150 8131779 8139907
* @summary Verify that the Montgomery multiply and square intrinsic works and correctly checks their arguments.
* @library /testlibrary /../../test/lib
* @library /testlibrary /test/lib
* @library /testlibrary
* @build MontgomeryMultiplyTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox

View file

@ -26,7 +26,7 @@
* @test
* @bug 8145336
* @summary PPC64: fix string intrinsics after CompactStrings change
* @library /testlibrary /../../test/lib
* @library /testlibrary /test/lib
* @build sun.hotspot.WhiteBox
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission

View file

@ -0,0 +1,75 @@
/*
* 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.
*
*/
import java.lang.invoke.*;
/**
* @test
* @bug 8148752
* @summary Test correct casting of MH arguments during inlining.
* @run main LongReferenceCastingTest
*/
public class LongReferenceCastingTest {
static final String MY_STRING = "myString";
static final MethodHandle MH;
static {
try {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(String.class, long.class, Object.class, String.class);
MH = lookup.findVirtual(LongReferenceCastingTest.class, "myMethod", mt);
} catch (Exception e) {
throw new Error(e);
}
}
public String myMethod(long l, Object o, String s) {
// The long argument occupies two stack slots, causing C2 to treat it as
// two arguments and casting the fist one two long and the second one to Object.
// As a result, Object o is casted to String and the o.toString() call is
// inlined as String::toString(). We fail at runtime because 'o' is not a String.
return o.toString();
}
public String toString() {
return MY_STRING;
}
public static void main(String[] args) throws Exception {
LongReferenceCastingTest test = new LongReferenceCastingTest();
try {
for (int i = 0; i < 20_000; ++i) {
if (!test.invoke().equals(MY_STRING)) {
throw new RuntimeException("Invalid string");
}
}
} catch (Throwable t) {
throw new RuntimeException("Test failed", t);
}
}
public String invoke() throws Throwable {
return (String) MH.invokeExact(this, 0L, (Object)this, MY_STRING);
}
}

View file

@ -35,6 +35,16 @@
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=false
* -XX:-EnableJVMCI
* compiler.jvmci.JVM_GetJVMCIRuntimeTest
* @run main/othervm -XX:+UnlockExperimentalVMOptions
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=true
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.threaded=true
* -XX:+EnableJVMCI
* compiler.jvmci.JVM_GetJVMCIRuntimeTest
* @run main/othervm -XX:+UnlockExperimentalVMOptions
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=false
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.threaded=true
* -XX:-EnableJVMCI
* compiler.jvmci.JVM_GetJVMCIRuntimeTest
*/
@ -43,22 +53,27 @@ package compiler.jvmci;
import jdk.vm.ci.runtime.JVMCI;
import jdk.test.lib.Asserts;
import java.lang.reflect.Method;
public class JVM_GetJVMCIRuntimeTest {
public class JVM_GetJVMCIRuntimeTest implements Runnable {
private static final boolean IS_POSITIVE = Boolean.getBoolean(
"compiler.jvmci.JVM_GetJVMCIRuntimeTest.positive");
private static final boolean IN_THREAD = Boolean.getBoolean(
"compiler.jvmci.JVM_GetJVMCIRuntimeTest.threaded");
private final Method initializeRuntime;
public static void main(String[] args) {
new JVM_GetJVMCIRuntimeTest().runTest();
public static void main(String[] args) throws Throwable {
JVM_GetJVMCIRuntimeTest instance = new JVM_GetJVMCIRuntimeTest();
if (IN_THREAD) {
Thread t = new Thread(instance);
t.start();
t.join();
} else {
instance.run();
}
}
private void runTest() {
public void run() {
Object result;
try {
result = invoke();
result = JVMCI.getRuntime();
} catch (InternalError e) {
if (IS_POSITIVE) {
throw new AssertionError("unexpected exception", e);
@ -70,28 +85,8 @@ public class JVM_GetJVMCIRuntimeTest {
}
Asserts.assertNotNull(result,
"initializeRuntime returned null");
Asserts.assertEQ(result, invoke(),
Asserts.assertEQ(result, JVMCI.getRuntime(),
"initializeRuntime returns different results");
}
private Object invoke() {
Object result;
try {
result = initializeRuntime.invoke(JVMCI.class);
} catch (ReflectiveOperationException e) {
throw new Error("can't invoke initializeRuntime", e);
}
return result;
}
private JVM_GetJVMCIRuntimeTest() {
Method method;
try {
method = JVMCI.class.getDeclaredMethod("initializeRuntime");
method.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new Error("can't find JVMCI::initializeRuntime", e);
}
initializeRuntime = method;
}
}

View file

@ -92,6 +92,7 @@ public class CodeInstallationTest {
asm.emitPrologue();
compiler.compile(asm);
asm.emitEpilogue();
HotSpotCompiledCode code = asm.finish(resolvedMethod);
InstalledCode installed = codeCache.addCode(resolvedMethod, code, null, null);

View file

@ -32,11 +32,13 @@ import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.DebugInfo;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.Call;
import jdk.vm.ci.code.site.ConstantReference;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.DataSectionReference;
import jdk.vm.ci.code.site.Infopoint;
import jdk.vm.ci.code.site.InfopointReason;
import jdk.vm.ci.code.site.Mark;
import jdk.vm.ci.code.site.Reference;
import jdk.vm.ci.code.site.Site;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
@ -45,6 +47,7 @@ import jdk.vm.ci.hotspot.HotSpotCompiledNmethod;
import jdk.vm.ci.hotspot.HotSpotConstant;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.InvokeTarget;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@ -60,6 +63,11 @@ public abstract class TestAssembler {
*/
public abstract void emitPrologue();
/**
* Emit the method epilogue code (e.g. the deopt handler).
*/
public abstract void emitEpilogue();
/**
* Emit code to grow the stack frame.
*
@ -181,6 +189,8 @@ public abstract class TestAssembler {
private int stackAlignment;
private int curStackSlot;
private StackSlot deoptRescue;
protected TestAssembler(CodeCacheProvider codeCache, int initialFrameSize, int stackAlignment, PlatformKind narrowOopKind, Register... registers) {
this.narrowOopKind = LIRKind.reference(narrowOopKind);
@ -216,6 +226,18 @@ public abstract class TestAssembler {
return StackSlot.get(kind, -curStackSlot, true);
}
protected void setDeoptRescueSlot(StackSlot deoptRescue) {
this.deoptRescue = deoptRescue;
}
protected void recordCall(InvokeTarget target, int size, boolean direct, DebugInfo debugInfo) {
sites.add(new Call(target, code.position(), size, direct, debugInfo));
}
protected void recordMark(Object id) {
sites.add(new Mark(code.position(), id));
}
protected void recordImplicitException(DebugInfo info) {
sites.add(new Infopoint(code.position(), info, InfopointReason.IMPLICIT_EXCEPTION));
}
@ -249,7 +271,7 @@ public abstract class TestAssembler {
byte[] finishedData = data.finish();
DataPatch[] finishedDataPatches = dataPatches.toArray(new DataPatch[0]);
return new HotSpotCompiledNmethod(method.getName(), finishedCode, finishedCode.length, finishedSites, new Assumption[0], new ResolvedJavaMethod[]{method}, new Comment[0], finishedData, 16,
finishedDataPatches, false, frameSize, 0, method, 0, id, 0L, false);
finishedDataPatches, false, frameSize, deoptRescue, method, 0, id, 0L, false);
}
protected static class Buffer {

View file

@ -33,6 +33,8 @@ import jdk.vm.ci.code.site.ConstantReference;
import jdk.vm.ci.code.site.DataSectionReference;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotConstant;
import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.VMConstant;
@ -63,6 +65,16 @@ public class AMD64TestAssembler extends TestAssembler {
emitFatNop();
code.emitByte(0x50 | AMD64.rbp.encoding); // PUSH rbp
emitMove(true, AMD64.rbp, AMD64.rsp); // MOV rbp, rsp
setDeoptRescueSlot(newStackSlot(LIRKind.value(AMD64Kind.QWORD)));
}
@Override
public void emitEpilogue() {
HotSpotVMConfig config = HotSpotVMConfig.config();
recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
recordCall(new HotSpotForeignCallTarget(config.handleDeoptStub), 5, true, null);
code.emitByte(0xE8); // CALL rel32
code.emitInt(0xDEADDEAD);
}
@Override

Some files were not shown because too many files have changed in this diff Show more