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 14708e1acdc3974f4539027cbbcfa6d69f83cf51 jdk-11+21
00b16d0457e43d23f6ca5ade6b243edce62750a0 jdk-12+1 00b16d0457e43d23f6ca5ade6b243edce62750a0 jdk-12+1
9937ef7499dcd7673714517fd5e450410c14ba4e jdk-11+22 9937ef7499dcd7673714517fd5e450410c14ba4e jdk-11+22
1edcf36fe15f79d6228d1a63eb680878e2386480 jdk-11+23
69b438908512d3dfef5852c6a843a5778333a309 jdk-12+2 69b438908512d3dfef5852c6a843a5778333a309 jdk-12+2
990db216e7199b2ba9989d8fa20b657e0ca7d969 jdk-12+3 990db216e7199b2ba9989d8fa20b657e0ca7d969 jdk-12+3

View File

@ -24,9 +24,6 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "asm/macroAssembler.inline.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/g1BarrierSet.hpp"
#include "gc/g1/g1BarrierSetAssembler.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp"
#include "gc/g1/g1BarrierSetRuntime.hpp" #include "gc/g1/g1BarrierSetRuntime.hpp"
@ -38,6 +35,11 @@
#include "runtime/thread.hpp" #include "runtime/thread.hpp"
#include "interpreter/interp_masm.hpp" #include "interpreter/interp_masm.hpp"
#include "runtime/sharedRuntime.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-> #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::static_call_type
|| entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type"); || entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type");
unsigned int start_offset = offset(); // We need a trampoline if branches are far.
if (far_branches() && !Compile::current()->in_scratch_emit_size()) { if (far_branches()) {
address stub = emit_trampoline_stub(start_offset, entry.target()); // We don't want to emit a trampoline if C2 is generating dummy
if (stub == NULL) { // code during its branch shortening phase.
return NULL; // CodeCache is full 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 // TEXASR bit description
enum transaction_failure_reason { enum transaction_failure_reason {
// Upper half (TEXASRU): // 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_failure_persistent = 7, // The failure is likely to recur on each execution.
tm_disallowed = 8, // The instruction is not permitted. tm_disallowed = 8, // The instruction is not permitted.
tm_nesting_of = 9, // The maximum transaction level was exceeded. 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_failure_summary = 36, // Failure has been detected and recorded.
tm_tfiar_exact = 37, // Value in the TFIAR is exact. tm_tfiar_exact = 37, // Value in the TFIAR is exact.
tm_rot = 38, // Rollback-only transaction. tm_rot = 38, // Rollback-only transaction.
tm_transaction_level = 52, // Transaction level (nesting depth + 1).
}; };
// PPC 1, section 2.4.1 Branch Instructions // 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 // Update rtm_counters based on abort status
// input: abort_status // input: abort_status
// rtm_counters (RTMLockingCounters*) // rtm_counters_Reg (RTMLockingCounters*)
void MacroAssembler::rtm_counters_update(Register abort_status, Register rtm_counters_Reg) { void MacroAssembler::rtm_counters_update(Register abort_status, Register rtm_counters_Reg) {
// Mapping to keep PreciseRTMLockingStatistics similar to x86. // Mapping to keep PreciseRTMLockingStatistics similar to x86.
// x86 ppc (! means inverted, ? means not the same) // 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. // 3 10 Set if an internal buffer overflowed.
// 4 ?12 Set if a debug breakpoint was hit. // 4 ?12 Set if a debug breakpoint was hit.
// 5 ?32 Set if an abort occurred during execution of a nested transaction. // 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. const int failure_bit[] = {tm_tabort, // Signal handler will set this too.
Assembler::tm_failure_persistent, // inverted: transient tm_failure_persistent,
Assembler::tm_trans_cf, tm_non_trans_cf,
Assembler::tm_footprint_of, tm_trans_cf,
Assembler::tm_non_trans_cf, tm_footprint_of,
Assembler::tm_suspended}; tm_failure_code,
const bool tm_failure_inv[] = {false, true, false, false, false, false}; tm_transaction_level};
assert(sizeof(tm_failure_bit)/sizeof(int) == RTMLockingCounters::ABORT_STATUS_LIMIT, "adapt mapping!");
const Register addr_Reg = R0; const int num_failure_bits = sizeof(failure_bit) / sizeof(int);
// Keep track of offset to where rtm_counters_Reg had pointed to. 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(); int counters_offs = RTMLockingCounters::abort_count_offset();
addi(addr_Reg, rtm_counters_Reg, counters_offs); ld(temp_Reg, counters_offs, rtm_counters_Reg);
const Register temp_Reg = rtm_counters_Reg;
//atomic_inc_ptr(addr_Reg, temp_Reg); We don't increment atomically
ldx(temp_Reg, addr_Reg);
addi(temp_Reg, temp_Reg, 1); 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) { if (PrintPreciseRTMLockingStatistics) {
int counters_offs_delta = RTMLockingCounters::abortX_count_offset() - counters_offs;
//mftexasr(abort_status); done by caller // #0 counter offset.
for (int i = 0; i < RTMLockingCounters::ABORT_STATUS_LIMIT; i++) { int abortX_offs = RTMLockingCounters::abortX_count_offset();
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);
Label check_abort; for (int nbit = 0; nbit < num_failure_bits; nbit++) {
rldicr_(temp_Reg, abort_status, tm_failure_bit[i], 0); for (int ncounter = 0; ncounter < num_counters; ncounter++) {
if (tm_failure_inv[i]) { if (bit2counter_map[nbit][ncounter] != 0) {
bne(CCR0, check_abort); Label check_abort;
} else { int abort_counter_offs = abortX_offs + (ncounter << 3);
beq(CCR0, check_abort);
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 // Restore abort_status.
add(rtm_counters_Reg, addr_Reg, temp_Reg); // restore mr(abort_status, abort_status_R0);
} }
// Branch if (random & (count-1) != 0), count is 2^n // 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, void MacroAssembler::rtm_retry_lock_on_abort(Register retry_count_Reg, Register abort_status_Reg,
Label& retryLabel, Label* checkRetry) { Label& retryLabel, Label* checkRetry) {
Label doneRetry; 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); rldicr_(R0, abort_status_Reg, tm_failure_persistent, 0);
bne(CCR0, doneRetry); 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); } if (checkRetry) { bind(*checkRetry); }
addic_(retry_count_Reg, retry_count_Reg, -1); addic_(retry_count_Reg, retry_count_Reg, -1);
blt(CCR0, doneRetry); blt(CCR0, doneRetry);

View File

@ -2029,6 +2029,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
vep_start_pc = (intptr_t)__ pc(); 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); __ save_LR_CR(r_temp_1);
__ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame. __ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
__ mr(r_callers_sp, R1_SP); // Remember frame pointer. __ mr(r_callers_sp, R1_SP); // Remember frame pointer.
@ -2947,6 +2954,11 @@ void SharedRuntime::generate_uncommon_trap_blob() {
InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer); InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer);
address start = __ pc(); address start = __ pc();
if (UseRTMLocking) {
// Abort RTM transaction before possible nmethod deoptimization.
__ tabort_();
}
Register unroll_block_reg = R21_tmp1; Register unroll_block_reg = R21_tmp1;
Register klass_index_reg = R22_tmp2; Register klass_index_reg = R22_tmp2;
Register unc_trap_reg = R23_tmp3; 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; 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. // Save registers, fpu state, and flags. Set R31 = return pc.
map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm, map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
&frame_size_in_bytes, &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); const int rc = pthread_mutex_unlock(cs);
assert0(rc == 0); 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(); _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 #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 // in that case I try reading the traceback table unsafe - I rather risk secondary crashes in
// error files than not having a callstack.) // error files than not having a callstack.)
#define CHECK_POINTER_READABLE(p) \ #define CHECK_POINTER_READABLE(p) \
if (!MiscUtils::is_readable_pointer(p)) { \ if (!os::is_readable_pointer(p)) { \
trcVerbose("pc not readable"); \ trcVerbose("pc not readable"); \
return false; \ return false; \
} }
@ -230,7 +230,7 @@ bool AixSymbols::get_function_name (
const short l = MIN2<short>(*((short*)pc2), namelen - 1); const short l = MIN2<short>(*((short*)pc2), namelen - 1);
// Be very careful. // Be very careful.
int i = 0; char* const p = (char*)pc2 + sizeof(short); 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]; p_name[i] = p[i];
i++; i++;
} }
@ -489,7 +489,7 @@ static void print_info_for_pc (outputStream* st, codeptr_t pc, char* buf,
const struct tbtable* tb = NULL; const struct tbtable* tb = NULL;
int displacement = -1; int displacement = -1;
if (!MiscUtils::is_readable_pointer(pc)) { if (!os::is_readable_pointer(pc)) {
st->print("(invalid)"); st->print("(invalid)");
return; 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); print_info_for_pc(st, cur_iar, buf, buf_size, demangle);
st->cr(); st->cr();
if (cur_iar && MiscUtils::is_readable_pointer(cur_iar)) { if (cur_iar && os::is_readable_pointer(cur_iar)) {
decode_instructions_at_pc( decode_instructions_at_pc(
"Decoded instructions at iar:", "Decoded instructions at iar:",
cur_iar, 32, 16, st); 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); print_info_for_pc(st, cur_lr, buf, buf_size, demangle);
st->cr(); st->cr();
if (cur_lr && MiscUtils::is_readable_pointer(cur_lr)) { if (cur_lr && os::is_readable_pointer(cur_lr)) {
decode_instructions_at_pc( decode_instructions_at_pc(
"Decoded instructions at lr:", "Decoded instructions at lr:",
cur_lr, 32, 16, st); cur_lr, 32, 16, st);
@ -729,7 +729,7 @@ void AixNativeCallstack::print_callstack_for_context(outputStream* st, const uco
// Check and print rtoc. // Check and print rtoc.
st->print("rtoc: " PTR64_FORMAT " ", p2i(cur_rtoc)); st->print("rtoc: " PTR64_FORMAT " ", p2i(cur_rtoc));
if (cur_rtoc == NULL || cur_rtoc == (codeptr_t)-1 || if (cur_rtoc == NULL || cur_rtoc == (codeptr_t)-1 ||
!MiscUtils::is_readable_pointer(cur_rtoc)) { !os::is_readable_pointer(cur_rtoc)) {
st->print("(invalid)"); st->print("(invalid)");
} else if (((uintptr_t)cur_rtoc) & 0x7) { } else if (((uintptr_t)cur_rtoc) & 0x7) {
st->print("(unaligned)"); 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->print_cr("Register to memory mapping:");
st->cr(); 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++) { for (int i = 0; i < 32; i++) {
st->print("r%-2d=", i); st->print("r%-2d=", i);
print_location(st, uc->uc_mcontext.regs->gpr[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) { 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 #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_notify", address, JVMCIRuntime::object_notify);
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_object_notifyAll", address, JVMCIRuntime::object_notifyAll); 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_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_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_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); 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); _outbuf->print("%s", termString);
#endif #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" const char* blobTypeName[] = {"noType"
, "nMethod (active)" , "nMethod (under construction)"
, "nMethod (inactive)" , "nMethod (active)"
, "nMethod (deopt)" , "nMethod (inactive)"
, "nMethod (zombie)" , "nMethod (deopt)"
, "nMethod (unloaded)" , "nMethod (zombie)"
, "runtime stub" , "nMethod (unloaded)"
, "ricochet stub" , "runtime stub"
, "deopt stub" , "ricochet stub"
, "uncommon trap stub" , "deopt stub"
, "exception stub" , "uncommon trap stub"
, "safepoint stub" , "exception stub"
, "adapter blob" , "safepoint stub"
, "MH adapter blob" , "adapter blob"
, "buffer blob" , "MH adapter blob"
, "lastType" , "buffer blob"
, "lastType"
}; };
const char* compTypeName[] = { "none", "c1", "c2", "jvmci" }; 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_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_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_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 unsigned int nBlocks_stub = 0;
static struct FreeBlk* FreeArray = NULL; 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_t2 = CodeHeapStatArray[ix].nBlocks_t2;
nBlocks_alive = CodeHeapStatArray[ix].nBlocks_alive; nBlocks_alive = CodeHeapStatArray[ix].nBlocks_alive;
nBlocks_dead = CodeHeapStatArray[ix].nBlocks_dead; nBlocks_dead = CodeHeapStatArray[ix].nBlocks_dead;
nBlocks_inconstr = CodeHeapStatArray[ix].nBlocks_inconstr;
nBlocks_unloaded = CodeHeapStatArray[ix].nBlocks_unloaded; nBlocks_unloaded = CodeHeapStatArray[ix].nBlocks_unloaded;
nBlocks_stub = CodeHeapStatArray[ix].nBlocks_stub; nBlocks_stub = CodeHeapStatArray[ix].nBlocks_stub;
FreeArray = CodeHeapStatArray[ix].FreeArray; FreeArray = CodeHeapStatArray[ix].FreeArray;
@ -248,6 +251,7 @@ void CodeHeapState::get_HeapStatGlobals(outputStream* out, const char* heapName)
nBlocks_t2 = 0; nBlocks_t2 = 0;
nBlocks_alive = 0; nBlocks_alive = 0;
nBlocks_dead = 0; nBlocks_dead = 0;
nBlocks_inconstr = 0;
nBlocks_unloaded = 0; nBlocks_unloaded = 0;
nBlocks_stub = 0; nBlocks_stub = 0;
FreeArray = NULL; FreeArray = NULL;
@ -274,6 +278,7 @@ void CodeHeapState::set_HeapStatGlobals(outputStream* out, const char* heapName)
CodeHeapStatArray[ix].nBlocks_t2 = nBlocks_t2; CodeHeapStatArray[ix].nBlocks_t2 = nBlocks_t2;
CodeHeapStatArray[ix].nBlocks_alive = nBlocks_alive; CodeHeapStatArray[ix].nBlocks_alive = nBlocks_alive;
CodeHeapStatArray[ix].nBlocks_dead = nBlocks_dead; CodeHeapStatArray[ix].nBlocks_dead = nBlocks_dead;
CodeHeapStatArray[ix].nBlocks_inconstr = nBlocks_inconstr;
CodeHeapStatArray[ix].nBlocks_unloaded = nBlocks_unloaded; CodeHeapStatArray[ix].nBlocks_unloaded = nBlocks_unloaded;
CodeHeapStatArray[ix].nBlocks_stub = nBlocks_stub; CodeHeapStatArray[ix].nBlocks_stub = nBlocks_stub;
CodeHeapStatArray[ix].FreeArray = FreeArray; CodeHeapStatArray[ix].FreeArray = FreeArray;
@ -554,6 +559,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
nBlocks_t2 = 0; nBlocks_t2 = 0;
nBlocks_alive = 0; nBlocks_alive = 0;
nBlocks_dead = 0; nBlocks_dead = 0;
nBlocks_inconstr = 0;
nBlocks_unloaded = 0; nBlocks_unloaded = 0;
nBlocks_stub = 0; nBlocks_stub = 0;
@ -587,6 +593,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
size_t disconnSpace = 0; size_t disconnSpace = 0;
size_t notentrSpace = 0; size_t notentrSpace = 0;
size_t deadSpace = 0; size_t deadSpace = 0;
size_t inconstrSpace = 0;
size_t unloadedSpace = 0; size_t unloadedSpace = 0;
size_t stubSpace = 0; size_t stubSpace = 0;
size_t freeSpace = 0; size_t freeSpace = 0;
@ -692,6 +699,10 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
nBlocks_dead++; nBlocks_dead++;
deadSpace += hb_bytelen; deadSpace += hb_bytelen;
break; break;
case nMethod_inconstruction:
nBlocks_inconstr++;
inconstrSpace += hb_bytelen;
break;
default: default:
break; break;
} }
@ -846,6 +857,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
StatArray[ix_beg].level = comp_lvl; StatArray[ix_beg].level = comp_lvl;
StatArray[ix_beg].compiler = cType; StatArray[ix_beg].compiler = cType;
break; break;
case nMethod_inconstruction: // let's count "in construction" nmethods here.
case nMethod_alive: case nMethod_alive:
StatArray[ix_beg].tx_count++; StatArray[ix_beg].tx_count++;
StatArray[ix_beg].tx_space += (unsigned short)hb_len; 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].level = comp_lvl;
StatArray[ix_end].compiler = cType; StatArray[ix_end].compiler = cType;
break; break;
case nMethod_inconstruction: // let's count "in construction" nmethods here.
case nMethod_alive: case nMethod_alive:
StatArray[ix_beg].tx_count++; StatArray[ix_beg].tx_count++;
StatArray[ix_beg].tx_space += (unsigned short)beg_space; 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].level = comp_lvl;
StatArray[ix].compiler = cType; StatArray[ix].compiler = cType;
break; break;
case nMethod_inconstruction: // let's count "in construction" nmethods here.
case nMethod_alive: case nMethod_alive:
StatArray[ix].tx_count++; StatArray[ix].tx_count++;
StatArray[ix].tx_space += (unsigned short)(granule_size>>log2_seg_size); 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; done = true;
if (!insane) { 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(" 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(" 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(" 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(" 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(" 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); 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); printBox(ast, '-', "Method hotness information at time of this analysis", NULL);
ast->print_cr("Highest possible method temperature: %12d", reset_val); 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("Threshold for method to be considered 'cold': %12.3f", -reset_val + reverse_free_ratio * NmethodSweepActivity);
ast->print_cr("min. hotness = %6d", minTemp); if (n_methods > 0) {
ast->print_cr("avg. hotness = %6d", avgTemp); avgTemp = hotnessAccumulator/n_methods;
ast->print_cr("max. hotness = %6d", maxTemp); 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") STRINGSTREAM_FLUSH("\n")
// This loop is intentionally printing directly to "out". // 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) { if (StatArray[ix].t2_count > granule_segs) {
out->print_cr("t2_count[%d] = %d", ix, StatArray[ix].t2_count); 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) { if (StatArray[ix].stub_count > granule_segs) {
out->print_cr("stub_count[%d] = %d", ix, StatArray[ix].stub_count); 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) { if (StatArray[ix].t2_space > granule_segs) {
out->print_cr("t2_space[%d] = %d", ix, StatArray[ix].t2_space); 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) { if (StatArray[ix].stub_space > granule_segs) {
out->print_cr("stub_space[%d] = %d", ix, StatArray[ix].stub_space); 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); 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. // 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) { 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, stub_count[%d] = %d", ix, StatArray[ix].t1_count, ix, StatArray[ix].t2_count, ix, StatArray[ix].stub_count); 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) { 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, stub_space[%d] = %d", ix, StatArray[ix].t1_space, ix, StatArray[ix].t2_space, ix, StatArray[ix].stub_space); 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 (!done || (nBlocks_free == 0)) {
if (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) { } else if (!done) {
ast->print_cr("Free block count mismatch could not be resolved."); ast->print_cr("Free block count mismatch could not be resolved.");
ast->print_cr("Try to run \"aggregate\" function to update counters"); 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()); ast->print("%5d", nm->hotness_counter());
//---< name and signature >--- //---< name and signature >---
ast->fill_to(67+6); ast->fill_to(67+6);
if (nm->is_in_use()) {blob_name = nm->method()->name_and_sig_as_C_string(); } 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_entrant()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
if (nm->is_zombie()) {ast->print("%14s", " zombie method"); } 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); ast->print("%s", blob_name);
} else { } else {
//---< block size in hex >--- //---< block size in hex >---
@ -1657,7 +1680,7 @@ void CodeHeapState::print_count(outputStream* out, CodeHeap* heap) {
{ {
if (nBlocks_alive > 0) { 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("") STRINGSTREAM_FLUSH_LOCKED("")
granules_per_line = 128; granules_per_line = 128;
@ -1846,7 +1869,7 @@ void CodeHeapState::print_space(outputStream* out, CodeHeap* heap) {
{ {
if (nBlocks_alive > 0) { 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; granules_per_line = 128;
for (unsigned int ix = 0; ix < alloc_granules; ix++) { 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) { 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("") STRINGSTREAM_FLUSH_LOCKED("")
granules_per_line = 128; 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) && 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 + 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())) && ((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())) && os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
is_readable_pointer(this_blob->content_begin()); os::is_readable_pointer(this_blob->content_begin());
// blob could have been flushed, freed, and merged. // blob could have been flushed, freed, and merged.
// this_blob < last_blob is an indicator for that. // this_blob < last_blob is an indicator for that.
if (blob_initialized && (this_blob > last_blob)) { 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 // 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(); 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>"; 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. // this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
nmethod* nm = this_blob->as_nmethod_or_null(); nmethod* nm = this_blob->as_nmethod_or_null();
Method* method = (nm == NULL) ? NULL : nm->method(); // may be uninitialized, i.e. != NULL, but invalid Method* method = (nm == NULL) ? NULL : nm->method(); // may be uninitialized, i.e. != NULL, but invalid
if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) && if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) && (cbType != nMethod_inconstruction) &&
is_readable_pointer(method) && is_readable_pointer(method->constants())) { os::is_readable_pointer(method) && os::is_readable_pointer(method->constants())) {
ResourceMark rm; ResourceMark rm;
//---< collect all data to locals as quickly as possible >--- //---< collect all data to locals as quickly as possible >---
unsigned int total_size = nm->total_size(); 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) { 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_runtime_stub()) return runtimeStub;
if (cb->is_deoptimization_stub()) return deoptimizationStub; if (cb->is_deoptimization_stub()) return deoptimizationStub;
if (cb->is_uncommon_trap_stub()) return uncommonTrapStub; 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(); nmethod* nm = cb->as_nmethod_or_null();
if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb. 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_zombie()) return nMethod_dead;
if (nm->is_unloaded()) return nMethod_unloaded; 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() && !(nm->is_not_entrant())) return nMethod_notused;
if (nm->is_alive()) return nMethod_alive; if (nm->is_alive()) return nMethod_alive;
if (nm->is_in_use()) return nMethod_inuse;
return nMethod_dead; return nMethod_dead;
} }
} }
return noType; 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 { enum blobType {
noType = 0, // must be! due to initialization by memset to zero noType = 0, // must be! due to initialization by memset to zero
// The nMethod_* values correspond 1:1 to the CompiledMethod enum values. // The nMethod_* values correspond to the CompiledMethod enum values.
nMethod_inuse, // executable. This is the "normal" state for a nmethod. // We can't use the CompiledMethod values 1:1 because we depend on noType == 0.
nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary. nMethod_inconstruction, // under construction. Very soon, the type will transition to "in_use".
nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist. nMethod_inuse, // executable. This is the "normal" state for a nmethod.
// Will transition to "zombie" after all activations are gone. nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary.
nMethod_zombie, // No more activations exist, ready for purge (remove from code cache). nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist.
nMethod_unloaded, // No activations exist, should not be called. Transient state on the way to "zombie". // Will transition to "zombie" after all activations are gone.
nMethod_alive = nMethod_notentrant, // Combined state: nmethod may have activations, thus can't be purged. nMethod_zombie, // No more activations exist, ready for purge (remove from code cache).
nMethod_dead = nMethod_zombie, // Combined state: nmethod does not have any activations. nMethod_unloaded, // No activations exist, should not be called. Transient state on the way to "zombie".
runtimeStub = nMethod_unloaded + 1, nMethod_alive = nMethod_notentrant, // Combined state: nmethod may have activations, thus can't be purged.
ricochetStub, nMethod_dead = nMethod_zombie, // Combined state: nmethod does not have any activations.
deoptimizationStub, runtimeStub = nMethod_unloaded + 1,
uncommonTrapStub, ricochetStub,
exceptionStub, deoptimizationStub,
safepointStub, uncommonTrapStub,
adapterBlob, exceptionStub,
mh_adapterBlob, safepointStub,
bufferBlob, adapterBlob,
lastType mh_adapterBlob,
bufferBlob,
lastType
}; };
private: 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, 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 void print_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
static blobType get_cbType(CodeBlob* cb); static blobType get_cbType(CodeBlob* cb);
static bool is_readable_pointer(const void* p);
public: public:
static void discard(outputStream* out, CodeHeap* heap); static void discard(outputStream* out, CodeHeap* heap);
@ -214,6 +215,7 @@ struct CodeHeapStat {
unsigned int nBlocks_t2; unsigned int nBlocks_t2;
unsigned int nBlocks_alive; unsigned int nBlocks_alive;
unsigned int nBlocks_dead; unsigned int nBlocks_dead;
unsigned int nBlocks_inconstr;
unsigned int nBlocks_unloaded; unsigned int nBlocks_unloaded;
unsigned int nBlocks_stub; unsigned int nBlocks_stub;
// FreeBlk data // FreeBlk data

View File

@ -10369,7 +10369,7 @@ myInit() {
<description> <description>
Can generate sampled allocation events. Can generate sampled allocation events.
If this capability is enabled then the heap sampling method 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. called and <eventlink id="SampledObjectAlloc"></eventlink> events can be generated.
</description> </description>
</capabilityfield> </capabilityfield>
@ -11552,41 +11552,47 @@ myInit() {
</category> </category>
<category id="heap_monitoring" label="Heap Monitoring"> <category id="heap_monitoring" label="Heap Monitoring">
<function id="SetHeapSamplingRate" phase="onload" num="156" since="11"> <function id="SetHeapSamplingInterval" phase="onload" num="156" since="11">
<synopsis>Set Heap Sampling Rate</synopsis> <synopsis>Set Heap Sampling Interval</synopsis>
<description> <description>
Generate a <eventlink id="SampledObjectAlloc"/> event when objects are allocated. Generate a <eventlink id="SampledObjectAlloc"/> event when objects are allocated.
Each thread keeps a counter of bytes allocated. The event will only be generated 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. since the last sample.
<p/> <p/>
Setting <paramlink id="sampling_rate"></paramlink> to 0 will cause an event to be Setting <paramlink id="sampling_interval"></paramlink> to 0 will cause an event to be
generated by each allocation supported by the system. 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> </description>
<origin>new</origin> <origin>new</origin>
<capabilities> <capabilities>
<required id="can_generate_sampled_object_alloc_events"></required> <required id="can_generate_sampled_object_alloc_events"></required>
</capabilities> </capabilities>
<parameters> <parameters>
<param id="sampling_rate"> <param id="sampling_interval">
<jint/> <jint/>
<description> <description>
The sampling rate in bytes. The sampler uses a statistical approach to The sampling interval in bytes. The sampler uses a statistical approach to
generate an event, on average, once for every <paramlink id="sampling_rate"/> bytes of generate an event, on average, once for every <paramlink id="sampling_interval"/> bytes of
memory allocated by a given thread. memory allocated by a given thread.
<p/> <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/> <p/>
Note: The overhead of this feature is directly correlated with the sampling rate. Note: The overhead of this feature is directly correlated with the sampling interval.
A high sampling rate, such as 1024 bytes, will incur a high overhead. A high sampling interval, such as 1024 bytes, will incur a high overhead.
A lower rate, such as 1024KB, will have a much lower overhead. Sampling should only 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. be used with an understanding that it may impact performance.
</description> </description>
</param> </param>
</parameters> </parameters>
<errors> <errors>
<error id="JVMTI_ERROR_ILLEGAL_ARGUMENT"> <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> </error>
</errors> </errors>
</function> </function>
@ -13586,20 +13592,23 @@ myInit() {
id="SampledObjectAlloc" const="JVMTI_EVENT_SAMPLED_OBJECT_ALLOC" num="86" since="11"> id="SampledObjectAlloc" const="JVMTI_EVENT_SAMPLED_OBJECT_ALLOC" num="86" since="11">
<description> <description>
Sent when an allocated object is sampled. 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. 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 This implies that, on average, one object will be sampled every time a thread has
allocated 512KB bytes since the last sample. allocated 512KB bytes since the last sample.
<p/> <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 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 happening in a fixed pattern (i.e., the same set of objects are being allocated
every 512KB). every 512KB).
<p/> <p/>
If another sampling rate is required, the user can call If another sampling interval is required, the user can call
<functionlink id="SetHeapSamplingRate"></functionlink> with a strictly positive integer value, representing <functionlink id="SetHeapSamplingInterval"></functionlink> with a strictly positive integer value,
the new sampling rate. representing the new sampling interval.
<p/> <p/>
This event is sent once the sampled allocation has been performed. It provides the object, stack trace 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. 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 */ } /* end GetAvailableProcessors */
jvmtiError jvmtiError
JvmtiEnv::SetHeapSamplingRate(jint sampling_rate) { JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {
if (sampling_rate < 0) { if (sampling_interval < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT; return JVMTI_ERROR_ILLEGAL_ARGUMENT;
} }
ThreadHeapSampler::set_sampling_rate(sampling_rate); ThreadHeapSampler::set_sampling_interval(sampling_interval);
return JVMTI_ERROR_NONE; return JVMTI_ERROR_NONE;
} /* end SetHeapSamplingRate */ } /* end SetHeapSamplingInterval */
// //
// System Properties functions // 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); 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 // 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 // The verbose parameter is only set by the debug code in one case
void os::print_location(outputStream* st, intptr_t x, bool verbose) { 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; return;
} }
} }
if (JNIHandles::is_global_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a global jni handle", p2i(addr)); bool accessible = is_readable_pointer(addr);
return;
} if (align_down((intptr_t)addr, sizeof(intptr_t)) != 0 && accessible) {
if (JNIHandles::is_weak_global_handle((jobject) addr)) { if (JNIHandles::is_global_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a weak global jni handle", p2i(addr)); st->print_cr(INTPTR_FORMAT " is a global jni handle", p2i(addr));
return; 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 #ifndef PRODUCT
// we don't keep the block list in product mode // we don't keep the block list in product mode
if (JNIHandles::is_local_handle((jobject) addr)) { if (JNIHandles::is_local_handle((jobject) addr)) {
st->print_cr(INTPTR_FORMAT " is a local jni handle", p2i(addr)); st->print_cr(INTPTR_FORMAT " is a local jni handle", p2i(addr));
return; return;
} }
#endif #endif
}
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) { for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
// Check for privilege stack // Check for privilege stack
@ -1155,6 +1176,11 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
return; 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)); 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_unreadable();
static void make_polling_page_readable(); 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 // Routines used to serialize the thread state without using membars
static void serialize_thread_states(); static void serialize_thread_states();

View File

@ -31,7 +31,7 @@
// Cheap random number generator // Cheap random number generator
uint64_t ThreadHeapSampler::_rnd; uint64_t ThreadHeapSampler::_rnd;
// Default is 512kb. // Default is 512kb.
int ThreadHeapSampler::_sampling_rate = 512 * 1024; int ThreadHeapSampler::_sampling_interval = 512 * 1024;
int ThreadHeapSampler::_enabled; int ThreadHeapSampler::_enabled;
// Statics for the fast log // 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). // 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 // This is done by generating a random number between 0 and 1 and applying
// the inverse cumulative distribution function for an exponential. // 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 // the probability distribution function is m*exp(-mx) so the CDF is
// p = 1 - exp(-mx), so // p = 1 - exp(-mx), so
// q = 1 - p = exp(-mx) // q = 1 - p = exp(-mx)
@ -96,14 +96,14 @@ void ThreadHeapSampler::pick_next_geometric_sample() {
// negative answer. // negative answer.
double log_val = (fast_log2(q) - 26); double log_val = (fast_log2(q) - 26);
double result = 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."); assert(result > 0 && result < SIZE_MAX, "Result is not in an acceptable range.");
size_t rate = static_cast<size_t>(result); size_t interval = static_cast<size_t>(result);
_bytes_until_sample = rate; _bytes_until_sample = interval;
} }
void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) { void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) {
if (get_sampling_rate() == 1) { if (get_sampling_interval() == 1) {
_bytes_until_sample = 1; _bytes_until_sample = 1;
return; return;
} }
@ -161,12 +161,12 @@ void ThreadHeapSampler::disable() {
OrderAccess::release_store(&_enabled, 0); OrderAccess::release_store(&_enabled, 0);
} }
int ThreadHeapSampler::get_sampling_rate() { int ThreadHeapSampler::get_sampling_interval() {
return OrderAccess::load_acquire(&_sampling_rate); return OrderAccess::load_acquire(&_sampling_interval);
} }
void ThreadHeapSampler::set_sampling_rate(int sampling_rate) { void ThreadHeapSampler::set_sampling_interval(int sampling_interval) {
OrderAccess::release_store(&_sampling_rate, sampling_rate); OrderAccess::release_store(&_sampling_interval, sampling_interval);
} }
// Methods used in assertion mode to check if a collector is present or not at // 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_geometric_sample();
void pick_next_sample(size_t overflowed_bytes = 0); void pick_next_sample(size_t overflowed_bytes = 0);
static int _enabled; 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 // Used for assertion mode to determine if there is a path to a TLAB slow path
// without a collector present. // without a collector present.
@ -63,8 +63,8 @@ class ThreadHeapSampler {
static void enable(); static void enable();
static void disable(); static void disable();
static void set_sampling_rate(int sampling_rate); static void set_sampling_interval(int sampling_interval);
static int get_sampling_rate(); static int get_sampling_interval();
bool sampling_collector_present() const; bool sampling_collector_present() const;
bool remove_sampling_collector(); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,8 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE; import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
@ -68,6 +70,15 @@ final class GCTR extends CounterMode {
return "GCTR"; 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 // input must be multiples of 128-bit blocks when calling update
int update(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) { int update(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
if (inLen - inOfs > in.length) { if (inLen - inOfs > in.length) {
@ -80,7 +91,25 @@ final class GCTR extends CounterMode {
throw new RuntimeException("output buffer too small"); 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 // 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 java.security.spec.InvalidParameterSpecException;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.PBEParameterSpec;
import sun.security.util.HexDumpEncoder;
import sun.security.util.*; import sun.security.util.*;
/** /**
@ -260,21 +259,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
String kdfAlgo = null; String kdfAlgo = null;
String cipherAlgo = null; String cipherAlgo = null;
DerValue pBES2Algorithms = new DerValue(encoded); DerValue pBES2_params = 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();
if (pBES2_params.tag != DerValue.tag_Sequence) { if (pBES2_params.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: " throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag"); + "not an ASN.1 SEQUENCE tag");
@ -293,7 +278,6 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private String parseKDF(DerValue keyDerivationFunc) throws IOException { private String parseKDF(DerValue keyDerivationFunc) throws IOException {
String kdfAlgo = null;
if (!pkcs5PBKDF2_OID.equals(keyDerivationFunc.data.getOID())) { if (!pkcs5PBKDF2_OID.equals(keyDerivationFunc.data.getOID())) {
throw new IOException("PBE parameter parsing error: " throw new IOException("PBE parameter parsing error: "
@ -318,34 +302,41 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
+ "not an ASN.1 OCTET STRING tag"); + "not an ASN.1 OCTET STRING tag");
} }
iCount = pBKDF2_params.data.getInteger(); iCount = pBKDF2_params.data.getInteger();
DerValue keyLength = pBKDF2_params.data.getDerValue(); // keyLength INTEGER (1..MAX) OPTIONAL,
if (keyLength.tag == DerValue.tag_Integer) { if (pBKDF2_params.data.available() > 0) {
keysize = keyLength.getInteger() * 8; // keysize (in bits) DerValue keyLength = pBKDF2_params.data.getDerValue();
} if (keyLength.tag == DerValue.tag_Integer) {
if (pBKDF2_params.tag == DerValue.tag_Sequence) { keysize = keyLength.getInteger() * 8; // keysize (in bits)
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");
} }
if (prf.data.available() != 0) { }
// parameter is 'NULL' for all HmacSHA KDFs // prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
DerValue parameter = prf.data.getDerValue(); String kdfAlgo = "HmacSHA1";
if (parameter.tag != DerValue.tag_Null) { 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: " 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 { protected byte[] engineGetEncoded() throws IOException {
DerOutputStream out = new DerOutputStream(); DerOutputStream out = new DerOutputStream();
DerOutputStream pBES2Algorithms = new DerOutputStream();
pBES2Algorithms.putOID(pkcs5PBES2_OID);
DerOutputStream pBES2_params = new DerOutputStream(); DerOutputStream pBES2_params = new DerOutputStream();
@ -410,7 +399,10 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
DerOutputStream pBKDF2_params = new DerOutputStream(); DerOutputStream pBKDF2_params = new DerOutputStream();
pBKDF2_params.putOctetString(salt); // choice: 'specified OCTET STRING' pBKDF2_params.putOctetString(salt); // choice: 'specified OCTET STRING'
pBKDF2_params.putInteger(iCount); 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(); DerOutputStream prf = new DerOutputStream();
// algorithm is id-hmacWithSHA1/SHA224/SHA256/SHA384/SHA512 // algorithm is id-hmacWithSHA1/SHA224/SHA256/SHA384/SHA512
@ -434,8 +426,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
} }
pBES2_params.write(DerValue.tag_Sequence, encryptionScheme); pBES2_params.write(DerValue.tag_Sequence, encryptionScheme);
pBES2Algorithms.write(DerValue.tag_Sequence, pBES2_params); out.write(DerValue.tag_Sequence, pBES2_params);
out.write(DerValue.tag_Sequence, pBES2Algorithms);
return out.toByteArray(); return out.toByteArray();
} }

View File

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

View File

@ -106,7 +106,7 @@ public class PatternSyntaxException
} }
sb.append(System.lineSeparator()); sb.append(System.lineSeparator());
sb.append(pattern); sb.append(pattern);
if (index >= 0) { if (index >= 0 && pattern != null && index < pattern.length()) {
sb.append(System.lineSeparator()); sb.append(System.lineSeparator());
for (int i = 0; i < index; i++) sb.append(' '); for (int i = 0; i < index; i++) sb.append(' ');
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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -87,6 +87,9 @@ public class ReflectionFactory {
private static boolean noInflation = false; private static boolean noInflation = false;
private static int inflationThreshold = 15; private static int inflationThreshold = 15;
// true if deserialization constructor checking is disabled
private static boolean disableSerialConstructorChecks = false;
private ReflectionFactory() { private ReflectionFactory() {
} }
@ -424,10 +427,64 @@ public class ReflectionFactory {
return generateConstructor(cl, constructorToCall); 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) { public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
Class<?> initCl = cl; Class<?> initCl = cl;
while (Serializable.class.isAssignableFrom(initCl)) { while (Serializable.class.isAssignableFrom(initCl)) {
if ((initCl = initCl.getSuperclass()) == null) { Class<?> prev = initCl;
if ((initCl = initCl.getSuperclass()) == null ||
(!disableSerialConstructorChecks && !superHasAccessibleConstructor(prev))) {
return null; return null;
} }
} }
@ -653,6 +710,9 @@ public class ReflectionFactory {
} }
} }
disableSerialConstructorChecks =
"true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
initted = true; initted = true;
} }

View File

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

View File

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

View File

@ -33,8 +33,11 @@ import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import java.util.Collection;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKey; 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.ClientHello.ClientHelloMessage;
import sun.security.ssl.SSLExtension.ExtensionConsumer; import sun.security.ssl.SSLExtension.ExtensionConsumer;
import sun.security.ssl.SSLExtension.SSLExtensionSpec; import sun.security.ssl.SSLExtension.SSLExtensionSpec;
@ -167,7 +170,7 @@ final class PreSharedKeyExtension {
int getIdsEncodedLength() { int getIdsEncodedLength() {
int idEncodedLength = 0; int idEncodedLength = 0;
for(PskIdentity curId : identities) { for (PskIdentity curId : identities) {
idEncodedLength += curId.getEncodedLength(); idEncodedLength += curId.getEncodedLength();
} }
@ -190,7 +193,7 @@ final class PreSharedKeyExtension {
byte[] buffer = new byte[encodedLength]; byte[] buffer = new byte[encodedLength];
ByteBuffer m = ByteBuffer.wrap(buffer); ByteBuffer m = ByteBuffer.wrap(buffer);
Record.putInt16(m, idsEncodedLength); Record.putInt16(m, idsEncodedLength);
for(PskIdentity curId : identities) { for (PskIdentity curId : identities) {
curId.writeEncoded(m); curId.writeEncoded(m);
} }
Record.putInt16(m, bindersEncodedLength); Record.putInt16(m, bindersEncodedLength);
@ -220,7 +223,7 @@ final class PreSharedKeyExtension {
String identitiesString() { String identitiesString() {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
for(PskIdentity curId : identities) { for (PskIdentity curId : identities) {
result.append(curId.toString() + "\n"); result.append(curId.toString() + "\n");
} }
@ -229,7 +232,7 @@ final class PreSharedKeyExtension {
String bindersString() { String bindersString() {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
for(byte[] curBinder : binders) { for (byte[] curBinder : binders) {
result.append("{" + Utilities.toHexString(curBinder) + "}\n"); result.append("{" + Utilities.toHexString(curBinder) + "}\n");
} }
@ -328,6 +331,7 @@ final class PreSharedKeyExtension {
public void consume(ConnectionContext context, public void consume(ConnectionContext context,
HandshakeMessage message, HandshakeMessage message,
ByteBuffer buffer) throws IOException { ByteBuffer buffer) throws IOException {
ClientHelloMessage clientHello = (ClientHelloMessage) message;
ServerHandshakeContext shc = (ServerHandshakeContext)context; ServerHandshakeContext shc = (ServerHandshakeContext)context;
// Is it a supported and enabled extension? // Is it a supported and enabled extension?
if (!shc.sslConfig.isAvailable(SSLExtension.CH_PRE_SHARED_KEY)) { if (!shc.sslConfig.isAvailable(SSLExtension.CH_PRE_SHARED_KEY)) {
@ -367,8 +371,7 @@ final class PreSharedKeyExtension {
int idIndex = 0; int idIndex = 0;
for (PskIdentity requestedId : pskSpec.identities) { for (PskIdentity requestedId : pskSpec.identities) {
SSLSessionImpl s = sessionCache.get(requestedId.identity); SSLSessionImpl s = sessionCache.get(requestedId.identity);
if (s != null && s.isRejoinable() && if (s != null && canRejoin(clientHello, shc, s)) {
s.getPreSharedKey().isPresent()) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine("Resuming session: ", s); SSLLogger.fine("Resuming session: ", s);
} }
@ -392,10 +395,68 @@ final class PreSharedKeyExtension {
// update the context // update the context
shc.handshakeExtensions.put( 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 private static final
class CHPreSharedKeyUpdate implements HandshakeConsumer { class CHPreSharedKeyUpdate implements HandshakeConsumer {
// Prevent instantiation of this class. // Prevent instantiation of this class.
@ -547,6 +608,18 @@ final class PreSharedKeyExtension {
return null; 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(); Optional<SecretKey> pskOpt = chc.resumingSession.getPreSharedKey();
if (!pskOpt.isPresent()) { if (!pskOpt.isPresent()) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@ -658,7 +731,7 @@ final class PreSharedKeyExtension {
} catch (NoSuchAlgorithmException | InvalidKeyException ex) { } catch (NoSuchAlgorithmException | InvalidKeyException ex) {
throw new IOException(ex); throw new IOException(ex);
} }
} catch(GeneralSecurityException ex) { } catch (GeneralSecurityException ex) {
throw new IOException(ex); throw new IOException(ex);
} }
} }

View File

@ -96,7 +96,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
private boolean invalidated; private boolean invalidated;
private X509Certificate[] localCerts; private X509Certificate[] localCerts;
private PrivateKey localPrivateKey; private PrivateKey localPrivateKey;
private final String[] localSupportedSignAlgs; private final Collection<SignatureScheme> localSupportedSignAlgs;
private String[] peerSupportedSignAlgs; // for certificate private String[] peerSupportedSignAlgs; // for certificate
private boolean useDefaultPeerSignAlgs = false; private boolean useDefaultPeerSignAlgs = false;
private List<byte[]> statusResponses; private List<byte[]> statusResponses;
@ -144,7 +144,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
this.sessionId = new SessionId(false, null); this.sessionId = new SessionId(false, null);
this.host = null; this.host = null;
this.port = -1; this.port = -1;
this.localSupportedSignAlgs = new String[0]; this.localSupportedSignAlgs = Collections.emptySet();
this.serverNameIndication = null; this.serverNameIndication = null;
this.requestedServerNames = Collections.<SNIServerName>emptyList(); this.requestedServerNames = Collections.<SNIServerName>emptyList();
this.useExtendedMasterSecret = false; this.useExtendedMasterSecret = false;
@ -179,8 +179,9 @@ final class SSLSessionImpl extends ExtendedSSLSession {
this.sessionId = id; this.sessionId = id;
this.host = hc.conContext.transport.getPeerHost(); this.host = hc.conContext.transport.getPeerHost();
this.port = hc.conContext.transport.getPeerPort(); this.port = hc.conContext.transport.getPeerPort();
this.localSupportedSignAlgs = this.localSupportedSignAlgs = hc.localSupportedSignAlgs == null ?
SignatureScheme.getAlgorithmNames(hc.localSupportedSignAlgs); Collections.emptySet() :
Collections.unmodifiableCollection(hc.localSupportedSignAlgs);
this.serverNameIndication = hc.negotiatedServerName; this.serverNameIndication = hc.negotiatedServerName;
this.requestedServerNames = Collections.<SNIServerName>unmodifiableList( this.requestedServerNames = Collections.<SNIServerName>unmodifiableList(
hc.getRequestedServerNames()); hc.getRequestedServerNames());
@ -969,16 +970,20 @@ final class SSLSessionImpl extends ExtendedSSLSession {
} }
/** /**
* Gets an array of supported signature algorithms that the local side is * Gets an array of supported signature algorithm names that the local
* willing to verify. * side is willing to verify.
*/ */
@Override @Override
public String[] getLocalSupportedSignatureAlgorithms() { public String[] getLocalSupportedSignatureAlgorithms() {
if (localSupportedSignAlgs != null) { return SignatureScheme.getAlgorithmNames(localSupportedSignAlgs);
return localSupportedSignAlgs.clone(); }
}
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) { 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 * If we need to change the client mode and the enabled
* protocols and cipher suites haven't specifically been * protocols and cipher suites haven't specifically been
@ -400,13 +407,6 @@ class TransportContext implements ConnectionContext, Closeable {
* default ones. * default ones.
*/ */
if (sslConfig.isClientMode != useClientMode) { 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( if (sslContext.isDefaultProtocolVesions(
sslConfig.enabledProtocols)) { sslConfig.enabledProtocols)) {
sslConfig.enabledProtocols = sslConfig.enabledProtocols =

View File

@ -297,6 +297,22 @@ JNU_NotifyAll(JNIEnv *env, jobject object);
} \ } \
} while (0) \ } 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) \ #define CHECK_NULL_RETURN(x, y) \
do { \ do { \
if ((x) == NULL) { \ 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -171,32 +171,38 @@ jboolean setInet6Address_ipaddress(JNIEnv *env, jobject iaObj, char *address) {
void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) { void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID); 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); (*env)->SetIntField(env, holder, iac_addressID, address);
} }
void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) { void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID); 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); (*env)->SetIntField(env, holder, iac_familyID, family);
} }
void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) { void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID); 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_hostNameID, host);
(*env)->SetObjectField(env, holder, iac_origHostNameID, host); (*env)->SetObjectField(env, holder, iac_origHostNameID, host);
} }
int getInetAddress_addr(JNIEnv *env, jobject iaObj) { int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID); 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); return (*env)->GetIntField(env, holder, iac_addressID);
} }
int getInetAddress_family(JNIEnv *env, jobject iaObj) { int getInetAddress_family(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID); 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); return (*env)->GetIntField(env, holder, iac_familyID);
} }
jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) { jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID); 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); return (*env)->GetObjectField(env, holder, iac_hostNameID);
} }
@ -211,7 +217,9 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
CHECK_NULL_RETURN(iaObj, NULL); CHECK_NULL_RETURN(iaObj, NULL);
address = NET_IPv4MappedToIPv4(caddr); address = NET_IPv4MappedToIPv4(caddr);
setInetAddress_addr(env, iaObj, address); setInetAddress_addr(env, iaObj, address);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4); setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
} else { } else {
jboolean ret; jboolean ret;
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID); iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
@ -220,6 +228,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
if (ret == JNI_FALSE) if (ret == JNI_FALSE)
return NULL; return NULL;
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv6); setInetAddress_family(env, iaObj, java_net_InetAddress_IPv6);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
setInet6Address_scopeid(env, iaObj, sa->sa6.sin6_scope_id); setInet6Address_scopeid(env, iaObj, sa->sa6.sin6_scope_id);
} }
*port = ntohs(sa->sa6.sin6_port); *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); iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
CHECK_NULL_RETURN(iaObj, NULL); CHECK_NULL_RETURN(iaObj, NULL);
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4); 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)); setInetAddress_addr(env, iaObj, ntohl(sa->sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
*port = ntohs(sa->sa4.sin_port); *port = ntohs(sa->sa4.sin_port);
} }
return iaObj; return iaObj;
@ -238,6 +249,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
{ {
jint family = getInetAddress_family(env, iaObj) == jint family = getInetAddress_family(env, iaObj) ==
java_net_InetAddress_IPv4 ? AF_INET : AF_INET6; java_net_InetAddress_IPv4 ? AF_INET : AF_INET6;
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
if (sa->sa.sa_family == AF_INET6) { if (sa->sa.sa_family == AF_INET6) {
jbyte *caddrNew = (jbyte *)&sa->sa6.sin6_addr; jbyte *caddrNew = (jbyte *)&sa->sa6.sin6_addr;
if (NET_IsIPv4Mapped(caddrNew)) { if (NET_IsIPv4Mapped(caddrNew)) {
@ -247,6 +259,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
} }
addrNew = NET_IPv4MappedToIPv4(caddrNew); addrNew = NET_IPv4MappedToIPv4(caddrNew);
addrCur = getInetAddress_addr(env, iaObj); addrCur = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
if (addrNew == addrCur) { if (addrNew == addrCur) {
return JNI_TRUE; return JNI_TRUE;
} else { } else {
@ -273,6 +286,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
} }
addrNew = ntohl(sa->sa4.sin_addr.s_addr); addrNew = ntohl(sa->sa4.sin_addr.s_addr);
addrCur = getInetAddress_addr(env, iaObj); addrCur = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
if (addrNew == addrCur) { if (addrNew == addrCur) {
return JNI_TRUE; return JNI_TRUE;
} else { } else {

View File

@ -739,13 +739,13 @@ ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified)
jzfile *zip = NULL; jzfile *zip = NULL;
/* Clear zip error message */ /* Clear zip error message */
if (pmsg != 0) { if (pmsg != NULL) {
*pmsg = NULL; *pmsg = NULL;
} }
zip = ZIP_Get_From_Cache(name, pmsg, lastModified); 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); ZFILE zfd = ZFILE_Open(name, mode);
zip = ZIP_Put_In_Cache(name, zfd, pmsg, lastModified); 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 *) setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *)
(iterator->ai_addr))->sin_addr.s_addr)); (iterator->ai_addr))->sin_addr.s_addr));
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
setInetAddress_hostName(env, iaObj, host); setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, i++, iaObj); (*env)->SetObjectArrayElement(env, ret, i++, iaObj);
iterator = iterator->ai_next; iterator = iterator->ai_next;
} }

