Merge
This commit is contained in:
commit
28e828130d
1
.hgtags
1
.hgtags
@ -496,5 +496,6 @@ e1b3def126240d5433902f3cb0e91a4c27f6db50 jdk-11+18
|
||||
14708e1acdc3974f4539027cbbcfa6d69f83cf51 jdk-11+21
|
||||
00b16d0457e43d23f6ca5ade6b243edce62750a0 jdk-12+1
|
||||
9937ef7499dcd7673714517fd5e450410c14ba4e jdk-11+22
|
||||
1edcf36fe15f79d6228d1a63eb680878e2386480 jdk-11+23
|
||||
69b438908512d3dfef5852c6a843a5778333a309 jdk-12+2
|
||||
990db216e7199b2ba9989d8fa20b657e0ca7d969 jdk-12+3
|
||||
|
@ -24,9 +24,6 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "c1/c1_LIRAssembler.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
#include "gc/g1/c1/g1BarrierSetC1.hpp"
|
||||
#include "gc/g1/g1BarrierSet.hpp"
|
||||
#include "gc/g1/g1BarrierSetAssembler.hpp"
|
||||
#include "gc/g1/g1BarrierSetRuntime.hpp"
|
||||
@ -38,6 +35,11 @@
|
||||
#include "runtime/thread.hpp"
|
||||
#include "interpreter/interp_masm.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#ifdef COMPILER1
|
||||
#include "c1/c1_LIRAssembler.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
#include "gc/g1/c1/g1BarrierSetC1.hpp"
|
||||
#endif
|
||||
|
||||
#define __ masm->
|
||||
|
||||
|
@ -739,13 +739,21 @@ address MacroAssembler::trampoline_call(Address entry, CodeBuffer *cbuf) {
|
||||
|| entry.rspec().type() == relocInfo::static_call_type
|
||||
|| entry.rspec().type() == relocInfo::virtual_call_type, "wrong reloc type");
|
||||
|
||||
unsigned int start_offset = offset();
|
||||
if (far_branches() && !Compile::current()->in_scratch_emit_size()) {
|
||||
address stub = emit_trampoline_stub(start_offset, entry.target());
|
||||
// We need a trampoline if branches are far.
|
||||
if (far_branches()) {
|
||||
// We don't want to emit a trampoline if C2 is generating dummy
|
||||
// code during its branch shortening phase.
|
||||
CompileTask* task = ciEnv::current()->task();
|
||||
bool in_scratch_emit_size =
|
||||
(task != NULL && is_c2_compile(task->comp_level()) &&
|
||||
Compile::current()->in_scratch_emit_size());
|
||||
if (!in_scratch_emit_size) {
|
||||
address stub = emit_trampoline_stub(offset(), entry.target());
|
||||
if (stub == NULL) {
|
||||
return NULL; // CodeCache is full
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cbuf) cbuf->set_insts_mark();
|
||||
relocate(entry.rspec());
|
||||
|
@ -1635,6 +1635,7 @@ class Assembler : public AbstractAssembler {
|
||||
// TEXASR bit description
|
||||
enum transaction_failure_reason {
|
||||
// Upper half (TEXASRU):
|
||||
tm_failure_code = 0, // The Failure Code is copied from tabort or treclaim operand.
|
||||
tm_failure_persistent = 7, // The failure is likely to recur on each execution.
|
||||
tm_disallowed = 8, // The instruction is not permitted.
|
||||
tm_nesting_of = 9, // The maximum transaction level was exceeded.
|
||||
@ -1650,6 +1651,7 @@ class Assembler : public AbstractAssembler {
|
||||
tm_failure_summary = 36, // Failure has been detected and recorded.
|
||||
tm_tfiar_exact = 37, // Value in the TFIAR is exact.
|
||||
tm_rot = 38, // Rollback-only transaction.
|
||||
tm_transaction_level = 52, // Transaction level (nesting depth + 1).
|
||||
};
|
||||
|
||||
// PPC 1, section 2.4.1 Branch Instructions
|
||||
|
@ -2412,7 +2412,7 @@ void MacroAssembler::atomic_ori_int(Register addr, Register result, int uimm16)
|
||||
|
||||
// Update rtm_counters based on abort status
|
||||
// input: abort_status
|
||||
// rtm_counters (RTMLockingCounters*)
|
||||
// rtm_counters_Reg (RTMLockingCounters*)
|
||||
void MacroAssembler::rtm_counters_update(Register abort_status, Register rtm_counters_Reg) {
|
||||
// Mapping to keep PreciseRTMLockingStatistics similar to x86.
|
||||
// x86 ppc (! means inverted, ? means not the same)
|
||||
@ -2422,52 +2422,96 @@ void MacroAssembler::rtm_counters_update(Register abort_status, Register rtm_cou
|
||||
// 3 10 Set if an internal buffer overflowed.
|
||||
// 4 ?12 Set if a debug breakpoint was hit.
|
||||
// 5 ?32 Set if an abort occurred during execution of a nested transaction.
|
||||
const int tm_failure_bit[] = {Assembler::tm_tabort, // Note: Seems like signal handler sets this, too.
|
||||
Assembler::tm_failure_persistent, // inverted: transient
|
||||
Assembler::tm_trans_cf,
|
||||
Assembler::tm_footprint_of,
|
||||
Assembler::tm_non_trans_cf,
|
||||
Assembler::tm_suspended};
|
||||
const bool tm_failure_inv[] = {false, true, false, false, false, false};
|
||||
assert(sizeof(tm_failure_bit)/sizeof(int) == RTMLockingCounters::ABORT_STATUS_LIMIT, "adapt mapping!");
|
||||
const int failure_bit[] = {tm_tabort, // Signal handler will set this too.
|
||||
tm_failure_persistent,
|
||||
tm_non_trans_cf,
|
||||
tm_trans_cf,
|
||||
tm_footprint_of,
|
||||
tm_failure_code,
|
||||
tm_transaction_level};
|
||||
|
||||
const Register addr_Reg = R0;
|
||||
// Keep track of offset to where rtm_counters_Reg had pointed to.
|
||||
const int num_failure_bits = sizeof(failure_bit) / sizeof(int);
|
||||
const int num_counters = RTMLockingCounters::ABORT_STATUS_LIMIT;
|
||||
|
||||
const int bit2counter_map[][num_counters] =
|
||||
// 0 = no map; 1 = mapped, no inverted logic; -1 = mapped, inverted logic
|
||||
// Inverted logic means that if a bit is set don't count it, or vice-versa.
|
||||
// Care must be taken when mapping bits to counters as bits for a given
|
||||
// counter must be mutually exclusive. Otherwise, the counter will be
|
||||
// incremented more than once.
|
||||
// counters:
|
||||
// 0 1 2 3 4 5
|
||||
// abort , persist, conflict, overflow, debug , nested bits:
|
||||
{{ 1 , 0 , 0 , 0 , 0 , 0 }, // abort
|
||||
{ 0 , -1 , 0 , 0 , 0 , 0 }, // failure_persistent
|
||||
{ 0 , 0 , 1 , 0 , 0 , 0 }, // non_trans_cf
|
||||
{ 0 , 0 , 1 , 0 , 0 , 0 }, // trans_cf
|
||||
{ 0 , 0 , 0 , 1 , 0 , 0 }, // footprint_of
|
||||
{ 0 , 0 , 0 , 0 , -1 , 0 }, // failure_code = 0xD4
|
||||
{ 0 , 0 , 0 , 0 , 0 , 1 }}; // transaction_level > 1
|
||||
// ...
|
||||
|
||||
// Move abort_status value to R0 and use abort_status register as a
|
||||
// temporary register because R0 as third operand in ld/std is treated
|
||||
// as base address zero (value). Likewise, R0 as second operand in addi
|
||||
// is problematic because it amounts to li.
|
||||
const Register temp_Reg = abort_status;
|
||||
const Register abort_status_R0 = R0;
|
||||
mr(abort_status_R0, abort_status);
|
||||
|
||||
// Increment total abort counter.
|
||||
int counters_offs = RTMLockingCounters::abort_count_offset();
|
||||
addi(addr_Reg, rtm_counters_Reg, counters_offs);
|
||||
const Register temp_Reg = rtm_counters_Reg;
|
||||
|
||||
//atomic_inc_ptr(addr_Reg, temp_Reg); We don't increment atomically
|
||||
ldx(temp_Reg, addr_Reg);
|
||||
ld(temp_Reg, counters_offs, rtm_counters_Reg);
|
||||
addi(temp_Reg, temp_Reg, 1);
|
||||
stdx(temp_Reg, addr_Reg);
|
||||
std(temp_Reg, counters_offs, rtm_counters_Reg);
|
||||
|
||||
// Increment specific abort counters.
|
||||
if (PrintPreciseRTMLockingStatistics) {
|
||||
int counters_offs_delta = RTMLockingCounters::abortX_count_offset() - counters_offs;
|
||||
|
||||
//mftexasr(abort_status); done by caller
|
||||
for (int i = 0; i < RTMLockingCounters::ABORT_STATUS_LIMIT; i++) {
|
||||
counters_offs += counters_offs_delta;
|
||||
li(temp_Reg, counters_offs_delta); // can't use addi with R0
|
||||
add(addr_Reg, addr_Reg, temp_Reg); // point to next counter
|
||||
counters_offs_delta = sizeof(uintx);
|
||||
// #0 counter offset.
|
||||
int abortX_offs = RTMLockingCounters::abortX_count_offset();
|
||||
|
||||
for (int nbit = 0; nbit < num_failure_bits; nbit++) {
|
||||
for (int ncounter = 0; ncounter < num_counters; ncounter++) {
|
||||
if (bit2counter_map[nbit][ncounter] != 0) {
|
||||
Label check_abort;
|
||||
rldicr_(temp_Reg, abort_status, tm_failure_bit[i], 0);
|
||||
if (tm_failure_inv[i]) {
|
||||
bne(CCR0, check_abort);
|
||||
int abort_counter_offs = abortX_offs + (ncounter << 3);
|
||||
|
||||
if (failure_bit[nbit] == tm_transaction_level) {
|
||||
// Don't check outer transaction, TL = 1 (bit 63). Hence only
|
||||
// 11 bits in the TL field are checked to find out if failure
|
||||
// occured in a nested transaction. This check also matches
|
||||
// the case when nesting_of = 1 (nesting overflow).
|
||||
rldicr_(temp_Reg, abort_status_R0, failure_bit[nbit], 10);
|
||||
} else if (failure_bit[nbit] == tm_failure_code) {
|
||||
// Check failure code for trap or illegal caught in TM.
|
||||
// Bits 0:7 are tested as bit 7 (persistent) is copied from
|
||||
// tabort or treclaim source operand.
|
||||
// On Linux: trap or illegal is TM_CAUSE_SIGNAL (0xD4).
|
||||
rldicl(temp_Reg, abort_status_R0, 8, 56);
|
||||
cmpdi(CCR0, temp_Reg, 0xD4);
|
||||
} else {
|
||||
beq(CCR0, check_abort);
|
||||
rldicr_(temp_Reg, abort_status_R0, failure_bit[nbit], 0);
|
||||
}
|
||||
//atomic_inc_ptr(addr_Reg, temp_Reg); We don't increment atomically
|
||||
ldx(temp_Reg, addr_Reg);
|
||||
|
||||
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);
|
||||
stdx(temp_Reg, addr_Reg);
|
||||
std(temp_Reg, abort_counter_offs, rtm_counters_Reg);
|
||||
|
||||
bind(check_abort);
|
||||
}
|
||||
}
|
||||
li(temp_Reg, -counters_offs); // can't use addi with R0
|
||||
add(rtm_counters_Reg, addr_Reg, temp_Reg); // restore
|
||||
}
|
||||
}
|
||||
// Restore abort_status.
|
||||
mr(abort_status, abort_status_R0);
|
||||
}
|
||||
|
||||
// Branch if (random & (count-1) != 0), count is 2^n
|
||||
@ -2569,8 +2613,28 @@ void MacroAssembler::rtm_profiling(Register abort_status_Reg, Register temp_Reg,
|
||||
void MacroAssembler::rtm_retry_lock_on_abort(Register retry_count_Reg, Register abort_status_Reg,
|
||||
Label& retryLabel, Label* checkRetry) {
|
||||
Label doneRetry;
|
||||
|
||||
// Don't retry if failure is persistent.
|
||||
// The persistent bit is set when a (A) Disallowed operation is performed in
|
||||
// transactional state, like for instance trying to write the TFHAR after a
|
||||
// transaction is started; or when there is (B) a Nesting Overflow (too many
|
||||
// nested transactions); or when (C) the Footprint overflows (too many
|
||||
// addressess touched in TM state so there is no more space in the footprint
|
||||
// area to track them); or in case of (D) a Self-Induced Conflict, i.e. a
|
||||
// store is performed to a given address in TM state, then once in suspended
|
||||
// state the same address is accessed. Failure (A) is very unlikely to occur
|
||||
// in the JVM. Failure (D) will never occur because Suspended state is never
|
||||
// used in the JVM. Thus mostly (B) a Nesting Overflow or (C) a Footprint
|
||||
// Overflow will set the persistent bit.
|
||||
rldicr_(R0, abort_status_Reg, tm_failure_persistent, 0);
|
||||
bne(CCR0, doneRetry);
|
||||
|
||||
// Don't retry if transaction was deliberately aborted, i.e. caused by a
|
||||
// tabort instruction.
|
||||
rldicr_(R0, abort_status_Reg, tm_tabort, 0);
|
||||
bne(CCR0, doneRetry);
|
||||
|
||||
// Retry if transaction aborted due to a conflict with another thread.
|
||||
if (checkRetry) { bind(*checkRetry); }
|
||||
addic_(retry_count_Reg, retry_count_Reg, -1);
|
||||
blt(CCR0, doneRetry);
|
||||
|
@ -2029,6 +2029,13 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
// --------------------------------------------------------------------------
|
||||
vep_start_pc = (intptr_t)__ pc();
|
||||
|
||||
if (UseRTMLocking) {
|
||||
// Abort RTM transaction before calling JNI
|
||||
// because critical section can be large and
|
||||
// abort anyway. Also nmethod can be deoptimized.
|
||||
__ tabort_();
|
||||
}
|
||||
|
||||
__ save_LR_CR(r_temp_1);
|
||||
__ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
|
||||
__ mr(r_callers_sp, R1_SP); // Remember frame pointer.
|
||||
@ -2947,6 +2954,11 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer);
|
||||
address start = __ pc();
|
||||
|
||||
if (UseRTMLocking) {
|
||||
// Abort RTM transaction before possible nmethod deoptimization.
|
||||
__ tabort_();
|
||||
}
|
||||
|
||||
Register unroll_block_reg = R21_tmp1;
|
||||
Register klass_index_reg = R22_tmp2;
|
||||
Register unc_trap_reg = R23_tmp3;
|
||||
@ -3090,6 +3102,13 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||
return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc;
|
||||
}
|
||||
|
||||
if (UseRTMLocking) {
|
||||
// Abort RTM transaction before calling runtime
|
||||
// because critical section can be large and so
|
||||
// will abort anyway. Also nmethod can be deoptimized.
|
||||
__ tabort_();
|
||||
}
|
||||
|
||||
// Save registers, fpu state, and flags. Set R31 = return pc.
|
||||
map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
|
||||
&frame_size_in_bytes,
|
||||
|
@ -49,16 +49,3 @@ void MiscUtils::leave_critsect(MiscUtils::critsect_t* cs) {
|
||||
const int rc = pthread_mutex_unlock(cs);
|
||||
assert0(rc == 0);
|
||||
}
|
||||
|
||||
bool MiscUtils::is_readable_pointer(const void* p) {
|
||||
if (!CanUseSafeFetch32()) {
|
||||
return true;
|
||||
}
|
||||
int* const aligned = (int*) align_down(p, 4);
|
||||
int cafebabe = 0xcafebabe;
|
||||
int deadbeef = 0xdeadbeef;
|
||||
return (SafeFetch32(aligned, cafebabe) != cafebabe) ||
|
||||
(SafeFetch32(aligned, deadbeef) != deadbeef);
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,13 +88,6 @@ namespace MiscUtils {
|
||||
_pcsobj->leave();
|
||||
}
|
||||
};
|
||||
|
||||
// Returns true if pointer can be dereferenced without triggering a segment
|
||||
// violation. Returns false if pointer is invalid.
|
||||
// Note: Depends on stub routines; prior to stub routine generation, will
|
||||
// always return true. Use CanUseSafeFetch32 to handle this case.
|
||||
bool is_readable_pointer(const void* p);
|
||||
|
||||
}
|
||||
|
||||
#endif // OS_AIX_VM_MISC_AIX_HPP
|
||||
|
@ -142,7 +142,7 @@ bool AixSymbols::get_function_name (
|
||||
// in that case I try reading the traceback table unsafe - I rather risk secondary crashes in
|
||||
// error files than not having a callstack.)
|
||||
#define CHECK_POINTER_READABLE(p) \
|
||||
if (!MiscUtils::is_readable_pointer(p)) { \
|
||||
if (!os::is_readable_pointer(p)) { \
|
||||
trcVerbose("pc not readable"); \
|
||||
return false; \
|
||||
}
|
||||
@ -230,7 +230,7 @@ bool AixSymbols::get_function_name (
|
||||
const short l = MIN2<short>(*((short*)pc2), namelen - 1);
|
||||
// Be very careful.
|
||||
int i = 0; char* const p = (char*)pc2 + sizeof(short);
|
||||
while (i < l && MiscUtils::is_readable_pointer(p + i)) {
|
||||
while (i < l && os::is_readable_pointer(p + i)) {
|
||||
p_name[i] = p[i];
|
||||
i++;
|
||||
}
|
||||
@ -489,7 +489,7 @@ static void print_info_for_pc (outputStream* st, codeptr_t pc, char* buf,
|
||||
const struct tbtable* tb = NULL;
|
||||
int displacement = -1;
|
||||
|
||||
if (!MiscUtils::is_readable_pointer(pc)) {
|
||||
if (!os::is_readable_pointer(pc)) {
|
||||
st->print("(invalid)");
|
||||
return;
|
||||
}
|
||||
@ -697,7 +697,7 @@ void AixNativeCallstack::print_callstack_for_context(outputStream* st, const uco
|
||||
print_info_for_pc(st, cur_iar, buf, buf_size, demangle);
|
||||
st->cr();
|
||||
|
||||
if (cur_iar && MiscUtils::is_readable_pointer(cur_iar)) {
|
||||
if (cur_iar && os::is_readable_pointer(cur_iar)) {
|
||||
decode_instructions_at_pc(
|
||||
"Decoded instructions at iar:",
|
||||
cur_iar, 32, 16, st);
|
||||
@ -710,7 +710,7 @@ void AixNativeCallstack::print_callstack_for_context(outputStream* st, const uco
|
||||
print_info_for_pc(st, cur_lr, buf, buf_size, demangle);
|
||||
st->cr();
|
||||
|
||||
if (cur_lr && MiscUtils::is_readable_pointer(cur_lr)) {
|
||||
if (cur_lr && os::is_readable_pointer(cur_lr)) {
|
||||
decode_instructions_at_pc(
|
||||
"Decoded instructions at lr:",
|
||||
cur_lr, 32, 16, st);
|
||||
@ -729,7 +729,7 @@ void AixNativeCallstack::print_callstack_for_context(outputStream* st, const uco
|
||||
// Check and print rtoc.
|
||||
st->print("rtoc: " PTR64_FORMAT " ", p2i(cur_rtoc));
|
||||
if (cur_rtoc == NULL || cur_rtoc == (codeptr_t)-1 ||
|
||||
!MiscUtils::is_readable_pointer(cur_rtoc)) {
|
||||
!os::is_readable_pointer(cur_rtoc)) {
|
||||
st->print("(invalid)");
|
||||
} else if (((uintptr_t)cur_rtoc) & 0x7) {
|
||||
st->print("(unaligned)");
|
||||
|
@ -603,7 +603,9 @@ void os::print_register_info(outputStream *st, const void *context) {
|
||||
st->print_cr("Register to memory mapping:");
|
||||
st->cr();
|
||||
|
||||
// this is only for the "general purpose" registers
|
||||
st->print("pc ="); print_location(st, (intptr_t)uc->uc_mcontext.regs->nip);
|
||||
st->print("lr ="); print_location(st, (intptr_t)uc->uc_mcontext.regs->link);
|
||||
st->print("ctr ="); print_location(st, (intptr_t)uc->uc_mcontext.regs->ctr);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
st->print("r%-2d=", i);
|
||||
print_location(st, uc->uc_mcontext.regs->gpr[i]);
|
||||
|
@ -628,7 +628,19 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context) {
|
||||
st->print("Not ported\n");
|
||||
if (context == NULL) return;
|
||||
|
||||
const ucontext_t *uc = (const ucontext_t*)context;
|
||||
|
||||
st->print_cr("Register to memory mapping:");
|
||||
st->cr();
|
||||
|
||||
st->print("pc ="); print_location(st, (intptr_t)uc->uc_mcontext.psw.addr);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
st->print("r%-2d=", i);
|
||||
print_location(st, uc->uc_mcontext.gregs[i]);
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
@ -450,6 +450,7 @@ void AOTCodeHeap::link_shared_runtime_symbols() {
|
||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_object_notify", address, JVMCIRuntime::object_notify);
|
||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_object_notifyAll", address, JVMCIRuntime::object_notifyAll);
|
||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_OSR_migration_end", address, SharedRuntime::OSR_migration_end);
|
||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_enable_stack_reserved_zone", address, SharedRuntime::enable_stack_reserved_zone);
|
||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_dynamic_invoke", address, CompilerRuntime::resolve_dynamic_invoke);
|
||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_string_by_symbol", address, CompilerRuntime::resolve_string_by_symbol);
|
||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_klass_by_symbol", address, CompilerRuntime::resolve_klass_by_symbol);
|
||||
|
@ -117,8 +117,9 @@
|
||||
_outbuf->print("%s", termString);
|
||||
#endif
|
||||
|
||||
const char blobTypeChar[] = {' ', 'N', 'I', 'X', 'Z', 'U', 'R', '?', 'D', 'T', 'E', 'S', 'A', 'M', 'B', 'L' };
|
||||
const char blobTypeChar[] = {' ', 'C', 'N', 'I', 'X', 'Z', 'U', 'R', '?', 'D', 'T', 'E', 'S', 'A', 'M', 'B', 'L' };
|
||||
const char* blobTypeName[] = {"noType"
|
||||
, "nMethod (under construction)"
|
||||
, "nMethod (active)"
|
||||
, "nMethod (inactive)"
|
||||
, "nMethod (deopt)"
|
||||
@ -156,7 +157,8 @@ static unsigned int nBlocks_t1 = 0; // counting "in_use" nmethods on
|
||||
static unsigned int nBlocks_t2 = 0; // counting "in_use" nmethods only.
|
||||
static unsigned int nBlocks_alive = 0; // counting "not_used" and "not_entrant" nmethods only.
|
||||
static unsigned int nBlocks_dead = 0; // counting "zombie" and "unloaded" methods only.
|
||||
static unsigned int nBlocks_unloaded = 0; // counting "unloaded" nmethods only. This is a transien state.
|
||||
static unsigned int nBlocks_inconstr = 0; // counting "inconstruction" nmethods only. This is a transient state.
|
||||
static unsigned int nBlocks_unloaded = 0; // counting "unloaded" nmethods only. This is a transient state.
|
||||
static unsigned int nBlocks_stub = 0;
|
||||
|
||||
static struct FreeBlk* FreeArray = NULL;
|
||||
@ -226,6 +228,7 @@ void CodeHeapState::get_HeapStatGlobals(outputStream* out, const char* heapName)
|
||||
nBlocks_t2 = CodeHeapStatArray[ix].nBlocks_t2;
|
||||
nBlocks_alive = CodeHeapStatArray[ix].nBlocks_alive;
|
||||
nBlocks_dead = CodeHeapStatArray[ix].nBlocks_dead;
|
||||
nBlocks_inconstr = CodeHeapStatArray[ix].nBlocks_inconstr;
|
||||
nBlocks_unloaded = CodeHeapStatArray[ix].nBlocks_unloaded;
|
||||
nBlocks_stub = CodeHeapStatArray[ix].nBlocks_stub;
|
||||
FreeArray = CodeHeapStatArray[ix].FreeArray;
|
||||
@ -248,6 +251,7 @@ void CodeHeapState::get_HeapStatGlobals(outputStream* out, const char* heapName)
|
||||
nBlocks_t2 = 0;
|
||||
nBlocks_alive = 0;
|
||||
nBlocks_dead = 0;
|
||||
nBlocks_inconstr = 0;
|
||||
nBlocks_unloaded = 0;
|
||||
nBlocks_stub = 0;
|
||||
FreeArray = NULL;
|
||||
@ -274,6 +278,7 @@ void CodeHeapState::set_HeapStatGlobals(outputStream* out, const char* heapName)
|
||||
CodeHeapStatArray[ix].nBlocks_t2 = nBlocks_t2;
|
||||
CodeHeapStatArray[ix].nBlocks_alive = nBlocks_alive;
|
||||
CodeHeapStatArray[ix].nBlocks_dead = nBlocks_dead;
|
||||
CodeHeapStatArray[ix].nBlocks_inconstr = nBlocks_inconstr;
|
||||
CodeHeapStatArray[ix].nBlocks_unloaded = nBlocks_unloaded;
|
||||
CodeHeapStatArray[ix].nBlocks_stub = nBlocks_stub;
|
||||
CodeHeapStatArray[ix].FreeArray = FreeArray;
|
||||
@ -554,6 +559,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
nBlocks_t2 = 0;
|
||||
nBlocks_alive = 0;
|
||||
nBlocks_dead = 0;
|
||||
nBlocks_inconstr = 0;
|
||||
nBlocks_unloaded = 0;
|
||||
nBlocks_stub = 0;
|
||||
|
||||
@ -587,6 +593,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
size_t disconnSpace = 0;
|
||||
size_t notentrSpace = 0;
|
||||
size_t deadSpace = 0;
|
||||
size_t inconstrSpace = 0;
|
||||
size_t unloadedSpace = 0;
|
||||
size_t stubSpace = 0;
|
||||
size_t freeSpace = 0;
|
||||
@ -692,6 +699,10 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
nBlocks_dead++;
|
||||
deadSpace += hb_bytelen;
|
||||
break;
|
||||
case nMethod_inconstruction:
|
||||
nBlocks_inconstr++;
|
||||
inconstrSpace += hb_bytelen;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -846,6 +857,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
StatArray[ix_beg].level = comp_lvl;
|
||||
StatArray[ix_beg].compiler = cType;
|
||||
break;
|
||||
case nMethod_inconstruction: // let's count "in construction" nmethods here.
|
||||
case nMethod_alive:
|
||||
StatArray[ix_beg].tx_count++;
|
||||
StatArray[ix_beg].tx_space += (unsigned short)hb_len;
|
||||
@ -902,6 +914,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
StatArray[ix_end].level = comp_lvl;
|
||||
StatArray[ix_end].compiler = cType;
|
||||
break;
|
||||
case nMethod_inconstruction: // let's count "in construction" nmethods here.
|
||||
case nMethod_alive:
|
||||
StatArray[ix_beg].tx_count++;
|
||||
StatArray[ix_beg].tx_space += (unsigned short)beg_space;
|
||||
@ -949,6 +962,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
StatArray[ix].level = comp_lvl;
|
||||
StatArray[ix].compiler = cType;
|
||||
break;
|
||||
case nMethod_inconstruction: // let's count "in construction" nmethods here.
|
||||
case nMethod_alive:
|
||||
StatArray[ix].tx_count++;
|
||||
StatArray[ix].tx_space += (unsigned short)(granule_size>>log2_seg_size);
|
||||
@ -971,11 +985,6 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n_methods > 0) {
|
||||
avgTemp = hotnessAccumulator/n_methods;
|
||||
} else {
|
||||
avgTemp = 0;
|
||||
}
|
||||
done = true;
|
||||
|
||||
if (!insane) {
|
||||
@ -990,6 +999,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
ast->print_cr(" Alive Space = " SIZE_FORMAT_W(8) "k, nBlocks_alive = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", aliveSpace/(size_t)K, nBlocks_alive, (100.0*aliveSpace)/size, (100.0*aliveSpace)/res_size);
|
||||
ast->print_cr(" disconnected = " SIZE_FORMAT_W(8) "k, nBlocks_disconn = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", disconnSpace/(size_t)K, nBlocks_disconn, (100.0*disconnSpace)/size, (100.0*disconnSpace)/res_size);
|
||||
ast->print_cr(" not entrant = " SIZE_FORMAT_W(8) "k, nBlocks_notentr = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", notentrSpace/(size_t)K, nBlocks_notentr, (100.0*notentrSpace)/size, (100.0*notentrSpace)/res_size);
|
||||
ast->print_cr(" inconstrSpace = " SIZE_FORMAT_W(8) "k, nBlocks_inconstr = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", inconstrSpace/(size_t)K, nBlocks_inconstr, (100.0*inconstrSpace)/size, (100.0*inconstrSpace)/res_size);
|
||||
ast->print_cr(" unloadedSpace = " SIZE_FORMAT_W(8) "k, nBlocks_unloaded = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", unloadedSpace/(size_t)K, nBlocks_unloaded, (100.0*unloadedSpace)/size, (100.0*unloadedSpace)/res_size);
|
||||
ast->print_cr(" deadSpace = " SIZE_FORMAT_W(8) "k, nBlocks_dead = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", deadSpace/(size_t)K, nBlocks_dead, (100.0*deadSpace)/size, (100.0*deadSpace)/res_size);
|
||||
ast->print_cr(" stubSpace = " SIZE_FORMAT_W(8) "k, nBlocks_stub = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", stubSpace/(size_t)K, nBlocks_stub, (100.0*stubSpace)/size, (100.0*stubSpace)/res_size);
|
||||
@ -1009,9 +1019,15 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
printBox(ast, '-', "Method hotness information at time of this analysis", NULL);
|
||||
ast->print_cr("Highest possible method temperature: %12d", reset_val);
|
||||
ast->print_cr("Threshold for method to be considered 'cold': %12.3f", -reset_val + reverse_free_ratio * NmethodSweepActivity);
|
||||
if (n_methods > 0) {
|
||||
avgTemp = hotnessAccumulator/n_methods;
|
||||
ast->print_cr("min. hotness = %6d", minTemp);
|
||||
ast->print_cr("avg. hotness = %6d", avgTemp);
|
||||
ast->print_cr("max. hotness = %6d", maxTemp);
|
||||
} else {
|
||||
avgTemp = 0;
|
||||
ast->print_cr("No hotness data available");
|
||||
}
|
||||
STRINGSTREAM_FLUSH("\n")
|
||||
|
||||
// This loop is intentionally printing directly to "out".
|
||||
@ -1024,6 +1040,9 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
if (StatArray[ix].t2_count > granule_segs) {
|
||||
out->print_cr("t2_count[%d] = %d", ix, StatArray[ix].t2_count);
|
||||
}
|
||||
if (StatArray[ix].tx_count > granule_segs) {
|
||||
out->print_cr("tx_count[%d] = %d", ix, StatArray[ix].tx_count);
|
||||
}
|
||||
if (StatArray[ix].stub_count > granule_segs) {
|
||||
out->print_cr("stub_count[%d] = %d", ix, StatArray[ix].stub_count);
|
||||
}
|
||||
@ -1036,6 +1055,9 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
if (StatArray[ix].t2_space > granule_segs) {
|
||||
out->print_cr("t2_space[%d] = %d", ix, StatArray[ix].t2_space);
|
||||
}
|
||||
if (StatArray[ix].tx_space > granule_segs) {
|
||||
out->print_cr("tx_space[%d] = %d", ix, StatArray[ix].tx_space);
|
||||
}
|
||||
if (StatArray[ix].stub_space > granule_segs) {
|
||||
out->print_cr("stub_space[%d] = %d", ix, StatArray[ix].stub_space);
|
||||
}
|
||||
@ -1043,11 +1065,11 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, const char* gra
|
||||
out->print_cr("dead_space[%d] = %d", ix, StatArray[ix].dead_space);
|
||||
}
|
||||
// this cast is awful! I need it because NT/Intel reports a signed/unsigned mismatch.
|
||||
if ((size_t)(StatArray[ix].t1_count+StatArray[ix].t2_count+StatArray[ix].stub_count+StatArray[ix].dead_count) > granule_segs) {
|
||||
out->print_cr("t1_count[%d] = %d, t2_count[%d] = %d, stub_count[%d] = %d", ix, StatArray[ix].t1_count, ix, StatArray[ix].t2_count, ix, StatArray[ix].stub_count);
|
||||
if ((size_t)(StatArray[ix].t1_count+StatArray[ix].t2_count+StatArray[ix].tx_count+StatArray[ix].stub_count+StatArray[ix].dead_count) > granule_segs) {
|
||||
out->print_cr("t1_count[%d] = %d, t2_count[%d] = %d, tx_count[%d] = %d, stub_count[%d] = %d", ix, StatArray[ix].t1_count, ix, StatArray[ix].t2_count, ix, StatArray[ix].tx_count, ix, StatArray[ix].stub_count);
|
||||
}
|
||||
if ((size_t)(StatArray[ix].t1_space+StatArray[ix].t2_space+StatArray[ix].stub_space+StatArray[ix].dead_space) > granule_segs) {
|
||||
out->print_cr("t1_space[%d] = %d, t2_space[%d] = %d, stub_space[%d] = %d", ix, StatArray[ix].t1_space, ix, StatArray[ix].t2_space, ix, StatArray[ix].stub_space);
|
||||
if ((size_t)(StatArray[ix].t1_space+StatArray[ix].t2_space+StatArray[ix].tx_space+StatArray[ix].stub_space+StatArray[ix].dead_space) > granule_segs) {
|
||||
out->print_cr("t1_space[%d] = %d, t2_space[%d] = %d, tx_space[%d] = %d, stub_space[%d] = %d", ix, StatArray[ix].t1_space, ix, StatArray[ix].t2_space, ix, StatArray[ix].tx_space, ix, StatArray[ix].stub_space);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1263,7 +1285,8 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
|
||||
ast->fill_to(67+6);
|
||||
if (nm->is_in_use()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
|
||||
if (nm->is_not_entrant()) {blob_name = nm->method()->name_and_sig_as_C_string(); }
|
||||
if (nm->is_zombie()) {ast->print("%14s", " zombie method"); }
|
||||
if (nm->is_not_installed()) {ast->print("%s", " not (yet) installed method "); }
|
||||
if (nm->is_zombie()) {ast->print("%s", " zombie method "); }
|
||||
ast->print("%s", blob_name);
|
||||
} else {
|
||||
//---< block size in hex >---
|
||||
@ -1657,7 +1680,7 @@ void CodeHeapState::print_count(outputStream* out, CodeHeap* heap) {
|
||||
|
||||
{
|
||||
if (nBlocks_alive > 0) {
|
||||
printBox(ast, '-', "not_used/not_entrant nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
|
||||
printBox(ast, '-', "not_used/not_entrant/not_installed nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
|
||||
STRINGSTREAM_FLUSH_LOCKED("")
|
||||
|
||||
granules_per_line = 128;
|
||||
@ -1846,7 +1869,7 @@ void CodeHeapState::print_space(outputStream* out, CodeHeap* heap) {
|
||||
|
||||
{
|
||||
if (nBlocks_alive > 0) {
|
||||
printBox(ast, '-', "not_used/not_entrant space consumption. ' ' indicates empty, '*' indicates full", NULL);
|
||||
printBox(ast, '-', "not_used/not_entrant/not_installed space consumption. ' ' indicates empty, '*' indicates full", NULL);
|
||||
|
||||
granules_per_line = 128;
|
||||
for (unsigned int ix = 0; ix < alloc_granules; ix++) {
|
||||
@ -2016,7 +2039,7 @@ void CodeHeapState::print_age(outputStream* out, CodeHeap* heap) {
|
||||
|
||||
{
|
||||
if (nBlocks_alive > 0) {
|
||||
printBox(ast, '-', "not_used/not_entrant age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
|
||||
printBox(ast, '-', "not_used/not_entrant/not_installed age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
|
||||
STRINGSTREAM_FLUSH_LOCKED("")
|
||||
|
||||
granules_per_line = 128;
|
||||
@ -2106,8 +2129,8 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
bool blob_initialized = (this_blob != NULL) && (this_blob->header_size() >= 0) && (this_blob->relocation_size() >= 0) &&
|
||||
((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
|
||||
((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
|
||||
is_readable_pointer((address)(this_blob->relocation_begin())) &&
|
||||
is_readable_pointer(this_blob->content_begin());
|
||||
os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
|
||||
os::is_readable_pointer(this_blob->content_begin());
|
||||
// blob could have been flushed, freed, and merged.
|
||||
// this_blob < last_blob is an indicator for that.
|
||||
if (blob_initialized && (this_blob > last_blob)) {
|
||||
@ -2122,7 +2145,7 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
}
|
||||
// this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
|
||||
const char* blob_name = this_blob->name();
|
||||
if ((blob_name == NULL) || !is_readable_pointer(blob_name)) {
|
||||
if ((blob_name == NULL) || !os::is_readable_pointer(blob_name)) {
|
||||
blob_name = "<unavailable>";
|
||||
}
|
||||
|
||||
@ -2146,8 +2169,8 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
// this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
|
||||
nmethod* nm = this_blob->as_nmethod_or_null();
|
||||
Method* method = (nm == NULL) ? NULL : nm->method(); // may be uninitialized, i.e. != NULL, but invalid
|
||||
if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) &&
|
||||
is_readable_pointer(method) && is_readable_pointer(method->constants())) {
|
||||
if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) && (cbType != nMethod_inconstruction) &&
|
||||
os::is_readable_pointer(method) && os::is_readable_pointer(method->constants())) {
|
||||
ResourceMark rm;
|
||||
//---< collect all data to locals as quickly as possible >---
|
||||
unsigned int total_size = nm->total_size();
|
||||
@ -2346,7 +2369,7 @@ void CodeHeapState::print_line_delim(outputStream* out, bufferedStream* ast, cha
|
||||
}
|
||||
|
||||
CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
|
||||
if ((cb != NULL) && is_readable_pointer(cb)) {
|
||||
if ((cb != NULL) && os::is_readable_pointer(cb)) {
|
||||
if (cb->is_runtime_stub()) return runtimeStub;
|
||||
if (cb->is_deoptimization_stub()) return deoptimizationStub;
|
||||
if (cb->is_uncommon_trap_stub()) return uncommonTrapStub;
|
||||
@ -2358,27 +2381,14 @@ CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
|
||||
|
||||
nmethod* nm = cb->as_nmethod_or_null();
|
||||
if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
|
||||
if (nm->is_not_installed()) return nMethod_inconstruction;
|
||||
if (nm->is_zombie()) return nMethod_dead;
|
||||
if (nm->is_unloaded()) return nMethod_unloaded;
|
||||
if (nm->is_in_use()) return nMethod_inuse;
|
||||
if (nm->is_alive() && !(nm->is_not_entrant())) return nMethod_notused;
|
||||
if (nm->is_alive()) return nMethod_alive;
|
||||
if (nm->is_in_use()) return nMethod_inuse;
|
||||
return nMethod_dead;
|
||||
}
|
||||
}
|
||||
return noType;
|
||||
}
|
||||
|
||||
// Check if pointer can be read from (4-byte read access).
|
||||
// Helps to prove validity of a not-NULL pointer.
|
||||
// Returns true in very early stages of VM life when stub is not yet generated.
|
||||
#define SAFEFETCH_DEFAULT true
|
||||
bool CodeHeapState::is_readable_pointer(const void* p) {
|
||||
if (!CanUseSafeFetch32()) {
|
||||
return SAFEFETCH_DEFAULT;
|
||||
}
|
||||
int* const aligned = (int*) align_down((intptr_t)p, 4);
|
||||
int cafebabe = 0xcafebabe; // tester value 1
|
||||
int deadbeef = 0xdeadbeef; // tester value 2
|
||||
return (SafeFetch32(aligned, cafebabe) != cafebabe) || (SafeFetch32(aligned, deadbeef) != deadbeef);
|
||||
}
|
||||
|
@ -44,7 +44,9 @@ class CodeHeapState : public CHeapObj<mtCode> {
|
||||
|
||||
enum blobType {
|
||||
noType = 0, // must be! due to initialization by memset to zero
|
||||
// The nMethod_* values correspond 1:1 to the CompiledMethod enum values.
|
||||
// The nMethod_* values correspond to the CompiledMethod enum values.
|
||||
// We can't use the CompiledMethod values 1:1 because we depend on noType == 0.
|
||||
nMethod_inconstruction, // under construction. Very soon, the type will transition to "in_use".
|
||||
nMethod_inuse, // executable. This is the "normal" state for a nmethod.
|
||||
nMethod_notused, // assumed inactive, marked not entrant. Could be revived if necessary.
|
||||
nMethod_notentrant, // no new activations allowed, marked for deoptimization. Old activations may still exist.
|
||||
@ -93,7 +95,6 @@ class CodeHeapState : public CHeapObj<mtCode> {
|
||||
static void print_line_delim(outputStream* out, bufferedStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
|
||||
static void print_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
|
||||
static blobType get_cbType(CodeBlob* cb);
|
||||
static bool is_readable_pointer(const void* p);
|
||||
|
||||
public:
|
||||
static void discard(outputStream* out, CodeHeap* heap);
|
||||
@ -214,6 +215,7 @@ struct CodeHeapStat {
|
||||
unsigned int nBlocks_t2;
|
||||
unsigned int nBlocks_alive;
|
||||
unsigned int nBlocks_dead;
|
||||
unsigned int nBlocks_inconstr;
|
||||
unsigned int nBlocks_unloaded;
|
||||
unsigned int nBlocks_stub;
|
||||
// FreeBlk data
|
||||
|
@ -10369,7 +10369,7 @@ myInit() {
|
||||
<description>
|
||||
Can generate sampled allocation events.
|
||||
If this capability is enabled then the heap sampling method
|
||||
<functionlink id="SetHeapSamplingRate"></functionlink> can be
|
||||
<functionlink id="SetHeapSamplingInterval"></functionlink> can be
|
||||
called and <eventlink id="SampledObjectAlloc"></eventlink> events can be generated.
|
||||
</description>
|
||||
</capabilityfield>
|
||||
@ -11552,41 +11552,47 @@ myInit() {
|
||||
</category>
|
||||
|
||||
<category id="heap_monitoring" label="Heap Monitoring">
|
||||
<function id="SetHeapSamplingRate" phase="onload" num="156" since="11">
|
||||
<synopsis>Set Heap Sampling Rate</synopsis>
|
||||
<function id="SetHeapSamplingInterval" phase="onload" num="156" since="11">
|
||||
<synopsis>Set Heap Sampling Interval</synopsis>
|
||||
<description>
|
||||
Generate a <eventlink id="SampledObjectAlloc"/> event when objects are allocated.
|
||||
Each thread keeps a counter of bytes allocated. The event will only be generated
|
||||
when that counter exceeds an average of <paramlink id="sampling_rate"></paramlink>
|
||||
when that counter exceeds an average of <paramlink id="sampling_interval"></paramlink>
|
||||
since the last sample.
|
||||
<p/>
|
||||
Setting <paramlink id="sampling_rate"></paramlink> to 0 will cause an event to be
|
||||
generated by each allocation supported by the system.
|
||||
Setting <paramlink id="sampling_interval"></paramlink> to 0 will cause an event to be
|
||||
generated by each allocation supported by the system once the new interval is taken into account.
|
||||
<p/>
|
||||
Note that updating the new sampling interval might take various number of allocations
|
||||
to provoke internal data structure updates. Therefore it is important to
|
||||
consider the sampling interval as an average. This includes the interval 0, where events
|
||||
might not be generated straight away for each allocation.
|
||||
</description>
|
||||
<origin>new</origin>
|
||||
<capabilities>
|
||||
<required id="can_generate_sampled_object_alloc_events"></required>
|
||||
</capabilities>
|
||||
<parameters>
|
||||
<param id="sampling_rate">
|
||||
<param id="sampling_interval">
|
||||
<jint/>
|
||||
<description>
|
||||
The sampling rate in bytes. The sampler uses a statistical approach to
|
||||
generate an event, on average, once for every <paramlink id="sampling_rate"/> bytes of
|
||||
The sampling interval in bytes. The sampler uses a statistical approach to
|
||||
generate an event, on average, once for every <paramlink id="sampling_interval"/> bytes of
|
||||
memory allocated by a given thread.
|
||||
<p/>
|
||||
Passing 0 as a sampling rate generates a sample for every allocation.
|
||||
Once the new sampling interval is taken into account, 0 as a sampling interval will generate
|
||||
a sample for every allocation.
|
||||
<p/>
|
||||
Note: The overhead of this feature is directly correlated with the sampling rate.
|
||||
A high sampling rate, such as 1024 bytes, will incur a high overhead.
|
||||
A lower rate, such as 1024KB, will have a much lower overhead. Sampling should only
|
||||
Note: The overhead of this feature is directly correlated with the sampling interval.
|
||||
A high sampling interval, such as 1024 bytes, will incur a high overhead.
|
||||
A lower interval, such as 1024KB, will have a much lower overhead. Sampling should only
|
||||
be used with an understanding that it may impact performance.
|
||||
</description>
|
||||
</param>
|
||||
</parameters>
|
||||
<errors>
|
||||
<error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
|
||||
<paramlink id="sampling_rate"></paramlink> is less than zero.
|
||||
<paramlink id="sampling_interval"></paramlink> is less than zero.
|
||||
</error>
|
||||
</errors>
|
||||
</function>
|
||||
@ -13586,20 +13592,23 @@ myInit() {
|
||||
id="SampledObjectAlloc" const="JVMTI_EVENT_SAMPLED_OBJECT_ALLOC" num="86" since="11">
|
||||
<description>
|
||||
Sent when an allocated object is sampled.
|
||||
By default, the sampling rate is a geometric variable with a 512KB mean.
|
||||
By default, the sampling interval is set to 512KB. The sampling is semi-random to avoid
|
||||
pattern-based bias and provides an approximate overall average interval over long periods of
|
||||
sampling.
|
||||
<p/>
|
||||
Each thread tracks how many bytes it has allocated since it sent the last event.
|
||||
When the number of bytes exceeds the sampling rate, it will send another event.
|
||||
When the number of bytes exceeds the sampling interval, it will send another event.
|
||||
This implies that, on average, one object will be sampled every time a thread has
|
||||
allocated 512KB bytes since the last sample.
|
||||
<p/>
|
||||
Note that this is a geometric variable: it will not sample every 512KB precisely.
|
||||
Note that the sampler is pseudo-random: it will not sample every 512KB precisely.
|
||||
The goal of this is to ensure high quality sampling even if allocation is
|
||||
happening in a fixed pattern (i.e., the same set of objects are being allocated
|
||||
every 512KB).
|
||||
<p/>
|
||||
If another sampling rate is required, the user can call
|
||||
<functionlink id="SetHeapSamplingRate"></functionlink> with a strictly positive integer value, representing
|
||||
the new sampling rate.
|
||||
If another sampling interval is required, the user can call
|
||||
<functionlink id="SetHeapSamplingInterval"></functionlink> with a strictly positive integer value,
|
||||
representing the new sampling interval.
|
||||
<p/>
|
||||
This event is sent once the sampled allocation has been performed. It provides the object, stack trace
|
||||
of the allocation, the thread allocating, the size of allocation, and the object's class.
|
||||
|
@ -3644,13 +3644,13 @@ JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {
|
||||
} /* end GetAvailableProcessors */
|
||||
|
||||
jvmtiError
|
||||
JvmtiEnv::SetHeapSamplingRate(jint sampling_rate) {
|
||||
if (sampling_rate < 0) {
|
||||
JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {
|
||||
if (sampling_interval < 0) {
|
||||
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
ThreadHeapSampler::set_sampling_rate(sampling_rate);
|
||||
ThreadHeapSampler::set_sampling_interval(sampling_interval);
|
||||
return JVMTI_ERROR_NONE;
|
||||
} /* end SetHeapSamplingRate */
|
||||
} /* end SetHeapSamplingInterval */
|
||||
|
||||
//
|
||||
// System Properties functions
|
||||
|
@ -995,6 +995,22 @@ void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
|
||||
st->print_cr(" elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs);
|
||||
}
|
||||
|
||||
|
||||
// Check if pointer can be read from (4-byte read access).
|
||||
// Helps to prove validity of a not-NULL pointer.
|
||||
// Returns true in very early stages of VM life when stub is not yet generated.
|
||||
#define SAFEFETCH_DEFAULT true
|
||||
bool os::is_readable_pointer(const void* p) {
|
||||
if (!CanUseSafeFetch32()) {
|
||||
return SAFEFETCH_DEFAULT;
|
||||
}
|
||||
int* const aligned = (int*) align_down((intptr_t)p, 4);
|
||||
int cafebabe = 0xcafebabe; // tester value 1
|
||||
int deadbeef = 0xdeadbeef; // tester value 2
|
||||
return (SafeFetch32(aligned, cafebabe) != cafebabe) || (SafeFetch32(aligned, deadbeef) != deadbeef);
|
||||
}
|
||||
|
||||
|
||||
// moved from debug.cpp (used to be find()) but still called from there
|
||||
// The verbose parameter is only set by the debug code in one case
|
||||
void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
@ -1094,6 +1110,10 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool accessible = is_readable_pointer(addr);
|
||||
|
||||
if (align_down((intptr_t)addr, sizeof(intptr_t)) != 0 && accessible) {
|
||||
if (JNIHandles::is_global_handle((jobject) addr)) {
|
||||
st->print_cr(INTPTR_FORMAT " is a global jni handle", p2i(addr));
|
||||
return;
|
||||
@ -1109,6 +1129,7 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
|
||||
// Check for privilege stack
|
||||
@ -1155,6 +1176,11 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (accessible) {
|
||||
st->print_cr(INTPTR_FORMAT " points into unknown readable memory", p2i(addr));
|
||||
return;
|
||||
}
|
||||
|
||||
st->print_cr(INTPTR_FORMAT " is an unknown value", p2i(addr));
|
||||
}
|
||||
|
||||
|
@ -412,6 +412,9 @@ class os: AllStatic {
|
||||
static void make_polling_page_unreadable();
|
||||
static void make_polling_page_readable();
|
||||
|
||||
// Check if pointer points to readable memory (by 4-byte read access)
|
||||
static bool is_readable_pointer(const void* p);
|
||||
|
||||
// Routines used to serialize the thread state without using membars
|
||||
static void serialize_thread_states();
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
// Cheap random number generator
|
||||
uint64_t ThreadHeapSampler::_rnd;
|
||||
// Default is 512kb.
|
||||
int ThreadHeapSampler::_sampling_rate = 512 * 1024;
|
||||
int ThreadHeapSampler::_sampling_interval = 512 * 1024;
|
||||
int ThreadHeapSampler::_enabled;
|
||||
|
||||
// Statics for the fast log
|
||||
@ -69,7 +69,7 @@ static double fast_log2(const double & d) {
|
||||
// Generates a geometric variable with the specified mean (512K by default).
|
||||
// This is done by generating a random number between 0 and 1 and applying
|
||||
// the inverse cumulative distribution function for an exponential.
|
||||
// Specifically: Let m be the inverse of the sample rate, then
|
||||
// Specifically: Let m be the inverse of the sample interval, then
|
||||
// the probability distribution function is m*exp(-mx) so the CDF is
|
||||
// p = 1 - exp(-mx), so
|
||||
// q = 1 - p = exp(-mx)
|
||||
@ -96,14 +96,14 @@ void ThreadHeapSampler::pick_next_geometric_sample() {
|
||||
// negative answer.
|
||||
double log_val = (fast_log2(q) - 26);
|
||||
double result =
|
||||
(0.0 < log_val ? 0.0 : log_val) * (-log(2.0) * (get_sampling_rate())) + 1;
|
||||
(0.0 < log_val ? 0.0 : log_val) * (-log(2.0) * (get_sampling_interval())) + 1;
|
||||
assert(result > 0 && result < SIZE_MAX, "Result is not in an acceptable range.");
|
||||
size_t rate = static_cast<size_t>(result);
|
||||
_bytes_until_sample = rate;
|
||||
size_t interval = static_cast<size_t>(result);
|
||||
_bytes_until_sample = interval;
|
||||
}
|
||||
|
||||
void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) {
|
||||
if (get_sampling_rate() == 1) {
|
||||
if (get_sampling_interval() == 1) {
|
||||
_bytes_until_sample = 1;
|
||||
return;
|
||||
}
|
||||
@ -161,12 +161,12 @@ void ThreadHeapSampler::disable() {
|
||||
OrderAccess::release_store(&_enabled, 0);
|
||||
}
|
||||
|
||||
int ThreadHeapSampler::get_sampling_rate() {
|
||||
return OrderAccess::load_acquire(&_sampling_rate);
|
||||
int ThreadHeapSampler::get_sampling_interval() {
|
||||
return OrderAccess::load_acquire(&_sampling_interval);
|
||||
}
|
||||
|
||||
void ThreadHeapSampler::set_sampling_rate(int sampling_rate) {
|
||||
OrderAccess::release_store(&_sampling_rate, sampling_rate);
|
||||
void ThreadHeapSampler::set_sampling_interval(int sampling_interval) {
|
||||
OrderAccess::release_store(&_sampling_interval, sampling_interval);
|
||||
}
|
||||
|
||||
// Methods used in assertion mode to check if a collector is present or not at
|
||||
|
@ -36,7 +36,7 @@ class ThreadHeapSampler {
|
||||
void pick_next_geometric_sample();
|
||||
void pick_next_sample(size_t overflowed_bytes = 0);
|
||||
static int _enabled;
|
||||
static int _sampling_rate;
|
||||
static int _sampling_interval;
|
||||
|
||||
// Used for assertion mode to determine if there is a path to a TLAB slow path
|
||||
// without a collector present.
|
||||
@ -63,8 +63,8 @@ class ThreadHeapSampler {
|
||||
static void enable();
|
||||
static void disable();
|
||||
|
||||
static void set_sampling_rate(int sampling_rate);
|
||||
static int get_sampling_rate();
|
||||
static void set_sampling_interval(int sampling_interval);
|
||||
static int get_sampling_interval();
|
||||
|
||||
bool sampling_collector_present() const;
|
||||
bool remove_sampling_collector();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,8 @@
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
|
||||
|
||||
@ -68,6 +70,15 @@ final class GCTR extends CounterMode {
|
||||
return "GCTR";
|
||||
}
|
||||
|
||||
// return the number of blocks until the lower 32 bits roll over
|
||||
private long blocksUntilRollover() {
|
||||
ByteBuffer buf = ByteBuffer.wrap(counter, counter.length - 4, 4);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
long ctr32 = 0xFFFFFFFFL & buf.getInt();
|
||||
long blocksLeft = (1L << 32) - ctr32;
|
||||
return blocksLeft;
|
||||
}
|
||||
|
||||
// input must be multiples of 128-bit blocks when calling update
|
||||
int update(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
|
||||
if (inLen - inOfs > in.length) {
|
||||
@ -80,8 +91,26 @@ final class GCTR extends CounterMode {
|
||||
throw new RuntimeException("output buffer too small");
|
||||
}
|
||||
|
||||
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
|
||||
int doFinal(byte[] in, int inOfs, int inLen, byte[] out,
|
||||
|
@ -33,7 +33,6 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
import sun.security.util.HexDumpEncoder;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
@ -260,21 +259,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
|
||||
String kdfAlgo = null;
|
||||
String cipherAlgo = null;
|
||||
|
||||
DerValue pBES2Algorithms = new DerValue(encoded);
|
||||
if (pBES2Algorithms.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("PBE parameter parsing error: "
|
||||
+ "not an ASN.1 SEQUENCE tag");
|
||||
}
|
||||
if (!pkcs5PBES2_OID.equals(pBES2Algorithms.data.getOID())) {
|
||||
throw new IOException("PBE parameter parsing error: "
|
||||
+ "expecting the object identifier for PBES2");
|
||||
}
|
||||
if (pBES2Algorithms.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("PBE parameter parsing error: "
|
||||
+ "not an ASN.1 SEQUENCE tag");
|
||||
}
|
||||
|
||||
DerValue pBES2_params = pBES2Algorithms.data.getDerValue();
|
||||
DerValue pBES2_params = new DerValue(encoded);
|
||||
if (pBES2_params.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("PBE parameter parsing error: "
|
||||
+ "not an ASN.1 SEQUENCE tag");
|
||||
@ -293,7 +278,6 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private String parseKDF(DerValue keyDerivationFunc) throws IOException {
|
||||
String kdfAlgo = null;
|
||||
|
||||
if (!pkcs5PBKDF2_OID.equals(keyDerivationFunc.data.getOID())) {
|
||||
throw new IOException("PBE parameter parsing error: "
|
||||
@ -318,10 +302,16 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
|
||||
+ "not an ASN.1 OCTET STRING tag");
|
||||
}
|
||||
iCount = pBKDF2_params.data.getInteger();
|
||||
// keyLength INTEGER (1..MAX) OPTIONAL,
|
||||
if (pBKDF2_params.data.available() > 0) {
|
||||
DerValue keyLength = pBKDF2_params.data.getDerValue();
|
||||
if (keyLength.tag == DerValue.tag_Integer) {
|
||||
keysize = keyLength.getInteger() * 8; // keysize (in bits)
|
||||
}
|
||||
}
|
||||
// prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
|
||||
String kdfAlgo = "HmacSHA1";
|
||||
if (pBKDF2_params.data.available() > 0) {
|
||||
if (pBKDF2_params.tag == DerValue.tag_Sequence) {
|
||||
DerValue prf = pBKDF2_params.data.getDerValue();
|
||||
kdfAlgo_OID = prf.data.getOID();
|
||||
@ -349,6 +339,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kdfAlgo;
|
||||
}
|
||||
@ -399,8 +390,6 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
|
||||
|
||||
protected byte[] engineGetEncoded() throws IOException {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
DerOutputStream pBES2Algorithms = new DerOutputStream();
|
||||
pBES2Algorithms.putOID(pkcs5PBES2_OID);
|
||||
|
||||
DerOutputStream pBES2_params = new DerOutputStream();
|
||||
|
||||
@ -410,7 +399,10 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
|
||||
DerOutputStream pBKDF2_params = new DerOutputStream();
|
||||
pBKDF2_params.putOctetString(salt); // choice: 'specified OCTET STRING'
|
||||
pBKDF2_params.putInteger(iCount);
|
||||
|
||||
if (keysize > 0) {
|
||||
pBKDF2_params.putInteger(keysize / 8); // derived key length (in octets)
|
||||
}
|
||||
|
||||
DerOutputStream prf = new DerOutputStream();
|
||||
// algorithm is id-hmacWithSHA1/SHA224/SHA256/SHA384/SHA512
|
||||
@ -434,8 +426,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi {
|
||||
}
|
||||
pBES2_params.write(DerValue.tag_Sequence, encryptionScheme);
|
||||
|
||||
pBES2Algorithms.write(DerValue.tag_Sequence, pBES2_params);
|
||||
out.write(DerValue.tag_Sequence, pBES2Algorithms);
|
||||
out.write(DerValue.tag_Sequence, pBES2_params);
|
||||
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
@ -1807,6 +1807,7 @@ public class KeyStore {
|
||||
keystore.load(dataStream, password);
|
||||
} else {
|
||||
keystore.keyStoreSpi.engineLoad(dataStream, param);
|
||||
keystore.initialized = true;
|
||||
}
|
||||
return keystore;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ public class PatternSyntaxException
|
||||
}
|
||||
sb.append(System.lineSeparator());
|
||||
sb.append(pattern);
|
||||
if (index >= 0) {
|
||||
if (index >= 0 && pattern != null && index < pattern.length()) {
|
||||
sb.append(System.lineSeparator());
|
||||
for (int i = 0; i < index; i++) sb.append(' ');
|
||||
sb.append('^');
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,6 +87,9 @@ public class ReflectionFactory {
|
||||
private static boolean noInflation = false;
|
||||
private static int inflationThreshold = 15;
|
||||
|
||||
// true if deserialization constructor checking is disabled
|
||||
private static boolean disableSerialConstructorChecks = false;
|
||||
|
||||
private ReflectionFactory() {
|
||||
}
|
||||
|
||||
@ -424,10 +427,64 @@ public class ReflectionFactory {
|
||||
return generateConstructor(cl, constructorToCall);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a class, determines whether its superclass has
|
||||
* any constructors that are accessible from the class.
|
||||
* This is a special purpose method intended to do access
|
||||
* checking for a serializable class and its superclasses
|
||||
* up to, but not including, the first non-serializable
|
||||
* superclass. This also implies that the superclass is
|
||||
* always non-null, because a serializable class must be a
|
||||
* class (not an interface) and Object is not serializable.
|
||||
*
|
||||
* @param cl the class from which access is checked
|
||||
* @return whether the superclass has a constructor accessible from cl
|
||||
*/
|
||||
private boolean superHasAccessibleConstructor(Class<?> cl) {
|
||||
Class<?> superCl = cl.getSuperclass();
|
||||
assert Serializable.class.isAssignableFrom(cl);
|
||||
assert superCl != null;
|
||||
if (packageEquals(cl, superCl)) {
|
||||
// accessible if any non-private constructor is found
|
||||
for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
|
||||
if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
// sanity check to ensure the parent is protected or public
|
||||
if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
|
||||
return false;
|
||||
}
|
||||
// accessible if any constructor is protected or public
|
||||
for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
|
||||
if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a constructor that allocates an instance of cl and that then initializes
|
||||
* the instance by calling the no-arg constructor of its first non-serializable
|
||||
* superclass. This is specified in the Serialization Specification, section 3.1,
|
||||
* in step 11 of the deserialization process. If cl is not serializable, returns
|
||||
* cl's no-arg constructor. If no accessible constructor is found, or if the
|
||||
* class hierarchy is somehow malformed (e.g., a serializable class has no
|
||||
* superclass), null is returned.
|
||||
*
|
||||
* @param cl the class for which a constructor is to be found
|
||||
* @return the generated constructor, or null if none is available
|
||||
*/
|
||||
public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
|
||||
Class<?> initCl = cl;
|
||||
while (Serializable.class.isAssignableFrom(initCl)) {
|
||||
if ((initCl = initCl.getSuperclass()) == null) {
|
||||
Class<?> prev = initCl;
|
||||
if ((initCl = initCl.getSuperclass()) == null ||
|
||||
(!disableSerialConstructorChecks && !superHasAccessibleConstructor(prev))) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -653,6 +710,9 @@ public class ReflectionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
disableSerialConstructorChecks =
|
||||
"true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
|
||||
|
||||
initted = true;
|
||||
}
|
||||
|
||||
|
@ -2098,7 +2098,8 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
RetryWithZero.run(pass -> {
|
||||
// Use JCE
|
||||
SecretKey skey = getPBEKey(pass);
|
||||
Cipher cipher = Cipher.getInstance(algOid.toString());
|
||||
Cipher cipher = Cipher.getInstance(
|
||||
mapPBEParamsToAlgorithm(algOid, algParams));
|
||||
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
|
||||
loadSafeContents(new DerInputStream(cipher.doFinal(rawData)));
|
||||
return null;
|
||||
|
@ -27,6 +27,7 @@ package sun.security.ssl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -46,6 +47,9 @@ final class PostHandshakeContext extends HandshakeContext {
|
||||
"Post-handshake not supported in " + negotiatedProtocol.name);
|
||||
}
|
||||
|
||||
this.localSupportedSignAlgs = new ArrayList<SignatureScheme>(
|
||||
context.conSession.getLocalSupportedSignatureSchemes());
|
||||
|
||||
handshakeConsumers = new LinkedHashMap<>(consumers);
|
||||
handshakeFinished = true;
|
||||
}
|
||||
|
@ -33,8 +33,11 @@ import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.Collection;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import static sun.security.ssl.ClientAuthType.CLIENT_AUTH_REQUIRED;
|
||||
import sun.security.ssl.ClientHello.ClientHelloMessage;
|
||||
import sun.security.ssl.SSLExtension.ExtensionConsumer;
|
||||
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
|
||||
@ -328,6 +331,7 @@ final class PreSharedKeyExtension {
|
||||
public void consume(ConnectionContext context,
|
||||
HandshakeMessage message,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
ClientHelloMessage clientHello = (ClientHelloMessage) message;
|
||||
ServerHandshakeContext shc = (ServerHandshakeContext)context;
|
||||
// Is it a supported and enabled extension?
|
||||
if (!shc.sslConfig.isAvailable(SSLExtension.CH_PRE_SHARED_KEY)) {
|
||||
@ -367,8 +371,7 @@ final class PreSharedKeyExtension {
|
||||
int idIndex = 0;
|
||||
for (PskIdentity requestedId : pskSpec.identities) {
|
||||
SSLSessionImpl s = sessionCache.get(requestedId.identity);
|
||||
if (s != null && s.isRejoinable() &&
|
||||
s.getPreSharedKey().isPresent()) {
|
||||
if (s != null && canRejoin(clientHello, shc, s)) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("Resuming session: ", s);
|
||||
}
|
||||
@ -396,6 +399,64 @@ final class PreSharedKeyExtension {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canRejoin(ClientHelloMessage clientHello,
|
||||
ServerHandshakeContext shc, SSLSessionImpl s) {
|
||||
|
||||
boolean result = s.isRejoinable() && s.getPreSharedKey().isPresent();
|
||||
|
||||
// Check protocol version
|
||||
if (result && s.getProtocolVersion() != shc.negotiatedProtocol) {
|
||||
if (SSLLogger.isOn &&
|
||||
SSLLogger.isOn("ssl,handshake,verbose")) {
|
||||
|
||||
SSLLogger.finest("Can't resume, incorrect protocol version");
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Validate the required client authentication.
|
||||
if (result &&
|
||||
(shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED)) {
|
||||
try {
|
||||
s.getPeerPrincipal();
|
||||
} catch (SSLPeerUnverifiedException e) {
|
||||
if (SSLLogger.isOn &&
|
||||
SSLLogger.isOn("ssl,handshake,verbose")) {
|
||||
SSLLogger.finest(
|
||||
"Can't resume, " +
|
||||
"client authentication is required");
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Make sure the list of supported signature algorithms matches
|
||||
Collection<SignatureScheme> sessionSigAlgs =
|
||||
s.getLocalSupportedSignatureSchemes();
|
||||
if (result &&
|
||||
!shc.localSupportedSignAlgs.containsAll(sessionSigAlgs)) {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("Can't resume. Session uses different " +
|
||||
"signature algorithms");
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure cipher suite can be negotiated
|
||||
if (result && (!shc.isNegotiable(s.getSuite()) ||
|
||||
!clientHello.cipherSuites.contains(s.getSuite()))) {
|
||||
if (SSLLogger.isOn &&
|
||||
SSLLogger.isOn("ssl,handshake,verbose")) {
|
||||
SSLLogger.finest(
|
||||
"Can't resume, unavailable session cipher suite");
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final
|
||||
class CHPreSharedKeyUpdate implements HandshakeConsumer {
|
||||
// Prevent instantiation of this class.
|
||||
@ -547,6 +608,18 @@ final class PreSharedKeyExtension {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure the list of supported signature algorithms matches
|
||||
Collection<SignatureScheme> sessionSigAlgs =
|
||||
chc.resumingSession.getLocalSupportedSignatureSchemes();
|
||||
if (!chc.localSupportedSignAlgs.containsAll(sessionSigAlgs)) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("Existing session uses different " +
|
||||
"signature algorithms");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// The session must have a pre-shared key
|
||||
Optional<SecretKey> pskOpt = chc.resumingSession.getPreSharedKey();
|
||||
if (!pskOpt.isPresent()) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
|
@ -96,7 +96,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
||||
private boolean invalidated;
|
||||
private X509Certificate[] localCerts;
|
||||
private PrivateKey localPrivateKey;
|
||||
private final String[] localSupportedSignAlgs;
|
||||
private final Collection<SignatureScheme> localSupportedSignAlgs;
|
||||
private String[] peerSupportedSignAlgs; // for certificate
|
||||
private boolean useDefaultPeerSignAlgs = false;
|
||||
private List<byte[]> statusResponses;
|
||||
@ -144,7 +144,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
||||
this.sessionId = new SessionId(false, null);
|
||||
this.host = null;
|
||||
this.port = -1;
|
||||
this.localSupportedSignAlgs = new String[0];
|
||||
this.localSupportedSignAlgs = Collections.emptySet();
|
||||
this.serverNameIndication = null;
|
||||
this.requestedServerNames = Collections.<SNIServerName>emptyList();
|
||||
this.useExtendedMasterSecret = false;
|
||||
@ -179,8 +179,9 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
||||
this.sessionId = id;
|
||||
this.host = hc.conContext.transport.getPeerHost();
|
||||
this.port = hc.conContext.transport.getPeerPort();
|
||||
this.localSupportedSignAlgs =
|
||||
SignatureScheme.getAlgorithmNames(hc.localSupportedSignAlgs);
|
||||
this.localSupportedSignAlgs = hc.localSupportedSignAlgs == null ?
|
||||
Collections.emptySet() :
|
||||
Collections.unmodifiableCollection(hc.localSupportedSignAlgs);
|
||||
this.serverNameIndication = hc.negotiatedServerName;
|
||||
this.requestedServerNames = Collections.<SNIServerName>unmodifiableList(
|
||||
hc.getRequestedServerNames());
|
||||
@ -969,16 +970,20 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of supported signature algorithms that the local side is
|
||||
* willing to verify.
|
||||
* Gets an array of supported signature algorithm names that the local
|
||||
* side is willing to verify.
|
||||
*/
|
||||
@Override
|
||||
public String[] getLocalSupportedSignatureAlgorithms() {
|
||||
if (localSupportedSignAlgs != null) {
|
||||
return localSupportedSignAlgs.clone();
|
||||
return SignatureScheme.getAlgorithmNames(localSupportedSignAlgs);
|
||||
}
|
||||
|
||||
return new String[0];
|
||||
/**
|
||||
* Gets an array of supported signature schemes that the local side is
|
||||
* willing to verify.
|
||||
*/
|
||||
public Collection<SignatureScheme> getLocalSupportedSignatureSchemes() {
|
||||
return localSupportedSignAlgs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,13 +393,6 @@ class TransportContext implements ConnectionContext, Closeable {
|
||||
}
|
||||
|
||||
void setUseClientMode(boolean useClientMode) {
|
||||
/*
|
||||
* If we need to change the client mode and the enabled
|
||||
* protocols and cipher suites haven't specifically been
|
||||
* set by the user, change them to the corresponding
|
||||
* default ones.
|
||||
*/
|
||||
if (sslConfig.isClientMode != useClientMode) {
|
||||
// Once handshaking has begun, the mode can not be reset for the
|
||||
// life of this engine.
|
||||
if (handshakeContext != null || isNegotiated) {
|
||||
@ -407,6 +400,13 @@ class TransportContext implements ConnectionContext, Closeable {
|
||||
"Cannot change mode after SSL traffic has started");
|
||||
}
|
||||
|
||||
/*
|
||||
* If we need to change the client mode and the enabled
|
||||
* protocols and cipher suites haven't specifically been
|
||||
* set by the user, change them to the corresponding
|
||||
* default ones.
|
||||
*/
|
||||
if (sslConfig.isClientMode != useClientMode) {
|
||||
if (sslContext.isDefaultProtocolVesions(
|
||||
sslConfig.enabledProtocols)) {
|
||||
sslConfig.enabledProtocols =
|
||||
|
@ -297,6 +297,22 @@ JNU_NotifyAll(JNIEnv *env, jobject object);
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
#define CHECK_NULL_THROW_NPE(env, x, msg) \
|
||||
do { \
|
||||
if ((x) == NULL) { \
|
||||
JNU_ThrowNullPointerException((env), (msg));\
|
||||
return; \
|
||||
} \
|
||||
} while(0) \
|
||||
|
||||
#define CHECK_NULL_THROW_NPE_RETURN(env, x, msg, z)\
|
||||
do { \
|
||||
if ((x) == NULL) { \
|
||||
JNU_ThrowNullPointerException((env), (msg));\
|
||||
return (z); \
|
||||
} \
|
||||
} while(0) \
|
||||
|
||||
#define CHECK_NULL_RETURN(x, y) \
|
||||
do { \
|
||||
if ((x) == NULL) { \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -171,32 +171,38 @@ jboolean setInet6Address_ipaddress(JNIEnv *env, jobject iaObj, char *address) {
|
||||
|
||||
void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
|
||||
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
|
||||
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
|
||||
(*env)->SetIntField(env, holder, iac_addressID, address);
|
||||
}
|
||||
|
||||
void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
|
||||
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
|
||||
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
|
||||
(*env)->SetIntField(env, holder, iac_familyID, family);
|
||||
}
|
||||
|
||||
void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
|
||||
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
|
||||
CHECK_NULL_THROW_NPE(env, holder, "InetAddress holder is null");
|
||||
(*env)->SetObjectField(env, holder, iac_hostNameID, host);
|
||||
(*env)->SetObjectField(env, holder, iac_origHostNameID, host);
|
||||
}
|
||||
|
||||
int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
|
||||
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
|
||||
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", -1);
|
||||
return (*env)->GetIntField(env, holder, iac_addressID);
|
||||
}
|
||||
|
||||
int getInetAddress_family(JNIEnv *env, jobject iaObj) {
|
||||
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
|
||||
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", -1);
|
||||
return (*env)->GetIntField(env, holder, iac_familyID);
|
||||
}
|
||||
|
||||
jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
|
||||
jobject holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
|
||||
CHECK_NULL_THROW_NPE_RETURN(env, holder, "InetAddress holder is null", NULL);
|
||||
return (*env)->GetObjectField(env, holder, iac_hostNameID);
|
||||
}
|
||||
|
||||
@ -211,7 +217,9 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
|
||||
CHECK_NULL_RETURN(iaObj, NULL);
|
||||
address = NET_IPv4MappedToIPv4(caddr);
|
||||
setInetAddress_addr(env, iaObj, address);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
} else {
|
||||
jboolean ret;
|
||||
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
|
||||
@ -220,6 +228,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
|
||||
if (ret == JNI_FALSE)
|
||||
return NULL;
|
||||
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv6);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
setInet6Address_scopeid(env, iaObj, sa->sa6.sin6_scope_id);
|
||||
}
|
||||
*port = ntohs(sa->sa6.sin6_port);
|
||||
@ -227,7 +236,9 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
|
||||
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
|
||||
CHECK_NULL_RETURN(iaObj, NULL);
|
||||
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
setInetAddress_addr(env, iaObj, ntohl(sa->sa4.sin_addr.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
*port = ntohs(sa->sa4.sin_port);
|
||||
}
|
||||
return iaObj;
|
||||
@ -238,6 +249,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
|
||||
{
|
||||
jint family = getInetAddress_family(env, iaObj) ==
|
||||
java_net_InetAddress_IPv4 ? AF_INET : AF_INET6;
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
|
||||
if (sa->sa.sa_family == AF_INET6) {
|
||||
jbyte *caddrNew = (jbyte *)&sa->sa6.sin6_addr;
|
||||
if (NET_IsIPv4Mapped(caddrNew)) {
|
||||
@ -247,6 +259,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
|
||||
}
|
||||
addrNew = NET_IPv4MappedToIPv4(caddrNew);
|
||||
addrCur = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
|
||||
if (addrNew == addrCur) {
|
||||
return JNI_TRUE;
|
||||
} else {
|
||||
@ -273,6 +286,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
|
||||
}
|
||||
addrNew = ntohl(sa->sa4.sin_addr.s_addr);
|
||||
addrCur = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
|
||||
if (addrNew == addrCur) {
|
||||
return JNI_TRUE;
|
||||
} else {
|
||||
|
@ -739,13 +739,13 @@ ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified)
|
||||
jzfile *zip = NULL;
|
||||
|
||||
/* Clear zip error message */
|
||||
if (pmsg != 0) {
|
||||
if (pmsg != NULL) {
|
||||
*pmsg = NULL;
|
||||
}
|
||||
|
||||
zip = ZIP_Get_From_Cache(name, pmsg, lastModified);
|
||||
|
||||
if (zip == NULL && *pmsg == NULL) {
|
||||
if (zip == NULL && pmsg != NULL && *pmsg == NULL) {
|
||||
ZFILE zfd = ZFILE_Open(name, mode);
|
||||
zip = ZIP_Put_In_Cache(name, zfd, pmsg, lastModified);
|
||||
}
|
||||
|
@ -193,7 +193,11 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
}
|
||||
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *)
|
||||
(iterator->ai_addr))->sin_addr.s_addr));
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
(*env)->SetObjectArrayElement(env, ret, i++, iaObj);
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
|
@ -198,6 +198,8 @@ lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6)
|
||||
return NULL;
|
||||
}
|
||||
setInetAddress_hostName(env, o, name);
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto done;
|
||||
(*env)->SetObjectArrayElement(env, result, index, o);
|
||||
(*env)->DeleteLocalRef(env, o);
|
||||
}
|
||||
@ -355,7 +357,11 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
|
||||
inetIndex++;
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
@ -376,6 +382,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
setInet6Address_scopeid(env, iaObj, scope);
|
||||
}
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
|
||||
inet6Index++;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -329,11 +329,11 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
|
||||
(JNIEnv *env, jclass cls, jobject iaObj)
|
||||
{
|
||||
netif *ifs, *curr;
|
||||
int family = (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) ?
|
||||
AF_INET : AF_INET6;
|
||||
jobject obj = NULL;
|
||||
jboolean match = JNI_FALSE;
|
||||
|
||||
int family = (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) ?
|
||||
AF_INET : AF_INET6;
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
ifs = enumInterfaces(env);
|
||||
if (ifs == NULL) {
|
||||
return NULL;
|
||||
@ -351,7 +351,7 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
|
||||
int address1 = htonl(
|
||||
((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr);
|
||||
int address2 = getInetAddress_addr(env, iaObj);
|
||||
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
if (address1 == address2) {
|
||||
match = JNI_TRUE;
|
||||
break;
|
||||
@ -698,6 +698,7 @@ static jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
|
||||
if (iaObj) {
|
||||
setInetAddress_addr(env, iaObj, htonl(
|
||||
((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -710,6 +711,7 @@ static jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
|
||||
if (ia2Obj) {
|
||||
setInetAddress_addr(env, ia2Obj, htonl(
|
||||
((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
(*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
|
||||
} else {
|
||||
return NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -531,9 +531,12 @@ Java_java_net_PlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
|
||||
iaObj = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
|
||||
family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
|
||||
AF_INET : AF_INET6;
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
if (family == AF_INET) { /* this API can't handle IPV6 addresses */
|
||||
int address = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
setInetAddress_addr(env, addressObj, address);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
@ -1014,6 +1017,7 @@ static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject val
|
||||
struct in_addr in;
|
||||
jobjectArray addrArray;
|
||||
jsize len;
|
||||
jint family;
|
||||
jobject addr;
|
||||
int i;
|
||||
|
||||
@ -1044,8 +1048,11 @@ static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject val
|
||||
in.s_addr = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
addr = (*env)->GetObjectArrayElement(env, addrArray, i);
|
||||
if (getInetAddress_family(env, addr) == java_net_InetAddress_IPv4) {
|
||||
family = getInetAddress_family(env, addr);
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (family == java_net_InetAddress_IPv4) {
|
||||
in.s_addr = htonl(getInetAddress_addr(env, addr));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1095,7 +1102,7 @@ static void mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject v
|
||||
struct in_addr in;
|
||||
|
||||
in.s_addr = htonl( getInetAddress_addr(env, value) );
|
||||
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(const char*)&in, sizeof(in)) < 0) {
|
||||
JNU_ThrowByNameWithMessageAndLastError
|
||||
@ -1458,6 +1465,7 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
|
||||
CHECK_NULL_RETURN(addr, NULL);
|
||||
|
||||
setInetAddress_addr(env, addr, ntohl(in.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
|
||||
/*
|
||||
* For IP_MULTICAST_IF return InetAddress
|
||||
@ -1890,6 +1898,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
|
||||
|
||||
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
|
||||
jint fd;
|
||||
jint family;
|
||||
jint ipv6_join_leave;
|
||||
|
||||
if (IS_NULL(fdObj)) {
|
||||
@ -1910,7 +1919,9 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
|
||||
ipv6_join_leave = ipv6_available();
|
||||
|
||||
#ifdef __linux__
|
||||
if (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) {
|
||||
family = getInetAddress_family(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (family == java_net_InetAddress_IPv4) {
|
||||
ipv6_join_leave = JNI_FALSE;
|
||||
}
|
||||
#endif
|
||||
@ -1951,6 +1962,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
|
||||
}
|
||||
|
||||
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
mname.imr_address.s_addr = 0;
|
||||
mname.imr_ifindex = (*env)->GetIntField(env, niObj, ni_indexID);
|
||||
mname_len = sizeof(struct ip_mreqn);
|
||||
@ -1969,11 +1981,14 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
|
||||
addr = (*env)->GetObjectArrayElement(env, addrArray, 0);
|
||||
|
||||
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
#ifdef __linux__
|
||||
mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
mname.imr_ifindex = 0;
|
||||
#else
|
||||
mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
#endif
|
||||
mname_len = sizeof(struct ip_mreq);
|
||||
}
|
||||
@ -2009,6 +2024,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
|
||||
}
|
||||
|
||||
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
mname.imr_address.s_addr = 0 ;
|
||||
mname.imr_ifindex = index;
|
||||
mname_len = sizeof(struct ip_mreqn);
|
||||
@ -2031,6 +2047,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
|
||||
mname.imr_interface.s_addr = in.s_addr;
|
||||
#endif
|
||||
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
mname_len = sizeof(struct ip_mreq);
|
||||
}
|
||||
}
|
||||
@ -2097,10 +2114,11 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
|
||||
jint address;
|
||||
family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
|
||||
AF_INET : AF_INET6;
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (family == AF_INET) { /* will convert to IPv4-mapped address */
|
||||
memset((char *) caddr, 0, 16);
|
||||
address = getInetAddress_addr(env, iaObj);
|
||||
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
caddr[10] = 0xff;
|
||||
caddr[11] = 0xff;
|
||||
|
||||
|
@ -764,6 +764,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
jboolean v4MappedAddress)
|
||||
{
|
||||
jint family = getInetAddress_family(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
memset((char *)sa, 0, sizeof(SOCKETADDRESS));
|
||||
|
||||
if (ipv6_available() &&
|
||||
@ -777,6 +778,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
// convert to IPv4-mapped address
|
||||
memset((char *)caddr, 0, 16);
|
||||
address = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
if (address == INADDR_ANY) {
|
||||
/* we would always prefer IPv6 wildcard address
|
||||
* caddr[10] = 0xff;
|
||||
@ -871,6 +873,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
return -1;
|
||||
}
|
||||
address = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
sa->sa4.sin_port = htons(port);
|
||||
sa->sa4.sin_addr.s_addr = htonl(address);
|
||||
sa->sa4.sin_family = AF_INET;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -146,7 +146,11 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
}
|
||||
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in *)
|
||||
(iterator->ai_addr))->sin_addr.s_addr));
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
(*env)->SetObjectArrayElement(env, ret, i++, iaObj);
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -187,7 +187,11 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
(*env)->SetObjectArrayElement(env, ret, (inetIndex | originalIndex), iaObj);
|
||||
inetIndex++;
|
||||
} else if (iterator->ai_family == AF_INET6) {
|
||||
@ -208,6 +212,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
setInet6Address_scopeid(env, iaObj, scope);
|
||||
}
|
||||
setInetAddress_hostName(env, iaObj, host);
|
||||
if ((*env)->ExceptionCheck(env))
|
||||
goto cleanupAndReturn;
|
||||
(*env)->SetObjectArrayElement(env, ret, (inet6Index | originalIndex), iaObj);
|
||||
inet6Index++;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -586,6 +586,7 @@ jobject createNetworkInterface
|
||||
/* default ctor will set family to AF_INET */
|
||||
|
||||
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.sa4.sin_addr.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
if (addrs->mask != -1) {
|
||||
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
|
||||
if (ibObj == NULL) {
|
||||
@ -599,6 +600,7 @@ jobject createNetworkInterface
|
||||
return NULL;
|
||||
}
|
||||
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.sa4.sin_addr.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
(*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
|
||||
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
|
||||
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
|
||||
@ -754,8 +756,9 @@ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
|
||||
(JNIEnv *env, jclass cls, jobject iaObj)
|
||||
{
|
||||
netif *ifList, *curr;
|
||||
jint addr = getInetAddress_addr(env, iaObj);
|
||||
jobject netifObj = NULL;
|
||||
jint addr = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
|
||||
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
|
||||
if (ipv6_available()) {
|
||||
|
@ -584,7 +584,7 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
|
||||
/* default ctor will set family to AF_INET */
|
||||
|
||||
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.sa4.sin_addr.s_addr));
|
||||
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
|
||||
if (ibObj == NULL) {
|
||||
free_netaddr(netaddrP);
|
||||
@ -597,6 +597,7 @@ static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
|
||||
return NULL;
|
||||
}
|
||||
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.sa4.sin_addr.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
(*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
|
||||
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
|
||||
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
|
||||
|
@ -219,16 +219,16 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
|
||||
jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
|
||||
int ipv6_supported = ipv6_available();
|
||||
int fd, fd1 = -1, lcladdrlen = 0;
|
||||
jint family;
|
||||
SOCKETADDRESS lcladdr;
|
||||
|
||||
if (getInetAddress_family(env, addressObj) == java_net_InetAddress_IPv6 &&
|
||||
!ipv6_supported)
|
||||
{
|
||||
family = getInetAddress_family(env, addressObj);
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||
"Protocol family not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
|
||||
return;
|
||||
@ -344,6 +344,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0
|
||||
}
|
||||
|
||||
family = getInetAddress_family(env, address);
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (family == java_net_InetAddress_IPv6 && !ipv6_available()) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||
"Protocol family not supported");
|
||||
@ -455,6 +456,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send
|
||||
}
|
||||
|
||||
family = getInetAddress_family(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (family == java_net_InetAddress_IPv4) {
|
||||
fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
|
||||
} else {
|
||||
@ -584,6 +586,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
|
||||
return -1;
|
||||
} else {
|
||||
address = getInetAddress_addr(env, addressObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
/* We only handle IPv4 for now. Will support IPv6 once its in the os */
|
||||
family = AF_INET;
|
||||
}
|
||||
@ -657,7 +660,9 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
|
||||
return 0;
|
||||
}
|
||||
setInetAddress_addr(env, addressObj, ntohl(remote_addr.sa4.sin_addr.s_addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
setInetAddress_family(env, addressObj, java_net_InetAddress_IPv4);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
|
||||
/* return port */
|
||||
return ntohs(remote_addr.sa4.sin_port);
|
||||
@ -1349,6 +1354,7 @@ static int getInetAddrFromIf (JNIEnv *env, int family, jobject nif, jobject *iad
|
||||
int fam;
|
||||
addr = (*env)->GetObjectArrayElement(env, addrArray, i);
|
||||
fam = getInetAddress_family(env, addr);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
if (fam == family) {
|
||||
*iaddr = addr;
|
||||
return 0;
|
||||
@ -1367,6 +1373,7 @@ static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr)
|
||||
}
|
||||
|
||||
iaddr->s_addr = htonl(getInetAddress_addr(env, addr));
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1471,6 +1478,7 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
|
||||
struct in_addr in;
|
||||
|
||||
in.s_addr = htonl(getInetAddress_addr(env, value));
|
||||
JNU_CHECK_EXCEPTION(env);
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(const char*)&in, sizeof(in)) < 0) {
|
||||
JNU_ThrowByNameWithMessageAndLastError
|
||||
@ -1712,7 +1720,7 @@ static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint
|
||||
CHECK_NULL_RETURN(addr, NULL);
|
||||
|
||||
setInetAddress_addr(env, addr, ntohl(in.s_addr));
|
||||
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
/*
|
||||
* For IP_MULTICAST_IF return InetAddress
|
||||
*/
|
||||
|
@ -794,6 +794,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
jboolean v4MappedAddress)
|
||||
{
|
||||
jint family = getInetAddress_family(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
memset((char *)sa, 0, sizeof(SOCKETADDRESS));
|
||||
|
||||
if (ipv6_available() &&
|
||||
@ -808,6 +809,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
// convert to IPv4-mapped address
|
||||
memset((char *)caddr, 0, 16);
|
||||
address = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
if (address == INADDR_ANY) {
|
||||
/* we would always prefer IPv6 wildcard address
|
||||
* caddr[10] = 0xff;
|
||||
@ -846,6 +848,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
return -1;
|
||||
}
|
||||
address = getInetAddress_addr(env, iaObj);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, -1);
|
||||
sa->sa4.sin_port = htons((short)port);
|
||||
sa->sa4.sin_addr.s_addr = (u_long)htonl(address);
|
||||
sa->sa4.sin_family = AF_INET;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -364,11 +364,11 @@ public class FileManager {
|
||||
* @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5
|
||||
*/
|
||||
public static boolean moveToTrash(final File file) throws FileNotFoundException {
|
||||
if (file == null || !file.exists()) throw new FileNotFoundException();
|
||||
if (file == null) throw new FileNotFoundException();
|
||||
final String fileName = file.getAbsolutePath();
|
||||
|
||||
final SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) security.checkWrite(fileName);
|
||||
if (security != null) security.checkDelete(fileName);
|
||||
|
||||
return _moveToTrash(fileName);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,6 +42,9 @@ import java.io.FilePermission;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.swing.JMenuBar;
|
||||
@ -364,14 +367,10 @@ public class Desktop {
|
||||
* @throws IllegalArgumentException if file doesn't exist
|
||||
*/
|
||||
private static void checkFileValidation(File file) {
|
||||
if (file == null) throw new NullPointerException("File must not be null");
|
||||
|
||||
if (!file.exists()) {
|
||||
throw new IllegalArgumentException("The file: "
|
||||
+ file.getPath() + " doesn't exist.");
|
||||
}
|
||||
|
||||
file.canRead();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -425,6 +424,7 @@ public class Desktop {
|
||||
* @see java.awt.AWTPermission
|
||||
*/
|
||||
public void open(File file) throws IOException {
|
||||
file = new File(file.getPath());
|
||||
checkAWTPermission();
|
||||
checkExec();
|
||||
checkActionSupport(Action.OPEN);
|
||||
@ -456,6 +456,7 @@ public class Desktop {
|
||||
* @see java.awt.AWTPermission
|
||||
*/
|
||||
public void edit(File file) throws IOException {
|
||||
file = new File(file.getPath());
|
||||
checkAWTPermission();
|
||||
checkExec();
|
||||
checkActionSupport(Action.EDIT);
|
||||
@ -486,6 +487,7 @@ public class Desktop {
|
||||
* allowed to create a subprocess
|
||||
*/
|
||||
public void print(File file) throws IOException {
|
||||
file = new File(file.getPath());
|
||||
checkExec();
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
@ -614,14 +616,6 @@ public class Desktop {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDelete() throws SecurityException {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new FilePermission("<<ALL FILES>>",
|
||||
SecurityConstants.FILE_DELETE_ACTION));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkQuitPermission() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
@ -950,6 +944,8 @@ public class Desktop {
|
||||
* @since 9
|
||||
*/
|
||||
public void openHelpViewer() {
|
||||
checkAWTPermission();
|
||||
checkExec();
|
||||
checkEventsProcessingPermission();
|
||||
checkActionSupport(Action.APP_HELP_VIEWER);
|
||||
peer.openHelpViewer();
|
||||
@ -995,9 +991,15 @@ public class Desktop {
|
||||
* @since 9
|
||||
*/
|
||||
public void browseFileDirectory(File file) {
|
||||
checkRead();
|
||||
file = new File(file.getPath());
|
||||
checkAWTPermission();
|
||||
checkExec();
|
||||
checkActionSupport(Action.BROWSE_FILE_DIR);
|
||||
checkFileValidation(file);
|
||||
File parentFile = file.getParentFile();
|
||||
if (parentFile == null || !parentFile.exists()) {
|
||||
throw new IllegalArgumentException("Parent folder doesn't exist");
|
||||
}
|
||||
peer.browseFileDirectory(file);
|
||||
}
|
||||
|
||||
@ -1017,10 +1019,18 @@ public class Desktop {
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public boolean moveToTrash(final File file) {
|
||||
checkDelete();
|
||||
public boolean moveToTrash(File file) {
|
||||
file = new File(file.getPath());
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkDelete(file.getPath());
|
||||
}
|
||||
checkActionSupport(Action.MOVE_TO_TRASH);
|
||||
checkFileValidation(file);
|
||||
final File finalFile = file;
|
||||
AccessController.doPrivileged((PrivilegedAction<?>) () -> {
|
||||
checkFileValidation(finalFile);
|
||||
return null;
|
||||
});
|
||||
return peer.moveToTrash(file);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -265,7 +265,7 @@ static void AddFontsToX11FontPath ( fDirRecord *fDirP )
|
||||
}
|
||||
|
||||
|
||||
newFontPath = SAFE_SIZE_ARRAY_ALLOC(malloc, totalDirCount, sizeof ( char **) );
|
||||
newFontPath = SAFE_SIZE_ARRAY_ALLOC(malloc, totalDirCount, sizeof(char *));
|
||||
/* if it fails free things and get out */
|
||||
if ( newFontPath == NULL ) {
|
||||
free ( ( void *) appendDirList );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,8 +44,11 @@ import javax.naming.ldap.Control;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
|
||||
/**
|
||||
* A thread that creates a connection to an LDAP server.
|
||||
@ -158,7 +161,18 @@ public final class Connection implements Runnable {
|
||||
|
||||
int readTimeout;
|
||||
int connectTimeout;
|
||||
private static final boolean IS_HOSTNAME_VERIFICATION_DISABLED
|
||||
= hostnameVerificationDisabledValue();
|
||||
|
||||
private static boolean hostnameVerificationDisabledValue() {
|
||||
PrivilegedAction<String> act = () -> System.getProperty(
|
||||
"com.sun.jndi.ldap.object.disableEndpointIdentification");
|
||||
String prop = AccessController.doPrivileged(act);
|
||||
if (prop == null) {
|
||||
return false;
|
||||
}
|
||||
return prop.isEmpty() ? true : Boolean.parseBoolean(prop);
|
||||
}
|
||||
// true means v3; false means v2
|
||||
// Called in LdapClient.authenticate() (which is synchronized)
|
||||
// when connection is "quiet" and not shared; no need to synchronize
|
||||
@ -321,15 +335,20 @@ public final class Connection implements Runnable {
|
||||
// the SSL handshake following socket connection as part of the timeout.
|
||||
// So explicitly set a socket read timeout, trigger the SSL handshake,
|
||||
// then reset the timeout.
|
||||
if (connectTimeout > 0 && socket instanceof SSLSocket) {
|
||||
if (socket instanceof SSLSocket) {
|
||||
SSLSocket sslSocket = (SSLSocket) socket;
|
||||
int socketTimeout = sslSocket.getSoTimeout();
|
||||
|
||||
if (!IS_HOSTNAME_VERIFICATION_DISABLED) {
|
||||
SSLParameters param = sslSocket.getSSLParameters();
|
||||
param.setEndpointIdentificationAlgorithm("LDAPS");
|
||||
sslSocket.setSSLParameters(param);
|
||||
}
|
||||
if (connectTimeout > 0) {
|
||||
sslSocket.setSoTimeout(connectTimeout); // reuse full timeout value
|
||||
}
|
||||
sslSocket.startHandshake();
|
||||
sslSocket.setSoTimeout(socketTimeout);
|
||||
}
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
@ -1188,7 +1188,7 @@ public interface HttpResponse<T> {
|
||||
|
||||
/**
|
||||
* Returns a response subscriber which publishes the response body
|
||||
* through a {@link Publisher Publisher<List<ByteBuffer>>}.
|
||||
* through a {@code Publisher<List<ByteBuffer>>}.
|
||||
*
|
||||
* <p> The {@link HttpResponse} using this subscriber is available
|
||||
* immediately after the response headers have been read, without
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -192,7 +192,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade
|
||||
}
|
||||
dprintf1("-size: %d\n", size);
|
||||
|
||||
if (size) {
|
||||
if (size != 0) {
|
||||
mszReaders = malloc(size);
|
||||
if (mszReaders == NULL) {
|
||||
throwOutOfMemoryError(env, NULL);
|
||||
@ -205,6 +205,8 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReade
|
||||
return NULL;
|
||||
}
|
||||
dprintf1("-String: %s\n", mszReaders);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = pcsc_multi2jstring(env, mszReaders);
|
||||
|
@ -146,6 +146,7 @@ public final class BinaryContainer implements SymbolTable {
|
||||
{"SharedRuntime::exception_handler_for_return_address", "_aot_exception_handler_for_return_address"},
|
||||
{"SharedRuntime::register_finalizer", "_aot_register_finalizer"},
|
||||
{"SharedRuntime::OSR_migration_end", "_aot_OSR_migration_end"},
|
||||
{"SharedRuntime::enable_stack_reserved_zone", "_aot_enable_stack_reserved_zone"},
|
||||
{"CompilerRuntime::resolve_dynamic_invoke", "_aot_resolve_dynamic_invoke"},
|
||||
{"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"},
|
||||
{"CompilerRuntime::resolve_klass_by_symbol", "_aot_resolve_klass_by_symbol"},
|
||||
|
@ -1552,7 +1552,9 @@ public class Modules extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
addExports.forEach((exportsFrom, exports) -> {
|
||||
if (msym.readModules.contains(exportsFrom)) {
|
||||
addVisiblePackages(msym, seen, exportsFrom, exports);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -80,12 +80,12 @@ ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
|
||||
group, timing));
|
||||
}
|
||||
} else {
|
||||
kt.flag = (mp_sign)0;
|
||||
if (group->meth->field_enc) {
|
||||
MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
|
||||
MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
|
||||
MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group, timing));
|
||||
} else {
|
||||
kt.flag = (mp_sign)0;
|
||||
MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group, timing));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -110,7 +110,7 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend {
|
||||
|
||||
@Override
|
||||
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) {
|
||||
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub);
|
||||
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub, config.requiresReservedStackCheck(graph.getMethods()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -46,7 +46,7 @@ public class AArch64HotSpotDeoptimizeCallerOp extends AArch64HotSpotEpilogueOp {
|
||||
|
||||
@Override
|
||||
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
|
||||
leaveFrame(crb, masm, /* emitSafepoint */false);
|
||||
leaveFrame(crb, masm, /* emitSafepoint */false, false);
|
||||
AArch64Call.directJmp(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,14 +24,29 @@
|
||||
|
||||
package org.graalvm.compiler.hotspot.aarch64;
|
||||
|
||||
import static jdk.vm.ci.aarch64.AArch64.lr;
|
||||
import static jdk.vm.ci.aarch64.AArch64.sp;
|
||||
import static jdk.vm.ci.aarch64.AArch64.zr;
|
||||
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
|
||||
|
||||
import org.graalvm.compiler.asm.Label;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64Address;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister;
|
||||
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
|
||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
|
||||
import org.graalvm.compiler.lir.LIRInstructionClass;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64BlockEndOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64Call;
|
||||
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
|
||||
|
||||
import jdk.vm.ci.code.CallingConvention;
|
||||
import jdk.vm.ci.code.Register;
|
||||
import jdk.vm.ci.code.RegisterValue;
|
||||
|
||||
/**
|
||||
* Superclass for operations that leave a method's frame.
|
||||
@ -53,9 +68,31 @@ abstract class AArch64HotSpotEpilogueOp extends AArch64BlockEndOp {
|
||||
this.thread = null; // no safepoint
|
||||
}
|
||||
|
||||
protected void leaveFrame(CompilationResultBuilder crb, AArch64MacroAssembler masm, boolean emitSafepoint) {
|
||||
protected void leaveFrame(CompilationResultBuilder crb, AArch64MacroAssembler masm, boolean emitSafepoint, boolean requiresReservedStackAccessCheck) {
|
||||
assert crb.frameContext != null : "We never elide frames in aarch64";
|
||||
crb.frameContext.leave(crb);
|
||||
if (requiresReservedStackAccessCheck) {
|
||||
HotSpotForeignCallsProvider foreignCalls = (HotSpotForeignCallsProvider) crb.foreignCalls;
|
||||
Label noReserved = new Label();
|
||||
try (ScratchRegister sc = masm.getScratchRegister()) {
|
||||
Register scratch = sc.getRegister();
|
||||
masm.ldr(64, scratch, masm.makeAddress(thread, config.javaThreadReservedStackActivationOffset, 8));
|
||||
masm.subs(64, zr, sp, scratch);
|
||||
}
|
||||
masm.branchConditionally(AArch64Assembler.ConditionFlag.LO, noReserved);
|
||||
ForeignCallLinkage enableStackReservedZone = foreignCalls.lookupForeignCall(ENABLE_STACK_RESERVED_ZONE);
|
||||
CallingConvention cc = enableStackReservedZone.getOutgoingCallingConvention();
|
||||
assert cc.getArgumentCount() == 1;
|
||||
Register arg0 = ((RegisterValue) cc.getArgument(0)).getRegister();
|
||||
masm.mov(64, arg0, thread);
|
||||
try (ScratchRegister sc = masm.getScratchRegister()) {
|
||||
masm.stp(64, fp, lr, AArch64Address.createPreIndexedImmediateAddress(sp, -2));
|
||||
AArch64Call.directCall(crb, masm, enableStackReservedZone, sc.getRegister(), null);
|
||||
masm.ldp(64, fp, lr, AArch64Address.createPostIndexedImmediateAddress(sp, 2));
|
||||
}
|
||||
AArch64Call.directJmp(crb, masm, foreignCalls.lookupForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR));
|
||||
masm.bind(noReserved);
|
||||
}
|
||||
if (emitSafepoint) {
|
||||
try (ScratchRegister sc = masm.getScratchRegister()) {
|
||||
Register scratch = sc.getRegister();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,10 +24,10 @@
|
||||
|
||||
package org.graalvm.compiler.hotspot.aarch64;
|
||||
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
|
||||
import static jdk.vm.ci.aarch64.AArch64.sp;
|
||||
import static jdk.vm.ci.code.ValueUtil.asRegister;
|
||||
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
|
||||
|
||||
import org.graalvm.compiler.asm.Label;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64Address;
|
||||
@ -69,7 +69,7 @@ public class AArch64HotSpotJumpToExceptionHandlerInCallerOp extends AArch64HotSp
|
||||
|
||||
@Override
|
||||
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
|
||||
leaveFrame(crb, masm, /* emitSafepoint */false);
|
||||
leaveFrame(crb, masm, /* emitSafepoint */false, false);
|
||||
|
||||
if (GraalServices.JAVA_SPECIFICATION_VERSION < 8) {
|
||||
// Restore sp from fp if the exception PC is a method handle call site.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -28,19 +28,18 @@ package org.graalvm.compiler.hotspot.aarch64;
|
||||
|
||||
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.INITIALIZE_KLASS_BY_SYMBOL;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_KLASS_BY_SYMBOL;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_STRING_BY_SYMBOL;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
|
||||
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.RESOLVE;
|
||||
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.INITIALIZE;
|
||||
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.LOAD_COUNTERS;
|
||||
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.RESOLVE;
|
||||
import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
|
||||
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
|
||||
import org.graalvm.compiler.asm.Label;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
|
||||
@ -81,10 +80,10 @@ import org.graalvm.compiler.lir.aarch64.AArch64FrameMapBuilder;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64Move;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64RestoreRegistersOp;
|
||||
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
|
||||
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
|
||||
import jdk.vm.ci.aarch64.AArch64;
|
||||
import jdk.vm.ci.aarch64.AArch64Kind;
|
||||
@ -93,6 +92,7 @@ import jdk.vm.ci.code.Register;
|
||||
import jdk.vm.ci.code.RegisterValue;
|
||||
import jdk.vm.ci.code.StackSlot;
|
||||
import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
|
||||
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
|
||||
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
|
||||
import jdk.vm.ci.meta.AllocatableValue;
|
||||
import jdk.vm.ci.meta.Constant;
|
||||
@ -103,7 +103,6 @@ import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
import jdk.vm.ci.meta.SpeculationLog;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
|
||||
/**
|
||||
* LIR generator specialized for AArch64 HotSpot.
|
||||
@ -502,7 +501,7 @@ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements H
|
||||
emitMove(operand, input);
|
||||
}
|
||||
Register thread = getProviders().getRegisters().getThreadRegister();
|
||||
append(new AArch64HotSpotReturnOp(operand, getStub() != null, config, thread));
|
||||
append(new AArch64HotSpotReturnOp(operand, getStub() != null, config, thread, getResult().requiresReservedStackAccessCheck()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,10 +24,10 @@
|
||||
|
||||
package org.graalvm.compiler.hotspot.aarch64;
|
||||
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
|
||||
import static jdk.vm.ci.aarch64.AArch64.lr;
|
||||
import static jdk.vm.ci.code.ValueUtil.asRegister;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
|
||||
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
|
||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||
@ -48,9 +48,11 @@ public final class AArch64HotSpotReturnOp extends AArch64HotSpotEpilogueOp {
|
||||
|
||||
@Use({REG, ILLEGAL}) private Value result;
|
||||
private final boolean isStub;
|
||||
private final boolean requiresReservedStackAccessCheck;
|
||||
|
||||
public AArch64HotSpotReturnOp(Value result, boolean isStub, GraalHotSpotVMConfig config, Register thread) {
|
||||
public AArch64HotSpotReturnOp(Value result, boolean isStub, GraalHotSpotVMConfig config, Register thread, boolean requiresReservedStackAccessCheck) {
|
||||
super(TYPE, config, thread);
|
||||
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
|
||||
assert validReturnValue(result);
|
||||
this.result = result;
|
||||
this.isStub = isStub;
|
||||
@ -66,7 +68,7 @@ public final class AArch64HotSpotReturnOp extends AArch64HotSpotEpilogueOp {
|
||||
@Override
|
||||
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
|
||||
final boolean emitSafepoint = !isStub;
|
||||
leaveFrame(crb, masm, emitSafepoint);
|
||||
leaveFrame(crb, masm, emitSafepoint, requiresReservedStackAccessCheck);
|
||||
masm.ret(lr);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,9 +24,9 @@
|
||||
|
||||
package org.graalvm.compiler.hotspot.aarch64;
|
||||
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER;
|
||||
import static jdk.vm.ci.aarch64.AArch64.lr;
|
||||
import static jdk.vm.ci.code.ValueUtil.asRegister;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER;
|
||||
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
|
||||
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
|
||||
@ -57,7 +57,7 @@ public final class AArch64HotSpotUnwindOp extends AArch64HotSpotEpilogueOp {
|
||||
|
||||
@Override
|
||||
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
|
||||
leaveFrame(crb, masm, /* emitSafepoint */false);
|
||||
leaveFrame(crb, masm, /* emitSafepoint */false, false);
|
||||
|
||||
ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
|
||||
CallingConvention cc = linkage.getOutgoingCallingConvention();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -111,7 +111,7 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend {
|
||||
|
||||
@Override
|
||||
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) {
|
||||
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub);
|
||||
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub, config.requiresReservedStackCheck(graph.getMethods()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -268,7 +268,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
||||
pollOnReturnScratchRegister = findPollOnReturnScratchRegister();
|
||||
}
|
||||
Register thread = getProviders().getRegisters().getThreadRegister();
|
||||
append(new AMD64HotSpotReturnOp(operand, getStub() != null, thread, pollOnReturnScratchRegister, config));
|
||||
append(new AMD64HotSpotReturnOp(operand, getStub() != null, thread, pollOnReturnScratchRegister, config, getResult().requiresReservedStackAccessCheck()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,18 +24,30 @@
|
||||
|
||||
package org.graalvm.compiler.hotspot.amd64;
|
||||
|
||||
import static jdk.vm.ci.amd64.AMD64.r15;
|
||||
import static jdk.vm.ci.amd64.AMD64.rsp;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
|
||||
|
||||
import org.graalvm.compiler.asm.Label;
|
||||
import org.graalvm.compiler.asm.amd64.AMD64Address;
|
||||
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
|
||||
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
|
||||
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
|
||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
|
||||
import org.graalvm.compiler.lir.LIRInstructionClass;
|
||||
import org.graalvm.compiler.lir.Opcode;
|
||||
import org.graalvm.compiler.lir.amd64.AMD64Call;
|
||||
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
|
||||
import org.graalvm.compiler.lir.gen.DiagnosticLIRGeneratorTool.ZapStackArgumentSpaceBeforeInstruction;
|
||||
|
||||
import jdk.vm.ci.amd64.AMD64.CPUFeature;
|
||||
import jdk.vm.ci.code.CallingConvention;
|
||||
import jdk.vm.ci.code.Register;
|
||||
import jdk.vm.ci.code.RegisterValue;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
|
||||
/**
|
||||
@ -50,20 +62,46 @@ final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueBlockEndOp implemen
|
||||
private final Register thread;
|
||||
private final Register scratchForSafepointOnReturn;
|
||||
private final GraalHotSpotVMConfig config;
|
||||
private final boolean requiresReservedStackAccessCheck;
|
||||
|
||||
AMD64HotSpotReturnOp(Value value, boolean isStub, Register thread, Register scratchForSafepointOnReturn, GraalHotSpotVMConfig config) {
|
||||
AMD64HotSpotReturnOp(Value value, boolean isStub, Register thread, Register scratchForSafepointOnReturn, GraalHotSpotVMConfig config, boolean requiresReservedStackAccessCheck) {
|
||||
super(TYPE);
|
||||
this.value = value;
|
||||
this.isStub = isStub;
|
||||
this.thread = thread;
|
||||
this.scratchForSafepointOnReturn = scratchForSafepointOnReturn;
|
||||
this.config = config;
|
||||
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
|
||||
leaveFrameAndRestoreRbp(crb, masm);
|
||||
if (!isStub) {
|
||||
if (requiresReservedStackAccessCheck) {
|
||||
HotSpotForeignCallsProvider foreignCalls = (HotSpotForeignCallsProvider) crb.foreignCalls;
|
||||
|
||||
Label noReserved = new Label();
|
||||
masm.cmpptr(rsp, new AMD64Address(r15, config.javaThreadReservedStackActivationOffset));
|
||||
masm.jccb(AMD64Assembler.ConditionFlag.Below, noReserved);
|
||||
// direct call to runtime without stub needs aligned stack
|
||||
int stackAdjust = crb.target.stackAlignment - crb.target.wordSize;
|
||||
if (stackAdjust > 0) {
|
||||
masm.subq(rsp, stackAdjust);
|
||||
}
|
||||
ForeignCallLinkage enableStackReservedZone = foreignCalls.lookupForeignCall(ENABLE_STACK_RESERVED_ZONE);
|
||||
CallingConvention cc = enableStackReservedZone.getOutgoingCallingConvention();
|
||||
assert cc.getArgumentCount() == 1;
|
||||
Register arg0 = ((RegisterValue) cc.getArgument(0)).getRegister();
|
||||
masm.movq(arg0, thread);
|
||||
AMD64Call.directCall(crb, masm, enableStackReservedZone, null, false, null);
|
||||
if (stackAdjust > 0) {
|
||||
masm.addq(rsp, stackAdjust);
|
||||
}
|
||||
AMD64Call.directJmp(crb, masm, foreignCalls.lookupForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR));
|
||||
masm.bind(noReserved);
|
||||
}
|
||||
|
||||
// Every non-stub compile method must have a poll before the return.
|
||||
AMD64HotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, scratchForSafepointOnReturn);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -152,7 +152,7 @@ public class SPARCHotSpotBackend extends HotSpotHostBackend {
|
||||
|
||||
@Override
|
||||
public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) {
|
||||
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub);
|
||||
return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub, config.requiresReservedStackCheck(graph.getMethods()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -195,7 +195,9 @@ public class SPARCHotSpotBackend extends HotSpotHostBackend {
|
||||
final int frameSize = crb.frameMap.totalFrameSize();
|
||||
final int stackpoinerChange = -frameSize;
|
||||
SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
|
||||
if (!isStub) {
|
||||
emitStackOverflowCheck(crb);
|
||||
}
|
||||
|
||||
if (SPARCAssembler.isSimm13(stackpoinerChange)) {
|
||||
masm.save(sp, stackpoinerChange, sp);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -194,7 +194,7 @@ public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSp
|
||||
emitMove(operand, input);
|
||||
}
|
||||
Register thread = getProviders().getRegisters().getThreadRegister();
|
||||
append(new SPARCHotSpotReturnOp(operand, getStub() != null, config, thread, getSafepointAddressValue()));
|
||||
append(new SPARCHotSpotReturnOp(operand, getStub() != null, config, thread, getSafepointAddressValue(), getResult().requiresReservedStackAccessCheck()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,17 +24,29 @@
|
||||
|
||||
package org.graalvm.compiler.hotspot.sparc;
|
||||
|
||||
import static jdk.vm.ci.sparc.SPARC.sp;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
|
||||
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
|
||||
|
||||
import org.graalvm.compiler.asm.Label;
|
||||
import org.graalvm.compiler.asm.sparc.SPARCAddress;
|
||||
import org.graalvm.compiler.asm.sparc.SPARCAssembler;
|
||||
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
|
||||
import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
|
||||
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
|
||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
|
||||
import org.graalvm.compiler.lir.LIRInstructionClass;
|
||||
import org.graalvm.compiler.lir.Opcode;
|
||||
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
|
||||
import org.graalvm.compiler.lir.sparc.SPARCCall;
|
||||
import org.graalvm.compiler.lir.sparc.SPARCControlFlow.ReturnOp;
|
||||
|
||||
import jdk.vm.ci.code.CallingConvention;
|
||||
import jdk.vm.ci.code.Register;
|
||||
import jdk.vm.ci.code.RegisterValue;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
|
||||
/**
|
||||
@ -47,22 +59,42 @@ final class SPARCHotSpotReturnOp extends SPARCHotSpotEpilogueOp {
|
||||
|
||||
@Use({REG, ILLEGAL}) protected Value value;
|
||||
@Use({REG, ILLEGAL}) protected Value safepointPollAddress;
|
||||
private final boolean requiresReservedStackAccessCheck;
|
||||
private final boolean isStub;
|
||||
private final GraalHotSpotVMConfig config;
|
||||
private final Register thread;
|
||||
|
||||
SPARCHotSpotReturnOp(Value value, boolean isStub, GraalHotSpotVMConfig config, Register thread, Value safepointPoll) {
|
||||
SPARCHotSpotReturnOp(Value value, boolean isStub, GraalHotSpotVMConfig config, Register thread, Value safepointPoll, boolean requiresReservedStackAccessCheck) {
|
||||
super(TYPE, SIZE);
|
||||
this.value = value;
|
||||
this.isStub = isStub;
|
||||
this.config = config;
|
||||
this.thread = thread;
|
||||
this.safepointPollAddress = safepointPoll;
|
||||
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
|
||||
if (!isStub) {
|
||||
if (requiresReservedStackAccessCheck) {
|
||||
try (ScratchRegister sc = masm.getScratchRegister()) {
|
||||
HotSpotForeignCallsProvider foreignCalls = (HotSpotForeignCallsProvider) crb.foreignCalls;
|
||||
Label noReserved = new Label();
|
||||
Register scratch = sc.getRegister();
|
||||
masm.ldx(new SPARCAddress(thread, config.javaThreadReservedStackActivationOffset), scratch);
|
||||
masm.compareBranch(sp, scratch, SPARCAssembler.ConditionFlag.LessUnsigned, SPARCAssembler.CC.Xcc, noReserved, SPARCAssembler.BranchPredict.PREDICT_TAKEN, null);
|
||||
ForeignCallLinkage enableStackReservedZone = foreignCalls.lookupForeignCall(ENABLE_STACK_RESERVED_ZONE);
|
||||
CallingConvention cc = enableStackReservedZone.getOutgoingCallingConvention();
|
||||
assert cc.getArgumentCount() == 1;
|
||||
Register arg0 = ((RegisterValue) cc.getArgument(0)).getRegister();
|
||||
masm.mov(thread, arg0);
|
||||
SPARCCall.directCall(crb, masm, enableStackReservedZone, scratch, null);
|
||||
masm.restoreWindow();
|
||||
SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR));
|
||||
masm.bind(noReserved);
|
||||
}
|
||||
}
|
||||
// Every non-stub compile method must have a poll before the return.
|
||||
SPARCHotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, safepointPollAddress);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -26,12 +26,15 @@ package org.graalvm.compiler.hotspot;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.compiler.core.common.CompressEncoding;
|
||||
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
|
||||
|
||||
import jdk.vm.ci.common.JVMCIError;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
||||
/**
|
||||
* Used to access native configuration details.
|
||||
@ -315,6 +318,17 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
|
||||
public final int jvmciCountersThreadOffset = getFieldOffset("JavaThread::_jvmci_counters", Integer.class, "jlong*");
|
||||
public final int javaThreadReservedStackActivationOffset = versioned.javaThreadReservedStackActivationOffset;
|
||||
|
||||
public boolean requiresReservedStackCheck(List<ResolvedJavaMethod> methods) {
|
||||
if (enableStackReservedZoneAddress != 0 && methods != null) {
|
||||
for (ResolvedJavaMethod method : methods) {
|
||||
if (((HotSpotResolvedJavaMethod) method).hasReservedStackAccess()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* An invalid value for {@link #rtldDefault}.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -50,6 +50,7 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.JavaType;
|
||||
import jdk.vm.ci.runtime.JVMCICompiler;
|
||||
import org.graalvm.compiler.word.Word;
|
||||
|
||||
/**
|
||||
* Common functionality of HotSpot host backends.
|
||||
@ -66,6 +67,10 @@ public abstract class HotSpotHostBackend extends HotSpotBackend {
|
||||
*/
|
||||
public static final ForeignCallDescriptor UNCOMMON_TRAP_HANDLER = new ForeignCallDescriptor("uncommonTrapHandler", void.class);
|
||||
|
||||
public static final ForeignCallDescriptor ENABLE_STACK_RESERVED_ZONE = new ForeignCallDescriptor("enableStackReservedZoneEntry", void.class, Word.class);
|
||||
|
||||
public static final ForeignCallDescriptor THROW_DELAYED_STACKOVERFLOW_ERROR = new ForeignCallDescriptor("throwDelayedStackoverflowError", void.class);
|
||||
|
||||
protected final GraalHotSpotVMConfig config;
|
||||
|
||||
public HotSpotHostBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -46,6 +46,7 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
|
||||
*/
|
||||
private StackSlot deoptimizationRescueSlot;
|
||||
protected final Object stub;
|
||||
private final boolean requiresReservedStackAccessCheck;
|
||||
|
||||
private int maxInterpreterFrameSize;
|
||||
|
||||
@ -55,9 +56,11 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
|
||||
*/
|
||||
private EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
|
||||
|
||||
public HotSpotLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, CallingConvention callingConvention, Object stub) {
|
||||
public HotSpotLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, CallingConvention callingConvention, Object stub,
|
||||
boolean requiresReservedStackAccessCheck) {
|
||||
super(compilationId, lir, frameMapBuilder, callingConvention);
|
||||
this.stub = stub;
|
||||
this.requiresReservedStackAccessCheck = requiresReservedStackAccessCheck;
|
||||
}
|
||||
|
||||
public EconomicMap<LIRFrameState, SaveRegistersOp> getCalleeSaveInfo() {
|
||||
@ -83,4 +86,8 @@ public class HotSpotLIRGenerationResult extends LIRGenerationResult {
|
||||
public int getMaxInterpreterFrameSize() {
|
||||
return maxInterpreterFrameSize;
|
||||
}
|
||||
|
||||
public boolean requiresReservedStackAccessCheck() {
|
||||
return requiresReservedStackAccessCheck;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -66,6 +66,8 @@ import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.
|
||||
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.SAFEPOINT;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.STACK_INSPECTABLE_LEAF;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.DEOPTIMIZATION_HANDLER;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
|
||||
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER;
|
||||
import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C;
|
||||
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
|
||||
@ -251,6 +253,12 @@ public abstract class HotSpotHostForeignCallsProvider extends HotSpotForeignCall
|
||||
registerForeignCall(UNCOMMON_TRAP_HANDLER, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
|
||||
registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
|
||||
|
||||
if (c.enableStackReservedZoneAddress != 0) {
|
||||
assert c.throwDelayedStackOverflowErrorEntry != 0 : "both must exist";
|
||||
registerForeignCall(ENABLE_STACK_RESERVED_ZONE, c.enableStackReservedZoneAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
|
||||
registerForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR, c.throwDelayedStackOverflowErrorEntry, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
|
||||
}
|
||||
|
||||
registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
|
||||
registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
|
||||
registerForeignCall(SIN.foreignCallDescriptor, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
|
||||
|
@ -140,7 +140,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
|
||||
*/
|
||||
@Override
|
||||
public Content getSignature(ExecutableElement method) {
|
||||
Content pre = new HtmlTree(HtmlTag.PRE);
|
||||
HtmlTree pre = new HtmlTree(HtmlTag.PRE);
|
||||
pre.setStyle(HtmlStyle.methodSignature);
|
||||
writer.addAnnotationInfo(method, pre);
|
||||
int annotationLength = pre.charCount();
|
||||
addModifiers(method, pre);
|
||||
|
@ -83,6 +83,7 @@ public enum HtmlStyle {
|
||||
memberNameLabel,
|
||||
memberNameLink,
|
||||
memberSummary,
|
||||
methodSignature,
|
||||
moduleLabelInPackage,
|
||||
moduleLabelInType,
|
||||
nameValue,
|
||||
|
@ -827,7 +827,7 @@ ul.ui-autocomplete li {
|
||||
margin: -100px 0 0 100px;
|
||||
z-index: 1;
|
||||
}
|
||||
.details pre {
|
||||
.methodSignature {
|
||||
white-space:normal;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -211,7 +211,7 @@ loadTransport(const char *name, TransportInfo *info)
|
||||
JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm);
|
||||
|
||||
/* Try version 1.1 first, fallback to 1.0 on error */
|
||||
for (i = 0; i < sizeof(supported_versions); ++i) {
|
||||
for (i = 0; i < sizeof(supported_versions)/sizeof(jint); ++i) {
|
||||
rc = (*onLoad)(jvm, &callback, supported_versions[i], &t);
|
||||
if (rc != JNI_EVERSION) {
|
||||
info->transportVersion = supported_versions[i];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2681,6 +2681,9 @@ void unpacker::attr_definitions::readBandData(int idx) {
|
||||
PRINTCR((1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s",
|
||||
count, isRedefined(idx), isPredefined(idx),
|
||||
ATTR_CONTEXT_NAME[attrc], lo->name));
|
||||
} else {
|
||||
abort("layout_definition pointer must not be NULL");
|
||||
return;
|
||||
}
|
||||
bool hasCallables = lo->hasCallables();
|
||||
band** bands = lo->bands();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -64,6 +64,9 @@ Java_com_sun_security_auth_module_UnixSystem_getUnixInfo
|
||||
jclass cls;
|
||||
|
||||
numSuppGroups = getgroups(0, NULL);
|
||||
if (numSuppGroups == -1) {
|
||||
return;
|
||||
}
|
||||
groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t));
|
||||
if (groups == NULL) {
|
||||
jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError");
|
||||
|
@ -67,8 +67,6 @@ gc/g1/plab/TestPLABResize.java 8191048 generi
|
||||
|
||||
gc/TestNUMAPageSize.java 8194949 generic-all
|
||||
|
||||
runtime/ReservedStack/ReservedStackTestCompiler.java 8181855 generic-all
|
||||
|
||||
serviceability/jvmti/GetModulesInfo/JvmtiGetAllModulesTest.java 8195156 generic-all
|
||||
|
||||
compiler/compilercontrol/directives/LogTest.java 8181753 generic-all
|
||||
@ -116,20 +114,17 @@ vmTestbase/nsk/stress/strace/strace006.java 8191047 generi
|
||||
vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 8191047 generic-all
|
||||
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn009/forceEarlyReturn009.java 8191047 generic-all
|
||||
|
||||
vmTestbase/nsk/jdi/ReferenceType/instances/instances001/instances001.java 8195600 generic-all
|
||||
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn007/TestDescription.java 8195600 generic-all
|
||||
|
||||
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance001/TestDescription.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance002/TestDescription.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance003/TestDescription.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects001/referringObjects001.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/ReferenceType/instances/instances002/instances002.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/stress/MonitorEvents/MonitorEvents002/TestDescription.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/stress/serial/heapwalking001/TestDescription.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/stress/serial/heapwalking002/TestDescription.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/stress/serial/mixed002/TestDescription.java 8203174 generic-all
|
||||
vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemoryException001.java 8203174 generic-all
|
||||
|
||||
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses026/TestDescription.java 8195627 generic-all
|
||||
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses028/TestDescription.java 8195627 generic-all
|
||||
@ -175,6 +170,7 @@ org.graalvm.compiler.core.test.ProfilingInfoTest
|
||||
org.graalvm.compiler.hotspot.test.CompilationWrapperTest 8205081
|
||||
org.graalvm.compiler.hotspot.test.HsErrLogTest 8205081
|
||||
org.graalvm.compiler.hotspot.test.OptionsInFileTest 8205081
|
||||
org.graalvm.compiler.hotspot.test.ReservedStackAccessTest 8205081
|
||||
org.graalvm.compiler.replacements.test.classfile.ClassfileBytecodeProviderTest 8205081
|
||||
org.graalvm.compiler.replacements.test.classfile.RedefineIntrinsicTest 8205081
|
||||
|
||||
|
@ -81,8 +81,7 @@ runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all
|
||||
|
||||
serviceability/sa/TestRevPtrsForInvokeDynamic.java 8191270 generic-all
|
||||
serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
|
||||
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatArrayCorrectnessTest.java 8205541 generic-all
|
||||
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatRateTest.java 8205652 generic-all
|
||||
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatRateTest.java 8207765 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
|
38
test/hotspot/jtreg/compiler/graalunit/JttLangMathALTest.java
Normal file
38
test/hotspot/jtreg/compiler/graalunit/JttLangMathALTest.java
Normal 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
|
||||
*/
|
38
test/hotspot/jtreg/compiler/graalunit/JttLangMathMZTest.java
Normal file
38
test/hotspot/jtreg/compiler/graalunit/JttLangMathMZTest.java
Normal 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
|
||||
*/
|
@ -34,5 +34,5 @@
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
|
||||
*
|
||||
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.lang.[mM] -exclude ExcludeList.txt
|
||||
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.reflect.Field_get -exclude ExcludeList.txt
|
||||
*/
|
@ -34,5 +34,5 @@
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
|
||||
*
|
||||
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.reflect.[fF] -exclude ExcludeList.txt
|
||||
* @run main/othervm compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.jtt.reflect.Field_set -exclude ExcludeList.txt
|
||||
*/
|
@ -25,13 +25,15 @@ JttHotpath org.graalvm.compiler.jtt.hotpath
|
||||
JttHotspot org.graalvm.compiler.jtt.hotspot
|
||||
JttJdk org.graalvm.compiler.jtt.jdk
|
||||
JttLangAL org.graalvm.compiler.jtt.lang.[a-lA-L]
|
||||
JttLangM org.graalvm.compiler.jtt.lang.[mM]
|
||||
JttLangMathAL org.graalvm.compiler.jtt.lang.Math_[a-lA-L]
|
||||
JttLangMathMZ org.graalvm.compiler.jtt.lang.Math_[m-zM-Z]
|
||||
JttLangNZ org.graalvm.compiler.jtt.lang.[n-zN-Z]
|
||||
JttLoop org.graalvm.compiler.jtt.loop
|
||||
Jtt.Micro org.graalvm.compiler.jtt.micro
|
||||
JttOptimize org.graalvm.compiler.jtt.optimize
|
||||
JttReflectAE org.graalvm.compiler.jtt.reflect.[a-eA-E]
|
||||
JttReflectF org.graalvm.compiler.jtt.reflect.[fF]
|
||||
JttReflectFieldGet org.graalvm.compiler.jtt.reflect.Field_get
|
||||
JttReflectFieldSet org.graalvm.compiler.jtt.reflect.Field_set
|
||||
JttReflectGZ org.graalvm.compiler.jtt.reflect.[g-zG-Z]
|
||||
JttThreads org.graalvm.compiler.jtt.threads
|
||||
LirJtt org.graalvm.compiler.lir.jtt
|
||||
|
@ -124,6 +124,8 @@ public class GraalUnitTestLauncher {
|
||||
throw new Exception("Failed to find tests, VM crashed with exit code " + exitCode);
|
||||
}
|
||||
|
||||
System.out.println("INFO: command output: [" + out.getOutput() + "]");
|
||||
|
||||
String[] lines = out.getStdout().split(" ");
|
||||
if (lines.length > 1) { // first line contains jar file name
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
|
@ -130,7 +130,7 @@ public class TestRTMAbortRatio {
|
||||
|
||||
@Override
|
||||
public String[] getMethodsToCompileNames() {
|
||||
return new String[] { getMethodWithLockName() };
|
||||
return new String[] { getMethodWithLockName(), "*.pageSize" };
|
||||
}
|
||||
|
||||
public void lock(boolean abort) {
|
||||
|
@ -47,6 +47,7 @@ import compiler.testlibrary.rtm.RTMTestBase;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.cli.CommandLineOptionTest;
|
||||
import jdk.test.lib.Platform;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -59,11 +60,18 @@ public class TestRTMSpinLoopCount {
|
||||
private static final int RTM_RETRY_COUNT = 1000;
|
||||
private static final boolean INFLATE_MONITOR = true;
|
||||
private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L;
|
||||
private static final int[] SPIN_LOOP_COUNTS
|
||||
= new int[] { 0, 100, 1_000, 10_000, 100_000 };
|
||||
private static int[] SPIN_LOOP_COUNTS;
|
||||
|
||||
protected void runTestCases() throws Throwable {
|
||||
|
||||
if (Platform.isPPC()) {
|
||||
SPIN_LOOP_COUNTS = new int[] { 0, 10, 100, 1_000, 10_000 };
|
||||
} else {
|
||||
SPIN_LOOP_COUNTS = new int[] { 0, 100, 1_000, 10_000, 100_000 };
|
||||
}
|
||||
|
||||
long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length];
|
||||
|
||||
for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) {
|
||||
aborts[i] = getAbortsCountOnLockBusy(
|
||||
TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]);
|
||||
|
@ -45,8 +45,8 @@ public class HeapMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
/** Set a specific sampling rate, 0 samples every allocation. */
|
||||
public native static void setSamplingRate(int rate);
|
||||
/** Set a specific sampling interval, 0 samples every allocation. */
|
||||
public native static void setSamplingInterval(int interval);
|
||||
public native static void enableSamplingEvents();
|
||||
public native static boolean enableSamplingEventsForTwoThreads(Thread firstThread, Thread secondThread);
|
||||
public native static void disableSamplingEvents();
|
||||
@ -131,7 +131,7 @@ public class HeapMonitor {
|
||||
|
||||
public static int[][][] sampleEverything() {
|
||||
enableSamplingEvents();
|
||||
setSamplingRate(0);
|
||||
setSamplingInterval(0);
|
||||
|
||||
// Loop around an allocation loop and wait until the tlabs have settled.
|
||||
final int maxTries = 10;
|
||||
|
@ -26,7 +26,7 @@ package MyPackage;
|
||||
/**
|
||||
* @test
|
||||
* @build Frame HeapMonitor
|
||||
* @summary Verifies the JVMTI Heap Monitor rate when allocating arrays.
|
||||
* @summary Verifies the JVMTI Heap Monitor interval when allocating arrays.
|
||||
* @compile HeapMonitorArrayAllSampledTest.java
|
||||
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorArrayAllSampledTest
|
||||
*/
|
||||
@ -46,7 +46,7 @@ public class HeapMonitorArrayAllSampledTest {
|
||||
public static void main(String[] args) {
|
||||
int sizes[] = {1000, 10000, 100000, 1000000};
|
||||
|
||||
HeapMonitor.setSamplingRate(0);
|
||||
HeapMonitor.setSamplingInterval(0);
|
||||
HeapMonitor.enableSamplingEvents();
|
||||
|
||||
for (int currentSize : sizes) {
|
||||
@ -56,8 +56,8 @@ public class HeapMonitorArrayAllSampledTest {
|
||||
allocate(currentSize);
|
||||
|
||||
// 10% error ensures a sanity test without becoming flaky.
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
|
||||
// statistical geometric variable around the sampling rate. This means that the test could be
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
|
||||
// statistical geometric variable around the sampling interval. This means that the test could be
|
||||
// unlucky and not achieve the mean average fast enough for the test case.
|
||||
if (!HeapMonitor.statsHaveExpectedNumberSamples(maxIteration, 10)) {
|
||||
throw new RuntimeException("Statistics should show about " + maxIteration + " samples.");
|
||||
|
@ -25,7 +25,7 @@ package MyPackage;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Verifies the JVMTI SetHeapSamplingRate returns an illegal argument for negative ints.
|
||||
* @summary Verifies the JVMTI SetHeapSamplingInterval returns an illegal argument for negative ints.
|
||||
* @build Frame HeapMonitor
|
||||
* @compile HeapMonitorIllegalArgumentTest.java
|
||||
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorIllegalArgumentTest
|
||||
|
@ -26,7 +26,7 @@ package MyPackage;
|
||||
/**
|
||||
* @test
|
||||
* @build Frame HeapMonitor
|
||||
* @summary Verifies the JVMTI Heap Monitor rate when allocating arrays.
|
||||
* @summary Verifies the JVMTI Heap Monitor interval when allocating arrays.
|
||||
* @compile HeapMonitorStatArrayCorrectnessTest.java
|
||||
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatArrayCorrectnessTest
|
||||
*/
|
||||
@ -46,8 +46,6 @@ public class HeapMonitorStatArrayCorrectnessTest {
|
||||
public static void main(String[] args) {
|
||||
int sizes[] = {1000, 10000, 100000};
|
||||
|
||||
HeapMonitor.enableSamplingEvents();
|
||||
|
||||
for (int currentSize : sizes) {
|
||||
System.out.println("Testing size " + currentSize);
|
||||
|
||||
@ -56,12 +54,16 @@ public class HeapMonitorStatArrayCorrectnessTest {
|
||||
throw new RuntimeException("Should not have any events stored yet.");
|
||||
}
|
||||
|
||||
HeapMonitor.enableSamplingEvents();
|
||||
|
||||
// 111 is as good a number as any.
|
||||
final int samplingMultiplier = 111;
|
||||
HeapMonitor.setSamplingRate(samplingMultiplier * currentSize);
|
||||
HeapMonitor.setSamplingInterval(samplingMultiplier * currentSize);
|
||||
|
||||
allocate(currentSize);
|
||||
|
||||
HeapMonitor.disableSamplingEvents();
|
||||
|
||||
// For simplifications, we ignore the array memory usage for array internals (with the array
|
||||
// sizes requested, it should be a negligible oversight).
|
||||
//
|
||||
@ -77,8 +79,8 @@ public class HeapMonitorStatArrayCorrectnessTest {
|
||||
expected /= samplingMultiplier;
|
||||
|
||||
// 10% error ensures a sanity test without becoming flaky.
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
|
||||
// statistical geometric variable around the sampling rate. This means that the test could be
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
|
||||
// statistical geometric variable around the sampling interval. This means that the test could be
|
||||
// unlucky and not achieve the mean average fast enough for the test case.
|
||||
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
|
||||
throw new RuntimeException("Statistics should show about " + expected + " samples.");
|
||||
|
@ -25,61 +25,67 @@ package MyPackage;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Verifies the JVMTI Heap Monitor sampling rate average.
|
||||
* @summary Verifies the JVMTI Heap Monitor sampling interval average.
|
||||
* @build Frame HeapMonitor
|
||||
* @compile HeapMonitorStatRateTest.java
|
||||
* @compile HeapMonitorStatIntervalTest.java
|
||||
* @requires vm.compMode != "Xcomp"
|
||||
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatRateTest
|
||||
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatIntervalTest
|
||||
*/
|
||||
|
||||
public class HeapMonitorStatRateTest {
|
||||
public class HeapMonitorStatIntervalTest {
|
||||
|
||||
private native static double getAverageRate();
|
||||
private native static double getAverageInterval();
|
||||
|
||||
private static boolean testRateOnce(int rate, boolean throwIfFailure) {
|
||||
private static boolean testIntervalOnce(int interval, boolean throwIfFailure) {
|
||||
HeapMonitor.resetEventStorage();
|
||||
HeapMonitor.setSamplingRate(rate);
|
||||
HeapMonitor.setSamplingInterval(interval);
|
||||
|
||||
HeapMonitor.enableSamplingEvents();
|
||||
|
||||
int allocationTotal = 10 * 1024 * 1024;
|
||||
int allocationIterations = 10;
|
||||
|
||||
double actualCount = 0;
|
||||
for (int i = 0; i < allocationIterations; i++) {
|
||||
HeapMonitor.resetEventStorage();
|
||||
HeapMonitor.allocateSize(allocationTotal);
|
||||
actualCount += HeapMonitor.getEventStorageElementCount();
|
||||
}
|
||||
|
||||
HeapMonitor.disableSamplingEvents();
|
||||
|
||||
double actualCount = HeapMonitor.getEventStorageElementCount();
|
||||
double expectedCount = allocationTotal / rate;
|
||||
double expectedCount = allocationTotal * allocationIterations / interval;
|
||||
|
||||
double error = Math.abs(actualCount - expectedCount);
|
||||
double errorPercentage = error / expectedCount * 100;
|
||||
|
||||
boolean failure = (errorPercentage > 10.0);
|
||||
boolean success = (errorPercentage < 10.0);
|
||||
|
||||
if (failure && throwIfFailure) {
|
||||
throw new RuntimeException("Rate average over 10% for rate " + rate + " -> " + actualCount
|
||||
+ ", " + expectedCount);
|
||||
if (!success && throwIfFailure) {
|
||||
throw new RuntimeException("Interval average over 10% for interval " + interval + " -> "
|
||||
+ actualCount + ", " + expectedCount);
|
||||
}
|
||||
|
||||
return failure;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
private static void testRate(int rate) {
|
||||
// Test the rate twice, it can happen that the test is "unlucky" and the rate just goes above
|
||||
private static void testInterval(int interval) {
|
||||
// Test the interval twice, it can happen that the test is "unlucky" and the interval just goes above
|
||||
// the 10% mark. So try again to squash flakiness.
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
|
||||
// statistical geometric variable around the sampling rate. This means that the test could be
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
|
||||
// statistical geometric variable around the sampling interval. This means that the test could be
|
||||
// unlucky and not achieve the mean average fast enough for the test case.
|
||||
if (!testRateOnce(rate, false)) {
|
||||
testRateOnce(rate, true);
|
||||
if (!testIntervalOnce(interval, false)) {
|
||||
testIntervalOnce(interval, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] tab = {1024, 8192};
|
||||
|
||||
for (int rateIdx = 0; rateIdx < tab.length; rateIdx++) {
|
||||
testRate(tab[rateIdx]);
|
||||
for (int intervalIdx = 0; intervalIdx < tab.length; intervalIdx++) {
|
||||
testInterval(tab[intervalIdx]);
|
||||
}
|
||||
}
|
||||
}
|
@ -41,19 +41,22 @@ public class HeapMonitorStatObjectCorrectnessTest {
|
||||
private native static boolean statsHaveExpectedNumberSamples(int expected, int percentError);
|
||||
|
||||
private static void allocate() {
|
||||
emptyStorage();
|
||||
|
||||
HeapMonitor.enableSamplingEvents();
|
||||
for (int j = 0; j < maxIteration; j++) {
|
||||
obj = new BigObject();
|
||||
}
|
||||
HeapMonitor.disableSamplingEvents();
|
||||
}
|
||||
|
||||
private static void testBigAllocationRate() {
|
||||
private static void testBigAllocationInterval() {
|
||||
final int sizeObject = 1400;
|
||||
|
||||
// 111 is as good a number as any.
|
||||
final int samplingMultiplier = 111;
|
||||
HeapMonitor.setSamplingRate(samplingMultiplier * sizeObject);
|
||||
HeapMonitor.setSamplingInterval(samplingMultiplier * sizeObject);
|
||||
|
||||
emptyStorage();
|
||||
allocate();
|
||||
|
||||
// For simplifications, the code is allocating:
|
||||
@ -76,8 +79,8 @@ public class HeapMonitorStatObjectCorrectnessTest {
|
||||
expected /= samplingMultiplier;
|
||||
|
||||
// 10% error ensures a sanity test without becoming flaky.
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
|
||||
// statistical geometric variable around the sampling rate. This means that the test could be
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
|
||||
// statistical geometric variable around the sampling interval. This means that the test could be
|
||||
// unlucky and not achieve the mean average fast enough for the test case.
|
||||
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
|
||||
throw new RuntimeException("Statistics should show about " + expected + " samples.");
|
||||
@ -94,16 +97,15 @@ public class HeapMonitorStatObjectCorrectnessTest {
|
||||
|
||||
private static void testEveryAllocationSampled() {
|
||||
// 0 means sample every allocation.
|
||||
HeapMonitor.setSamplingRate(0);
|
||||
HeapMonitor.setSamplingInterval(0);
|
||||
|
||||
emptyStorage();
|
||||
allocate();
|
||||
|
||||
double expected = maxIteration;
|
||||
|
||||
// 10% error ensures a sanity test without becoming flaky.
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a
|
||||
// statistical geometric variable around the sampling rate. This means that the test could be
|
||||
// Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
|
||||
// statistical geometric variable around the sampling interval. This means that the test could be
|
||||
// unlucky and not achieve the mean average fast enough for the test case.
|
||||
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
|
||||
throw new RuntimeException("Statistics should show about " + expected + " samples.");
|
||||
@ -111,9 +113,7 @@ public class HeapMonitorStatObjectCorrectnessTest {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
HeapMonitor.enableSamplingEvents();
|
||||
|
||||
testBigAllocationRate();
|
||||
testBigAllocationInterval();
|
||||
testEveryAllocationSampled();
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,8 @@ public class HeapMonitorThreadTest {
|
||||
final int numThreads = 5;
|
||||
List<ThreadInformation> threadList = ThreadInformation.createThreadList(numThreads);
|
||||
|
||||
// Sample at a rate of 8k.
|
||||
HeapMonitor.setSamplingRate(1 << 13);
|
||||
// Sample at a interval of 8k.
|
||||
HeapMonitor.setSamplingInterval(1 << 13);
|
||||
HeapMonitor.enableSamplingEvents();
|
||||
|
||||
System.err.println("Starting threads");
|
||||
|
@ -62,10 +62,10 @@ public class HeapMonitorVMEventsTest implements Cloneable {
|
||||
double diff = Math.abs(first - second) * 100;
|
||||
diff /= first;
|
||||
|
||||
// Accept a 10% error rate: with objects being allocated: this allows a bit of room in
|
||||
// Accept a 10% error interval: with objects being allocated: this allows a bit of room in
|
||||
// case other items are getting allocated during the test.
|
||||
if (diff > 10) {
|
||||
throw new RuntimeException("Error rate is over the accepted rate: " + diff
|
||||
throw new RuntimeException("Error interval is over the accepted interval: " + diff
|
||||
+ ": " + first + " , " + second);
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ extern "C" {
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define PRINT_OUT 0
|
||||
#define PRINT_OUT 1
|
||||
|
||||
static jvmtiEnv *jvmti = NULL;
|
||||
static jvmtiEnv *second_jvmti = NULL;
|
||||
@ -369,7 +369,7 @@ static int event_storage_get_count(EventStorage* storage) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static double event_storage_get_average_rate(EventStorage* storage) {
|
||||
static double event_storage_get_average_interval(EventStorage* storage) {
|
||||
double accumulation = 0;
|
||||
int max_size;
|
||||
int i;
|
||||
@ -839,8 +839,8 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_MyPackage_HeapMonitor_setSamplingRate(JNIEnv* env, jclass cls, jint value) {
|
||||
(*jvmti)->SetHeapSamplingRate(jvmti, value);
|
||||
Java_MyPackage_HeapMonitor_setSamplingInterval(JNIEnv* env, jclass cls, jint value) {
|
||||
(*jvmti)->SetHeapSamplingInterval(jvmti, value);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
@ -940,8 +940,8 @@ Java_MyPackage_HeapMonitorNoCapabilityTest_allSamplingMethodsFail(JNIEnv *env,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (check_capability_error((*jvmti)->SetHeapSamplingRate(jvmti, 1<<19),
|
||||
"Set Heap Sampling Rate")) {
|
||||
if (check_capability_error((*jvmti)->SetHeapSamplingInterval(jvmti, 1<<19),
|
||||
"Set Heap Sampling Interval")) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -950,23 +950,23 @@ Java_MyPackage_HeapMonitorNoCapabilityTest_allSamplingMethodsFail(JNIEnv *env,
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_MyPackage_HeapMonitorIllegalArgumentTest_testIllegalArgument(JNIEnv *env,
|
||||
jclass cls) {
|
||||
if (check_error((*jvmti)->SetHeapSamplingRate(jvmti, 0),
|
||||
"Sampling rate 0 failed\n")){
|
||||
if (check_error((*jvmti)->SetHeapSamplingInterval(jvmti, 0),
|
||||
"Sampling interval 0 failed\n")){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (check_error((*jvmti)->SetHeapSamplingRate(jvmti, 1024),
|
||||
"Sampling rate 1024 failed\n")){
|
||||
if (check_error((*jvmti)->SetHeapSamplingInterval(jvmti, 1024),
|
||||
"Sampling interval 1024 failed\n")){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!check_error((*jvmti)->SetHeapSamplingRate(jvmti, -1),
|
||||
"Sampling rate -1 passed\n")){
|
||||
if (!check_error((*jvmti)->SetHeapSamplingInterval(jvmti, -1),
|
||||
"Sampling interval -1 passed\n")){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!check_error((*jvmti)->SetHeapSamplingRate(jvmti, -1024),
|
||||
"Sampling rate -1024 passed\n")){
|
||||
if (!check_error((*jvmti)->SetHeapSamplingInterval(jvmti, -1024),
|
||||
"Sampling interval -1024 passed\n")){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -974,8 +974,8 @@ Java_MyPackage_HeapMonitorIllegalArgumentTest_testIllegalArgument(JNIEnv *env,
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_MyPackage_HeapMonitorStatRateTest_getAverageRate(JNIEnv *env, jclass cls) {
|
||||
return event_storage_get_average_rate(&global_event_storage);
|
||||
Java_MyPackage_HeapMonitorStatIntervalTest_getAverageInterval(JNIEnv *env, jclass cls) {
|
||||
return event_storage_get_average_interval(&global_event_storage);
|
||||
}
|
||||
|
||||
typedef struct sThreadsFound {
|
||||
|
@ -52,6 +52,7 @@
|
||||
* referrers with supported type(Strong, PhantomReference, SoftReference, WeakReference)
|
||||
*
|
||||
* @requires vm.gc != "Z"
|
||||
* @requires !vm.graal.enabled
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
|
@ -52,6 +52,7 @@
|
||||
* can't force collection of thread group because of thread group always has 1 referrer - parent thread group, so
|
||||
* just test disableCollection/enableCollection don't throw any unexpected exceptions
|
||||
*
|
||||
* @requires !vm.graal.enabled
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
|
@ -52,6 +52,7 @@
|
||||
* - check the number of instances is correct
|
||||
* done
|
||||
*
|
||||
* @requires !vm.graal.enabled
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
|
@ -34,6 +34,7 @@
|
||||
* in debuggee VM through 'ArrayType.newInstance()' till VMOutOfMemoryException. Any other exception
|
||||
* thrown by 'ArrayType.newInstance()' is treated as product bug.
|
||||
*
|
||||
* @requires !vm.graal.enabled
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user