This commit is contained in:
Phil Race 2018-07-19 10:17:22 -07:00
commit 28e828130d
129 changed files with 2316 additions and 591 deletions

View File

@ -496,5 +496,6 @@ e1b3def126240d5433902f3cb0e91a4c27f6db50 jdk-11+18
14708e1acdc3974f4539027cbbcfa6d69f83cf51 jdk-11+21
00b16d0457e43d23f6ca5ade6b243edce62750a0 jdk-12+1
9937ef7499dcd7673714517fd5e450410c14ba4e jdk-11+22
1edcf36fe15f79d6228d1a63eb680878e2386480 jdk-11+23
69b438908512d3dfef5852c6a843a5778333a309 jdk-12+2
990db216e7199b2ba9989d8fa20b657e0ca7d969 jdk-12+3

View File

@ -24,9 +24,6 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "gc/g1/c1/g1BarrierSetC1.hpp"
#include "gc/g1/g1BarrierSet.hpp"
#include "gc/g1/g1BarrierSetAssembler.hpp"
#include "gc/g1/g1BarrierSetRuntime.hpp"
@ -38,6 +35,11 @@
#include "runtime/thread.hpp"
#include "interpreter/interp_masm.hpp"
#include "runtime/sharedRuntime.hpp"
#ifdef COMPILER1
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "gc/g1/c1/g1BarrierSetC1.hpp"
#endif
#define __ masm->

View File