View File

@ -198,6 +198,8 @@ lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6)
return NULL; return NULL;
} }
setInetAddress_hostName(env, o, name); setInetAddress_hostName(env, o, name);
if ((*env)->ExceptionCheck(env))
goto done;
(*env)->SetObjectArrayElement(env, result, index, o); (*env)->SetObjectArrayElement(env, result, index, o);
(*env)->DeleteLocalRef(env, o); (*env)->DeleteLocalRef(env, o);
} }
@ -355,7 +357,11 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
goto cleanupAndReturn; goto cleanupAndReturn;
} }
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); 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); setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj); (*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
inetIndex++; inetIndex++;
} else if (iterator->ai_family == AF_INET6) { } 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); setInet6Address_scopeid(env, iaObj, scope);
} }
setInetAddress_hostName(env, iaObj, host); setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj); (*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
inet6Index++; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -329,11 +329,11 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
(JNIEnv *env, jclass cls, jobject iaObj) (JNIEnv *env, jclass cls, jobject iaObj)
{ {
netif *ifs, *curr; netif *ifs, *curr;
int family = (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) ?
AF_INET : AF_INET6;
jobject obj = NULL; jobject obj = NULL;
jboolean match = JNI_FALSE; 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); ifs = enumInterfaces(env);
if (ifs == NULL) { if (ifs == NULL) {
return NULL; return NULL;
@ -351,7 +351,7 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
int address1 = htonl( int address1 = htonl(
((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr); ((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr);
int address2 = getInetAddress_addr(env, iaObj); int address2 = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
if (address1 == address2) { if (address1 == address2) {
match = JNI_TRUE; match = JNI_TRUE;
break; break;
@ -698,6 +698,7 @@ static jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
if (iaObj) { if (iaObj) {
setInetAddress_addr(env, iaObj, htonl( setInetAddress_addr(env, iaObj, htonl(
((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr)); ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
} else { } else {
return NULL; return NULL;
} }
@ -710,6 +711,7 @@ static jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
if (ia2Obj) { if (ia2Obj) {
setInetAddress_addr(env, ia2Obj, htonl( setInetAddress_addr(env, ia2Obj, htonl(
((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); ((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
(*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj); (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
} else { } else {
return NULL; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -531,9 +531,12 @@ Java_java_net_PlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
iaObj = NET_SockaddrToInetAddress(env, &rmtaddr, &port); iaObj = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ? family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
AF_INET : AF_INET6; AF_INET : AF_INET6;
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (family == AF_INET) { /* this API can't handle IPV6 addresses */ if (family == AF_INET) { /* this API can't handle IPV6 addresses */
int address = getInetAddress_addr(env, iaObj); int address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
setInetAddress_addr(env, addressObj, address); setInetAddress_addr(env, addressObj, address);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
} }
return port; 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; struct in_addr in;
jobjectArray addrArray; jobjectArray addrArray;
jsize len; jsize len;
jint family;
jobject addr; jobject addr;
int i; 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; in.s_addr = 0;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
addr = (*env)->GetObjectArrayElement(env, addrArray, 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)); in.s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION(env);
break; 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; struct in_addr in;
in.s_addr = htonl( getInetAddress_addr(env, value) ); in.s_addr = htonl( getInetAddress_addr(env, value) );
JNU_CHECK_EXCEPTION(env);
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char*)&in, sizeof(in)) < 0) { (const char*)&in, sizeof(in)) < 0) {
JNU_ThrowByNameWithMessageAndLastError JNU_ThrowByNameWithMessageAndLastError
@ -1458,6 +1465,7 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
CHECK_NULL_RETURN(addr, NULL); CHECK_NULL_RETURN(addr, NULL);
setInetAddress_addr(env, addr, ntohl(in.s_addr)); setInetAddress_addr(env, addr, ntohl(in.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
/* /*
* For IP_MULTICAST_IF return InetAddress * 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); jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
jint fd; jint fd;
jint family;
jint ipv6_join_leave; jint ipv6_join_leave;
if (IS_NULL(fdObj)) { if (IS_NULL(fdObj)) {
@ -1910,7 +1919,9 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
ipv6_join_leave = ipv6_available(); ipv6_join_leave = ipv6_available();
#ifdef __linux__ #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; ipv6_join_leave = JNI_FALSE;
} }
#endif #endif
@ -1951,6 +1962,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
} }
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj)); mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
mname.imr_address.s_addr = 0; mname.imr_address.s_addr = 0;
mname.imr_ifindex = (*env)->GetIntField(env, niObj, ni_indexID); mname.imr_ifindex = (*env)->GetIntField(env, niObj, ni_indexID);
mname_len = sizeof(struct ip_mreqn); 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); addr = (*env)->GetObjectArrayElement(env, addrArray, 0);
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj)); mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
#ifdef __linux__ #ifdef __linux__
mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr)); mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION(env);
mname.imr_ifindex = 0; mname.imr_ifindex = 0;
#else #else
mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr)); mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION(env);
#endif #endif
mname_len = sizeof(struct ip_mreq); 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)); mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
mname.imr_address.s_addr = 0 ; mname.imr_address.s_addr = 0 ;
mname.imr_ifindex = index; mname.imr_ifindex = index;
mname_len = sizeof(struct ip_mreqn); 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; mname.imr_interface.s_addr = in.s_addr;
#endif #endif
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj)); mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
JNU_CHECK_EXCEPTION(env);
mname_len = sizeof(struct ip_mreq); mname_len = sizeof(struct ip_mreq);
} }
} }
@ -2097,10 +2114,11 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
jint address; jint address;
family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ? family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
AF_INET : AF_INET6; AF_INET : AF_INET6;
JNU_CHECK_EXCEPTION(env);
if (family == AF_INET) { /* will convert to IPv4-mapped address */ if (family == AF_INET) { /* will convert to IPv4-mapped address */
memset((char *) caddr, 0, 16); memset((char *) caddr, 0, 16);
address = getInetAddress_addr(env, iaObj); address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION(env);
caddr[10] = 0xff; caddr[10] = 0xff;
caddr[11] = 0xff; caddr[11] = 0xff;

View File

@ -764,6 +764,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
jboolean v4MappedAddress) jboolean v4MappedAddress)
{ {
jint family = getInetAddress_family(env, iaObj); jint family = getInetAddress_family(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
memset((char *)sa, 0, sizeof(SOCKETADDRESS)); memset((char *)sa, 0, sizeof(SOCKETADDRESS));
if (ipv6_available() && if (ipv6_available() &&
@ -777,6 +778,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
// convert to IPv4-mapped address // convert to IPv4-mapped address
memset((char *)caddr, 0, 16); memset((char *)caddr, 0, 16);
address = getInetAddress_addr(env, iaObj); address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (address == INADDR_ANY) { if (address == INADDR_ANY) {
/* we would always prefer IPv6 wildcard address /* we would always prefer IPv6 wildcard address
* caddr[10] = 0xff; * caddr[10] = 0xff;
@ -871,6 +873,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
return -1; return -1;
} }
address = getInetAddress_addr(env, iaObj); address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
sa->sa4.sin_port = htons(port); sa->sa4.sin_port = htons(port);
sa->sa4.sin_addr.s_addr = htonl(address); sa->sa4.sin_addr.s_addr = htonl(address);
sa->sa4.sin_family = AF_INET; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -146,7 +146,11 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
} }
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *) setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *)
(iterator->ai_addr))->sin_addr.s_addr)); (iterator->ai_addr))->sin_addr.s_addr));
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
setInetAddress_hostName(env, iaObj, host); setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, i++, iaObj); (*env)->SetObjectArrayElement(env, ret, i++, iaObj);
iterator = iterator->ai_next; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -187,7 +187,11 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
goto cleanupAndReturn; goto cleanupAndReturn;
} }
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); 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); setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj); (*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
inetIndex++; inetIndex++;
} else if (iterator->ai_family == AF_INET6) { } 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); setInet6Address_scopeid(env, iaObj, scope);
} }
setInetAddress_hostName(env, iaObj, host); setInetAddress_hostName(env, iaObj, host);
if ((*env)->ExceptionCheck(env))
goto cleanupAndReturn;
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj); (*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
inet6Index++; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -586,6 +586,7 @@ jobject createNetworkInterface
/* default ctor will set family to AF_INET */ /* default ctor will set family to AF_INET */
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.sa4.sin_addr.s_addr)); setInetAddress_addr(env, iaObj, ntohl(addrs->addr.sa4.sin_addr.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
if (addrs->mask != -1) { if (addrs->mask != -1) {
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
if (ibObj == NULL) { if (ibObj == NULL) {
@ -599,6 +600,7 @@ jobject createNetworkInterface
return NULL; return NULL;
} }
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.sa4.sin_addr.s_addr)); 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)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask); (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj); (*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) (JNIEnv *env, jclass cls, jobject iaObj)
{ {
netif *ifList, *curr; netif *ifList, *curr;
jint addr = getInetAddress_addr(env, iaObj);
jobject netifObj = NULL; 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 // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
if (ipv6_available()) { if (ipv6_available()) {

View File

@ -584,7 +584,7 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
/* default ctor will set family to AF_INET */ /* default ctor will set family to AF_INET */
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.sa4.sin_addr.s_addr)); 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); ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
if (ibObj == NULL) { if (ibObj == NULL) {
free_netaddr(netaddrP); free_netaddr(netaddrP);
@ -597,6 +597,7 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
return NULL; return NULL;
} }
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.sa4.sin_addr.s_addr)); 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)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask); (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj); (*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); jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
int ipv6_supported = ipv6_available(); int ipv6_supported = ipv6_available();
int fd, fd1 = -1, lcladdrlen = 0; int fd, fd1 = -1, lcladdrlen = 0;
jint family;
SOCKETADDRESS lcladdr; SOCKETADDRESS lcladdr;
if (getInetAddress_family(env, addressObj) == java_net_InetAddress_IPv6 && family = getInetAddress_family(env, addressObj);
!ipv6_supported) JNU_CHECK_EXCEPTION(env);
{ if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Protocol family not supported"); "Protocol family not supported");
return; return;
} }
if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) { if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed"); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
return; return;
@ -344,6 +344,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0
} }
family = getInetAddress_family(env, address); family = getInetAddress_family(env, address);
JNU_CHECK_EXCEPTION(env);
if (family == java_net_InetAddress_IPv6 && !ipv6_available()) { if (family == java_net_InetAddress_IPv6 && !ipv6_available()) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Protocol family not supported"); "Protocol family not supported");
@ -455,6 +456,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send
} }
family = getInetAddress_family(env, iaObj); family = getInetAddress_family(env, iaObj);
JNU_CHECK_EXCEPTION(env);
if (family == java_net_InetAddress_IPv4) { if (family == java_net_InetAddress_IPv4) {
fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
} else { } else {
@ -584,6 +586,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
return -1; return -1;
} else { } else {
address = getInetAddress_addr(env, addressObj); 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 */ /* We only handle IPv4 for now. Will support IPv6 once its in the os */
family = AF_INET; family = AF_INET;
} }
@ -657,7 +660,9 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
return 0; return 0;
} }
setInetAddress_addr(env, addressObj, ntohl(remote_addr.sa4.sin_addr.s_addr)); 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); setInetAddress_family(env, addressObj, java_net_InetAddress_IPv4);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
/* return port */ /* return port */
return ntohs(remote_addr.sa4.sin_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; int fam;
addr = (*env)->GetObjectArrayElement(env, addrArray, i); addr = (*env)->GetObjectArrayElement(env, addrArray, i);
fam = getInetAddress_family(env, addr); fam = getInetAddress_family(env, addr);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (fam == family) { if (fam == family) {
*iaddr = addr; *iaddr = addr;
return 0; 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)); iaddr->s_addr = htonl(getInetAddress_addr(env, addr));
JNU_CHECK_EXCEPTION_RETURN(env, -1);
return 0; return 0;
} }
@ -1471,6 +1478,7 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
struct in_addr in; struct in_addr in;
in.s_addr = htonl(getInetAddress_addr(env, value)); in.s_addr = htonl(getInetAddress_addr(env, value));
JNU_CHECK_EXCEPTION(env);
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(const char*)&in, sizeof(in)) < 0) { (const char*)&in, sizeof(in)) < 0) {
JNU_ThrowByNameWithMessageAndLastError JNU_ThrowByNameWithMessageAndLastError
@ -1712,7 +1720,7 @@ static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint
CHECK_NULL_RETURN(addr, NULL); CHECK_NULL_RETURN(addr, NULL);
setInetAddress_addr(env, addr, ntohl(in.s_addr)); setInetAddress_addr(env, addr, ntohl(in.s_addr));
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
/* /*
* For IP_MULTICAST_IF return InetAddress * For IP_MULTICAST_IF return InetAddress
*/ */

View File

@ -794,6 +794,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
jboolean v4MappedAddress) jboolean v4MappedAddress)
{ {
jint family = getInetAddress_family(env, iaObj); jint family = getInetAddress_family(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
memset((char *)sa, 0, sizeof(SOCKETADDRESS)); memset((char *)sa, 0, sizeof(SOCKETADDRESS));
if (ipv6_available() && if (ipv6_available() &&
@ -808,6 +809,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
// convert to IPv4-mapped address // convert to IPv4-mapped address
memset((char *)caddr, 0, 16); memset((char *)caddr, 0, 16);
address = getInetAddress_addr(env, iaObj); address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
if (address == INADDR_ANY) { if (address == INADDR_ANY) {
/* we would always prefer IPv6 wildcard address /* we would always prefer IPv6 wildcard address
* caddr[10] = 0xff; * caddr[10] = 0xff;
@ -846,6 +848,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
return -1; return -1;
} }
address = getInetAddress_addr(env, iaObj); address = getInetAddress_addr(env, iaObj);
JNU_CHECK_EXCEPTION_RETURN(env, -1);
sa->sa4.sin_port = htons((short)port); sa->sa4.sin_port = htons((short)port);
sa->sa4.sin_addr.s_addr = (u_long)htonl(address); sa->sa4.sin_addr.s_addr = (u_long)htonl(address);
sa->sa4.sin_family = AF_INET; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -364,11 +364,11 @@ public class FileManager {
* @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5 * @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5
*/ */
public static boolean moveToTrash(final File file) throws FileNotFoundException { 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 String fileName = file.getAbsolutePath();
final SecurityManager security = System.getSecurityManager(); final SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(fileName); if (security != null) security.checkDelete(fileName);
return _moveToTrash(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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,6 +42,9 @@ import java.io.FilePermission;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects; import java.util.Objects;
import javax.swing.JMenuBar; import javax.swing.JMenuBar;
@ -363,15 +366,11 @@ public class Desktop {
* @throws NullPointerException if file is null * @throws NullPointerException if file is null
* @throws IllegalArgumentException if file doesn't exist * @throws IllegalArgumentException if file doesn't exist
*/ */
private static void checkFileValidation(File file){ private static void checkFileValidation(File file) {
if (file == null) throw new NullPointerException("File must not be null");
if (!file.exists()) { if (!file.exists()) {
throw new IllegalArgumentException("The file: " throw new IllegalArgumentException("The file: "
+ file.getPath() + " doesn't exist."); + file.getPath() + " doesn't exist.");
} }
file.canRead();
} }
/** /**
@ -425,6 +424,7 @@ public class Desktop {
* @see java.awt.AWTPermission * @see java.awt.AWTPermission
*/ */
public void open(File file) throws IOException { public void open(File file) throws IOException {
file = new File(file.getPath());
checkAWTPermission(); checkAWTPermission();
checkExec(); checkExec();
checkActionSupport(Action.OPEN); checkActionSupport(Action.OPEN);
@ -456,6 +456,7 @@ public class Desktop {
* @see java.awt.AWTPermission * @see java.awt.AWTPermission
*/ */
public void edit(File file) throws IOException { public void edit(File file) throws IOException {
file = new File(file.getPath());
checkAWTPermission(); checkAWTPermission();
checkExec(); checkExec();
checkActionSupport(Action.EDIT); checkActionSupport(Action.EDIT);
@ -486,6 +487,7 @@ public class Desktop {
* allowed to create a subprocess * allowed to create a subprocess
*/ */
public void print(File file) throws IOException { public void print(File file) throws IOException {
file = new File(file.getPath());
checkExec(); checkExec();
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { 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() { private void checkQuitPermission() {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
@ -950,6 +944,8 @@ public class Desktop {
* @since 9 * @since 9
*/ */
public void openHelpViewer() { public void openHelpViewer() {
checkAWTPermission();
checkExec();
checkEventsProcessingPermission(); checkEventsProcessingPermission();
checkActionSupport(Action.APP_HELP_VIEWER); checkActionSupport(Action.APP_HELP_VIEWER);
peer.openHelpViewer(); peer.openHelpViewer();
@ -995,9 +991,15 @@ public class Desktop {
* @since 9 * @since 9
*/ */
public void browseFileDirectory(File file) { public void browseFileDirectory(File file) {
checkRead(); file = new File(file.getPath());
checkAWTPermission();
checkExec();
checkActionSupport(Action.BROWSE_FILE_DIR); checkActionSupport(Action.BROWSE_FILE_DIR);
checkFileValidation(file); checkFileValidation(file);
File parentFile = file.getParentFile();
if (parentFile == null || !parentFile.exists()) {
throw new IllegalArgumentException("Parent folder doesn't exist");
}
peer.browseFileDirectory(file); peer.browseFileDirectory(file);
} }
@ -1017,10 +1019,18 @@ public class Desktop {
* *
* @since 9 * @since 9
*/ */
public boolean moveToTrash(final File file) { public boolean moveToTrash(File file) {
checkDelete(); file = new File(file.getPath());
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkDelete(file.getPath());
}
checkActionSupport(Action.MOVE_TO_TRASH); checkActionSupport(Action.MOVE_TO_TRASH);
checkFileValidation(file); final File finalFile = file;
AccessController.doPrivileged((PrivilegedAction<?>) () -> {
checkFileValidation(finalFile);
return null;
});
return peer.moveToTrash(file); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -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 it fails free things and get out */
if ( newFontPath == NULL ) { if ( newFontPath == NULL ) {
free ( ( void *) appendDirList ); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -44,8 +44,11 @@ import javax.naming.ldap.Control;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays; import java.util.Arrays;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import javax.net.ssl.SSLParameters;
/** /**
* A thread that creates a connection to an LDAP server. * A thread that creates a connection to an LDAP server.
@ -158,7 +161,18 @@ public final class Connection implements Runnable {
int readTimeout; int readTimeout;
int connectTimeout; 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 // true means v3; false means v2
// Called in LdapClient.authenticate() (which is synchronized) // Called in LdapClient.authenticate() (which is synchronized)
// when connection is "quiet" and not shared; no need to synchronize // 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. // the SSL handshake following socket connection as part of the timeout.
// So explicitly set a socket read timeout, trigger the SSL handshake, // So explicitly set a socket read timeout, trigger the SSL handshake,
// then reset the timeout. // then reset the timeout.
if (connectTimeout > 0 && socket instanceof SSLSocket) { if (socket instanceof SSLSocket) {
SSLSocket sslSocket = (SSLSocket) socket; SSLSocket sslSocket = (SSLSocket) socket;
int socketTimeout = sslSocket.getSoTimeout(); int socketTimeout = sslSocket.getSoTimeout();
if (!IS_HOSTNAME_VERIFICATION_DISABLED) {
sslSocket.setSoTimeout(connectTimeout); // reuse full timeout value SSLParameters param = sslSocket.getSSLParameters();
param.setEndpointIdentificationAlgorithm("LDAPS");
sslSocket.setSSLParameters(param);
}
if (connectTimeout > 0) {
sslSocket.setSoTimeout(connectTimeout); // reuse full timeout value
}
sslSocket.startHandshake(); sslSocket.startHandshake();
sslSocket.setSoTimeout(socketTimeout); sslSocket.setSoTimeout(socketTimeout);
} }
return socket; return socket;
} }

View File

@ -1188,7 +1188,7 @@ public interface HttpResponse<T> {
/** /**
* Returns a response subscriber which publishes the response body * 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 * <p> The {@link HttpResponse} using this subscriber is available
* immediately after the response headers have been read, without * 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -192,7 +192,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade
} }
dprintf1("-size: %d\n", size); dprintf1("-size: %d\n", size);
if (size) { if (size != 0) {
mszReaders = malloc(size); mszReaders = malloc(size);
if (mszReaders == NULL) { if (mszReaders == NULL) {
throwOutOfMemoryError(env, NULL); throwOutOfMemoryError(env, NULL);
@ -205,6 +205,8 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade
return NULL; return NULL;
} }
dprintf1("-String: %s\n", mszReaders); dprintf1("-String: %s\n", mszReaders);
} else {
return NULL;
} }
result = pcsc_multi2jstring(env, mszReaders); 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::exception_handler_for_return_address", "_aot_exception_handler_for_return_address"},
{"SharedRuntime::register_finalizer", "_aot_register_finalizer"}, {"SharedRuntime::register_finalizer", "_aot_register_finalizer"},
{"SharedRuntime::OSR_migration_end", "_aot_OSR_migration_end"}, {"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_dynamic_invoke", "_aot_resolve_dynamic_invoke"},
{"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"}, {"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"},
{"CompilerRuntime::resolve_klass_by_symbol", "_aot_resolve_klass_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) -> { 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. * Use is subject to license terms.
* *
* This library is free software; you can redistribute it and/or * 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)); group, timing));
} }
} else { } else {
kt.flag = (mp_sign)0;
if (group->meth->field_enc) { if (group->meth->field_enc) {
MP_CHECKOK(group->meth->field_enc(px, rx, group->meth)); MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
MP_CHECKOK(group->meth->field_enc(py, ry, group->meth)); MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group, timing)); MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group, timing));
} else { } else {
kt.flag = (mp_sign)0;
MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group, timing)); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -110,7 +110,7 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend {
@Override @Override
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) { 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 @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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,7 +46,7 @@ public class AArch64HotSpotDeoptimizeCallerOp extends AArch64HotSpotEpilogueOp {
@Override @Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { 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)); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,14 +24,29 @@
package org.graalvm.compiler.hotspot.aarch64; 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;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister; 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.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.aarch64.AArch64BlockEndOp; import org.graalvm.compiler.lir.aarch64.AArch64BlockEndOp;
import org.graalvm.compiler.lir.aarch64.AArch64Call;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder; import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register; import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
/** /**
* Superclass for operations that leave a method's frame. * Superclass for operations that leave a method's frame.
@ -53,9 +68,31 @@ abstract class AArch64HotSpotEpilogueOp extends AArch64BlockEndOp {
this.thread = null; // no safepoint 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"; assert crb.frameContext != null : "We never elide frames in aarch64";
crb.frameContext.leave(crb); 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) { if (emitSafepoint) {
try (ScratchRegister sc = masm.getScratchRegister()) { try (ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister(); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,10 +24,10 @@
package org.graalvm.compiler.hotspot.aarch64; 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.aarch64.AArch64.sp;
import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.asRegister;
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp; 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.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address; import org.graalvm.compiler.asm.aarch64.AArch64Address;
@ -69,7 +69,7 @@ public class AArch64HotSpotJumpToExceptionHandlerInCallerOp extends AArch64HotSp
@Override @Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
leaveFrame(crb, masm, /* emitSafepoint */false); leaveFrame(crb, masm, /* emitSafepoint */false, false);
if (GraalServices.JAVA_SPECIFICATION_VERSION < 8) { if (GraalServices.JAVA_SPECIFICATION_VERSION < 8) {
// Restore sp from fp if the exception PC is a method handle call site. // 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. * Copyright (c) 2018, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
@ -28,19 +28,18 @@ package org.graalvm.compiler.hotspot.aarch64;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; 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.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_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_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_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.INITIALIZE;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.LOAD_COUNTERS; 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.asConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue; import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
import java.util.function.Function; import java.util.function.Function;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode; import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag; 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;
import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp; import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp;
import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp; 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.AArch64RestoreRegistersOp;
import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.aarch64.AArch64; import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.aarch64.AArch64Kind; 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.RegisterValue;
import jdk.vm.ci.code.StackSlot; import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant; import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import jdk.vm.ci.hotspot.HotSpotObjectConstant; import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Constant; 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.PlatformKind;
import jdk.vm.ci.meta.SpeculationLog; import jdk.vm.ci.meta.SpeculationLog;
import jdk.vm.ci.meta.Value; import jdk.vm.ci.meta.Value;
import org.graalvm.compiler.options.OptionValues;
/** /**
* LIR generator specialized for AArch64 HotSpot. * LIR generator specialized for AArch64 HotSpot.
@ -502,7 +501,7 @@ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements H
emitMove(operand, input); emitMove(operand, input);
} }
Register thread = getProviders().getRegisters().getThreadRegister(); Register thread = getProviders().getRegisters().getThreadRegister();
append(new AArch64HotSpotReturnOp(operand, getStub() != null, config, thread)); append(new AArch64HotSpotReturnOp(operand, getStub() != null, config, thread, getResult().requiresReservedStackAccessCheck()));
} }
@Override @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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,10 +24,10 @@
package org.graalvm.compiler.hotspot.aarch64; 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.aarch64.AArch64.lr;
import static jdk.vm.ci.code.ValueUtil.asRegister; 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.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@ -48,9 +48,11 @@ public final class AArch64HotSpotReturnOp extends AArch64HotSpotEpilogueOp {
@Use({REG, ILLEGAL}) private Value result; @Use({REG, ILLEGAL}) private Value result;
private final boolean isStub; 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); super(TYPE, config, thread);
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
assert validReturnValue(result); assert validReturnValue(result);
this.result = result; this.result = result;
this.isStub = isStub; this.isStub = isStub;
@ -66,7 +68,7 @@ public final class AArch64HotSpotReturnOp extends AArch64HotSpotEpilogueOp {
@Override @Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
final boolean emitSafepoint = !isStub; final boolean emitSafepoint = !isStub;
leaveFrame(crb, masm, emitSafepoint); leaveFrame(crb, masm, emitSafepoint, requiresReservedStackAccessCheck);
masm.ret(lr); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,9 +24,9 @@
package org.graalvm.compiler.hotspot.aarch64; 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.aarch64.AArch64.lr;
import static jdk.vm.ci.code.ValueUtil.asRegister; 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.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
@ -57,7 +57,7 @@ public final class AArch64HotSpotUnwindOp extends AArch64HotSpotEpilogueOp {
@Override @Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { 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); ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
CallingConvention cc = linkage.getOutgoingCallingConvention(); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -111,7 +111,7 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend {
@Override @Override
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) { 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 @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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -268,7 +268,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
pollOnReturnScratchRegister = findPollOnReturnScratchRegister(); pollOnReturnScratchRegister = findPollOnReturnScratchRegister();
} }
Register thread = getProviders().getRegisters().getThreadRegister(); 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 @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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,18 +24,30 @@
package org.graalvm.compiler.hotspot.amd64; 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.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; 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.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode; 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.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.gen.DiagnosticLIRGeneratorTool.ZapStackArgumentSpaceBeforeInstruction; import org.graalvm.compiler.lir.gen.DiagnosticLIRGeneratorTool.ZapStackArgumentSpaceBeforeInstruction;
import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.vm.ci.amd64.AMD64.CPUFeature;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register; import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.meta.Value; import jdk.vm.ci.meta.Value;
/** /**
@ -50,20 +62,46 @@ final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueBlockEndOp implemen
private final Register thread; private final Register thread;
private final Register scratchForSafepointOnReturn; private final Register scratchForSafepointOnReturn;
private final GraalHotSpotVMConfig config; 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); super(TYPE);
this.value = value; this.value = value;
this.isStub = isStub; this.isStub = isStub;
this.thread = thread; this.thread = thread;
this.scratchForSafepointOnReturn = scratchForSafepointOnReturn; this.scratchForSafepointOnReturn = scratchForSafepointOnReturn;
this.config = config; this.config = config;
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
} }
@Override @Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
leaveFrameAndRestoreRbp(crb, masm); leaveFrameAndRestoreRbp(crb, masm);
if (!isStub) { 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. // Every non-stub compile method must have a poll before the return.
AMD64HotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, scratchForSafepointOnReturn); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -152,7 +152,7 @@ public class SPARCHotSpotBackend extends HotSpotHostBackend {
@Override @Override
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) { 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 @Override
@ -195,7 +195,9 @@ public class SPARCHotSpotBackend extends HotSpotHostBackend {
final int frameSize = crb.frameMap.totalFrameSize(); final int frameSize = crb.frameMap.totalFrameSize();
final int stackpoinerChange = -frameSize; final int stackpoinerChange = -frameSize;
SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
emitStackOverflowCheck(crb); if (!isStub) {
emitStackOverflowCheck(crb);
}
if (SPARCAssembler.isSimm13(stackpoinerChange)) { if (SPARCAssembler.isSimm13(stackpoinerChange)) {
masm.save(sp, stackpoinerChange, sp); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -194,7 +194,7 @@ public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSp
emitMove(operand, input); emitMove(operand, input);
} }
Register thread = getProviders().getRegisters().getThreadRegister(); 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 @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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,17 +24,29 @@
package org.graalvm.compiler.hotspot.sparc; 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.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; 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;
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.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode; import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder; import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.sparc.SPARCCall;
import org.graalvm.compiler.lir.sparc.SPARCControlFlow.ReturnOp; 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.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.meta.Value; 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 value;
@Use({REG, ILLEGAL}) protected Value safepointPollAddress; @Use({REG, ILLEGAL}) protected Value safepointPollAddress;
private final boolean requiresReservedStackAccessCheck;
private final boolean isStub; private final boolean isStub;
private final GraalHotSpotVMConfig config; private final GraalHotSpotVMConfig config;
private final Register thread; 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); super(TYPE, SIZE);
this.value = value; this.value = value;
this.isStub = isStub; this.isStub = isStub;
this.config = config; this.config = config;
this.thread = thread; this.thread = thread;
this.safepointPollAddress = safepointPoll; this.safepointPollAddress = safepointPoll;
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
} }
@Override @Override
public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
if (!isStub) { 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. // Every non-stub compile method must have a poll before the return.
SPARCHotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, safepointPollAddress); 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.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.List;
import org.graalvm.compiler.core.common.CompressEncoding; import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/** /**
* Used to access native configuration details. * 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 jvmciCountersThreadOffset = getFieldOffset("JavaThread::_jvmci_counters", Integer.class, "jlong*");
public final int javaThreadReservedStackActivationOffset = versioned.javaThreadReservedStackActivationOffset; 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}. * 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,6 +50,7 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.runtime.JVMCICompiler; import jdk.vm.ci.runtime.JVMCICompiler;
import org.graalvm.compiler.word.Word;
/** /**
* Common functionality of HotSpot host backends. * 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 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; protected final GraalHotSpotVMConfig config;
public HotSpotHostBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,6 +46,7 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
*/ */
private StackSlot deoptimizationRescueSlot; private StackSlot deoptimizationRescueSlot;
protected final Object stub; protected final Object stub;
private final boolean requiresReservedStackAccessCheck;
private int maxInterpreterFrameSize; private int maxInterpreterFrameSize;
@ -55,9 +56,11 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
*/ */
private EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE); 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); super(compilationId, lir, frameMapBuilder, callingConvention);
this.stub = stub; this.stub = stub;
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
} }
public EconomicMap<LIRFrameState, SaveRegistersOp> getCalleeSaveInfo() { public EconomicMap<LIRFrameState, SaveRegistersOp> getCalleeSaveInfo() {
@ -83,4 +86,8 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
public int getMaxInterpreterFrameSize() { public int getMaxInterpreterFrameSize() {
return maxInterpreterFrameSize; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -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.SAFEPOINT;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.STACK_INSPECTABLE_LEAF; 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.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.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER;
import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C; import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION; 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(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); 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_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(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); registerForeignCall(SIN.foreignCallDescriptor, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);

View File

@ -140,7 +140,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
*/ */
@Override @Override
public Content getSignature(ExecutableElement method) { 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); writer.addAnnotationInfo(method, pre);
int annotationLength = pre.charCount(); int annotationLength = pre.charCount();
addModifiers(method, pre); addModifiers(method, pre);

View File

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

View File

@ -827,7 +827,7 @@ ul.ui-autocomplete li {
margin: -100px 0 0 100px; margin: -100px 0 0 100px;
z-index: 1; z-index: 1;
} }
.details pre { .methodSignature {
white-space:normal; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -211,7 +211,7 @@ loadTransport(const char *name, TransportInfo *info)
JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm); JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm);
/* Try version 1.1 first, fallback to 1.0 on error */ /* 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); rc = (*onLoad)(jvm, &callback, supported_versions[i], &t);
if (rc != JNI_EVERSION) { if (rc != JNI_EVERSION) {
info->transportVersion = supported_versions[i]; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -2681,6 +2681,9 @@ void unpacker::attr_definitions::readBandData(int idx) {
PRINTCR((1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s", PRINTCR((1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s",
count, isRedefined(idx), isPredefined(idx), count, isRedefined(idx), isPredefined(idx),
ATTR_CONTEXT_NAME[attrc], lo->name)); ATTR_CONTEXT_NAME[attrc], lo->name));
} else {
abort("layout_definition pointer must not be NULL");
return;
} }
bool hasCallables = lo->hasCallables(); bool hasCallables = lo->hasCallables();
band** bands = lo->bands(); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -64,6 +64,9 @@ Java_com_sun_security_auth_module_UnixSystem_getUnixInfo
jclass cls; jclass cls;
numSuppGroups = getgroups(0, NULL); numSuppGroups = getgroups(0, NULL);
if (numSuppGroups == -1) {
return;
}
groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t)); groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t));
if (groups == NULL) { if (groups == NULL) {
jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError"); 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 gc/TestNUMAPageSize.java 8194949 generic-all
runtime/ReservedStack/ReservedStackTestCompiler.java 8181855 generic-all
serviceability/jvmti/GetModulesInfo/JvmtiGetAllModulesTest.java 8195156 generic-all serviceability/jvmti/GetModulesInfo/JvmtiGetAllModulesTest.java 8195156 generic-all
compiler/compilercontrol/directives/LogTest.java 8181753 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/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 8191047 generic-all
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn009/forceEarlyReturn009.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/ThreadReference/forceEarlyReturn/forceEarlyReturn007/TestDescription.java 8195600 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance001/TestDescription.java 8203174 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/newinstance002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance003/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/instances002/instances002.java 8203174 generic-all
vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.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/MonitorEvents/MonitorEvents002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/heapwalking001/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/heapwalking002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/mixed002/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/redefineclasses026/TestDescription.java 8195627 generic-all
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses028/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.CompilationWrapperTest 8205081
org.graalvm.compiler.hotspot.test.HsErrLogTest 8205081 org.graalvm.compiler.hotspot.test.HsErrLogTest 8205081
org.graalvm.compiler.hotspot.test.OptionsInFileTest 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.ClassfileBytecodeProviderTest 8205081
org.graalvm.compiler.replacements.test.classfile.RedefineIntrinsicTest 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/TestRevPtrsForInvokeDynamic.java 8191270 generic-all
serviceability/sa/sadebugd/SADebugDTest.java 8163805 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 8207765 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatRateTest.java 8205652 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 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 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 JttHotspot org.graalvm.compiler.jtt.hotspot
JttJdk org.graalvm.compiler.jtt.jdk JttJdk org.graalvm.compiler.jtt.jdk
JttLangAL org.graalvm.compiler.jtt.lang.[a-lA-L] 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] JttLangNZ org.graalvm.compiler.jtt.lang.[n-zN-Z]
JttLoop org.graalvm.compiler.jtt.loop JttLoop org.graalvm.compiler.jtt.loop
Jtt.Micro org.graalvm.compiler.jtt.micro Jtt.Micro org.graalvm.compiler.jtt.micro
JttOptimize org.graalvm.compiler.jtt.optimize JttOptimize org.graalvm.compiler.jtt.optimize
JttReflectAE org.graalvm.compiler.jtt.reflect.[a-eA-E] 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] JttReflectGZ org.graalvm.compiler.jtt.reflect.[g-zG-Z]
JttThreads org.graalvm.compiler.jtt.threads JttThreads org.graalvm.compiler.jtt.threads
LirJtt org.graalvm.compiler.lir.jtt 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); 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(" "); String[] lines = out.getStdout().split(" ");
if (lines.length > 1) { // first line contains jar file name if (lines.length > 1) { // first line contains jar file name
for (int i = 1; i < lines.length; i++) { for (int i = 1; i < lines.length; i++) {

View File

@ -130,7 +130,7 @@ public class TestRTMAbortRatio {
@Override @Override
public String[] getMethodsToCompileNames() { public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName() }; return new String[] { getMethodWithLockName(), "*.pageSize" };
} }
public void lock(boolean abort) { 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.Asserts;
import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.Platform;
import java.util.List; import java.util.List;
@ -59,11 +60,18 @@ public class TestRTMSpinLoopCount {
private static final int RTM_RETRY_COUNT = 1000; private static final int RTM_RETRY_COUNT = 1000;
private static final boolean INFLATE_MONITOR = true; private static final boolean INFLATE_MONITOR = true;
private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L; private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L;
private static final int[] SPIN_LOOP_COUNTS private static int[] SPIN_LOOP_COUNTS;
= new int[] { 0, 100, 1_000, 10_000, 100_000 };
protected void runTestCases() throws Throwable { 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]; long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length];
for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) { for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) {
aborts[i] = getAbortsCountOnLockBusy( aborts[i] = getAbortsCountOnLockBusy(
TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]); TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]);

View File

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

View File

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

View File

@ -25,7 +25,7 @@ package MyPackage;
/** /**
* @test * @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 * @build Frame HeapMonitor
* @compile HeapMonitorIllegalArgumentTest.java * @compile HeapMonitorIllegalArgumentTest.java
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorIllegalArgumentTest * @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorIllegalArgumentTest

View File

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

View File

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

View File

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

View File

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

View File

@ -62,10 +62,10 @@ public class HeapMonitorVMEventsTest implements Cloneable {
double diff = Math.abs(first - second) * 100; double diff = Math.abs(first - second) * 100;
diff /= first; 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. // case other items are getting allocated during the test.
if (diff > 10) { 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); + ": " + first + " , " + second);
} }
} }

View File

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

View File

@ -52,6 +52,7 @@
* referrers with supported type(Strong, PhantomReference, SoftReference, WeakReference) * referrers with supported type(Strong, PhantomReference, SoftReference, WeakReference)
* *
* @requires vm.gc != "Z" * @requires vm.gc != "Z"
* @requires !vm.graal.enabled
* @library /vmTestbase * @library /vmTestbase
* /test/lib * /test/lib
* @run driver jdk.test.lib.FileInstaller . . * @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 * 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 * just test disableCollection/enableCollection don't throw any unexpected exceptions
* *
* @requires !vm.graal.enabled
* @library /vmTestbase * @library /vmTestbase
* /test/lib * /test/lib
* @run driver jdk.test.lib.FileInstaller . . * @run driver jdk.test.lib.FileInstaller . .

View File

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

View File

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

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