@ -739,11 +739,19 @@ address MacroAssembler::trampoline_call(Address entry, CodeBuffer *cbuf) {
|| entry.rspec().type() == relocInfo::static_call_type
|| entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type");
unsigned int start_offset = offset();
if (far_branches() && !Compile::current()->in_scratch_emit_size()) {
address stub = emit_trampoline_stub(start_offset, entry.target());
if (stub == NULL) {
return NULL; // CodeCache is full
// We need a trampoline if branches are far.
if (far_branches()) {
// We don't want to emit a trampoline if C2 is generating dummy
// code during its branch shortening phase.
CompileTask* task = ciEnv::current()->task();
bool in_scratch_emit_size =
(task != NULL && is_c2_compile(task->comp_level()) &&
Compile::current()->in_scratch_emit_size());
if (!in_scratch_emit_size) {
address stub = emit_trampoline_stub(offset(), entry.target());
if (stub == NULL) {
return NULL; // CodeCache is full
}
}
}

View File

@ -1635,6 +1635,7 @@ class Assembler : public AbstractAssembler {
// TEXASR bit description
enum transaction_failure_reason {
// Upper half (TEXASRU):
tm_failure_code = 0, // The Failure Code is copied from tabort or treclaim operand.
tm_failure_persistent = 7, // The failure is likely to recur on each execution.
tm_disallowed = 8, // The instruction is not permitted.
tm_nesting_of = 9, // The maximum transaction level was exceeded.
@ -1650,6 +1651,7 @@ class Assembler : public AbstractAssembler {
tm_failure_summary = 36, // Failure has been detected and recorded.
tm_tfiar_exact = 37, // Value in the TFIAR is exact.
tm_rot = 38, // Rollback-only transaction.
tm_transaction_level = 52, // Transaction level (nesting depth + 1).
};
// PPC 1, section 2.4.1 Branch Instructions

View File

@ -2412,7 +2412,7 @@ void MacroAssembler::atomic_ori_int(Register addr, Register result, int uimm16)
// Update rtm_counters based on abort status
// input: abort_status
// rtm_counters (RTMLockingCounters*)
// rtm_counters_Reg (RTMLockingCounters*)
void MacroAssembler::rtm_counters_update(Register abort_status, Register rtm_counters_Reg) {
// Mapping to keep PreciseRTMLockingStatistics similar to x86.
// x86 ppc (! means inverted, ? means not the same)
@ -2422,52 +2422,96 @@ void MacroAssembler::rtm_counters_update(Register abort_status, Register rtm_cou
// 3 10 Set if an internal buffer overflowed.
// 4 ?12 Set if a debug breakpoint was hit.
// 5 ?32 Set if an abort occurred during execution of a nested transaction.
const int tm_failure_bit[] = {Assembler::tm_tabort, // Note: Seems like signal handler sets this, too.
Assembler::tm_failure_persistent, // inverted: transient
Assembler::tm_trans_cf,
Assembler::tm_footprint_of,
Assembler::tm_non_trans_cf,
Assembler::tm_suspended};
const bool tm_failure_inv[] = {false, true, false, false, false, false};
assert(sizeof(tm_failure_bit)/sizeof(int) == RTMLockingCounters::ABORT_STATUS_LIMIT, "adapt mapping!");
const int failure_bit[] = {tm_tabort, // Signal handler will set this too.
tm_failure_persistent,
tm_non_trans_cf,
tm_trans_cf,
tm_footprint_of,
tm_failure_code,
tm_transaction_level};
const Register addr_Reg = R0;
// Keep track of offset to where rtm_counters_Reg had pointed to.
const int num_failure_bits = sizeof(failure_bit) / sizeof(int);
const int num_counters = RTMLockingCounters::ABORT_STATUS_LIMIT;
const int bit2counter_map[][num_counters] =
// 0 = no map; 1 = mapped, no inverted logic; -1 = mapped, inverted logic
// Inverted logic means that if a bit is set don't count it, or vice-versa.
// Care must be taken when mapping bits to counters as bits for a given
// counter must be mutually exclusive. Otherwise, the counter will be
// incremented more than once.
// counters:
// 0 1 2 3 4 5
// abort , persist, conflict, overflow, debug , nested bits:
{{ 1 , 0 , 0 , 0 , 0 , 0 }, // abort
{ 0 , -1 , 0 , 0 , 0 , 0 }, // failure_persistent
{ 0 , 0 , 1 , 0 , 0 , 0 }, // non_trans_cf
{ 0 , 0 , 1 , 0 , 0 , 0 }, // trans_cf
{ 0 , 0 , 0 , 1 , 0 , 0 }, // footprint_of
{ 0 , 0 , 0 , 0 , -1 , 0 }, // failure_code = 0xD4
{ 0 , 0 , 0 , 0 , 0 , 1 }}; // transaction_level > 1
// ...
// Move abort_status value to R0 and use abort_status register as a
// temporary register because R0 as third operand in ld/std is treated
// as base address zero (value). Likewise, R0 as second operand in addi
// is problematic because it amounts to li.
const Register temp_Reg = abort_status;
const Register abort_status_R0 = R0;
mr(abort_status_R0, abort_status);
// Increment total abort counter.
int counters_offs = RTMLockingCounters::abort_count_offset();
addi(addr_Reg, rtm_counters_Reg, counters_offs);
const Register temp_Reg = rtm_counters_Reg;
//atomic_inc_ptr(addr_Reg, temp_Reg); We don't increment atomically
ldx(temp_Reg, addr_Reg);
ld(temp_Reg, counters_offs, rtm_counters_Reg);
addi(temp_Reg, temp_Reg, 1);
stdx(temp_Reg, addr_Reg);
std(temp_Reg, counters_offs, rtm_counters_Reg);
// Increment specific abort counters.
if (PrintPreciseRTMLockingStatistics) {
int counters_offs_delta = RTMLockingCounters::abortX_count_offset() - counters_offs;
//mftexasr(abort_status); done by caller
for (int i = 0; i < RTMLockingCounters::ABORT_STATUS_LIMIT; i++) {
counters_offs += counters_offs_delta;
li(temp_Reg, counters_offs_delta); // can't use addi with R0
add(addr_Reg, addr_Reg, temp_Reg); // point to next counter
counters_offs_delta = sizeof(uintx);
// #0 counter offset.
int abortX_offs = RTMLockingCounters::abortX_count_offset();
Label check_abort;
rldicr_(temp_Reg, abort_status, tm_failure_bit[i], 0);
if (tm_failure_inv[i]) {
bne(CCR0, check_abort);
} else {
beq(CCR0, check_abort);
for (int nbit = 0; nbit < num_failure_bits; nbit++) {
for (int ncounter = 0; ncounter < num_counters; ncounter++) {
if (bit2counter_map[nbit][ncounter] != 0) {
Label check_abort;
int abort_counter_offs = abortX_offs + (ncounter << 3);
if (failure_bit[nbit] == tm_transaction_level) {
// Don't check outer transaction, TL = 1 (bit 63). Hence only
// 11 bits in the TL field are checked to find out if failure
// occured in a nested transaction. This check also matches
// the case when nesting_of = 1 (nesting overflow).
rldicr_(temp_Reg, abort_status_R0, failure_bit[nbit], 10);
} else if (failure_bit[nbit] == tm_failure_code) {
// Check failure code for trap or illegal caught in TM.
// Bits 0:7 are tested as bit 7 (persistent) is copied from
// tabort or treclaim source operand.
// On Linux: trap or illegal is TM_CAUSE_SIGNAL (0xD4).
rldicl(temp_Reg, abort_status_R0, 8, 56);
cmpdi(CCR0, temp_Reg, 0xD4);
} else {
rldicr_(temp_Reg, abort_status_R0, failure_bit[nbit], 0);
}
if (bit2counter_map[nbit][ncounter] == 1) {
beq(CCR0, check_abort);
} else {
bne(CCR0, check_abort);
}
// We don't increment atomically.
ld(temp_Reg, abort_counter_offs, rtm_counters_Reg);
addi(temp_Reg, temp_Reg, 1);
std(temp_Reg, abort_counter_offs, rtm_counters_Reg);
bind(check_abort);
}
}
//atomic_inc_ptr(addr_Reg, temp_Reg); We don't increment atomically
ldx(temp_Reg, addr_Reg);
addi(temp_Reg, temp_Reg, 1);
stdx(temp_Reg, addr_Reg);
bind(check_abort);
}
}
li(temp_Reg, -counters_offs); // can't use addi with R0
add(rtm_counters_Reg, addr_Reg, temp_Reg); // restore
// Restore abort_status.
mr(abort_status, abort_status_R0);
}
// Branch if (random & (count-1) != 0), count is 2^n
@ -2569,8 +2613,28 @@ void MacroAssembler::rtm_profiling(Register abort_status_Reg, Register temp_Reg,
void MacroAssembler::rtm_retry_lock_on_abort(Register retry_count_Reg, Register abort_status_Reg,
Label& retryLabel, Label* checkRetry) {
Label doneRetry;
// Don't retry if failure is persistent.
// The persistent bit is set when a (A) Disallowed operation is performed in
// transactional state, like for instance trying to write the TFHAR after a
// transaction is started; or when there is (B) a Nesting Overflow (too many
// nested transactions); or when (C) the Footprint overflows (too many
// addressess touched in TM state so there is no more space in the footprint
// area to track them); or in case of (D) a Self-Induced Conflict, i.e. a
// store is performed to a given address in TM state, then once in suspended
// state the same address is accessed. Failure (A) is very unlikely to occur
// in the JVM. Failure (D) will never occur because Suspended state is never
// used in the JVM. Thus mostly (B) a Nesting Overflow or (C) a Footprint
// Overflow will set the persistent bit.
rldicr_(R0, abort_status_Reg, tm_failure_persistent, 0);
bne(CCR0, doneRetry);
// Don't retry if transaction was deliberately aborted, i.e. caused by a
// tabort instruction.
rldicr_(R0, abort_status_Reg, tm_tabort, 0);
bne(CCR0, doneRetry);
// Retry if transaction aborted due to a conflict with another thread.
if (checkRetry) { bind(*checkRetry); }
addic_(retry_count_Reg, retry_count_Reg, -1);
blt(CCR0, doneRetry);

View File

@ -2029,6 +2029,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
// --------------------------------------------------------------------------
vep_start_pc = (intptr_t)__ pc();
if (UseRTMLocking) {
// Abort RTM transaction before calling JNI
// because critical section can be large and
// abort anyway. Also nmethod can be deoptimized.
__ tabort_();
}
__ save_LR_CR(r_temp_1);
__ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
__ mr(r_callers_sp, R1_SP); // Remember frame pointer.
@ -2947,6 +2954,11 @@ void SharedRuntime::generate_uncommon_trap_blob() {
InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer);
address start = __ pc();
if (UseRTMLocking) {
// Abort RTM transaction before possible nmethod deoptimization.
__ tabort_();
}
Register unroll_block_reg = R21_tmp1;
Register klass_index_reg = R22_tmp2;
Register unc_trap_reg = R23_tmp3;
@ -3090,6 +3102,13 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc;
}
if (UseRTMLocking) {
// Abort RTM transaction before calling runtime
// because critical section can be large and so
// will abort anyway. Also nmethod can be deoptimized.
__ tabort_();
}
// Save registers, fpu state, and flags. Set R31 = return pc.
map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
&frame_size_in_bytes,

View File

@ -49,16 +49,3 @@ void MiscUtils::leave_critsect(MiscUtils::critsect_t* cs) {
const int rc = pthread_mutex_unlock(cs);
assert0(rc == 0);
}
bool MiscUtils::is_readable_pointer(const void* p) {
if (!CanUseSafeFetch32()) {
return true;
}
int* const aligned = (int*) align_down(p, 4);
int cafebabe = 0xcafebabe;
int deadbeef = 0xdeadbeef;
return (SafeFetch32(aligned, cafebabe) != cafebabe) ||
(SafeFetch32(aligned, deadbeef) != deadbeef);
}

View File

@ -88,13 +88,6 @@ namespace MiscUtils {
_pcsobj->leave();
}
};
// Returns true if pointer can be dereferenced without triggering a segment
// violation. Returns false if pointer is invalid.
// Note: Depends on stub routines; prior to stub routine generation, will
// always return true. Use CanUseSafeFetch32 to handle this case.
bool is_readable_pointer(const void* p);
}
#endif // OS_AIX_VM_MISC_AIX_HPP

View File

@ -142,7 +142,7 @@ bool AixSymbols::get_function_name (
// in that case I try reading the traceback table unsafe - I rather risk secondary crashes in
// error files than not having a callstack.)
#define CHECK_POINTER_READABLE(p) \
if (!MiscUtils::is_readable_pointer(p)) { \
if (!os::is_readable_pointer(p)) { \
trcVerbose("pc not readable"); \
return false; \
}
@ -230,7 +230,7 @@ bool AixSymbols::get_function_name (
const short l = MIN2<short>(*((short*)pc2), namelen - 1);
// Be very careful.
int i = 0; char* const p = (char*)pc2 + sizeof(short);
while (i < l && MiscUtils::is_readable_pointer(p + i)) {
while (i < l && os::is_readable_pointer(p + i)) {
p_name[i] = p[i];
i++;
}
@ -489,7 +489,7 @@ static void print_info_for_pc (outputStream* st, codeptr_t pc, char* buf,
const struct tbtable* tb = NULL;
int displacement = -1;
if (!MiscUtils::is_readable_pointer(pc)) {
if (!os::is_readable_pointer(pc)) {
st->print("(invalid)");
return;
}
@ -697,7 +697,7 @@ void AixNativeCallstack::print_callstack_for_context(outputStream* st, const uco
print_info_for_pc(st, cur_iar, buf, buf_size, demangle);
st->cr();
if (cur_iar && MiscUtils::is_readable_pointer(cur_iar)) {
if (cur_iar && os::is_readable_pointer(cur_iar)) {
decode_instructions_at_pc(
"Decoded instructions at iar:",
cur_iar, 32, 16, st);
@ -710,7 +710,7 @@ void AixNativeCallstack::print_callstack_for_context(outputStream* st, const uco
print_info_for_pc(st, cur_lr, buf, buf_size, demangle);
st->cr();
if (cur_lr && MiscUtils::is_readable_pointer(cur_lr)) {
if (cur_lr && os::is_readable_pointer(cur_lr)) {
decode_instructions_at_pc(
"Decoded instructions at lr:",
cur_lr, 32, 16, st);
@ -729,7 +729,7 @@ void AixNativeCallstack::print_callstack_for_context(outputStream* st, const uco
// Check and print rtoc.
st->print("rtoc: " PTR64_FORMAT " ", p2i(cur_rtoc));
if (cur_rtoc == NULL || cur_rtoc == (codeptr_t)-1 ||
!MiscUtils::is_readable_pointer(cur_rtoc)) {
!os::is_readable_pointer(cur_rtoc)) {
st->print("(invalid)");
} else if (((uintptr_t)cur_rtoc) & 0x7) {
st->print("(unaligned)");

View File

@ -603,7 +603,9 @@ void os::print_register_info(outputStream *st, const void *context) {
st->print_cr("Register to memory mapping:");
st->cr();
// this is only for the "general purpose" registers
st->print("pc ="); print_location(st, (intptr_t)uc->uc_mcontext.regs->nip);
st->print("lr ="); print_location(st, (intptr_t)uc->uc_mcontext.regs->link);
st->print("ctr ="); print_location(st, (intptr_t)uc->uc_mcontext.regs->ctr);
for (int i = 0; i < 32; i++) {
st->print("r%-2d=", i);
print_location(st, uc->uc_mcontext.regs->gpr[i]);

View File

@ -628,7 +628,19 @@ void os::print_context(outputStream *st, const void *context) {
}
void os::print_register_info(outputStream *st, const void *context) {
st->print("Not ported\n");
if (context == NULL) return;
const ucontext_t *uc = (const ucontext_t*)context;
st->print_cr("Register to memory mapping:");
st->cr();
st->print("pc ="); print_location(st, (intptr_t)uc->uc_mcontext.psw.addr);
for (int i = 0; i < 16; i++) {
st->print("r%-2d=", i);
print_location(st, uc->uc_mcontext.gregs[i]);
}
st->cr();
}
#ifndef PRODUCT

View File

@ -450,6 +450,7 @@ void AOTCodeHeap::link_shared_runtime_symbols() {
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_object_notify", address, JVMCIRuntime::object_notify);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_object_notifyAll", address, JVMCIRuntime::object_notifyAll);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_OSR_migration_end", address, SharedRuntime::OSR_migration_end);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_enable_stack_reserved_zone", address, SharedRuntime::enable_stack_reserved_zone);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_dynamic_invoke", address, CompilerRuntime::resolve_dynamic_invoke);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_string_by_symbol", address, CompilerRuntime::resolve_string_by_symbol);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_klass_by_symbol", address, CompilerRuntime::resolve_klass_by_symbol);

View File

@ -117,23 +117,24 @@
_outbuf->print("%s", termString);
#endif
const char blobTypeChar[] = {' ', 'N', 'I', 'X', 'Z', 'U', 'R', '?', 'D', 'T', 'E', 'S', 'A', 'M', 'B', 'L' };
const char blobTypeChar[] = {' ', 'C', 'N', 'I', 'X', 'Z', 'U', 'R', '?', 'D', 'T', 'E', 'S', 'A', 'M', 'B', 'L' };
const char* blobTypeName[] = {"noType"
, "nMethod (active)"
, "nMethod (inactive)"
, "nMethod (deopt)"
, "nMethod (zombie)"
, "nMethod (unloaded)"
, "runtime stub"
, "ricochet stub"
, "deopt stub"
, "uncommon trap stub"
, "exception stub"
, "safepoint stub"
, "adapter blob"
, "MH adapter blob"
, "buffer blob"
, "lastType"
, "nMethod (under construction)"
, "nMethod (active)"
, "nMethod (inactive)"
, "nMethod (deopt)"
, "nMethod (zombie)"
, "nMethod (unloaded)"
, "runtime stub"
, "ricochet stub"
, "deopt stub"
, "uncommon trap stub"
, "exception stub"
, "safepoint stub"
, "adapter blob"
, "MH adapter blob"
, "buffer blob"
, "lastType"
};
const char* compTypeName[] = { "none", "c1", "c2", "jvmci" };
@ -156,7 +157,8 @@ static unsigned int nBlocks_t1 = 0; // counting "in_use" nmethods on
static unsigned int nBlocks_t2 = 0; // counting "in_use" nmethods only.
static unsigned int nBlocks_alive = 0; // counting "not_used" and "not_entrant" nmethods only.
static unsigned int nBlocks_dead = 0; // counting "zombie" and "unloaded" methods only.
static unsigned int nBlocks_unloaded = 0; // counting "unloaded" nmethods only. This is a transien state.
static unsigned int nBlocks_inconstr = 0; // counting "inconstruction" nmethods only. This is a transient state.
static unsigned int nBlocks_unloaded = 0; // counting "unloaded" nmethods only. This is a transient state.
static unsigned int nBlocks_stub = 0;
static struct FreeBlk* FreeArray = NULL;
@ -226,6 +228,7 @@ void CodeHeapState::get_HeapStatGlobals(outputStream* out, const char* heapName)
nBlocks_t2 = CodeHeapStatArray[ix].nBlocks_t2;
nBlocks_alive = CodeHeapStatArray[ix].nBlocks_alive;
nBlocks_dead = CodeHeapStatArray[ix].nBlocks_dead;
nBlocks_inconstr = CodeHeapStatArray[ix].nBlocks_inconstr;
nBlocks_unloaded = CodeHeapStatArray[ix].nBlocks_unloaded;
nBlocks_stub = CodeHeapStatArray[ix].nBlocks_stub;
FreeArray = CodeHeapStatArray[ix].FreeArray;
@ -248,6 +251,7 @@ void CodeHeapState::get_HeapStatGlobals(outputStream* out, const char* heapName)
nBlocks_t2 = 0;
nBlocks_alive = 0;
nBlocks_dead = 0;
nBlocks_inconstr = 0;
nBlocks_unloaded = 0;
nBlocks_stub = 0;
FreeArray = NULL;
@ -274,6 +278,7 @@ void CodeHeapState::set_HeapStatGlobals(outputStream* out, const char* heapName)
CodeHeapStatArray[ix].nBlocks_t2 = nBlocks_t2;
CodeHeapStatArray[ix].nBlocks_alive = nBlocks_alive;
CodeHeapStatArray[ix].nBlocks_dead = nBlocks_dead;
CodeHeapStatArray[ix].nBlocks_inconstr = nBlocks_inconstr;
CodeHeapStatArray[ix].nBlocks_unloaded = nBlocks_unloaded;
CodeHeapStatArray[ix].nBlocks_stub = nBlocks_stub;
CodeHeapStatArray[ix].FreeArray = FreeArray;
@ -554,6 +559,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
nBlocks_t2 = 0;
nBlocks_alive = 0;
nBlocks_dead = 0;
nBlocks_inconstr = 0;
nBlocks_unloaded = 0;
nBlocks_stub = 0;
@ -587,6 +593,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
size_t disconnSpace = 0;
size_t notentrSpace = 0;
size_t deadSpace = 0;
size_t inconstrSpace = 0;
size_t unloadedSpace = 0;
size_t stubSpace = 0;
size_t freeSpace = 0;
@ -692,6 +699,10 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
nBlocks_dead++;
deadSpace += hb_bytelen;
break;
case nMethod_inconstruction:
nBlocks_inconstr++;
inconstrSpace += hb_bytelen;
break;
default:
break;
}
@ -846,6 +857,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
StatArray[ix_beg].level = comp_lvl;
StatArray[ix_beg].compiler = cType;
break;
case nMethod_inconstruction: // let's count "in construction" nmethods here.
case nMethod_alive:
StatArray[ix_beg].tx_count++;
StatArray[ix_beg].tx_space += (unsigned short)hb_len;
@ -902,6 +914,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
StatArray[ix_end].level = comp_lvl;
StatArray[ix_end].compiler = cType;
break;
case nMethod_inconstruction: // let's count "in construction" nmethods here.
case nMethod_alive:
StatArray[ix_beg].tx_count++;
StatArray[ix_beg].tx_space += (unsigned short)beg_space;
@ -949,6 +962,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
StatArray[ix].level = comp_lvl;
StatArray[ix].compiler = cType;
break;
case nMethod_inconstruction: // let's count "in construction" nmethods here.
case nMethod_alive:
StatArray[ix].tx_count++;
StatArray[ix].tx_space += (unsigned short)(granule_size>>log2_seg_size);
@ -971,11 +985,6 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
}
}
}
if (n_methods > 0) {
avgTemp = hotnessAccumulator/n_methods;
} else {
avgTemp = 0;
}
done = true;
if (!insane) {
@ -990,6 +999,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
ast->print_cr(" Alive Space = " SIZE_FORMAT_W(8) "k, nBlocks_alive = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", aliveSpace/(size_t)K, nBlocks_alive, (100.0*aliveSpace)/size, (100.0*aliveSpace)/res_size);
ast->print_cr(" disconnected = " SIZE_FORMAT_W(8) "k, nBlocks_disconn = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", disconnSpace/(size_t)K, nBlocks_disconn, (100.0*disconnSpace)/size, (100.0*disconnSpace)/res_size);
ast->print_cr(" not entrant = " SIZE_FORMAT_W(8) "k, nBlocks_notentr = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", notentrSpace/(size_t)K, nBlocks_notentr, (100.0*notentrSpace)/size, (100.0*notentrSpace)/res_size);
ast->print_cr(" inconstrSpace = " SIZE_FORMAT_W(8) "k, nBlocks_inconstr = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", inconstrSpace/(size_t)K, nBlocks_inconstr, (100.0*inconstrSpace)/size, (100.0*inconstrSpace)/res_size);
ast->print_cr(" unloadedSpace = " SIZE_FORMAT_W(8) "k, nBlocks_unloaded = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", unloadedSpace/(size_t)K, nBlocks_unloaded, (100.0*unloadedSpace)/size, (100.0*unloadedSpace)/res_size);
ast->print_cr(" deadSpace = " SIZE_FORMAT_W(8) "k, nBlocks_dead = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", deadSpace/(size_t)K, nBlocks_dead, (100.0*deadSpace)/size, (100.0*deadSpace)/res_size);
ast->print_cr(" stubSpace = " SIZE_FORMAT_W(8) "k, nBlocks_stub = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", stubSpace/(size_t)K, nBlocks_stub, (100.0*stubSpace)/size, (100.0*stubSpace)/res_size);
@ -1009,9 +1019,15 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
printBox(ast, '-', "Method hotness information at time of this analysis", NULL);
ast->print_cr("Highest possible method temperature: %12d", reset_val);
ast->print_cr("Threshold for method to be considered 'cold': %12.3f", -reset_val + reverse_free_ratio * NmethodSweepActivity);
ast->print_cr("min. hotness = %6d", minTemp);
ast->print_cr("avg. hotness = %6d", avgTemp);
ast->print_cr("max. hotness = %6d", maxTemp);
if (n_methods > 0) {
avgTemp = hotnessAccumulator/n_methods;
ast->print_cr("min. hotness = %6d", minTemp);
ast->print_cr("avg. hotness = %6d", avgTemp);
ast->print_cr("max. hotness = %6d", maxTemp);
} else {
avgTemp = 0;
ast->print_cr("No hotness data available");
}
STRINGSTREAM_FLUSH("\n")
// This loop is intentionally printing directly to "out".
@ -1024,6 +1040,9 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
if (StatArray[ix].t2_count > granule_segs) {
out->print_cr("t2_count[%d] = %d", ix, StatArray[ix].t2_count);
}
if (StatArray[ix].tx_count > granule_segs) {
out->print_cr("tx_count[%d] = %d", ix, StatArray[ix].tx_count);
}
if (StatArray[ix].stub_count > granule_segs) {
out->print_cr("stub_count[%d] = %d", ix, StatArray[ix].stub_count);
}
@ -1036,6 +1055,9 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
if (StatArray[ix].t2_space > granule_segs) {
out->print_cr("t2_space[%d] = %d", ix, StatArray[ix].t2_space);
}
if (StatArray[ix].tx_space > granule_segs) {
out->print_cr("tx_space[%d] = %d", ix, StatArray[ix].tx_space);
}
if (StatArray[ix].stub_space > granule_segs) {
out->print_cr("stub_space[%d] = %d", ix, StatArray[ix].stub_space);
}
@ -1043,11 +1065,11 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
out->print_cr("dead_space[%d] = %d", ix, StatArray[ix].dead_space);
}
// this cast is awful! I need it because NT/Intel reports a signed/unsigned mismatch.
if ((size_t)(StatArray[ix].t1_count+StatArray[ix].t2_count+StatArray[ix].stub_count+StatArray[ix].dead_count) > granule_segs) {
out->print_cr("t1_count[%d] = %d, t2_count[%d] = %d, stub_count[%d] = %d", ix, StatArray[ix].t1_count, ix, StatArray[ix].t2_count, ix, StatArray[ix].stub_count);
if ((size_t)(StatArray[ix].t1_count+StatArray[ix].t2_count+StatArray[ix].tx_count+StatArray[ix].stub_count+StatArray[ix].dead_count) > granule_segs) {
out->print_cr("t1_count[%d] = %d, t2_count[%d] = %d, tx_count[%d] = %d, stub_count[%d] = %d", ix, StatArray[ix].t1_count, ix, StatArray[ix].t2_count, ix, StatArray[ix].tx_count, ix, StatArray[ix].stub_count);
}
if ((size_t)(StatArray[ix].t1_space+StatArray[ix].t2_space+StatArray[ix].stub_space+StatArray[ix].dead_space) > granule_segs) {
out->print_cr("t1_space[%d] = %d, t2_space[%d] = %d, stub_space[%d] = %d", ix, StatArray[ix].t1_space, ix, StatArray[ix].t2_space, ix, StatArray[ix].stub_space);
if ((size_t)(StatArray[ix].t1_space+StatArray[ix].t2_space+StatArray[ix].tx_space+StatArray[ix].stub_space+StatArray[ix].dead_space) > granule_segs) {
out->print_cr("t1_space[%d] = %d, t2_space[%d] = %d, tx_space[%d] = %d, stub_space[%d] = %d", ix, StatArray[ix].t1_space, ix, StatArray[ix].t2_space, ix, StatArray[ix].tx_space, ix, StatArray[ix].stub_space);
}
}
@ -1131,7 +1153,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
if (!done || (nBlocks_free == 0)) {
if (nBlocks_free == 0) {
printBox(ast, '-', "no free blocks found in", heapName);
printBox(ast, '-', "no free blocks found in ", heapName);
} else if (!done) {
ast->print_cr("Free block count mismatch could not be resolved.");
ast->print_cr("Try to run \"aggregate\" function to update counters");
@ -1261,9 +1283,10 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
ast->print("%5d", nm->hotness_counter());
//---< name and signature >---
ast->fill_to(67+6);
if (nm->is_in_use()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
if (nm->is_not_entrant()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
if (nm->is_zombie()) {ast->print("%14s", " zombie method"); }
if (nm->is_in_use()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
if (nm->is_not_entrant()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
if (nm->is_not_installed()) {ast->print("%s", " not (yet) installed method "); }
if (nm->is_zombie()) {ast->print("%s", " zombie method "); }
ast->print("%s", blob_name);
} else {
//---< block size in hex >---
@ -1657,7 +1680,7 @@ void CodeHeapState::print_count(outputStream* out, CodeHeap* heap) {
{
if (nBlocks_alive > 0) {
printBox(ast, '-', "not_used/not_entrant nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
printBox(ast, '-', "not_used/not_entrant/not_installed nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
STRINGSTREAM_FLUSH_LOCKED("")
granules_per_line = 128;
@ -1846,7 +1869,7 @@ void CodeHeapState::print_space(outputStream* out, CodeHeap* heap) {
{
if (nBlocks_alive > 0) {
printBox(ast, '-', "not_used/not_entrant space consumption. ' ' indicates empty, '*' indicates full", NULL);
printBox(ast, '-', "not_used/not_entrant/not_installed space consumption. ' ' indicates empty, '*' indicates full", NULL);
granules_per_line = 128;
for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@ -2016,7 +2039,7 @@ void CodeHeapState::print_age(outputStream* out, CodeHeap* heap) {
{
if (nBlocks_alive > 0) {
printBox(ast, '-', "not_used/not_entrant age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
printBox(ast, '-', "not_used/not_entrant/not_installed age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
STRINGSTREAM_FLUSH_LOCKED("")
granules_per_line = 128;
@ -2106,8 +2129,8 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
bool blob_initialized = (this_blob != NULL) && (this_blob->header_size() >= 0) && (this_blob->relocation_size() >= 0) &&
((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
is_readable_pointer((address)(this_blob->relocation_begin())) &&
is_readable_pointer(this_blob->content_begin());
os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
os::is_readable_pointer(this_blob->content_begin());
// blob could have been flushed, freed, and merged.
// this_blob < last_blob is an indicator for that.
if (blob_initialized && (this_blob > last_blob)) {
@ -2122,7 +2145,7 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
}
// this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
const char* blob_name = this_blob->name();
if ((blob_name == NULL) || !is_readable_pointer(blob_name)) {
if ((blob_name == NULL) || !os::is_readable_pointer(blob_name)) {
blob_name = "<unavailable>";
}
@ -2146,8 +2169,8 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
// this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
nmethod* nm = this_blob->as_nmethod_or_null();
Method* method = (nm == NULL) ? NULL : nm->method(); // may be uninitialized, i.e. != NULL, but invalid
if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) &&
is_readable_pointer(method) && is_readable_pointer(method->constants())) {
if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) && (cbType != nMethod_inconstruction) &&
os::is_readable_pointer(method) && os::is_readable_pointer(method->constants())) {
ResourceMark rm;
//---< collect all data to locals as quickly as possible >---
unsigned int total_size = nm->total_size();
@ -2346,7 +2369,7 @@ void CodeHeapState::print_line_delim(outputStream* out, bufferedStream* ast, cha
}
CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
if ((cb != NULL) && is_readable_pointer(cb)) {
if ((cb != NULL) && os::is_readable_pointer(cb)) {
if (cb->is_runtime_stub()) return runtimeStub;
if (cb->is_deoptimization_stub()) return deoptimizationStub;
if (cb->is_uncommon_trap_stub()) return uncommonTrapStub;
@ -2358,27 +2381,14 @@ CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
nmethod* nm = cb->as_nmethod_or_null();
if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
if (nm->is_not_installed()) return nMethod_inconstruction;
if (nm->is_zombie()) return nMethod_dead;
if (nm->is_unloaded()) return nMethod_unloaded;
if (nm->is_in_use()) return nMethod_inuse;
if (nm->is_alive() && !(nm->is_not_entrant())) return nMethod_notused;
if (nm->is_alive()) return nMethod_alive;
if (nm->is_in_use()) return nMethod_inuse;
return nMethod_dead;
}
}
return noType;
}
// Check if pointer can be read from (4-byte read access).
// Helps to prove validity of a not-NULL pointer.
// Returns true in very early stages of VM life when stub is not yet generated.
#define SAFEFETCH_DEFAULT true
bool CodeHeapState::is_readable_pointer(const void* p) {
if (!CanUseSafeFetch32()) {
return SAFEFETCH_DEFAULT;
}
int* const aligned = (int*) align_down((intptr_t)p, 4);
int cafebabe = 0xcafebabe; // tester value 1
int deadbeef = 0xdeadbeef; // tester value 2
return (SafeFetch32(aligned, cafebabe) != cafebabe) || (SafeFetch32(aligned, deadbeef) != deadbeef);
}

View File

@ -43,26 +43,28 @@ class CodeHeapState : public CHeapObj<mtCode> {
};
enum blobType {
noType = 0, // must be! due to initialization by memset to zero
// The nMethod_* values correspond 1:1 to the CompiledMethod enum values.
nMethod_inuse, // executable. This is the "normal" state for a nmethod.
nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary.
nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist.
// Will transition to "zombie" after all activations are gone.
nMethod_zombie, // No more activations exist, ready for purge (remove from code cache).
nMethod_unloaded, // No activations exist, should not be called. Transient state on the way to "zombie".
nMethod_alive = nMethod_notentrant, // Combined state: nmethod may have activations, thus can't be purged.
nMethod_dead = nMethod_zombie, // Combined state: nmethod does not have any activations.
runtimeStub = nMethod_unloaded + 1,
ricochetStub,
deoptimizationStub,
uncommonTrapStub,
exceptionStub,
safepointStub,
adapterBlob,
mh_adapterBlob,
bufferBlob,
lastType
noType = 0, // must be! due to initialization by memset to zero
// The nMethod_* values correspond to the CompiledMethod enum values.
// We can't use the CompiledMethod values 1:1 because we depend on noType == 0.
nMethod_inconstruction, // under construction. Very soon, the type will transition to "in_use".
nMethod_inuse, // executable. This is the "normal" state for a nmethod.
nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary.
nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist.
// Will transition to "zombie" after all activations are gone.
nMethod_zombie, // No more activations exist, ready for purge (remove from code cache).
nMethod_unloaded, // No activations exist, should not be called. Transient state on the way to "zombie".
nMethod_alive = nMethod_notentrant, // Combined state: nmethod may have activations, thus can't be purged.
nMethod_dead = nMethod_zombie, // Combined state: nmethod does not have any activations.
runtimeStub = nMethod_unloaded + 1,
ricochetStub,
deoptimizationStub,
uncommonTrapStub,
exceptionStub,
safepointStub,
adapterBlob,
mh_adapterBlob,
bufferBlob,
lastType
};
private:
@ -93,7 +95,6 @@ class CodeHeapState : public CHeapObj<mtCode> {
static void print_line_delim(outputStream* out, bufferedStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
static void print_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
static blobType get_cbType(CodeBlob* cb);
static bool is_readable_pointer(const void* p);
public:
static void discard(outputStream* out, CodeHeap* heap);
@ -214,6 +215,7 @@ struct CodeHeapStat {
unsigned int nBlocks_t2;
unsigned int nBlocks_alive;
unsigned int nBlocks_dead;
unsigned int nBlocks_inconstr;
unsigned int nBlocks_unloaded;
unsigned int nBlocks_stub;
// FreeBlk data

View File

@ -10369,7 +10369,7 @@ myInit() {
<description>
Can generate sampled allocation events.
If this capability is enabled then the heap sampling method
<functionlink id="SetHeapSamplingRate"></functionlink> can be
<functionlink id="SetHeapSamplingInterval"></functionlink> can be
called and <eventlink id="SampledObjectAlloc"></eventlink> events can be generated.
</description>
</capabilityfield>
@ -11552,41 +11552,47 @@ myInit() {
</category>
<category id="heap_monitoring" label="Heap Monitoring">
<function id="SetHeapSamplingRate" phase="onload" num="156" since="11">
<synopsis>Set Heap Sampling Rate</synopsis>
<function id="SetHeapSamplingInterval" phase="onload" num="156" since="11">
<synopsis>Set Heap Sampling Interval</synopsis>
<description>
Generate a <eventlink id="SampledObjectAlloc"/> event when objects are allocated.
Each thread keeps a counter of bytes allocated. The event will only be generated
when that counter exceeds an average of <paramlink id="sampling_rate"></paramlink>
when that counter exceeds an average of <paramlink id="sampling_interval"></paramlink>
since the last sample.
<p/>
Setting <paramlink id="sampling_rate"></paramlink> to 0 will cause an event to be
generated by each allocation supported by the system.
Setting <paramlink id="sampling_interval"></paramlink> to 0 will cause an event to be
generated by each allocation supported by the system once the new interval is taken into account.
<p/>
Note that updating the new sampling interval might take various number of allocations
to provoke internal data structure updates. Therefore it is important to
consider the sampling interval as an average. This includes the interval 0, where events
might not be generated straight away for each allocation.
</description>
<origin>new</origin>
<capabilities>
<required id="can_generate_sampled_object_alloc_events"></required>
</capabilities>
<parameters>
<param id="sampling_rate">
<param id="sampling_interval">
<jint/>
<description>
The sampling rate in bytes. The sampler uses a statistical approach to
generate an event, on average, once for every <paramlink id="sampling_rate"/> bytes of
The sampling interval in bytes. The sampler uses a statistical approach to
generate an event, on average, once for every <paramlink id="sampling_interval"/> bytes of
memory allocated by a given thread.
<p/>
Passing 0 as a sampling rate generates a sample for every allocation.
Once the new sampling interval is taken into account, 0 as a sampling interval will generate
a sample for every allocation.
<p/>
Note: The overhead of this feature is directly correlated with the sampling rate.
A high sampling rate, such as 1024 bytes, will incur a high overhead.
A lower rate, such as 1024KB, will have a much lower overhead. Sampling should only
Note: The overhead of this feature is directly correlated with the sampling interval.
A high sampling interval, such as 1024 bytes, will incur a high overhead.
A lower interval, such as 1024KB, will have a much lower overhead. Sampling should only
be used with an understanding that it may impact performance.
</description>
</param>
</parameters>
<errors>
<error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
<paramlink id="sampling_rate"></paramlink> is less than zero.
<paramlink id="sampling_interval"></paramlink> is less than zero.
</error>
</errors>
</function>
@ -13586,20 +13592,23 @@ myInit() {
id="SampledObjectAlloc" const="JVMTI_EVENT_SAMPLED_OBJECT_ALLOC" num="86" since="11">
<description>
Sent when an allocated object is sampled.
By default, the sampling rate is a geometric variable with a 512KB mean.
By default, the sampling interval is set to 512KB. The sampling is semi-random to avoid
pattern-based bias and provides an approximate overall average interval over long periods of
sampling.
<p/>
Each thread tracks how many bytes it has allocated since it sent the last event.
When the number of bytes exceeds the sampling rate, it will send another event.
When the number of bytes exceeds the sampling interval, it will send another event.
This implies that, on average, one object will be sampled every time a thread has
allocated 512KB bytes since the last sample.
<p/>
Note that this is a geometric variable: it will not sample every 512KB precisely.
Note that the sampler is pseudo-random: it will not sample every 512KB precisely.
The goal of this is to ensure high quality sampling even if allocation is
happening in a fixed pattern (i.e., the same set of objects are being allocated
every 512KB).
<p/>
If another sampling rate is required, the user can call
<functionlink id="SetHeapSamplingRate"></functionlink> with a strictly positive integer value, representing
the new sampling rate.
If another sampling interval is required, the user can call
<functionlink id="SetHeapSamplingInterval"></functionlink> with a strictly positive integer value,
representing the new sampling interval.
<p/>
This event is sent once the sampled allocation has been performed. It provides the object, stack trace
of the allocation, the thread allocating, the size of allocation, and the object's class.

View File

@ -3644,13 +3644,13 @@ JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {
} /* end GetAvailableProcessors */
jvmtiError
JvmtiEnv::SetHeapSamplingRate(jint sampling_rate) {
if (sampling_rate < 0) {
JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {
if (sampling_interval < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
ThreadHeapSampler::set_sampling_rate(sampling_rate);
ThreadHeapSampler::set_sampling_interval(sampling_interval);
return JVMTI_ERROR_NONE;
} /* end SetHeapSamplingRate */
} /* end SetHeapSamplingInterval */
//
// System Properties functions

View File

@ -995,6 +995,22 @@ void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
st->print_cr(" elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs);
}
// Check if pointer can be read from (4-byte read access).
// Helps to prove validity of a not-NULL pointer.
// Returns true in very early stages of VM life when stub is not yet generated.
#define SAFEFETCH_DEFAULT true
bool os::is_readable_pointer(const void* p) {
if (!CanUseSafeFetch32()) {
return SAFEFETCH_DEFAULT;
}
int* const aligned = (int*) align_down((intptr_t)p, 4);
int cafebabe = 0xcafebabe; // tester value 1
int deadbeef = 0xdeadbeef; // tester value 2
return (SafeFetch32(aligned, cafebabe) != cafebabe) || (SafeFetch32(aligned, deadbeef) != deadbeef);
}
// moved from debug.cpp (used to be find()) but still called from there
// The verbose parameter is only set by the debug code in one case
void os::print_location(outputStream* st, intptr_t x, bool verbose) {
@ -1094,21 +1110,26 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
return;
}
}
if (JNIHandles::is_global_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a global jni handle", p2i(addr));
return;
}
if (JNIHandles::is_weak_global_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a weak global jni handle", p2i(addr));
return;
}
bool accessible = is_readable_pointer(addr);
if (align_down((intptr_t)addr, sizeof(intptr_t)) != 0 && accessible) {
if (JNIHandles::is_global_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a global jni handle", p2i(addr));
return;
}
if (JNIHandles::is_weak_global_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a weak global jni handle", p2i(addr));
return;
}
#ifndef PRODUCT
// we don't keep the block list in product mode
if (JNIHandles::is_local_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a local jni handle", p2i(addr));
return;
}
// we don't keep the block list in product mode
if (JNIHandles::is_local_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a local jni handle", p2i(addr));
return;
}
#endif
}
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
// Check for privilege stack
@ -1155,6 +1176,11 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
return;
}
if (accessible) {
st->print_cr(INTPTR_FORMAT " points into unknown readable memory", p2i(addr));
return;
}
st->print_cr(INTPTR_FORMAT " is an unknown value", p2i(addr));
}

View File

@ -412,6 +412,9 @@ class os: AllStatic {
static void make_polling_page_unreadable();
static void make_polling_page_readable();
// Check if pointer points to readable memory (by 4-byte read access)
static bool is_readable_pointer(const void* p);
// Routines used to serialize the thread state without using membars
static void serialize_thread_states();

View File

@ -31,7 +31,7 @@
// Cheap random number generator
uint64_t ThreadHeapSampler::_rnd;
// Default is 512kb.
int ThreadHeapSampler::_sampling_rate = 512 * 1024;
int ThreadHeapSampler::_sampling_interval = 512 * 1024;
int ThreadHeapSampler::_enabled;
// Statics for the fast log
@ -69,7 +69,7 @@ static double fast_log2(const double & d) {
// Generates a geometric variable with the specified mean (512K by default).
// This is done by generating a random number between 0 and 1 and applying
// the inverse cumulative distribution function for an exponential.
// Specifically: Let m be the inverse of the sample rate, then
// Specifically: Let m be the inverse of the sample interval, then
// the probability distribution function is m*exp(-mx) so the CDF is
// p = 1 - exp(-mx), so
// q = 1 - p = exp(-mx)
@ -96,14 +96,14 @@ void ThreadHeapSampler::pick_next_geometric_sample() {
// negative answer.
double log_val = (fast_log2(q) - 26);
double result =
(0.0 < log_val ? 0.0 : log_val) * (-log(2.0) * (get_sampling_rate())) + 1;
(0.0 < log_val ? 0.0 : log_val) * (-log(2.0) * (get_sampling_interval())) + 1;
assert(result > 0 && result < SIZE_MAX, "Result is not in an acceptable range.");
size_t rate = static_cast<size_t>(result);
_bytes_until_sample = rate;
size_t interval = static_cast<size_t>(result);
_bytes_until_sample = interval;
}
void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) {
if (get_sampling_rate() == 1) {
if (get_sampling_interval() == 1) {
_bytes_until_sample = 1;
return;
}
@ -161,12 +161,12 @@ void ThreadHeapSampler::disable() {
OrderAccess::release_store(&_enabled, 0);
}
int ThreadHeapSampler::get_sampling_rate() {
return OrderAccess::load_acquire(&_sampling_rate);
int ThreadHeapSampler::get_sampling_interval() {
return OrderAccess::load_acquire(&_sampling_interval);
}
void ThreadHeapSampler::set_sampling_rate(int sampling_rate) {
OrderAccess::release_store(&_sampling_rate, sampling_rate);
void ThreadHeapSampler::set_sampling_interval(int sampling_interval) {
OrderAccess::release_store(&_sampling_interval, sampling_interval);
}
// Methods used in assertion mode to check if a collector is present or not at

View File

@ -36,7 +36,7 @@ class ThreadHeapSampler {
void pick_next_geometric_sample();
void pick_next_sample(size_t overflowed_bytes = 0);
static int _enabled;
static int _sampling_rate;
static int _sampling_interval;
// Used for assertion mode to determine if there is a path to a TLAB slow path
// without a collector present.
@ -63,8 +63,8 @@ class ThreadHeapSampler {
static void enable();
static void disable();
static void set_sampling_rate(int sampling_rate);
static int get_sampling_rate();
static void set_sampling_interval(int sampling_interval);
static int get_sampling_interval();
bool sampling_collector_present() const;
bool remove_sampling_collector();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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,6 +29,8 @@
package com.sun.crypto.provider;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.crypto.IllegalBlockSizeException;
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
@ -68,6 +70,15 @@ final class GCTR extends CounterMode {
return "GCTR";
}
// return the number of blocks until the lower 32 bits roll over
private long blocksUntilRollover() {
ByteBuffer buf = ByteBuffer.wrap(counter, counter.length - 4, 4);
buf.order(ByteOrder.BIG_ENDIAN);
long ctr32 = 0xFFFFFFFFL & buf.getInt();
long blocksLeft = (1L << 32) - ctr32;
return blocksLeft;
}
// input must be multiples of 128-bit blocks when calling update
int update(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
if (inLen - inOfs > in.length) {
@ -80,7 +91,25 @@ final class GCTR extends CounterMode {
throw new RuntimeException("output buffer too small");
}
return encrypt(in, inOfs, inLen, out, outOfs);
long blocksLeft = blocksUntilRollover();
int numOfCompleteBlocks = inLen / AES_BLOCK_SIZE;
if (numOfCompleteBlocks >= blocksLeft) {
// Counter Mode encryption cannot be used because counter will
// roll over incorrectly. Use GCM-specific code instead.
byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
for (int i = 0; i < numOfCompleteBlocks; i++) {
embeddedCipher.encryptBlock(counter, 0, encryptedCntr, 0);
for (int n = 0; n < AES_BLOCK_SIZE; n++) {
int index = (i * AES_BLOCK_SIZE + n);
out[outOfs + index] =
(byte) ((in[inOfs + index] ^ encryptedCntr[n]));
}
GaloisCounterMode.increment32(counter);
}
return inLen;
} else {
return encrypt(in, inOfs, inLen, out, outOfs);
}
}
// input can be arbitrary size when calling doFinal

View File

@ -33,7 +33,6 @@ import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.security.util.HexDumpEncoder;
import sun.security.util.*;
/**
@ -260,21 +259,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
String kdfAlgo = null;
String cipherAlgo = null;
DerValue pBES2Algorithms = new DerValue(encoded);
if (pBES2Algorithms.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
}
if (!pkcs5PBES2_OID.equals(pBES2Algorithms.data.getOID())) {
throw new IOException("PBE parameter parsing error: "
+ "expecting the object identifier for PBES2");
}
if (pBES2Algorithms.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
}
DerValue pBES2_params = pBES2Algorithms.data.getDerValue();
DerValue pBES2_params = new DerValue(encoded);
if (pBES2_params.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
@ -293,7 +278,6 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
@SuppressWarnings("deprecation")
private String parseKDF(DerValue keyDerivationFunc) throws IOException {
String kdfAlgo = null;
if (!pkcs5PBKDF2_OID.equals(keyDerivationFunc.data.getOID())) {
throw new IOException("PBE parameter parsing error: "
@ -318,34 +302,41 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
+ "not an ASN.1 OCTET STRING tag");
}
iCount = pBKDF2_params.data.getInteger();
DerValue keyLength = pBKDF2_params.data.getDerValue();
if (keyLength.tag == DerValue.tag_Integer) {
keysize = keyLength.getInteger() * 8; // keysize (in bits)
}
if (pBKDF2_params.tag == DerValue.tag_Sequence) {
DerValue prf = pBKDF2_params.data.getDerValue();
kdfAlgo_OID = prf.data.getOID();
if (hmacWithSHA1_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA1";
} else if (hmacWithSHA224_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA224";
} else if (hmacWithSHA256_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA256";
} else if (hmacWithSHA384_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA384";
} else if (hmacWithSHA512_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA512";
} else {
throw new IOException("PBE parameter parsing error: "
+ "expecting the object identifier for a HmacSHA key "
+ "derivation function");
// keyLength INTEGER (1..MAX) OPTIONAL,
if (pBKDF2_params.data.available() > 0) {
DerValue keyLength = pBKDF2_params.data.getDerValue();
if (keyLength.tag == DerValue.tag_Integer) {
keysize = keyLength.getInteger() * 8; // keysize (in bits)
}
if (prf.data.available() != 0) {
// parameter is 'NULL' for all HmacSHA KDFs
DerValue parameter = prf.data.getDerValue();
if (parameter.tag != DerValue.tag_Null) {
}
// prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
String kdfAlgo = "HmacSHA1";
if (pBKDF2_params.data.available() > 0) {
if (pBKDF2_params.tag == DerValue.tag_Sequence) {
DerValue prf = pBKDF2_params.data.getDerValue();
kdfAlgo_OID = prf.data.getOID();
if (hmacWithSHA1_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA1";
} else if (hmacWithSHA224_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA224";
} else if (hmacWithSHA256_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA256";
} else if (hmacWithSHA384_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA384";
} else if (hmacWithSHA512_OID.equals(kdfAlgo_OID)) {
kdfAlgo = "HmacSHA512";
} else {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 NULL tag");
+ "expecting the object identifier for a HmacSHA key "
+ "derivation function");
}
if (prf.data.available() != 0) {
// parameter is 'NULL' for all HmacSHA KDFs
DerValue parameter = prf.data.getDerValue();
if (parameter.tag != DerValue.tag_Null) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 NULL tag");
}
}
}
}
@ -399,8 +390,6 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
protected byte[] engineGetEncoded() throws IOException {
DerOutputStream out = new DerOutputStream();
DerOutputStream pBES2Algorithms = new DerOutputStream();
pBES2Algorithms.putOID(pkcs5PBES2_OID);
DerOutputStream pBES2_params = new DerOutputStream();
@ -410,7 +399,10 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
DerOutputStream pBKDF2_params = new DerOutputStream();
pBKDF2_params.putOctetString(salt); // choice: 'specified OCTET STRING'
pBKDF2_params.putInteger(iCount);
pBKDF2_params.putInteger(keysize / 8); // derived key length (in octets)
if (keysize > 0) {
pBKDF2_params.putInteger(keysize / 8); // derived key length (in octets)
}
DerOutputStream prf = new DerOutputStream();
// algorithm is id-hmacWithSHA1/SHA224/SHA256/SHA384/SHA512
@ -434,8 +426,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
}
pBES2_params.write(DerValue.tag_Sequence, encryptionScheme);
pBES2Algorithms.write(DerValue.tag_Sequence, pBES2_params);
out.write(DerValue.tag_Sequence, pBES2Algorithms);
out.write(DerValue.tag_Sequence, pBES2_params);
return out.toByteArray();
}

View File

@ -1807,6 +1807,7 @@ public class KeyStore {
keystore.load(dataStream, password);
} else {
keystore.keyStoreSpi.engineLoad(dataStream, param);
keystore.initialized = true;
}
return keystore;
}

View File

@ -106,7 +106,7 @@ public class PatternSyntaxException
}
sb.append(System.lineSeparator());
sb.append(pattern);
if (index >= 0) {
if (index >= 0 && pattern != null && index < pattern.length()) {
sb.append(System.lineSeparator());
for (int i = 0; i < index; i++) sb.append(' ');
sb.append('^');

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2018, 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
@ -87,6 +87,9 @@ public class ReflectionFactory {
private static boolean noInflation = false;
private static int inflationThreshold = 15;
// true if deserialization constructor checking is disabled
private static boolean disableSerialConstructorChecks = false;
private ReflectionFactory() {
}
@ -424,10 +427,64 @@ public class ReflectionFactory {
return generateConstructor(cl, constructorToCall);
}
/**
* Given a class, determines whether its superclass has
* any constructors that are accessible from the class.
* This is a special purpose method intended to do access
* checking for a serializable class and its superclasses
* up to, but not including, the first non-serializable
* superclass. This also implies that the superclass is
* always non-null, because a serializable class must be a
* class (not an interface) and Object is not serializable.
*
* @param cl the class from which access is checked
* @return whether the superclass has a constructor accessible from cl
*/
private boolean superHasAccessibleConstructor(Class<?> cl) {
Class<?> superCl = cl.getSuperclass();
assert Serializable.class.isAssignableFrom(cl);
assert superCl != null;
if (packageEquals(cl, superCl)) {
// accessible if any non-private constructor is found
for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
return true;
}
}
return false;
} else {
// sanity check to ensure the parent is protected or public
if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
return false;
}
// accessible if any constructor is protected or public
for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
return true;
}
}
return false;
}
}
/**
* Returns a constructor that allocates an instance of cl and that then initializes
* the instance by calling the no-arg constructor of its first non-serializable
* superclass. This is specified in the Serialization Specification, section 3.1,
* in step 11 of the deserialization process. If cl is not serializable, returns
* cl's no-arg constructor. If no accessible constructor is found, or if the
* class hierarchy is somehow malformed (e.g., a serializable class has no
* superclass), null is returned.
*
* @param cl the class for which a constructor is to be found
* @return the generated constructor, or null if none is available
*/
public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
Class<?> initCl = cl;
while (Serializable.class.isAssignableFrom(initCl)) {
if ((initCl = initCl.getSuperclass()) == null) {
Class<?> prev = initCl;
if ((initCl = initCl.getSuperclass()) == null ||
(!disableSerialConstructorChecks && !superHasAccessibleConstructor(prev))) {
return null;
}
}
@ -653,6 +710,9 @@ public class ReflectionFactory {
}
}
disableSerialConstructorChecks =
"true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
initted = true;
}

View File

@ -2098,7 +2098,8 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
RetryWithZero.run(pass -> {
// Use JCE
SecretKey skey = getPBEKey(pass);
Cipher cipher = Cipher.getInstance(algOid.toString());
Cipher cipher = Cipher.getInstance(
mapPBEParamsToAlgorithm(algOid, algParams));
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
loadSafeContents(new DerInputStream(cipher.doFinal(rawData)));
return null;

View File

@ -27,6 +27,7 @@ package sun.security.ssl;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
@ -46,6 +47,9 @@ final class PostHandshakeContext extends HandshakeContext {
"Post-handshake not supported in " + negotiatedProtocol.name);
}
this.localSupportedSignAlgs = new ArrayList<SignatureScheme>(
context.conSession.getLocalSupportedSignatureSchemes());
handshakeConsumers = new LinkedHashMap<>(consumers);
handshakeFinished = true;
}

View File

@ -33,8 +33,11 @@ import java.util.ArrayList;
import java.util.Locale;
import java.util.Arrays;
import java.util.Optional;
import java.util.Collection;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.net.ssl.SSLPeerUnverifiedException;
import static sun.security.ssl.ClientAuthType.CLIENT_AUTH_REQUIRED;
import sun.security.ssl.ClientHello.ClientHelloMessage;
import sun.security.ssl.SSLExtension.ExtensionConsumer;
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
@ -167,7 +170,7 @@ final class PreSharedKeyExtension {
int getIdsEncodedLength() {
int idEncodedLength = 0;
for(PskIdentity curId : identities) {
for (PskIdentity curId : identities) {
idEncodedLength += curId.getEncodedLength();
}
@ -190,7 +193,7 @@ final class PreSharedKeyExtension {
byte[] buffer = new byte[encodedLength];
ByteBuffer m = ByteBuffer.wrap(buffer);
Record.putInt16(m, idsEncodedLength);
for(PskIdentity curId : identities) {
for (PskIdentity curId : identities) {
curId.writeEncoded(m);
}
Record.putInt16(m, bindersEncodedLength);
@ -220,7 +223,7 @@ final class PreSharedKeyExtension {
String identitiesString() {
StringBuilder result = new StringBuilder();
for(PskIdentity curId : identities) {
for (PskIdentity curId : identities) {
result.append(curId.toString() + "\n");
}
@ -229,7 +232,7 @@ final class PreSharedKeyExtension {
String bindersString() {
StringBuilder result = new StringBuilder();
for(byte[] curBinder : binders) {
for (byte[] curBinder : binders) {
result.append("{" + Utilities.toHexString(curBinder) + "}\n");
}
@ -328,6 +331,7 @@ final class PreSharedKeyExtension {
public void consume(ConnectionContext context,
HandshakeMessage message,
ByteBuffer buffer) throws IOException {
ClientHelloMessage clientHello = (ClientHelloMessage) message;
ServerHandshakeContext shc = (ServerHandshakeContext)context;
// Is it a supported and enabled extension?
if (!shc.sslConfig.isAvailable(SSLExtension.CH_PRE_SHARED_KEY)) {
@ -367,8 +371,7 @@ final class PreSharedKeyExtension {
int idIndex = 0;
for (PskIdentity requestedId : pskSpec.identities) {
SSLSessionImpl s = sessionCache.get(requestedId.identity);
if (s != null && s.isRejoinable() &&
s.getPreSharedKey().isPresent()) {
if (s != null && canRejoin(clientHello, shc, s)) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine("Resuming session: ", s);
}
@ -392,10 +395,68 @@ final class PreSharedKeyExtension {
// update the context
shc.handshakeExtensions.put(
SSLExtension.CH_PRE_SHARED_KEY, pskSpec);
SSLExtension.CH_PRE_SHARED_KEY, pskSpec);
}
}
private static boolean canRejoin(ClientHelloMessage clientHello,
ServerHandshakeContext shc, SSLSessionImpl s) {
boolean result = s.isRejoinable() && s.getPreSharedKey().isPresent();
// Check protocol version
if (result && s.getProtocolVersion() != shc.negotiatedProtocol) {
if (SSLLogger.isOn &&
SSLLogger.isOn("ssl,handshake,verbose")) {
SSLLogger.finest("Can't resume, incorrect protocol version");
}
result = false;
}
// Validate the required client authentication.
if (result &&
(shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED)) {
try {
s.getPeerPrincipal();
} catch (SSLPeerUnverifiedException e) {
if (SSLLogger.isOn &&
SSLLogger.isOn("ssl,handshake,verbose")) {
SSLLogger.finest(
"Can't resume, " +
"client authentication is required");
}
result = false;
}
// Make sure the list of supported signature algorithms matches
Collection<SignatureScheme> sessionSigAlgs =
s.getLocalSupportedSignatureSchemes();
if (result &&
!shc.localSupportedSignAlgs.containsAll(sessionSigAlgs)) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine("Can't resume. Session uses different " +
"signature algorithms");
}
result = false;
}
}
// Ensure cipher suite can be negotiated
if (result && (!shc.isNegotiable(s.getSuite()) ||
!clientHello.cipherSuites.contains(s.getSuite()))) {
if (SSLLogger.isOn &&
SSLLogger.isOn("ssl,handshake,verbose")) {
SSLLogger.finest(
"Can't resume, unavailable session cipher suite");
}
result = false;
}
return result;
}
private static final
class CHPreSharedKeyUpdate implements HandshakeConsumer {
// Prevent instantiation of this class.
@ -547,6 +608,18 @@ final class PreSharedKeyExtension {
return null;
}
// Make sure the list of supported signature algorithms matches
Collection<SignatureScheme> sessionSigAlgs =
chc.resumingSession.getLocalSupportedSignatureSchemes();
if (!chc.localSupportedSignAlgs.containsAll(sessionSigAlgs)) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine("Existing session uses different " +
"signature algorithms");
}
return null;
}
// The session must have a pre-shared key
Optional<SecretKey> pskOpt = chc.resumingSession.getPreSharedKey();
if (!pskOpt.isPresent()) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@ -658,7 +731,7 @@ final class PreSharedKeyExtension {
} catch (NoSuchAlgorithmException | InvalidKeyException ex) {
throw new IOException(ex);
}
} catch(GeneralSecurityException ex) {
} catch (GeneralSecurityException ex) {
throw new IOException(ex);
}
}

View File

@ -96,7 +96,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
private boolean invalidated;
private X509Certificate[] localCerts;
private PrivateKey localPrivateKey;
private final String[] localSupportedSignAlgs;
private final Collection<SignatureScheme> localSupportedSignAlgs;
private String[] peerSupportedSignAlgs; // for certificate
private boolean useDefaultPeerSignAlgs = false;
private List<byte[]> statusResponses;
@ -144,7 +144,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
this.sessionId = new SessionId(false, null);
this.host = null;
this.port = -1;
this.localSupportedSignAlgs = new String[0];
this.localSupportedSignAlgs = Collections.emptySet();
this.serverNameIndication = null;
this.requestedServerNames = Collections.<SNIServerName>emptyList();
this.useExtendedMasterSecret = false;
@ -179,8 +179,9 @@ final class SSLSessionImpl extends ExtendedSSLSession {
this.sessionId = id;
this.host = hc.conContext.transport.getPeerHost();
this.port = hc.conContext.transport.getPeerPort();
this.localSupportedSignAlgs =
SignatureScheme.getAlgorithmNames(hc.localSupportedSignAlgs);
this.localSupportedSignAlgs = hc.localSupportedSignAlgs == null ?
Collections.emptySet() :
Collections.unmodifiableCollection(hc.localSupportedSignAlgs);
this.serverNameIndication = hc.negotiatedServerName;
this.requestedServerNames = Collections.<SNIServerName>unmodifiableList(
hc.getRequestedServerNames());
@ -969,16 +970,20 @@ final class SSLSessionImpl extends ExtendedSSLSession {
}
/**
* Gets an array of supported signature algorithms that the local side is
* willing to verify.
* Gets an array of supported signature algorithm names that the local
* side is willing to verify.
*/
@Override
public String[] getLocalSupportedSignatureAlgorithms() {
if (localSupportedSignAlgs != null) {
return localSupportedSignAlgs.clone();
}
return SignatureScheme.getAlgorithmNames(localSupportedSignAlgs);
}
return new String[0];
/**
* Gets an array of supported signature schemes that the local side is
* willing to verify.
*/
public Collection<SignatureScheme> getLocalSupportedSignatureSchemes() {
return localSupportedSignAlgs;
}
/**

View File

@ -393,6 +393,13 @@ class TransportContext implements ConnectionContext, Closeable {
}
void setUseClientMode(boolean useClientMode) {
// Once handshaking has begun, the mode can not be reset for the
// life of this engine.
if (handshakeContext != null || isNegotiated) {
throw new IllegalArgumentException(
"Cannot change mode after SSL traffic has started");
}
/*
* If we need to change the client mode and the enabled
* protocols and cipher suites haven't specifically been
@ -400,13 +407,6 @@ class TransportContext implements ConnectionContext, Closeable {
* default ones.
*/
if (sslConfig.isClientMode != useClientMode) {
// Once handshaking has begun, the mode can not be reset for the
// life of this engine.
if (handshakeContext != null || isNegotiated) {
throw new IllegalArgumentException(
"Cannot change mode after SSL traffic has started");
}
if (sslContext.isDefaultProtocolVesions(
sslConfig.enabledProtocols)) {
sslConfig.enabledProtocols =

View File

@ -297,6 +297,22 @@ JNU_NotifyAll(JNIEnv *env, jobject object);
} \
} while (0) \
#define CHECK_NULL_THROW_NPE(env, x, msg) \
do { \
if ((x) == NULL) { \
JNU_ThrowNullPointerException((env), (msg));\
return; \
} \
} while(0) \
#define CHECK_NULL_THROW_NPE_RETURN(env, x, msg, z)\
do { \
if ((x) == NULL) { \
JNU_ThrowNullPointerException((env), (msg));\
return (z); \
} \
} while(0) \
#define CHECK_NULL_RETURN(x, y) \
do { \
if ((x) == NULL) { \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018, 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
@ -171,32 +171,38 @@ jboolean setInet6Address_ipaddress(JNIEnv *env, jobject iaObj, char *address) {
void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
(*env)->SetIntField(env, holder, iac_addressID, address);
}
void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
(*env)->SetIntField(env, holder, iac_familyID, family);
}
void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
(*env)->SetObjectField(env, holder, iac_hostNameID, host);
(*env)->SetObjectField(env, holder, iac_origHostNameID, host);
}
int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", -1);
return (*env)->GetIntField(env, holder, iac_addressID);
}
int getInetAddress_family(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", -1);
return (*env)->GetIntField(env, holder, iac_familyID);
}
jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", NULL);
return (*env)->GetObjectField(env, holder, iac_hostNameID);
}
@ -211,7 +217,9 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
CHECK_NULL_RETURN(iaObj, NULL);
address = NET_IPv4MappedToIPv4(caddr);
setInetAddress_addr(env, iaObj, address);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
} else {
jboolean ret;
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
@ -220,6 +228,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
if (ret == JNI_FALSE)
return NULL;
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv6);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
setInet6Address_scopeid(env, iaObj, sa->sa6.sin6_scope_id);
}
*port = ntohs(sa->sa6.sin6_port);
@ -227,7 +236,9 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
CHECK_NULL_RETURN(iaObj, NULL);
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
setInetAddress_addr(env, iaObj, ntohl(sa->sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
*port = ntohs(sa->sa4.sin_port);
}
return iaObj;
@ -238,6 +249,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
{
jint family = getInetAddress_family(env, iaObj) ==
java_net_InetAddress_IPv4 ? AF_INET : AF_INET6;
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
if (sa->sa.sa_family == AF_INET6) {
jbyte *caddrNew = (jbyte *)&sa->sa6.sin6_addr;
if (NET_IsIPv4Mapped(caddrNew)) {
@ -247,6 +259,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
}
addrNew = NET_IPv4MappedToIPv4(caddrNew);
addrCur = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
if (addrNew == addrCur) {
return JNI_TRUE;
} else {
@ -273,6 +286,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
}
addrNew = ntohl(sa->sa4.sin_addr.s_addr);
addrCur = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
if (addrNew == addrCur) {
return JNI_TRUE;
} else {

View File

@ -739,13 +739,13 @@ ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified)
jzfile *zip = NULL;
/* Clear zip error message */
if (pmsg != 0) {
if (pmsg != NULL) {
*pmsg = NULL;
}
zip = ZIP_Get_From_Cache(name, pmsg, lastModified);
if (zip == NULL && *pmsg == NULL) {
if (zip == NULL && pmsg != NULL && *pmsg == NULL) {
ZFILE zfd = ZFILE_Open(name, mode);
zip = ZIP_Put_In_Cache(name, zfd, pmsg, lastModified);
}

View File

@ -193,7 +193,11 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
}
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *)
(iterator->ai_addr))->sin_addr.s_addr));
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, i++, iaObj);
iterator = iterator->ai_next;
}

View File

@ -198,6 +198,8 @@ lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6)
return NULL;
}
setInetAddress_hostName(env, o, name);
if ((*env)->ExceptionCheck(env))
goto done;
(*env)->SetObjectArrayElement(env, result, index, o);
(*env)->DeleteLocalRef(env, o);
}
@ -355,7 +357,11 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
goto cleanupAndReturn;
}
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
inetIndex++;
} else if (iterator->ai_family == AF_INET6) {
@ -376,6 +382,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
setInet6Address_scopeid(env, iaObj, scope);
}
setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
inet6Index++;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -329,11 +329,11 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
(JNIEnv *env, jclass cls, jobject iaObj)
{
netif *ifs, *curr;
int family = (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) ?
AF_INET : AF_INET6;
jobject obj = NULL;
jboolean match = JNI_FALSE;
int family = (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) ?
AF_INET : AF_INET6;
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
ifs = enumInterfaces(env);
if (ifs == NULL) {
return NULL;
@ -351,7 +351,7 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
int address1 = htonl(
((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr);
int address2 = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
if (address1 == address2) {
match = JNI_TRUE;
break;
@ -698,6 +698,7 @@ static jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
if (iaObj) {
setInetAddress_addr(env, iaObj, htonl(
((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
} else {
return NULL;
}
@ -710,6 +711,7 @@ static jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
if (ia2Obj) {
setInetAddress_addr(env, ia2Obj, htonl(
((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
(*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
} else {
return NULL;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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
@ -531,9 +531,12 @@ Java_java_net_PlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
iaObj = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
AF_INET : AF_INET6;
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (family == AF_INET) { /* this API can't handle IPV6 addresses */
int address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
setInetAddress_addr(env, addressObj, address);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
}
return port;
}
@ -1014,6 +1017,7 @@ static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject val
struct in_addr in;
jobjectArray addrArray;
jsize len;
jint family;
jobject addr;
int i;
@ -1044,8 +1048,11 @@ static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject val
in.s_addr = 0;
for (i = 0; i < len; i++) {
addr = (*env)->GetObjectArrayElement(env, addrArray, i);
if (getInetAddress_family(env, addr) == java_net_InetAddress_IPv4) {
family = getInetAddress_family(env, addr);
JNU_CHECK_EXCEPTION(env);
if (family == java_net_InetAddress_IPv4) {
in.s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION(env);
break;
}
}
@ -1095,7 +1102,7 @@ static void mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject v
struct in_addr in;
in.s_addr = htonl( getInetAddress_addr(env, value) );
JNU_CHECK_EXCEPTION(env);
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char*)&in, sizeof(in)) < 0) {
JNU_ThrowByNameWithMessageAndLastError
@ -1458,6 +1465,7 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
CHECK_NULL_RETURN(addr, NULL);
setInetAddress_addr(env, addr, ntohl(in.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
/*
* For IP_MULTICAST_IF return InetAddress
@ -1890,6 +1898,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
jint fd;
jint family;
jint ipv6_join_leave;
if (IS_NULL(fdObj)) {
@ -1910,7 +1919,9 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
ipv6_join_leave = ipv6_available();
#ifdef __linux__
if (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) {
family = getInetAddress_family(env, iaObj);
JNU_CHECK_EXCEPTION(env);
if (family == java_net_InetAddress_IPv4) {
ipv6_join_leave = JNI_FALSE;
}
#endif
@ -1951,6 +1962,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
}
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
mname.imr_address.s_addr = 0;
mname.imr_ifindex = (*env)->GetIntField(env, niObj, ni_indexID);
mname_len = sizeof(struct ip_mreqn);
@ -1969,11 +1981,14 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
addr = (*env)->GetObjectArrayElement(env, addrArray, 0);
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
#ifdef __linux__
mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION(env);
mname.imr_ifindex = 0;
#else
mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION(env);
#endif
mname_len = sizeof(struct ip_mreq);
}
@ -2009,6 +2024,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
}
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
mname.imr_address.s_addr = 0 ;
mname.imr_ifindex = index;
mname_len = sizeof(struct ip_mreqn);
@ -2031,6 +2047,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
mname.imr_interface.s_addr = in.s_addr;
#endif
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
mname_len = sizeof(struct ip_mreq);
}
}
@ -2097,10 +2114,11 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
jint address;
family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
AF_INET : AF_INET6;
JNU_CHECK_EXCEPTION(env);
if (family == AF_INET) { /* will convert to IPv4-mapped address */
memset((char *) caddr, 0, 16);
address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION(env);
caddr[10] = 0xff;
caddr[11] = 0xff;

View File

@ -764,6 +764,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
jboolean v4MappedAddress)
{
jint family = getInetAddress_family(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
memset((char *)sa, 0, sizeof(SOCKETADDRESS));
if (ipv6_available() &&
@ -777,6 +778,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
// convert to IPv4-mapped address
memset((char *)caddr, 0, 16);
address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (address == INADDR_ANY) {
/* we would always prefer IPv6 wildcard address
* caddr[10] = 0xff;
@ -871,6 +873,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
return -1;
}
address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
sa->sa4.sin_port = htons(port);
sa->sa4.sin_addr.s_addr = htonl(address);
sa->sa4.sin_family = AF_INET;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -146,7 +146,11 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
}
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *)
(iterator->ai_addr))->sin_addr.s_addr));
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, i++, iaObj);
iterator = iterator->ai_next;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -187,7 +187,11 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
goto cleanupAndReturn;
}
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
inetIndex++;
} else if (iterator->ai_family == AF_INET6) {
@ -208,6 +212,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
setInet6Address_scopeid(env, iaObj, scope);
}
setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
inet6Index++;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -586,6 +586,7 @@ jobject createNetworkInterface
/* default ctor will set family to AF_INET */
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
if (addrs->mask != -1) {
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
if (ibObj == NULL) {
@ -599,6 +600,7 @@ jobject createNetworkInterface
return NULL;
}
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
(*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
@ -754,8 +756,9 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
(JNIEnv *env, jclass cls, jobject iaObj)
{
netif *ifList, *curr;
jint addr = getInetAddress_addr(env, iaObj);
jobject netifObj = NULL;
jint addr = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
if (ipv6_available()) {

View File

@ -584,7 +584,7 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
/* default ctor will set family to AF_INET */
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
if (ibObj == NULL) {
free_netaddr(netaddrP);
@ -597,6 +597,7 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
return NULL;
}
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
(*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);

View File

@ -219,16 +219,16 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
int ipv6_supported = ipv6_available();
int fd, fd1 = -1, lcladdrlen = 0;
jint family;
SOCKETADDRESS lcladdr;
if (getInetAddress_family(env, addressObj) == java_net_InetAddress_IPv6 &&
!ipv6_supported)
{
family = getInetAddress_family(env, addressObj);
JNU_CHECK_EXCEPTION(env);
if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Protocol family not supported");
return;
}
if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
return;
@ -344,6 +344,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0
}
family = getInetAddress_family(env, address);
JNU_CHECK_EXCEPTION(env);
if (family == java_net_InetAddress_IPv6 && !ipv6_available()) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Protocol family not supported");
@ -455,6 +456,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send
}
family = getInetAddress_family(env, iaObj);
JNU_CHECK_EXCEPTION(env);
if (family == java_net_InetAddress_IPv4) {
fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
} else {
@ -584,6 +586,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
return -1;
} else {
address = getInetAddress_addr(env, addressObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
/* We only handle IPv4 for now. Will support IPv6 once its in the os */
family = AF_INET;
}
@ -657,7 +660,9 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
return 0;
}
setInetAddress_addr(env, addressObj, ntohl(remote_addr.sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, -1);
setInetAddress_family(env, addressObj, java_net_InetAddress_IPv4);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
/* return port */
return ntohs(remote_addr.sa4.sin_port);
@ -1349,6 +1354,7 @@ static int getInetAddrFromIf (JNIEnv *env, int family, jobject nif, jobject *iad
int fam;
addr = (*env)->GetObjectArrayElement(env, addrArray, i);
fam = getInetAddress_family(env, addr);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (fam == family) {
*iaddr = addr;
return 0;
@ -1367,6 +1373,7 @@ static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr)
}
iaddr->s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION_RETURN(env, -1);
return 0;
}
@ -1471,6 +1478,7 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
struct in_addr in;
in.s_addr = htonl(getInetAddress_addr(env, value));
JNU_CHECK_EXCEPTION(env);
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char*)&in, sizeof(in)) < 0) {
JNU_ThrowByNameWithMessageAndLastError
@ -1712,7 +1720,7 @@ static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint
CHECK_NULL_RETURN(addr, NULL);
setInetAddress_addr(env, addr, ntohl(in.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
/*
* For IP_MULTICAST_IF return InetAddress
*/

View File

@ -794,6 +794,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
jboolean v4MappedAddress)
{
jint family = getInetAddress_family(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
memset((char *)sa, 0, sizeof(SOCKETADDRESS));
if (ipv6_available() &&
@ -808,6 +809,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
// convert to IPv4-mapped address
memset((char *)caddr, 0, 16);
address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (address == INADDR_ANY) {
/* we would always prefer IPv6 wildcard address
* caddr[10] = 0xff;
@ -846,6 +848,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
return -1;
}
address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
sa->sa4.sin_port = htons((short)port);
sa->sa4.sin_addr.s_addr = (u_long)htonl(address);
sa->sa4.sin_family = AF_INET;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2018, 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
@ -364,11 +364,11 @@ public class FileManager {
* @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5
*/
public static boolean moveToTrash(final File file) throws FileNotFoundException {
if (file == null || !file.exists()) throw new FileNotFoundException();
if (file == null) throw new FileNotFoundException();
final String fileName = file.getAbsolutePath();
final SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(fileName);
if (security != null) security.checkDelete(fileName);
return _moveToTrash(fileName);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2018, 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
@ -42,6 +42,9 @@ import java.io.FilePermission;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
import javax.swing.JMenuBar;
@ -363,15 +366,11 @@ public class Desktop {
* @throws NullPointerException if file is null
* @throws IllegalArgumentException if file doesn't exist
*/
private static void checkFileValidation(File file){
if (file == null) throw new NullPointerException("File must not be null");
private static void checkFileValidation(File file) {
if (!file.exists()) {
throw new IllegalArgumentException("The file: "
+ file.getPath() + " doesn't exist.");
}
file.canRead();
}
/**
@ -425,6 +424,7 @@ public class Desktop {
* @see java.awt.AWTPermission
*/
public void open(File file) throws IOException {
file = new File(file.getPath());
checkAWTPermission();
checkExec();
checkActionSupport(Action.OPEN);
@ -456,6 +456,7 @@ public class Desktop {
* @see java.awt.AWTPermission
*/
public void edit(File file) throws IOException {
file = new File(file.getPath());
checkAWTPermission();
checkExec();
checkActionSupport(Action.EDIT);
@ -486,6 +487,7 @@ public class Desktop {
* allowed to create a subprocess
*/
public void print(File file) throws IOException {
file = new File(file.getPath());
checkExec();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@ -614,14 +616,6 @@ public class Desktop {
}
}
private void checkDelete() throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new FilePermission("<<ALL FILES>>",
SecurityConstants.FILE_DELETE_ACTION));
}
}
private void checkQuitPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@ -950,6 +944,8 @@ public class Desktop {
* @since 9
*/
public void openHelpViewer() {
checkAWTPermission();
checkExec();
checkEventsProcessingPermission();
checkActionSupport(Action.APP_HELP_VIEWER);
peer.openHelpViewer();
@ -995,9 +991,15 @@ public class Desktop {
* @since 9
*/
public void browseFileDirectory(File file) {
checkRead();
file = new File(file.getPath());
checkAWTPermission();
checkExec();
checkActionSupport(Action.BROWSE_FILE_DIR);
checkFileValidation(file);
File parentFile = file.getParentFile();
if (parentFile == null || !parentFile.exists()) {
throw new IllegalArgumentException("Parent folder doesn't exist");
}
peer.browseFileDirectory(file);
}
@ -1017,10 +1019,18 @@ public class Desktop {
*
* @since 9
*/
public boolean moveToTrash(final File file) {
checkDelete();
public boolean moveToTrash(File file) {
file = new File(file.getPath());
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkDelete(file.getPath());
}
checkActionSupport(Action.MOVE_TO_TRASH);
checkFileValidation(file);
final File finalFile = file;
AccessController.doPrivileged((PrivilegedAction<?>) () -> {
checkFileValidation(finalFile);
return null;
});
return peer.moveToTrash(file);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018, 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
@ -265,7 +265,7 @@ static void AddFontsToX11FontPath ( fDirRecord *fDirP )
}
newFontPath = SAFE_SIZE_ARRAY_ALLOC(malloc, totalDirCount, sizeof ( char **) );
newFontPath = SAFE_SIZE_ARRAY_ALLOC(malloc, totalDirCount, sizeof(char *));
/* if it fails free things and get out */
if ( newFontPath == NULL ) {
free ( ( void *) appendDirList );

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2018, 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
@ -44,8 +44,11 @@ import javax.naming.ldap.Control;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import javax.net.SocketFactory;
import javax.net.ssl.SSLParameters;
/**
* A thread that creates a connection to an LDAP server.
@ -158,7 +161,18 @@ public final class Connection implements Runnable {
int readTimeout;
int connectTimeout;
private static final boolean IS_HOSTNAME_VERIFICATION_DISABLED
= hostnameVerificationDisabledValue();
private static boolean hostnameVerificationDisabledValue() {
PrivilegedAction<String> act = () -> System.getProperty(
"com.sun.jndi.ldap.object.disableEndpointIdentification");
String prop = AccessController.doPrivileged(act);
if (prop == null) {
return false;
}
return prop.isEmpty() ? true : Boolean.parseBoolean(prop);
}
// true means v3; false means v2
// Called in LdapClient.authenticate() (which is synchronized)
// when connection is "quiet" and not shared; no need to synchronize
@ -321,15 +335,20 @@ public final class Connection implements Runnable {
// the SSL handshake following socket connection as part of the timeout.
// So explicitly set a socket read timeout, trigger the SSL handshake,
// then reset the timeout.
if (connectTimeout > 0 && socket instanceof SSLSocket) {
if (socket instanceof SSLSocket) {
SSLSocket sslSocket = (SSLSocket) socket;
int socketTimeout = sslSocket.getSoTimeout();
sslSocket.setSoTimeout(connectTimeout); // reuse full timeout value
if (!IS_HOSTNAME_VERIFICATION_DISABLED) {
SSLParameters param = sslSocket.getSSLParameters();
param.setEndpointIdentificationAlgorithm("LDAPS");
sslSocket.setSSLParameters(param);
}
if (connectTimeout > 0) {
sslSocket.setSoTimeout(connectTimeout); // reuse full timeout value
}
sslSocket.startHandshake();
sslSocket.setSoTimeout(socketTimeout);
}
return socket;
}

View File

@ -1188,7 +1188,7 @@ public interface HttpResponse<T> {
/**
* Returns a response subscriber which publishes the response body
* through a {@link Publisher Publisher<List<ByteBuffer>>}.
* through a {@code Publisher<List<ByteBuffer>>}.
*
* <p> The {@link HttpResponse} using this subscriber is available
* immediately after the response headers have been read, without

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2018, 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
@ -192,7 +192,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade
}
dprintf1("-size: %d\n", size);
if (size) {
if (size != 0) {
mszReaders = malloc(size);
if (mszReaders == NULL) {
throwOutOfMemoryError(env, NULL);
@ -205,6 +205,8 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade
return NULL;
}
dprintf1("-String: %s\n", mszReaders);
} else {
return NULL;
}
result = pcsc_multi2jstring(env, mszReaders);

View File

@ -146,6 +146,7 @@ public final class BinaryContainer implements SymbolTable {
{"SharedRuntime::exception_handler_for_return_address", "_aot_exception_handler_for_return_address"},
{"SharedRuntime::register_finalizer", "_aot_register_finalizer"},
{"SharedRuntime::OSR_migration_end", "_aot_OSR_migration_end"},
{"SharedRuntime::enable_stack_reserved_zone", "_aot_enable_stack_reserved_zone"},
{"CompilerRuntime::resolve_dynamic_invoke", "_aot_resolve_dynamic_invoke"},
{"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"},
{"CompilerRuntime::resolve_klass_by_symbol", "_aot_resolve_klass_by_symbol"},

View File

@ -1552,7 +1552,9 @@ public class Modules extends JCTree.Visitor {
}
addExports.forEach((exportsFrom, exports) -> {
addVisiblePackages(msym, seen, exportsFrom, exports);
if (msym.readModules.contains(exportsFrom)) {
addVisiblePackages(msym, seen, exportsFrom, exports);
}
});
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* This library is free software; you can redistribute it and/or
@ -80,12 +80,12 @@ ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
group, timing));
}
} else {
kt.flag = (mp_sign)0;
if (group->meth->field_enc) {
MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group, timing));
} else {
kt.flag = (mp_sign)0;
MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group, timing));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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
@ -110,7 +110,7 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend {
@Override
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) {
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub);
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub, config.requiresReservedStackCheck(graph.getMethods()));
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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
@ -46,7 +46,7 @@ public class AArch64HotSpotDeoptimizeCallerOp extends AArch64HotSpotEpilogueOp {
@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
leaveFrame(crb, masm, /* emitSafepoint */false);
leaveFrame(crb, masm, /* emitSafepoint */false, false);
AArch64Call.directJmp(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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,14 +24,29 @@
package org.graalvm.compiler.hotspot.aarch64;
import static jdk.vm.ci.aarch64.AArch64.lr;
import static jdk.vm.ci.aarch64.AArch64.sp;
import static jdk.vm.ci.aarch64.AArch64.zr;
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.aarch64.AArch64BlockEndOp;
import org.graalvm.compiler.lir.aarch64.AArch64Call;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
/**
* Superclass for operations that leave a method's frame.
@ -53,9 +68,31 @@ abstract class AArch64HotSpotEpilogueOp extends AArch64BlockEndOp {
this.thread = null; // no safepoint
}
protected void leaveFrame(CompilationResultBuilder crb, AArch64MacroAssembler masm, boolean emitSafepoint) {
protected void leaveFrame(CompilationResultBuilder crb, AArch64MacroAssembler masm, boolean emitSafepoint, boolean requiresReservedStackAccessCheck) {
assert crb.frameContext != null : "We never elide frames in aarch64";
crb.frameContext.leave(crb);
if (requiresReservedStackAccessCheck) {
HotSpotForeignCallsProvider foreignCalls = (HotSpotForeignCallsProvider) crb.foreignCalls;
Label noReserved = new Label();
try (ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister();
masm.ldr(64, scratch, masm.makeAddress(thread, config.javaThreadReservedStackActivationOffset, 8));
masm.subs(64, zr, sp, scratch);
}
masm.branchConditionally(AArch64Assembler.ConditionFlag.LO, noReserved);
ForeignCallLinkage enableStackReservedZone = foreignCalls.lookupForeignCall(ENABLE_STACK_RESERVED_ZONE);
CallingConvention cc = enableStackReservedZone.getOutgoingCallingConvention();
assert cc.getArgumentCount() == 1;
Register arg0 = ((RegisterValue) cc.getArgument(0)).getRegister();
masm.mov(64, arg0, thread);
try (ScratchRegister sc = masm.getScratchRegister()) {
masm.stp(64, fp, lr, AArch64Address.createPreIndexedImmediateAddress(sp, -2));
AArch64Call.directCall(crb, masm, enableStackReservedZone, sc.getRegister(), null);
masm.ldp(64, fp, lr, AArch64Address.createPostIndexedImmediateAddress(sp, 2));
}
AArch64Call.directJmp(crb, masm, foreignCalls.lookupForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR));
masm.bind(noReserved);
}
if (emitSafepoint) {
try (ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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,10 +24,10 @@
package org.graalvm.compiler.hotspot.aarch64;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static jdk.vm.ci.aarch64.AArch64.sp;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address;
@ -69,7 +69,7 @@ public class AArch64HotSpotJumpToExceptionHandlerInCallerOp extends AArch64HotSp
@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
leaveFrame(crb, masm, /* emitSafepoint */false);
leaveFrame(crb, masm, /* emitSafepoint */false, false);
if (GraalServices.JAVA_SPECIFICATION_VERSION < 8) {
// Restore sp from fp if the exception PC is a method handle call site.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -28,19 +28,18 @@ package org.graalvm.compiler.hotspot.aarch64;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.hotspot.HotSpotBackend.INITIALIZE_KLASS_BY_SYMBOL;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_KLASS_BY_SYMBOL;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_STRING_BY_SYMBOL;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.RESOLVE;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.INITIALIZE;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.LOAD_COUNTERS;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.RESOLVE;
import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
import java.util.function.Function;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
@ -81,10 +80,10 @@ import org.graalvm.compiler.lir.aarch64.AArch64FrameMapBuilder;
import org.graalvm.compiler.lir.aarch64.AArch64Move;
import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp;
import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp;
import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
import org.graalvm.compiler.lir.aarch64.AArch64RestoreRegistersOp;
import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.aarch64.AArch64Kind;
@ -93,6 +92,7 @@ import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Constant;
@ -103,7 +103,6 @@ import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.SpeculationLog;
import jdk.vm.ci.meta.Value;
import org.graalvm.compiler.options.OptionValues;
/**
* LIR generator specialized for AArch64 HotSpot.
@ -502,7 +501,7 @@ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements H
emitMove(operand, input);
}
Register thread = getProviders().getRegisters().getThreadRegister();
append(new AArch64HotSpotReturnOp(operand, getStub() != null, config, thread));
append(new AArch64HotSpotReturnOp(operand, getStub() != null, config, thread, getResult().requiresReservedStackAccessCheck()));
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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,10 +24,10 @@
package org.graalvm.compiler.hotspot.aarch64;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static jdk.vm.ci.aarch64.AArch64.lr;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@ -48,9 +48,11 @@ public final class AArch64HotSpotReturnOp extends AArch64HotSpotEpilogueOp {
@Use({REG, ILLEGAL}) private Value result;
private final boolean isStub;
private final boolean requiresReservedStackAccessCheck;
public AArch64HotSpotReturnOp(Value result, boolean isStub, GraalHotSpotVMConfig config, Register thread) {
public AArch64HotSpotReturnOp(Value result, boolean isStub, GraalHotSpotVMConfig config, Register thread, boolean requiresReservedStackAccessCheck) {
super(TYPE, config, thread);
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
assert validReturnValue(result);
this.result = result;
this.isStub = isStub;
@ -66,7 +68,7 @@ public final class AArch64HotSpotReturnOp extends AArch64HotSpotEpilogueOp {
@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
final boolean emitSafepoint = !isStub;
leaveFrame(crb, masm, emitSafepoint);
leaveFrame(crb, masm, emitSafepoint, requiresReservedStackAccessCheck);
masm.ret(lr);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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,9 +24,9 @@
package org.graalvm.compiler.hotspot.aarch64;
import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER;
import static jdk.vm.ci.aarch64.AArch64.lr;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
@ -57,7 +57,7 @@ public final class AArch64HotSpotUnwindOp extends AArch64HotSpotEpilogueOp {
@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
leaveFrame(crb, masm, /* emitSafepoint */false);
leaveFrame(crb, masm, /* emitSafepoint */false, false);
ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
CallingConvention cc = linkage.getOutgoingCallingConvention();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018, 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
@ -111,7 +111,7 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend {
@Override
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) {
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub);
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub, config.requiresReservedStackCheck(graph.getMethods()));
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018, 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
@ -268,7 +268,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
pollOnReturnScratchRegister = findPollOnReturnScratchRegister();
}
Register thread = getProviders().getRegisters().getThreadRegister();
append(new AMD64HotSpotReturnOp(operand, getStub() != null, thread, pollOnReturnScratchRegister, config));
append(new AMD64HotSpotReturnOp(operand, getStub() != null, thread, pollOnReturnScratchRegister, config, getResult().requiresReservedStackAccessCheck()));
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018, 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,18 +24,30 @@
package org.graalvm.compiler.hotspot.amd64;
import static jdk.vm.ci.amd64.AMD64.r15;
import static jdk.vm.ci.amd64.AMD64.rsp;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.amd64.AMD64Call;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.gen.DiagnosticLIRGeneratorTool.ZapStackArgumentSpaceBeforeInstruction;
import jdk.vm.ci.amd64.AMD64.CPUFeature;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.meta.Value;
/**
@ -50,20 +62,46 @@ final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueBlockEndOp implemen
private final Register thread;
private final Register scratchForSafepointOnReturn;
private final GraalHotSpotVMConfig config;
private final boolean requiresReservedStackAccessCheck;
AMD64HotSpotReturnOp(Value value, boolean isStub, Register thread, Register scratchForSafepointOnReturn, GraalHotSpotVMConfig config) {
AMD64HotSpotReturnOp(Value value, boolean isStub, Register thread, Register scratchForSafepointOnReturn, GraalHotSpotVMConfig config, boolean requiresReservedStackAccessCheck) {
super(TYPE);
this.value = value;
this.isStub = isStub;
this.thread = thread;
this.scratchForSafepointOnReturn = scratchForSafepointOnReturn;
this.config = config;
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
}
@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
leaveFrameAndRestoreRbp(crb, masm);
if (!isStub) {
if (requiresReservedStackAccessCheck) {
HotSpotForeignCallsProvider foreignCalls = (HotSpotForeignCallsProvider) crb.foreignCalls;
Label noReserved = new Label();
masm.cmpptr(rsp, new AMD64Address(r15, config.javaThreadReservedStackActivationOffset));
masm.jccb(AMD64Assembler.ConditionFlag.Below, noReserved);
// direct call to runtime without stub needs aligned stack
int stackAdjust = crb.target.stackAlignment - crb.target.wordSize;
if (stackAdjust > 0) {
masm.subq(rsp, stackAdjust);
}
ForeignCallLinkage enableStackReservedZone = foreignCalls.lookupForeignCall(ENABLE_STACK_RESERVED_ZONE);
CallingConvention cc = enableStackReservedZone.getOutgoingCallingConvention();
assert cc.getArgumentCount() == 1;
Register arg0 = ((RegisterValue) cc.getArgument(0)).getRegister();
masm.movq(arg0, thread);
AMD64Call.directCall(crb, masm, enableStackReservedZone, null, false, null);
if (stackAdjust > 0) {
masm.addq(rsp, stackAdjust);
}
AMD64Call.directJmp(crb, masm, foreignCalls.lookupForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR));
masm.bind(noReserved);
}
// Every non-stub compile method must have a poll before the return.
AMD64HotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, scratchForSafepointOnReturn);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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
@ -152,7 +152,7 @@ public class SPARCHotSpotBackend extends HotSpotHostBackend {
@Override
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) {
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub);
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub, config.requiresReservedStackCheck(graph.getMethods()));
}
@Override
@ -195,7 +195,9 @@ public class SPARCHotSpotBackend extends HotSpotHostBackend {
final int frameSize = crb.frameMap.totalFrameSize();
final int stackpoinerChange = -frameSize;
SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
emitStackOverflowCheck(crb);
if (!isStub) {
emitStackOverflowCheck(crb);
}
if (SPARCAssembler.isSimm13(stackpoinerChange)) {
masm.save(sp, stackpoinerChange, sp);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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
@ -194,7 +194,7 @@ public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSp
emitMove(operand, input);
}
Register thread = getProviders().getRegisters().getThreadRegister();
append(new SPARCHotSpotReturnOp(operand, getStub() != null, config, thread, getSafepointAddressValue()));
append(new SPARCHotSpotReturnOp(operand, getStub() != null, config, thread, getSafepointAddressValue(), getResult().requiresReservedStackAccessCheck()));
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018, 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,17 +24,29 @@
package org.graalvm.compiler.hotspot.sparc;
import static jdk.vm.ci.sparc.SPARC.sp;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.sparc.SPARCAddress;
import org.graalvm.compiler.asm.sparc.SPARCAssembler;
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.sparc.SPARCCall;
import org.graalvm.compiler.lir.sparc.SPARCControlFlow.ReturnOp;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.meta.Value;
/**
@ -47,22 +59,42 @@ final class SPARCHotSpotReturnOp extends SPARCHotSpotEpilogueOp {
@Use({REG, ILLEGAL}) protected Value value;
@Use({REG, ILLEGAL}) protected Value safepointPollAddress;
private final boolean requiresReservedStackAccessCheck;
private final boolean isStub;
private final GraalHotSpotVMConfig config;
private final Register thread;
SPARCHotSpotReturnOp(Value value, boolean isStub, GraalHotSpotVMConfig config, Register thread, Value safepointPoll) {
SPARCHotSpotReturnOp(Value value, boolean isStub, GraalHotSpotVMConfig config, Register thread, Value safepointPoll, boolean requiresReservedStackAccessCheck) {
super(TYPE, SIZE);
this.value = value;
this.isStub = isStub;
this.config = config;
this.thread = thread;
this.safepointPollAddress = safepointPoll;
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
}
@Override
public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
if (!isStub) {
if (requiresReservedStackAccessCheck) {
try (ScratchRegister sc = masm.getScratchRegister()) {
HotSpotForeignCallsProvider foreignCalls = (HotSpotForeignCallsProvider) crb.foreignCalls;
Label noReserved = new Label();
Register scratch = sc.getRegister();
masm.ldx(new SPARCAddress(thread, config.javaThreadReservedStackActivationOffset), scratch);
masm.compareBranch(sp, scratch, SPARCAssembler.ConditionFlag.LessUnsigned, SPARCAssembler.CC.Xcc, noReserved, SPARCAssembler.BranchPredict.PREDICT_TAKEN, null);
ForeignCallLinkage enableStackReservedZone = foreignCalls.lookupForeignCall(ENABLE_STACK_RESERVED_ZONE);
CallingConvention cc = enableStackReservedZone.getOutgoingCallingConvention();
assert cc.getArgumentCount() == 1;
Register arg0 = ((RegisterValue) cc.getArgument(0)).getRegister();
masm.mov(thread, arg0);
SPARCCall.directCall(crb, masm, enableStackReservedZone, scratch, null);
masm.restoreWindow();
SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR));
masm.bind(noReserved);
}
}
// Every non-stub compile method must have a poll before the return.
SPARCHotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, safepointPollAddress);
}

View File

@ -0,0 +1,226 @@
/*
* Copyright (c) 2018, 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.
*/
package org.graalvm.compiler.hotspot.test;
import java.io.IOException;
import java.util.concurrent.locks.ReentrantLock;
import java.util.List;
import org.graalvm.compiler.test.SubprocessUtil;
import org.graalvm.compiler.test.SubprocessUtil.Subprocess;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
public class ReservedStackAccessTest extends HotSpotGraalCompilerTest {
@Before
public void check() {
Assume.assumeTrue(runtime().getVMConfig().enableStackReservedZoneAddress != 0);
}
public void stackAccessTest() {
Assume.assumeTrue(runtime().getVMConfig().enableStackReservedZoneAddress != 0);
int passed = 0;
for (int i = 0; i < 1000; i++) {
// Each iteration has to be executed by a new thread. The test
// relies on the random size area pushed by the VM at the beginning
// of the stack of each Java thread it creates.
RunWithSOEContext r = new RunWithSOEContext(new ReentrantLockTest(), 256);
Thread thread = new Thread(r);
thread.start();
try {
thread.join();
assertTrue(r.result.equals("PASSED"), r.result);
++passed;
} catch (InterruptedException ex) {
}
}
System.out.println("RESULT: " + (passed == 1000 ? "PASSED" : "FAILED"));
}
public static void main(String[] args) {
new ReservedStackAccessTest().stackAccessTest();
}
@Test
public void run() throws IOException, InterruptedException {
Assume.assumeTrue(runtime().getVMConfig().enableStackReservedZoneAddress != 0);
List<String> vmArgs = SubprocessUtil.withoutDebuggerArguments(SubprocessUtil.getVMCommandLine());
vmArgs.add("-XX:+UseJVMCICompiler");
vmArgs.add("-Dgraal.Inline=false");
vmArgs.add("-XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread");
Subprocess proc = SubprocessUtil.java(vmArgs, ReservedStackAccessTest.class.getName());
boolean passed = false;
for (String line : proc.output) {
if (line.equals("RESULT: PASSED")) {
passed = true;
}
}
if (!passed) {
for (String line : proc.output) {
System.err.println("" + line);
}
}
assertTrue(passed);
}
static class ReentrantLockTest {
private ReentrantLock[] lockArray;
// Frame sizes vary a lot between interpreted code and compiled code
// so the lock array has to be big enough to cover all cases.
// If test fails with message "Not conclusive test", try to increase
// LOCK_ARRAY_SIZE value
private static final int LOCK_ARRAY_SIZE = 8192;
private boolean stackOverflowErrorReceived;
StackOverflowError soe = null;
int index = -1;
public void initialize() {
lockArray = new ReentrantLock[LOCK_ARRAY_SIZE];
for (int i = 0; i < LOCK_ARRAY_SIZE; i++) {
lockArray[i] = new ReentrantLock();
}
stackOverflowErrorReceived = false;
}
public String getResult() {
if (!stackOverflowErrorReceived) {
return "ERROR: Not conclusive test: no StackOverflowError received";
}
for (int i = 0; i < LOCK_ARRAY_SIZE; i++) {
if (lockArray[i].isLocked()) {
if (!lockArray[i].isHeldByCurrentThread()) {
StringBuilder s = new StringBuilder();
s.append("FAILED: ReentrantLock ");
s.append(i);
s.append(" looks corrupted");
return s.toString();
}
}
}
return "PASSED";
}
public void run() {
try {
lockAndCall(0);
} catch (StackOverflowError e) {
soe = e;
stackOverflowErrorReceived = true;
}
}
private void lockAndCall(int i) {
index = i;
if (i < LOCK_ARRAY_SIZE) {
lockArray[i].lock();
lockAndCall(i + 1);
}
}
}
static class RunWithSOEContext implements Runnable {
int counter;
int deframe;
int decounter;
int setupSOEFrame;
int testStartFrame;
ReentrantLockTest test;
String result = "FAILED: no result";
RunWithSOEContext(ReentrantLockTest test, int deframe) {
this.test = test;
this.deframe = deframe;
}
@Override
public void run() {
counter = 0;
decounter = deframe;
test.initialize();
recursiveCall();
System.out.println("Framework got StackOverflowError at frame = " + counter);
System.out.println("Test started execution at frame = " + (counter - deframe));
result = test.getResult();
}
@SuppressWarnings("unused")
void recursiveCall() {
// Unused local variables to increase the frame size
long l1;
long l2;
long l3;
long l4;
long l5;
long l6;
long l7;
long l8;
long l9;
long l10;
long l11;
long l12;
long l13;
long l14;
long l15;
long l16;
long l17;
long l18;
long l19;
long l20;
long l21;
long l22;
long l23;
long l24;
long l25;
long l26;
long l27;
long l28;
long l30;
long l31;
long l32;
long l33;
long l34;
long l35;
long l36;
long l37;
counter++;
try {
recursiveCall();
} catch (StackOverflowError e) {
}
decounter--;
if (decounter == 0) {
setupSOEFrame = counter;
testStartFrame = counter - deframe;
test.run();
}
}
}
}

View File

@ -26,12 +26,15 @@ package org.graalvm.compiler.hotspot;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Used to access native configuration details.
@ -315,6 +318,17 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int jvmciCountersThreadOffset = getFieldOffset("JavaThread::_jvmci_counters", Integer.class, "jlong*");
public final int javaThreadReservedStackActivationOffset = versioned.javaThreadReservedStackActivationOffset;
public boolean requiresReservedStackCheck(List<ResolvedJavaMethod> methods) {
if (enableStackReservedZoneAddress != 0 && methods != null) {
for (ResolvedJavaMethod method : methods) {
if (((HotSpotResolvedJavaMethod) method).hasReservedStackAccess()) {
return true;
}
}
}
return false;
}
/**
* An invalid value for {@link #rtldDefault}.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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,6 +50,7 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.runtime.JVMCICompiler;
import org.graalvm.compiler.word.Word;
/**
* Common functionality of HotSpot host backends.
@ -66,6 +67,10 @@ public abstract class HotSpotHostBackend extends HotSpotBackend {
*/
public static final ForeignCallDescriptor UNCOMMON_TRAP_HANDLER = new ForeignCallDescriptor("uncommonTrapHandler", void.class);
public static final ForeignCallDescriptor ENABLE_STACK_RESERVED_ZONE = new ForeignCallDescriptor("enableStackReservedZoneEntry", void.class, Word.class);
public static final ForeignCallDescriptor THROW_DELAYED_STACKOVERFLOW_ERROR = new ForeignCallDescriptor("throwDelayedStackoverflowError", void.class);
protected final GraalHotSpotVMConfig config;
public HotSpotHostBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2018, 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
@ -46,6 +46,7 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
*/
private StackSlot deoptimizationRescueSlot;
protected final Object stub;
private final boolean requiresReservedStackAccessCheck;
private int maxInterpreterFrameSize;
@ -55,9 +56,11 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
*/
private EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
public HotSpotLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, CallingConvention callingConvention, Object stub) {
public HotSpotLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, CallingConvention callingConvention, Object stub,
boolean requiresReservedStackAccessCheck) {
super(compilationId, lir, frameMapBuilder, callingConvention);
this.stub = stub;
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
}
public EconomicMap<LIRFrameState, SaveRegistersOp> getCalleeSaveInfo() {
@ -83,4 +86,8 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
public int getMaxInterpreterFrameSize() {
return maxInterpreterFrameSize;
}
public boolean requiresReservedStackAccessCheck() {
return requiresReservedStackAccessCheck;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, 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
@ -66,6 +66,8 @@ import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.SAFEPOINT;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.STACK_INSPECTABLE_LEAF;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.DEOPTIMIZATION_HANDLER;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER;
import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
@ -251,6 +253,12 @@ public abstract class HotSpotHostForeignCallsProvider extends HotSpotForeignCall
registerForeignCall(UNCOMMON_TRAP_HANDLER, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
if (c.enableStackReservedZoneAddress != 0) {
assert c.throwDelayedStackOverflowErrorEntry != 0 : "both must exist";
registerForeignCall(ENABLE_STACK_RESERVED_ZONE, c.enableStackReservedZoneAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
registerForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR, c.throwDelayedStackOverflowErrorEntry, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
}
registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
registerForeignCall(SIN.foreignCallDescriptor, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);

View File

@ -140,7 +140,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
*/
@Override
public Content getSignature(ExecutableElement method) {
Content pre = new HtmlTree(HtmlTag.PRE);
HtmlTree pre = new HtmlTree(HtmlTag.PRE);
pre.setStyle(HtmlStyle.methodSignature);
writer.addAnnotationInfo(method, pre);
int annotationLength = pre.charCount();
addModifiers(method, pre);

View File

@ -83,6 +83,7 @@ public enum HtmlStyle {
memberNameLabel,
memberNameLink,
memberSummary,
methodSignature,
moduleLabelInPackage,
moduleLabelInType,
nameValue,

View File

@ -827,7 +827,7 @@ ul.ui-autocomplete li {
margin: -100px 0 0 100px;
z-index: 1;
}
.details pre {
.methodSignature {
white-space:normal;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018, 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
@ -211,7 +211,7 @@ loadTransport(const char *name, TransportInfo *info)
JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm);
/* Try version 1.1 first, fallback to 1.0 on error */
for (i = 0; i < sizeof(supported_versions); ++i) {
for (i = 0; i < sizeof(supported_versions)/sizeof(jint); ++i) {
rc = (*onLoad)(jvm, &callback, supported_versions[i], &t);
if (rc != JNI_EVERSION) {
info->transportVersion = supported_versions[i];

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2018, 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
@ -2681,6 +2681,9 @@ void unpacker::attr_definitions::readBandData(int idx) {
PRINTCR((1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s",
count, isRedefined(idx), isPredefined(idx),
ATTR_CONTEXT_NAME[attrc], lo->name));
} else {
abort("layout_definition pointer must not be NULL");
return;
}
bool hasCallables = lo->hasCallables();
band** bands = lo->bands();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -64,6 +64,9 @@ Java_com_sun_security_auth_module_UnixSystem_getUnixInfo
jclass cls;
numSuppGroups = getgroups(0, NULL);
if (numSuppGroups == -1) {
return;
}
groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t));
if (groups == NULL) {
jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError");

View File

@ -67,8 +67,6 @@ gc/g1/plab/TestPLABResize.java 8191048 generi
gc/TestNUMAPageSize.java 8194949 generic-all
runtime/ReservedStack/ReservedStackTestCompiler.java 8181855 generic-all
serviceability/jvmti/GetModulesInfo/JvmtiGetAllModulesTest.java 8195156 generic-all
compiler/compilercontrol/directives/LogTest.java 8181753 generic-all
@ -116,20 +114,17 @@ vmTestbase/nsk/stress/strace/strace006.java 8191047 generi
vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 8191047 generic-all
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn009/forceEarlyReturn009.java 8191047 generic-all
vmTestbase/nsk/jdi/ReferenceType/instances/instances001/instances001.java 8195600 generic-all
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn007/TestDescription.java 8195600 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance001/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance003/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects001/referringObjects001.java 8203174 generic-all
vmTestbase/nsk/jdi/ReferenceType/instances/instances002/instances002.java 8203174 generic-all
vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/MonitorEvents/MonitorEvents002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/heapwalking001/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/heapwalking002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/mixed002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemoryException001.java 8203174 generic-all
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses026/TestDescription.java 8195627 generic-all
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses028/TestDescription.java 8195627 generic-all
@ -175,6 +170,7 @@ org.graalvm.compiler.core.test.ProfilingInfoTest
org.graalvm.compiler.hotspot.test.CompilationWrapperTest 8205081
org.graalvm.compiler.hotspot.test.HsErrLogTest 8205081
org.graalvm.compiler.hotspot.test.OptionsInFileTest 8205081
org.graalvm.compiler.hotspot.test.ReservedStackAccessTest 8205081
org.graalvm.compiler.replacements.test.classfile.ClassfileBytecodeProviderTest 8205081
org.graalvm.compiler.replacements.test.classfile.RedefineIntrinsicTest 8205081

View File

@ -81,8 +81,7 @@ runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all
serviceability/sa/TestRevPtrsForInvokeDynamic.java 8191270 generic-all
serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatArrayCorrectnessTest.java 8205541 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatRateTest.java 8205652 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatRateTest.java 8207765 generic-all
#############################################################################

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018, 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
* @summary
* @requires vm.opt.final.EnableJVMCI == true
*
* @modules jdk.internal.vm.compiler
*
* @library /test/lib /compiler/graalunit /
*
* @build compiler.graalunit.common.GraalUnitTestLauncher
*
* @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
*
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.lang.Math_[a-lA-L] -exclude ExcludeList.txt
*/

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018, 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
* @summary
* @requires vm.opt.final.EnableJVMCI == true
*
* @modules jdk.internal.vm.compiler
*
* @library /test/lib /compiler/graalunit /
*
* @build compiler.graalunit.common.GraalUnitTestLauncher
*
* @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
*
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.lang.Math_[m-zM-Z] -exclude ExcludeList.txt
*/

View File

@ -34,5 +34,5 @@
*
* @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
*
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.lang.[mM] -exclude ExcludeList.txt
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.reflect.Field_get -exclude ExcludeList.txt
*/

View File

@ -34,5 +34,5 @@
*
* @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
*
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.reflect.[fF] -exclude ExcludeList.txt
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.reflect.Field_set -exclude ExcludeList.txt
*/

View File

@ -25,13 +25,15 @@ JttHotpath org.graalvm.compiler.jtt.hotpath
JttHotspot org.graalvm.compiler.jtt.hotspot
JttJdk org.graalvm.compiler.jtt.jdk
JttLangAL org.graalvm.compiler.jtt.lang.[a-lA-L]
JttLangM org.graalvm.compiler.jtt.lang.[mM]
JttLangMathAL org.graalvm.compiler.jtt.lang.Math_[a-lA-L]
JttLangMathMZ org.graalvm.compiler.jtt.lang.Math_[m-zM-Z]
JttLangNZ org.graalvm.compiler.jtt.lang.[n-zN-Z]
JttLoop org.graalvm.compiler.jtt.loop
Jtt.Micro org.graalvm.compiler.jtt.micro
JttOptimize org.graalvm.compiler.jtt.optimize
JttReflectAE org.graalvm.compiler.jtt.reflect.[a-eA-E]
JttReflectF org.graalvm.compiler.jtt.reflect.[fF]
JttReflectFieldGet org.graalvm.compiler.jtt.reflect.Field_get
JttReflectFieldSet org.graalvm.compiler.jtt.reflect.Field_set
JttReflectGZ org.graalvm.compiler.jtt.reflect.[g-zG-Z]
JttThreads org.graalvm.compiler.jtt.threads
LirJtt org.graalvm.compiler.lir.jtt

View File

@ -124,6 +124,8 @@ public class GraalUnitTestLauncher {
throw new Exception("Failed to find tests, VM crashed with exit code " + exitCode);
}
System.out.println("INFO: command output: [" + out.getOutput() + "]");
String[] lines = out.getStdout().split(" ");
if (lines.length > 1) { // first line contains jar file name
for (int i = 1; i < lines.length; i++) {

View File

@ -130,7 +130,7 @@ public class TestRTMAbortRatio {
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName() };
return new String[] { getMethodWithLockName(), "*.pageSize" };
}
public void lock(boolean abort) {

View File

@ -47,6 +47,7 @@ import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.Platform;
import java.util.List;
@ -59,11 +60,18 @@ public class TestRTMSpinLoopCount {
private static final int RTM_RETRY_COUNT = 1000;
private static final boolean INFLATE_MONITOR = true;
private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L;
private static final int[] SPIN_LOOP_COUNTS
= new int[] { 0, 100, 1_000, 10_000, 100_000 };
private static int[] SPIN_LOOP_COUNTS;
protected void runTestCases() throws Throwable {
if (Platform.isPPC()) {
SPIN_LOOP_COUNTS = new int[] { 0, 10, 100, 1_000, 10_000 };
} else {
SPIN_LOOP_COUNTS = new int[] { 0, 100, 1_000, 10_000, 100_000 };
}
long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length];
for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) {
aborts[i] = getAbortsCountOnLockBusy(
TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]);

View File

@ -45,8 +45,8 @@ public class HeapMonitor {
}
}
/** Set a specific sampling rate, 0 samples every allocation. */
public native static void setSamplingRate(int rate);
/** Set a specific sampling interval, 0 samples every allocation. */
public native static void setSamplingInterval(int interval);
public native static void enableSamplingEvents();
public native static boolean enableSamplingEventsForTwoThreads(Thread firstThread, Thread secondThread);
public native static void disableSamplingEvents();
@ -131,7 +131,7 @@ public class HeapMonitor {
public static int[][][] sampleEverything() {
enableSamplingEvents();
setSamplingRate(0);
setSamplingInterval(0);
// Loop around an allocation loop and wait until the tlabs have settled.
final int maxTries = 10;

View File

@ -26,7 +26,7 @@ package MyPackage;
/**
* @test
* @build Frame HeapMonitor
* @summary Verifies the JVMTI Heap Monitor rate when allocating arrays.
* @summary Verifies the JVMTI Heap Monitor interval when allocating arrays.
* @compile HeapMonitorArrayAllSampledTest.java
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorArrayAllSampledTest
*/
@ -46,7 +46,7 @@ public class HeapMonitorArrayAllSampledTest {
public static void main(String[] args) {
int sizes[] = {1000, 10000, 100000, 1000000};
HeapMonitor.setSamplingRate(0);
HeapMonitor.setSamplingInterval(0);
HeapMonitor.enableSamplingEvents();
for (int currentSize : sizes) {
@ -56,8 +56,8 @@ public class HeapMonitorArrayAllSampledTest {
allocate(currentSize);
// 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
// statistical geometric variable around the sampling rate. This means that the test could be
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples(maxIteration, 10)) {
throw new RuntimeException("Statistics should show about " + maxIteration + " samples.");

View File

@ -25,7 +25,7 @@ package MyPackage;
/**
* @test
* @summary Verifies the JVMTI SetHeapSamplingRate returns an illegal argument for negative ints.
* @summary Verifies the JVMTI SetHeapSamplingInterval returns an illegal argument for negative ints.
* @build Frame HeapMonitor
* @compile HeapMonitorIllegalArgumentTest.java
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorIllegalArgumentTest

View File

@ -26,7 +26,7 @@ package MyPackage;
/**
* @test
* @build Frame HeapMonitor
* @summary Verifies the JVMTI Heap Monitor rate when allocating arrays.
* @summary Verifies the JVMTI Heap Monitor interval when allocating arrays.
* @compile HeapMonitorStatArrayCorrectnessTest.java
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatArrayCorrectnessTest
*/
@ -46,8 +46,6 @@ public class HeapMonitorStatArrayCorrectnessTest {
public static void main(String[] args) {
int sizes[] = {1000, 10000, 100000};
HeapMonitor.enableSamplingEvents();
for (int currentSize : sizes) {
System.out.println("Testing size " + currentSize);
@ -56,12 +54,16 @@ public class HeapMonitorStatArrayCorrectnessTest {
throw new RuntimeException("Should not have any events stored yet.");
}
HeapMonitor.enableSamplingEvents();
// 111 is as good a number as any.
final int samplingMultiplier = 111;
HeapMonitor.setSamplingRate(samplingMultiplier * currentSize);
HeapMonitor.setSamplingInterval(samplingMultiplier * currentSize);
allocate(currentSize);
HeapMonitor.disableSamplingEvents();
// For simplifications, we ignore the array memory usage for array internals (with the array
// sizes requested, it should be a negligible oversight).
//
@ -77,8 +79,8 @@ public class HeapMonitorStatArrayCorrectnessTest {
expected /= samplingMultiplier;
// 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
// statistical geometric variable around the sampling rate. This means that the test could be
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
throw new RuntimeException("Statistics should show about " + expected + " samples.");

View File

@ -25,61 +25,67 @@ package MyPackage;
/**
* @test
* @summary Verifies the JVMTI Heap Monitor sampling rate average.
* @summary Verifies the JVMTI Heap Monitor sampling interval average.
* @build Frame HeapMonitor
* @compile HeapMonitorStatRateTest.java
* @compile HeapMonitorStatIntervalTest.java
* @requires vm.compMode != "Xcomp"
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatRateTest
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatIntervalTest
*/
public class HeapMonitorStatRateTest {
public class HeapMonitorStatIntervalTest {
private native static double getAverageRate();
private native static double getAverageInterval();
private static boolean testRateOnce(int rate, boolean throwIfFailure) {
private static boolean testIntervalOnce(int interval, boolean throwIfFailure) {
HeapMonitor.resetEventStorage();
HeapMonitor.setSamplingRate(rate);
HeapMonitor.setSamplingInterval(interval);
HeapMonitor.enableSamplingEvents();
int allocationTotal = 10 * 1024 * 1024;
HeapMonitor.allocateSize(allocationTotal);
int allocationIterations = 10;
double actualCount = 0;
for (int i = 0; i < allocationIterations; i++) {
HeapMonitor.resetEventStorage();
HeapMonitor.allocateSize(allocationTotal);
actualCount += HeapMonitor.getEventStorageElementCount();
}
HeapMonitor.disableSamplingEvents();
double actualCount = HeapMonitor.getEventStorageElementCount();
double expectedCount = allocationTotal / rate;
double expectedCount = allocationTotal * allocationIterations / interval;
double error = Math.abs(actualCount - expectedCount);
double errorPercentage = error / expectedCount * 100;
boolean failure = (errorPercentage > 10.0);
boolean success = (errorPercentage < 10.0);
if (failure && throwIfFailure) {
throw new RuntimeException("Rate average over 10% for rate " + rate + " -> " + actualCount
+ ", " + expectedCount);
if (!success && throwIfFailure) {
throw new RuntimeException("Interval average over 10% for interval " + interval + " -> "
+ actualCount + ", " + expectedCount);
}
return failure;
return success;
}
private static void testRate(int rate) {
// Test the rate twice, it can happen that the test is "unlucky" and the rate just goes above
private static void testInterval(int interval) {
// Test the interval twice, it can happen that the test is "unlucky" and the interval just goes above
// the 10% mark. So try again to squash flakiness.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
// statistical geometric variable around the sampling rate. This means that the test could be
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case.
if (!testRateOnce(rate, false)) {
testRateOnce(rate, true);
if (!testIntervalOnce(interval, false)) {
testIntervalOnce(interval, true);
}
}
public static void main(String[] args) {
int[] tab = {1024, 8192};
for (int rateIdx = 0; rateIdx < tab.length; rateIdx++) {
testRate(tab[rateIdx]);
for (int intervalIdx = 0; intervalIdx < tab.length; intervalIdx++) {
testInterval(tab[intervalIdx]);
}
}
}

View File

@ -41,19 +41,22 @@ public class HeapMonitorStatObjectCorrectnessTest {
private native static boolean statsHaveExpectedNumberSamples(int expected, int percentError);
private static void allocate() {
emptyStorage();
HeapMonitor.enableSamplingEvents();
for (int j = 0; j < maxIteration; j++) {
obj = new BigObject();
}
HeapMonitor.disableSamplingEvents();
}
private static void testBigAllocationRate() {
private static void testBigAllocationInterval() {
final int sizeObject = 1400;
// 111 is as good a number as any.
final int samplingMultiplier = 111;
HeapMonitor.setSamplingRate(samplingMultiplier * sizeObject);
HeapMonitor.setSamplingInterval(samplingMultiplier * sizeObject);
emptyStorage();
allocate();
// For simplifications, the code is allocating:
@ -76,8 +79,8 @@ public class HeapMonitorStatObjectCorrectnessTest {
expected /= samplingMultiplier;
// 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
// statistical geometric variable around the sampling rate. This means that the test could be
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
throw new RuntimeException("Statistics should show about " + expected + " samples.");
@ -94,16 +97,15 @@ public class HeapMonitorStatObjectCorrectnessTest {
private static void testEveryAllocationSampled() {
// 0 means sample every allocation.
HeapMonitor.setSamplingRate(0);
HeapMonitor.setSamplingInterval(0);
emptyStorage();
allocate();
double expected = maxIteration;
// 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
// statistical geometric variable around the sampling rate. This means that the test could be
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
throw new RuntimeException("Statistics should show about " + expected + " samples.");
@ -111,9 +113,7 @@ public class HeapMonitorStatObjectCorrectnessTest {
}
public static void main(String[] args) {
HeapMonitor.enableSamplingEvents();
testBigAllocationRate();
testBigAllocationInterval();
testEveryAllocationSampled();
}

View File

@ -41,8 +41,8 @@ public class HeapMonitorThreadTest {
final int numThreads = 5;
List<ThreadInformation> threadList = ThreadInformation.createThreadList(numThreads);
// Sample at a rate of 8k.
HeapMonitor.setSamplingRate(1 << 13);
// Sample at a interval of 8k.
HeapMonitor.setSamplingInterval(1 << 13);
HeapMonitor.enableSamplingEvents();
System.err.println("Starting threads");

View File

@ -62,10 +62,10 @@ public class HeapMonitorVMEventsTest implements Cloneable {
double diff = Math.abs(first - second) * 100;
diff /= first;
// Accept a 10% error rate: with objects being allocated: this allows a bit of room in
// Accept a 10% error interval: with objects being allocated: this allows a bit of room in
// case other items are getting allocated during the test.
if (diff > 10) {
throw new RuntimeException("Error rate is over the accepted rate: " + diff
throw new RuntimeException("Error interval is over the accepted interval: " + diff
+ ": " + first + " , " + second);
}
}

View File

@ -45,7 +45,7 @@ extern "C" {
#define TRUE 1
#define FALSE 0
#define PRINT_OUT 0
#define PRINT_OUT 1
static jvmtiEnv *jvmti = NULL;
static jvmtiEnv *second_jvmti = NULL;
@ -369,7 +369,7 @@ static int event_storage_get_count(EventStorage* storage) {
return result;
}
static double event_storage_get_average_rate(EventStorage* storage) {
static double event_storage_get_average_interval(EventStorage* storage) {
double accumulation = 0;
int max_size;
int i;
@ -839,8 +839,8 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
}
JNIEXPORT void JNICALL
Java_MyPackage_HeapMonitor_setSamplingRate(JNIEnv* env, jclass cls, jint value) {
(*jvmti)->SetHeapSamplingRate(jvmti, value);
Java_MyPackage_HeapMonitor_setSamplingInterval(JNIEnv* env, jclass cls, jint value) {
(*jvmti)->SetHeapSamplingInterval(jvmti, value);
}
JNIEXPORT jboolean JNICALL
@ -940,8 +940,8 @@ Java_MyPackage_HeapMonitorNoCapabilityTest_allSamplingMethodsFail(JNIEnv *env,
return FALSE;
}
if (check_capability_error((*jvmti)->SetHeapSamplingRate(jvmti, 1<<19),
"Set Heap Sampling Rate")) {
if (check_capability_error((*jvmti)->SetHeapSamplingInterval(jvmti, 1<<19),
"Set Heap Sampling Interval")) {
return FALSE;
}
return TRUE;
@ -950,23 +950,23 @@ Java_MyPackage_HeapMonitorNoCapabilityTest_allSamplingMethodsFail(JNIEnv *env,
JNIEXPORT jboolean JNICALL
Java_MyPackage_HeapMonitorIllegalArgumentTest_testIllegalArgument(JNIEnv *env,
jclass cls) {
if (check_error((*jvmti)->SetHeapSamplingRate(jvmti, 0),
"Sampling rate 0 failed\n")){
if (check_error((*jvmti)->SetHeapSamplingInterval(jvmti, 0),
"Sampling interval 0 failed\n")){
return FALSE;
}
if (check_error((*jvmti)->SetHeapSamplingRate(jvmti, 1024),
"Sampling rate 1024 failed\n")){
if (check_error((*jvmti)->SetHeapSamplingInterval(jvmti, 1024),
"Sampling interval 1024 failed\n")){
return FALSE;
}
if (!check_error((*jvmti)->SetHeapSamplingRate(jvmti, -1),
"Sampling rate -1 passed\n")){
if (!check_error((*jvmti)->SetHeapSamplingInterval(jvmti, -1),
"Sampling interval -1 passed\n")){
return FALSE;
}
if (!check_error((*jvmti)->SetHeapSamplingRate(jvmti, -1024),
"Sampling rate -1024 passed\n")){
if (!check_error((*jvmti)->SetHeapSamplingInterval(jvmti, -1024),
"Sampling interval -1024 passed\n")){
return FALSE;
}
@ -974,8 +974,8 @@ Java_MyPackage_HeapMonitorIllegalArgumentTest_testIllegalArgument(JNIEnv *env,
}
JNIEXPORT jdouble JNICALL
Java_MyPackage_HeapMonitorStatRateTest_getAverageRate(JNIEnv *env, jclass cls) {
return event_storage_get_average_rate(&global_event_storage);
Java_MyPackage_HeapMonitorStatIntervalTest_getAverageInterval(JNIEnv *env, jclass cls) {
return event_storage_get_average_interval(&global_event_storage);
}
typedef struct sThreadsFound {

View File

@ -52,6 +52,7 @@
* referrers with supported type(Strong, PhantomReference, SoftReference, WeakReference)
*
* @requires vm.gc != "Z"
* @requires !vm.graal.enabled
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .

View File

@ -52,6 +52,7 @@
* can't force collection of thread group because of thread group always has 1 referrer - parent thread group, so
* just test disableCollection/enableCollection don't throw any unexpected exceptions
*
* @requires !vm.graal.enabled
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .

View File

@ -52,6 +52,7 @@
* - check the number of instances is correct
* done
*
* @requires !vm.graal.enabled
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .

View File

@ -34,6 +34,7 @@
* in debuggee VM through 'ArrayType.newInstance()' till VMOutOfMemoryException. Any other exception
* thrown by 'ArrayType.newInstance()' is treated as product bug.
*
* @requires !vm.graal.enabled
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .

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