This commit is contained in:
Phil Race 2019-10-18 09:25:06 -07:00
commit 53439611f0
192 changed files with 8379 additions and 897 deletions

View File

@ -591,3 +591,4 @@ cddef3bde924f3ff4f17f3d369280cf69d0450e5 jdk-14+14
d29f0181ba424a95d881aba5eabf2e393abcc70f jdk-14+16
5c83830390baafb76a1fbe33443c57620bd45fb9 jdk-14+17
e84d8379815ba0d3e50fb096d28c25894cb50b8c jdk-14+18
9b67dd88a9313e982ec5f710a7747161bc8f0c23 jdk-14+19

View File

@ -489,31 +489,43 @@ AC_DEFUN([BASIC_SETUP_TOOL],
# for unknown variables in the end.
CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
tool_override=[$]$1
AC_MSG_NOTICE([User supplied override $1="$tool_override"])
# Check if we try to supply an empty value
if test "x[$]$1" = x; then
AC_MSG_NOTICE([Setting user supplied tool $1= (no value)])
if test "x$tool_override" = x; then
AC_MSG_CHECKING([for $1])
AC_MSG_RESULT([disabled])
else
# Split up override in command part and argument part
tool_and_args=($tool_override)
[ tool_command=${tool_and_args[0]} ]
[ unset 'tool_and_args[0]' ]
[ tool_args=${tool_and_args[@]} ]
# Check if the provided tool contains a complete path.
tool_specified="[$]$1"
tool_basename="${tool_specified##*/}"
if test "x$tool_basename" = "x$tool_specified"; then
tool_basename="${tool_command##*/}"
if test "x$tool_basename" = "x$tool_command"; then
# A command without a complete path is provided, search $PATH.
AC_MSG_NOTICE([Will search for user supplied tool $1=$tool_basename])
AC_MSG_NOTICE([Will search for user supplied tool "$tool_basename"])
AC_PATH_PROG($1, $tool_basename)
if test "x[$]$1" = x; then
AC_MSG_ERROR([User supplied tool $tool_basename could not be found])
AC_MSG_ERROR([User supplied tool $1="$tool_basename" could not be found])
fi
else
# Otherwise we believe it is a complete path. Use it as it is.
AC_MSG_NOTICE([Will use user supplied tool $1=$tool_specified])
AC_MSG_CHECKING([for $1])
if test ! -x "$tool_specified"; then
AC_MSG_NOTICE([Will use user supplied tool "$tool_command"])
AC_MSG_CHECKING([for $tool_command])
if test ! -x "$tool_command"; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([User supplied tool $1=$tool_specified does not exist or is not executable])
AC_MSG_ERROR([User supplied tool $1="$tool_command" does not exist or is not executable])
fi
AC_MSG_RESULT([$tool_specified])
$1="$tool_command"
AC_MSG_RESULT([found])
fi
if test "x$tool_args" != x; then
# If we got arguments, re-append them to the command after the fixup.
$1="[$]$1 $tool_args"
fi
fi
fi

View File

@ -564,8 +564,8 @@ endif
# Param 1 - The path to base the name of the log file / command line file on
# Param 2 - The command to run
ExecuteWithLog = \
$(call LogCmdlines, Exececuting: [$(strip $2)]) \
$(call MakeDir, $(dir $(strip $1))) \
$(call LogCmdlines, Executing: [$(strip $2)]) \
$(call MakeDir, $(dir $(strip $1)) $(MAKESUPPORT_OUTPUTDIR)/failure-logs) \
$(call WriteFile, $2, $(strip $1).cmdline) \
( $(RM) $(strip $1).log && $(strip $2) > >($(TEE) -a $(strip $1).log) 2> >($(TEE) -a $(strip $1).log >&2) || \
( exitcode=$(DOLLAR)? && \

View File

@ -97,6 +97,7 @@ JVM_GetCPMethodSignatureUTF
JVM_GetDeclaredClasses
JVM_GetDeclaringClass
JVM_GetEnclosingMethodInfo
JVM_GetExtendedNPEMessage
JVM_GetFieldIxModifiers
JVM_GetFieldTypeAnnotations
JVM_GetInheritedAccessControlContext

View File

@ -6352,7 +6352,7 @@ void MacroAssembler::string_indexof_char(Register str1, Register cnt1, Register
movptr(result, str1);
if (UseAVX >= 2) {
cmpl(cnt1, stride);
jcc(Assembler::less, SCAN_TO_CHAR_LOOP);
jcc(Assembler::less, SCAN_TO_CHAR);
cmpl(cnt1, 2*stride);
jcc(Assembler::less, SCAN_TO_8_CHAR_INIT);
movdl(vec1, ch);
@ -6379,10 +6379,8 @@ void MacroAssembler::string_indexof_char(Register str1, Register cnt1, Register
}
bind(SCAN_TO_8_CHAR);
cmpl(cnt1, stride);
if (UseAVX >= 2) {
jcc(Assembler::less, SCAN_TO_CHAR);
} else {
jcc(Assembler::less, SCAN_TO_CHAR_LOOP);
jcc(Assembler::less, SCAN_TO_CHAR);
if (UseAVX < 2) {
movdl(vec1, ch);
pshuflw(vec1, vec1, 0x00);
pshufd(vec1, vec1, 0);

View File

@ -114,7 +114,8 @@ class MacroAssembler: public Assembler {
// short offset operators (jmp and jcc)
char* disp = (char*) &branch[1];
int imm8 = target - (address) &disp[1];
guarantee(this->is8bit(imm8), "Short forward jump exceeds 8-bit offset at %s:%d", file, line);
guarantee(this->is8bit(imm8), "Short forward jump exceeds 8-bit offset at %s:%d",
file == NULL ? "<NULL>" : file, line);
*disp = imm8;
} else {
int* disp = (int*) &branch[(op == 0x0F || op == 0xC7)? 2: 1];

View File

@ -1304,6 +1304,97 @@ static void save_or_restore_arguments(MacroAssembler* masm,
}
}
// Registers need to be saved for runtime call
static Register caller_saved_registers[] = {
rcx, rdx, rsi, rdi
};
// Save caller saved registers except r1 and r2
static void save_registers_except(MacroAssembler* masm, Register r1, Register r2) {
int reg_len = (int)(sizeof(caller_saved_registers) / sizeof(Register));
for (int index = 0; index < reg_len; index ++) {
Register this_reg = caller_saved_registers[index];
if (this_reg != r1 && this_reg != r2) {
__ push(this_reg);
}
}
}
// Restore caller saved registers except r1 and r2
static void restore_registers_except(MacroAssembler* masm, Register r1, Register r2) {
int reg_len = (int)(sizeof(caller_saved_registers) / sizeof(Register));
for (int index = reg_len - 1; index >= 0; index --) {
Register this_reg = caller_saved_registers[index];
if (this_reg != r1 && this_reg != r2) {
__ pop(this_reg);
}
}
}
// Pin object, return pinned object or null in rax
static void gen_pin_object(MacroAssembler* masm,
Register thread, VMRegPair reg) {
__ block_comment("gen_pin_object {");
Label is_null;
Register tmp_reg = rax;
VMRegPair tmp(tmp_reg->as_VMReg());
if (reg.first()->is_stack()) {
// Load the arg up from the stack
simple_move32(masm, reg, tmp);
reg = tmp;
} else {
__ movl(tmp_reg, reg.first()->as_Register());
}
__ testptr(reg.first()->as_Register(), reg.first()->as_Register());
__ jccb(Assembler::equal, is_null);
// Save registers that may be used by runtime call
Register arg = reg.first()->is_Register() ? reg.first()->as_Register() : noreg;
save_registers_except(masm, arg, thread);
__ call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::pin_object),
thread, reg.first()->as_Register());
// Restore saved registers
restore_registers_except(masm, arg, thread);
__ bind(is_null);
__ block_comment("} gen_pin_object");
}
// Unpin object
static void gen_unpin_object(MacroAssembler* masm,
Register thread, VMRegPair reg) {
__ block_comment("gen_unpin_object {");
Label is_null;
// temp register
__ push(rax);
Register tmp_reg = rax;
VMRegPair tmp(tmp_reg->as_VMReg());
simple_move32(masm, reg, tmp);
__ testptr(rax, rax);
__ jccb(Assembler::equal, is_null);
// Save registers that may be used by runtime call
Register arg = reg.first()->is_Register() ? reg.first()->as_Register() : noreg;
save_registers_except(masm, arg, thread);
__ call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::unpin_object),
thread, rax);
// Restore saved registers
restore_registers_except(masm, arg, thread);
__ bind(is_null);
__ pop(rax);
__ block_comment("} gen_unpin_object");
}
// Check GCLocker::needs_gc and enter the runtime if it's true. This
// keeps a new JNI critical region from starting until a GC has been
// forced. Save down any oops in registers and describe them in an
@ -1837,7 +1928,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
__ get_thread(thread);
if (is_critical_native) {
if (is_critical_native && !Universe::heap()->supports_object_pinning()) {
check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args,
oop_handle_offset, oop_maps, in_regs, in_sig_bt);
}
@ -1875,6 +1966,11 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
//
OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
// Inbound arguments that need to be pinned for critical natives
GrowableArray<int> pinned_args(total_in_args);
// Current stack slot for storing register based array argument
int pinned_slot = oop_handle_offset;
// Mark location of rbp,
// map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, rbp->as_VMReg());
@ -1886,7 +1982,28 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
switch (in_sig_bt[i]) {
case T_ARRAY:
if (is_critical_native) {
unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
VMRegPair in_arg = in_regs[i];
if (Universe::heap()->supports_object_pinning()) {
// gen_pin_object handles save and restore
// of any clobbered registers
gen_pin_object(masm, thread, in_arg);
pinned_args.append(i);
// rax has pinned array
VMRegPair result_reg(rax->as_VMReg());
if (!in_arg.first()->is_stack()) {
assert(pinned_slot <= stack_slots, "overflow");
simple_move32(masm, result_reg, VMRegImpl::stack2reg(pinned_slot));
pinned_slot += VMRegImpl::slots_per_word;
} else {
// Write back pinned value, it will be used to unpin this argument
__ movptr(Address(rbp, reg2offset_in(in_arg.first())), result_reg.first()->as_Register());
}
// We have the array in register, use it
in_arg = result_reg;
}
unpack_array_argument(masm, in_arg, in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
c_arg++;
break;
}
@ -2079,6 +2196,26 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
default : ShouldNotReachHere();
}
// unpin pinned arguments
pinned_slot = oop_handle_offset;
if (pinned_args.length() > 0) {
// save return value that may be overwritten otherwise.
save_native_result(masm, ret_type, stack_slots);
for (int index = 0; index < pinned_args.length(); index ++) {
int i = pinned_args.at(index);
assert(pinned_slot <= stack_slots, "overflow");
if (!in_regs[i].first()->is_stack()) {
int offset = pinned_slot * VMRegImpl::stack_slot_size;
__ movl(in_regs[i].first()->as_Register(), Address(rsp, offset));
pinned_slot += VMRegImpl::slots_per_word;
}
// gen_pin_object handles save and restore
// of any other clobbered registers
gen_unpin_object(masm, thread, in_regs[i]);
}
restore_native_result(masm, ret_type, stack_slots);
}
// Switch thread to "native transition" state before reading the synchronization state.
// This additional state is necessary because reading and testing the synchronization
// state is not atomic w.r.t. GC, as this scenario demonstrates:

View File

@ -1280,7 +1280,7 @@ const bool Matcher::match_rule_supported(int opcode) {
case Op_AbsVS:
case Op_AbsVI:
case Op_AddReductionVI:
if (UseSSE < 3) // requires at least SSE3
if (UseSSE < 3 || !VM_Version::supports_ssse3()) // requires at least SSSE3
ret_value = false;
break;
case Op_MulReductionVI:

View File

@ -1034,8 +1034,6 @@ jlong os::elapsed_frequency() {
}
bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
double os::elapsedVTime() {
struct rusage usage;
@ -3625,11 +3623,6 @@ void os::set_native_thread_name(const char *name) {
return;
}
bool os::distribute_processes(uint length, uint* distribution) {
// Not yet implemented.
return false;
}
bool os::bind_to_processor(uint processor_id) {
// Not yet implemented.
return false;

View File

@ -44,7 +44,6 @@ class Aix {
static julong _physical_memory;
static pthread_t _main_thread;
static Mutex* _createThread_lock;
static int _page_size;
// -1 = uninitialized, 0 = AIX, 1 = OS/400 (PASE)
@ -90,8 +89,6 @@ class Aix {
public:
static void init_thread_fpu_state();
static pthread_t main_thread(void) { return _main_thread; }
static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }
static Mutex* createThread_lock(void) { return _createThread_lock; }
static void hotspot_sigmask(Thread* thread);
// Given an address, returns the size of the page backing that address

View File

@ -64,8 +64,6 @@ inline void os::dll_unload(void *lib) {
::dlclose(lib);
}
inline const int os::default_file_open_flags() { return 0;}
inline jlong os::lseek(int fd, jlong offset, int whence) {
return (jlong) ::lseek64(fd, offset, whence);
}

View File

@ -877,8 +877,6 @@ jlong os::elapsed_frequency() {
}
bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
double os::elapsedVTime() {
// better than nothing, but not much
@ -3282,11 +3280,6 @@ void os::set_native_thread_name(const char *name) {
#endif
}
bool os::distribute_processes(uint length, uint* distribution) {
// Not yet implemented.
return false;
}
bool os::bind_to_processor(uint processor_id) {
// Not yet implemented.
return false;

View File

@ -67,8 +67,6 @@ inline void os::dll_unload(void *lib) {
::dlclose(lib);
}
inline const int os::default_file_open_flags() { return 0;}
inline jlong os::lseek(int fd, jlong offset, int whence) {
return (jlong) ::lseek(fd, offset, whence);
}

View File

@ -131,14 +131,34 @@ class CgroupMemorySubsystem: CgroupSubsystem {
* hierarchy. If set to true consider also memory.stat
* file if everything else seems unlimited */
bool _uses_mem_hierarchy;
volatile jlong _memory_limit_in_bytes;
volatile jlong _next_check_counter;
public:
CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) {
_uses_mem_hierarchy = false;
_memory_limit_in_bytes = -1;
_next_check_counter = min_jlong;
}
bool is_hierarchical() { return _uses_mem_hierarchy; }
void set_hierarchical(bool value) { _uses_mem_hierarchy = value; }
bool should_check_memory_limit() {
return os::elapsed_counter() > _next_check_counter;
}
jlong memory_limit_in_bytes() { return _memory_limit_in_bytes; }
void set_memory_limit_in_bytes(jlong value) {
_memory_limit_in_bytes = value;
// max memory limit is unlikely to change, but we want to remain
// responsive to configuration changes. A very short (20ms) grace time
// between re-read avoids excessive overhead during startup without
// significantly reducing the VMs ability to promptly react to reduced
// memory availability
_next_check_counter = os::elapsed_counter() + (NANOSECS_PER_SEC/50);
}
};
CgroupMemorySubsystem* memory = NULL;
@ -461,6 +481,16 @@ jlong OSContainer::uses_mem_hierarchy() {
* OSCONTAINER_ERROR for not supported
*/
jlong OSContainer::memory_limit_in_bytes() {
if (!memory->should_check_memory_limit()) {
return memory->memory_limit_in_bytes();
}
jlong memory_limit = read_memory_limit_in_bytes();
// Update CgroupMemorySubsystem to avoid re-reading container settings too often
memory->set_memory_limit_in_bytes(memory_limit);
return memory_limit;
}
jlong OSContainer::read_memory_limit_in_bytes() {
GET_CONTAINER_INFO(julong, memory, "/memory.limit_in_bytes",
"Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, memlimit);

View File

@ -36,6 +36,7 @@ class OSContainer: AllStatic {
private:
static bool _is_initialized;
static bool _is_containerized;
static jlong read_memory_limit_in_bytes();
public:
static void init();

View File

@ -148,11 +148,9 @@ uintptr_t os::Linux::_initial_thread_stack_size = 0;
int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
int (*os::Linux::_pthread_setname_np)(pthread_t, const char*) = NULL;
Mutex* os::Linux::_createThread_lock = NULL;
pthread_t os::Linux::_main_thread;
int os::Linux::_page_size = -1;
bool os::Linux::_supports_fast_thread_cpu_time = false;
uint32_t os::Linux::_os_version = 0;
const char * os::Linux::_glibc_version = NULL;
const char * os::Linux::_libpthread_version = NULL;
@ -1364,8 +1362,6 @@ jlong os::elapsed_frequency() {
}
bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
double os::elapsedVTime() {
struct rusage usage;
@ -4823,48 +4819,6 @@ jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
}
void os::Linux::initialize_os_info() {
assert(_os_version == 0, "OS info already initialized");
struct utsname _uname;
uint32_t major;
uint32_t minor;
uint32_t fix;
int rc;
// Kernel version is unknown if
// verification below fails.
_os_version = 0x01000000;
rc = uname(&_uname);
if (rc != -1) {
rc = sscanf(_uname.release,"%d.%d.%d", &major, &minor, &fix);
if (rc == 3) {
if (major < 256 && minor < 256 && fix < 256) {
// Kernel version format is as expected,
// set it overriding unknown state.
_os_version = (major << 16) |
(minor << 8 ) |
(fix << 0 ) ;
}
}
}
}
uint32_t os::Linux::os_version() {
assert(_os_version != 0, "not initialized");
return _os_version & 0x00FFFFFF;
}
bool os::Linux::os_version_is_known() {
assert(_os_version != 0, "not initialized");
return _os_version & 0x01000000 ? false : true;
}
/////
// glibc on Linux platform uses non-documented flag
// to indicate, that some special sort of signal
@ -5084,8 +5038,6 @@ void os::init(void) {
Linux::initialize_system_info();
Linux::initialize_os_info();
os::Linux::CPUPerfTicks pticks;
bool res = os::Linux::get_tick_information(&pticks, -1);
@ -5262,9 +5214,6 @@ jint os::init_2(void) {
}
}
// Initialize lock used to serialize thread creation (see os::create_thread)
Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false));
// at-exit methods are called in the reverse order of their registration.
// atexit functions are called on return from main or as a result of a
// call to exit(3C). There can be only 32 of these functions registered
@ -5465,11 +5414,6 @@ void os::set_native_thread_name(const char *name) {
}
}
bool os::distribute_processes(uint length, uint* distribution) {
// Not yet implemented.
return false;
}
bool os::bind_to_processor(uint processor_id) {
// Not yet implemented.
return false;

View File

@ -55,20 +55,10 @@ class Linux {
static GrowableArray<int>* _cpu_to_node;
static GrowableArray<int>* _nindex_to_node;
// 0x00000000 = uninitialized,
// 0x01000000 = kernel version unknown,
// otherwise a 32-bit number:
// Ox00AABBCC
// AA, Major Version
// BB, Minor Version
// CC, Fix Version
static uint32_t _os_version;
protected:
static julong _physical_memory;
static pthread_t _main_thread;
static Mutex* _createThread_lock;
static int _page_size;
static julong available_memory();
@ -136,8 +126,6 @@ class Linux {
// returns kernel thread id (similar to LWP id on Solaris), which can be
// used to access /proc
static pid_t gettid();
static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }
static Mutex* createThread_lock(void) { return _createThread_lock; }
static void hotspot_sigmask(Thread* thread);
static address initial_thread_stack_bottom(void) { return _initial_thread_stack_bottom; }
@ -196,7 +184,6 @@ class Linux {
// Stack overflow handling
static bool manually_expand_stack(JavaThread * t, address addr);
static int max_register_window_saves_before_flushing();
// fast POSIX clocks support
static void fast_thread_clock_init(void);
@ -211,10 +198,6 @@ class Linux {
static jlong fast_thread_cpu_time(clockid_t clockid);
static void initialize_os_info();
static bool os_version_is_known();
static uint32_t os_version();
// Stack repair handling
// none present

View File

@ -59,8 +59,6 @@ inline void os::dll_unload(void *lib) {
::dlclose(lib);
}
inline const int os::default_file_open_flags() { return 0;}
inline jlong os::lseek(int fd, jlong offset, int whence) {
return (jlong) ::lseek64(fd, offset, whence);
}

View File

@ -167,11 +167,6 @@ size_t os::lasterror(char *buf, size_t len) {
return n;
}
bool os::is_debugger_attached() {
// not implemented
return false;
}
void os::wait_for_keypress_at_exit(void) {
// don't do anything on posix platforms
return;

View File

@ -265,8 +265,6 @@ void os::Solaris::try_enable_extended_io() {
}
}
static int _processors_online = 0;
jint os::Solaris::_os_thread_limit = 0;
volatile jint os::Solaris::_os_thread_count = 0;
@ -291,7 +289,6 @@ static volatile hrtime_t max_hrtime = 0;
void os::Solaris::initialize_system_info() {
set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
_processors_online = sysconf(_SC_NPROCESSORS_ONLN);
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) *
(julong)sysconf(_SC_PAGESIZE);
}
@ -320,7 +317,6 @@ int os::active_processor_count() {
// Query the number of cpus available to us.
if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
_processors_online = pset_cpus;
return pset_cpus;
}
}
@ -328,136 +324,6 @@ int os::active_processor_count() {
return online_cpus;
}
static bool find_processors_in_pset(psetid_t pset,
processorid_t** id_array,
uint_t* id_length) {
bool result = false;
// Find the number of processors in the processor set.
if (pset_info(pset, NULL, id_length, NULL) == 0) {
// Make up an array to hold their ids.
*id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal);
// Fill in the array with their processor ids.
if (pset_info(pset, NULL, id_length, *id_array) == 0) {
result = true;
}
}
return result;
}
// Callers of find_processors_online() must tolerate imprecise results --
// the system configuration can change asynchronously because of DR
// or explicit psradm operations.
//
// We also need to take care that the loop (below) terminates as the
// number of processors online can change between the _SC_NPROCESSORS_ONLN
// request and the loop that builds the list of processor ids. Unfortunately
// there's no reliable way to determine the maximum valid processor id,
// so we use a manifest constant, MAX_PROCESSOR_ID, instead. See p_online
// man pages, which claim the processor id set is "sparse, but
// not too sparse". MAX_PROCESSOR_ID is used to ensure that we eventually
// exit the loop.
//
// In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's
// not available on S8.0.
static bool find_processors_online(processorid_t** id_array,
uint* id_length) {
const processorid_t MAX_PROCESSOR_ID = 100000;
// Find the number of processors online.
*id_length = sysconf(_SC_NPROCESSORS_ONLN);
// Make up an array to hold their ids.
*id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal);
// Processors need not be numbered consecutively.
long found = 0;
processorid_t next = 0;
while (found < *id_length && next < MAX_PROCESSOR_ID) {
processor_info_t info;
if (processor_info(next, &info) == 0) {
// NB, PI_NOINTR processors are effectively online ...
if (info.pi_state == P_ONLINE || info.pi_state == P_NOINTR) {
(*id_array)[found] = next;
found += 1;
}
}
next += 1;
}
if (found < *id_length) {
// The loop above didn't identify the expected number of processors.
// We could always retry the operation, calling sysconf(_SC_NPROCESSORS_ONLN)
// and re-running the loop, above, but there's no guarantee of progress
// if the system configuration is in flux. Instead, we just return what
// we've got. Note that in the worst case find_processors_online() could
// return an empty set. (As a fall-back in the case of the empty set we
// could just return the ID of the current processor).
*id_length = found;
}
return true;
}
static bool assign_distribution(processorid_t* id_array,
uint id_length,
uint* distribution,
uint distribution_length) {
// We assume we can assign processorid_t's to uint's.
assert(sizeof(processorid_t) == sizeof(uint),
"can't convert processorid_t to uint");
// Quick check to see if we won't succeed.
if (id_length < distribution_length) {
return false;
}
// Assign processor ids to the distribution.
// Try to shuffle processors to distribute work across boards,
// assuming 4 processors per board.
const uint processors_per_board = ProcessDistributionStride;
// Find the maximum processor id.
processorid_t max_id = 0;
for (uint m = 0; m < id_length; m += 1) {
max_id = MAX2(max_id, id_array[m]);
}
// The next id, to limit loops.
const processorid_t limit_id = max_id + 1;
// Make up markers for available processors.
bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id, mtInternal);
for (uint c = 0; c < limit_id; c += 1) {
available_id[c] = false;
}
for (uint a = 0; a < id_length; a += 1) {
available_id[id_array[a]] = true;
}
// Step by "boards", then by "slot", copying to "assigned".
// NEEDS_CLEANUP: The assignment of processors should be stateful,
// remembering which processors have been assigned by
// previous calls, etc., so as to distribute several
// independent calls of this method. What we'd like is
// It would be nice to have an API that let us ask
// how many processes are bound to a processor,
// but we don't have that, either.
// In the short term, "board" is static so that
// subsequent distributions don't all start at board 0.
static uint board = 0;
uint assigned = 0;
// Until we've found enough processors ....
while (assigned < distribution_length) {
// ... find the next available processor in the board.
for (uint slot = 0; slot < processors_per_board; slot += 1) {
uint try_id = board * processors_per_board + slot;
if ((try_id < limit_id) && (available_id[try_id] == true)) {
distribution[assigned] = try_id;
available_id[try_id] = false;
assigned += 1;
break;
}
}
board += 1;
if (board * processors_per_board + 0 >= limit_id) {
board = 0;
}
}
FREE_C_HEAP_ARRAY(bool, available_id);
return true;
}
void os::set_native_thread_name(const char *name) {
if (Solaris::_pthread_setname_np != NULL) {
// Only the first 31 bytes of 'name' are processed by pthread_setname_np
@ -470,31 +336,6 @@ void os::set_native_thread_name(const char *name) {
}
}
bool os::distribute_processes(uint length, uint* distribution) {
bool result = false;
// Find the processor id's of all the available CPUs.
processorid_t* id_array = NULL;
uint id_length = 0;
// There are some races between querying information and using it,
// since processor sets can change dynamically.
psetid_t pset = PS_NONE;
// Are we running in a processor set?
if ((pset_bind(PS_QUERY, P_PID, P_MYID, &pset) == 0) && pset != PS_NONE) {
result = find_processors_in_pset(pset, &id_array, &id_length);
} else {
result = find_processors_online(&id_array, &id_length);
}
if (result == true) {
if (id_length >= length) {
result = assign_distribution(id_array, id_length, distribution, length);
} else {
result = false;
}
}
FREE_C_HEAP_ARRAY(processorid_t, id_array);
return result;
}
bool os::bind_to_processor(uint processor_id) {
// We assume that a processorid_t can be stored in a uint.
assert(sizeof(uint) == sizeof(processorid_t),
@ -1237,8 +1078,6 @@ bool os::getTimesSecs(double* process_real_time,
}
bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
double os::elapsedVTime() {
return (double)gethrvtime() / (double)hrtime_hz;

View File

@ -271,10 +271,6 @@ class Solaris {
static void correct_stack_boundaries_for_primordial_thread(Thread* thr);
// Stack overflow handling
static int max_register_window_saves_before_flushing();
// Stack repair handling
// none present

View File

@ -61,8 +61,6 @@ inline void os::map_stack_shadow_pages(address sp) {
inline void os::dll_unload(void *lib) { ::dlclose(lib); }
inline const int os::default_file_open_flags() { return 0;}
//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

View File

@ -826,11 +826,6 @@ void os::set_native_thread_name(const char *name) {
} __except(EXCEPTION_EXECUTE_HANDLER) {}
}
bool os::distribute_processes(uint length, uint* distribution) {
// Not yet implemented.
return false;
}
bool os::bind_to_processor(uint processor_id) {
// Not yet implemented.
return false;
@ -911,8 +906,6 @@ FILETIME java_to_windows_time(jlong l) {
}
bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
double os::elapsedVTime() {
FILETIME created;
@ -3904,12 +3897,6 @@ void os::win32::setmode_streams() {
_setmode(_fileno(stderr), _O_BINARY);
}
bool os::is_debugger_attached() {
return IsDebuggerPresent() ? true : false;
}
void os::wait_for_keypress_at_exit(void) {
if (PauseAtExit) {
fprintf(stderr, "Press any key to continue...\n");

View File

@ -30,8 +30,6 @@
inline const char* os::dll_file_extension() { return ".dll"; }
inline const int os::default_file_open_flags() { return O_BINARY | O_NOINHERIT;}
inline void os::dll_unload(void *lib) {
::FreeLibrary((HMODULE)lib);
}

View File

@ -86,12 +86,6 @@ size_t os::Posix::_compiler_thread_min_stack_allowed = 104 * K;
size_t os::Posix::_java_thread_min_stack_allowed = 86 * K;
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
int os::Solaris::max_register_window_saves_before_flushing() {
// We should detect this at run time. For now, filling
// in with a constant.
return 8;
}
static void handle_unflushed_register_windows(gwindows_t *win) {
int restore_count = win->wbcnt;
int i;

View File

@ -1545,7 +1545,7 @@ bool java_lang_Class::offsets_computed = false;
int java_lang_Class::classRedefinedCount_offset = -1;
#define CLASS_FIELDS_DO(macro) \
macro(classRedefinedCount_offset, k, "classRedefinedCount", int_signature, false) ; \
macro(classRedefinedCount_offset, k, "classRedefinedCount", int_signature, false); \
macro(_class_loader_offset, k, "classLoader", classloader_signature, false); \
macro(_component_mirror_offset, k, "componentType", class_signature, false); \
macro(_module_offset, k, "module", module_signature, false); \
@ -1938,7 +1938,6 @@ static inline bool version_matches(Method* method, int version) {
return method != NULL && (method->constants()->version() == version);
}
// This class provides a simple wrapper over the internal structure of
// exception backtrace to insulate users of the backtrace from needing
// to know what it looks like.
@ -1950,7 +1949,11 @@ class BacktraceBuilder: public StackObj {
typeArrayOop _methods;
typeArrayOop _bcis;
objArrayOop _mirrors;
typeArrayOop _names; // needed to insulate method name against redefinition
typeArrayOop _names; // Needed to insulate method name against redefinition.
// This is set to a java.lang.Boolean(true) if the top frame
// of the backtrace is omitted because it shall be hidden.
// Else it is null.
oop _has_hidden_top_frame;
int _index;
NoSafepointVerifier _nsv;
@ -1960,6 +1963,7 @@ class BacktraceBuilder: public StackObj {
trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset,
trace_names_offset = java_lang_Throwable::trace_names_offset,
trace_next_offset = java_lang_Throwable::trace_next_offset,
trace_hidden_offset = java_lang_Throwable::trace_hidden_offset,
trace_size = java_lang_Throwable::trace_size,
trace_chunk_size = java_lang_Throwable::trace_chunk_size
};
@ -1985,11 +1989,15 @@ class BacktraceBuilder: public StackObj {
assert(names != NULL, "names array should be initialized in backtrace");
return names;
}
static oop get_has_hidden_top_frame(objArrayHandle chunk) {
oop hidden = chunk->obj_at(trace_hidden_offset);
return hidden;
}
public:
// constructor for new backtrace
BacktraceBuilder(TRAPS): _head(NULL), _methods(NULL), _bcis(NULL), _mirrors(NULL), _names(NULL) {
BacktraceBuilder(TRAPS): _head(NULL), _methods(NULL), _bcis(NULL), _mirrors(NULL), _names(NULL), _has_hidden_top_frame(NULL) {
expand(CHECK);
_backtrace = Handle(THREAD, _head);
_index = 0;
@ -2000,6 +2008,7 @@ class BacktraceBuilder: public StackObj {
_bcis = get_bcis(backtrace);
_mirrors = get_mirrors(backtrace);
_names = get_names(backtrace);
_has_hidden_top_frame = get_has_hidden_top_frame(backtrace);
assert(_methods->length() == _bcis->length() &&
_methods->length() == _mirrors->length() &&
_mirrors->length() == _names->length(),
@ -2037,6 +2046,7 @@ class BacktraceBuilder: public StackObj {
new_head->obj_at_put(trace_bcis_offset, new_bcis());
new_head->obj_at_put(trace_mirrors_offset, new_mirrors());
new_head->obj_at_put(trace_names_offset, new_names());
new_head->obj_at_put(trace_hidden_offset, NULL);
_head = new_head();
_methods = new_methods();
@ -2077,6 +2087,16 @@ class BacktraceBuilder: public StackObj {
_index++;
}
void set_has_hidden_top_frame(TRAPS) {
if (_has_hidden_top_frame == NULL) {
jvalue prim;
prim.z = 1;
PauseNoSafepointVerifier pnsv(&_nsv);
_has_hidden_top_frame = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK);
_head->obj_at_put(trace_hidden_offset, _has_hidden_top_frame);
}
}
};
struct BacktraceElement : public StackObj {
@ -2406,7 +2426,13 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHand
}
}
if (method->is_hidden()) {
if (skip_hidden) continue;
if (skip_hidden) {
if (total_count == 0) {
// The top frame will be hidden from the stack trace.
bt.set_has_hidden_top_frame(CHECK);
}
continue;
}
}
bt.push(method, bci, CHECK);
total_count++;
@ -2523,6 +2549,37 @@ void java_lang_Throwable::get_stack_trace_elements(Handle throwable,
}
}
bool java_lang_Throwable::get_top_method_and_bci(oop throwable, Method** method, int* bci) {
Thread* THREAD = Thread::current();
objArrayHandle result(THREAD, objArrayOop(backtrace(throwable)));
BacktraceIterator iter(result, THREAD);
// No backtrace available.
if (!iter.repeat()) return false;
// If the exception happened in a frame that has been hidden, i.e.,
// omitted from the back trace, we can not compute the message.
oop hidden = ((objArrayOop)backtrace(throwable))->obj_at(trace_hidden_offset);
if (hidden != NULL) {
return false;
}
// Get first backtrace element.
BacktraceElement bte = iter.next(THREAD);
InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(bte._mirror()));
assert(holder != NULL, "first element should be non-null");
Method* m = holder->method_with_orig_idnum(bte._method_id, bte._version);
// Original version is no longer available.
if (m == NULL || !version_matches(m, bte._version)) {
return false;
}
*method = m;
*bci = bte._bci;
return true;
}
oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) {
// Allocate java.lang.StackTraceElement instance
InstanceKlass* k = SystemDictionary::StackTraceElement_klass();

View File

@ -518,7 +518,8 @@ class java_lang_Throwable: AllStatic {
trace_mirrors_offset = 2,
trace_names_offset = 3,
trace_next_offset = 4,
trace_size = 5,
trace_hidden_offset = 5,
trace_size = 6,
trace_chunk_size = 32
};
@ -568,6 +569,8 @@ class java_lang_Throwable: AllStatic {
static void java_printStackTrace(Handle throwable, TRAPS);
// Debugging
friend class JavaClasses;
// Gets the method and bci of the top frame (TOS). Returns false if this failed.
static bool get_top_method_and_bci(oop throwable, Method** method, int* bci);
};

View File

@ -155,6 +155,7 @@ class GCTimer;
do_klass(reflect_ConstantPool_klass, reflect_ConstantPool ) \
do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, reflect_UnsafeStaticFieldAccessorImpl ) \
do_klass(reflect_CallerSensitive_klass, reflect_CallerSensitive ) \
do_klass(reflect_NativeConstructorAccessorImpl_klass, reflect_NativeConstructorAccessorImpl ) \
\
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle ) \

View File

@ -243,6 +243,7 @@
template(reflect_Reflection, "jdk/internal/reflect/Reflection") \
template(reflect_CallerSensitive, "jdk/internal/reflect/CallerSensitive") \
template(reflect_CallerSensitive_signature, "Ljdk/internal/reflect/CallerSensitive;") \
template(reflect_NativeConstructorAccessorImpl, "jdk/internal/reflect/NativeConstructorAccessorImpl")\
template(checkedExceptions_name, "checkedExceptions") \
template(clazz_name, "clazz") \
template(exceptionTypes_name, "exceptionTypes") \

View File

@ -45,13 +45,25 @@ void EpsilonArguments::initialize() {
FLAG_SET_DEFAULT(ExitOnOutOfMemoryError, true);
}
// Warn users that non-resizable heap might be better for some configurations.
// We are not adjusting the heap size by ourselves, because it affects startup time.
if (InitialHeapSize != MaxHeapSize) {
log_warning(gc)("Consider setting -Xms equal to -Xmx to avoid resizing hiccups");
}
// Warn users that AlwaysPreTouch might be better for some configurations.
// We are not turning this on by ourselves, because it affects startup time.
if (FLAG_IS_DEFAULT(AlwaysPreTouch) && !AlwaysPreTouch) {
log_warning(gc)("Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups");
}
if (EpsilonMaxTLABSize < MinTLABSize) {
warning("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
log_warning(gc)("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
EpsilonMaxTLABSize = MinTLABSize;
}
if (!EpsilonElasticTLAB && EpsilonElasticTLABDecay) {
warning("Disabling EpsilonElasticTLABDecay because EpsilonElasticTLAB is disabled");
log_warning(gc)("Disabling EpsilonElasticTLABDecay because EpsilonElasticTLAB is disabled");
FLAG_SET_DEFAULT(EpsilonElasticTLABDecay, false);
}

View File

@ -1630,7 +1630,6 @@ jint G1CollectedHeap::initialize_young_gen_sampling_thread() {
}
jint G1CollectedHeap::initialize() {
os::enable_vtime();
// Necessary to satisfy locking discipline assertions.
@ -4076,7 +4075,7 @@ private:
Atomic::add(r->rem_set()->occupied_locked(), &_rs_length);
if (!is_young) {
g1h->_hot_card_cache->reset_card_counts(r);
g1h->hot_card_cache()->reset_card_counts(r);
}
if (!evacuation_failed) {

View File

@ -129,7 +129,6 @@ class G1RegionMappingChangedListener : public G1MappingChangedListener {
};
class G1CollectedHeap : public CollectedHeap {
friend class G1FreeCollectionSetTask;
friend class VM_CollectForMetadataAllocation;
friend class VM_G1CollectForAllocation;
friend class VM_G1CollectFull;
@ -1138,7 +1137,7 @@ public:
return _reserved.contains(addr);
}
G1HotCardCache* g1_hot_card_cache() const { return _hot_card_cache; }
G1HotCardCache* hot_card_cache() const { return _hot_card_cache; }
G1CardTable* card_table() const {
return _card_table;

View File

@ -114,8 +114,9 @@ void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(Heap
hr->rem_set()->clear();
hr->clear_cardtable();
if (_g1h->g1_hot_card_cache()->use_cache()) {
_g1h->g1_hot_card_cache()->reset_card_counts(hr);
G1HotCardCache* hcc = _g1h->hot_card_cache();
if (hcc->use_cache()) {
hcc->reset_card_counts(hr);
}
}

View File

@ -487,7 +487,7 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1h,
G1CardTable* ct,
G1HotCardCache* hot_card_cache) :
_scan_state(new G1RemSetScanState()),
_prev_period_summary(),
_prev_period_summary(false),
_g1h(g1h),
_ct(ct),
_g1p(_g1h->policy()),
@ -1404,7 +1404,7 @@ void G1RemSet::print_periodic_summary_info(const char* header, uint period_count
if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
(period_count % G1SummarizeRSetStatsPeriod == 0)) {
G1RemSetSummary current(this);
G1RemSetSummary current;
_prev_period_summary.subtract_from(&current);
Log(gc, remset) log;
@ -1421,7 +1421,7 @@ void G1RemSet::print_summary_info() {
Log(gc, remset, exit) log;
if (log.is_trace()) {
log.trace(" Cumulative RS summary");
G1RemSetSummary current(this);
G1RemSetSummary current;
ResourceMark rm;
LogStream ls(log.trace());
current.print_on(&ls);

View File

@ -81,8 +81,7 @@ double G1RemSetSummary::rs_thread_vtime(uint thread) const {
return _rs_threads_vtimes[thread];
}
G1RemSetSummary::G1RemSetSummary() :
_rem_set(NULL),
G1RemSetSummary::G1RemSetSummary(bool should_update) :
_total_mutator_refined_cards(0),
_total_concurrent_refined_cards(0),
_num_coarsenings(0),
@ -91,17 +90,10 @@ G1RemSetSummary::G1RemSetSummary() :
_sampling_thread_vtime(0.0f) {
memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);
}
G1RemSetSummary::G1RemSetSummary(G1RemSet* rem_set) :
_rem_set(rem_set),
_total_mutator_refined_cards(0),
_total_concurrent_refined_cards(0),
_num_coarsenings(0),
_num_vtimes(G1ConcurrentRefine::max_num_threads()),
_rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
_sampling_thread_vtime(0.0f) {
update();
if (should_update) {
update();
}
}
G1RemSetSummary::~G1RemSetSummary() {

View File

@ -36,8 +36,6 @@ class G1RemSetSummary {
private:
friend class GetRSThreadVTimeClosure;
G1RemSet* _rem_set;
size_t _total_mutator_refined_cards;
size_t _total_concurrent_refined_cards;
@ -57,8 +55,7 @@ private:
void update();
public:
G1RemSetSummary();
G1RemSetSummary(G1RemSet* remset);
G1RemSetSummary(bool should_update = true);
~G1RemSetSummary();

View File

@ -268,17 +268,12 @@ oop ShenandoahBarrierSet::oop_load_from_native_barrier(oop obj) {
}
ShenandoahMarkingContext* const marking_context = _heap->marking_context();
if (_heap->is_evacuation_in_progress()) {
// Normal GC
if (!marking_context->is_marked(obj)) {
return NULL;
}
} else if (_heap->is_concurrent_traversal_in_progress()) {
// Traversal GC
if (marking_context->is_complete() &&
!marking_context->is_marked(resolve_forwarded_not_null(obj))) {
if (_heap->is_evacuation_in_progress() && !marking_context->is_marked(obj)) {
Thread* thr = Thread::current();
if (thr->is_Java_thread()) {
return NULL;
} else {
return obj;
}
}

View File

@ -27,6 +27,7 @@
class ShenandoahHeap;
class ShenandoahMarkingContext;
class ShenandoahHeapRegionSet;
class Thread;
class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure {
@ -65,6 +66,20 @@ private:
inline void do_oop_work(T* p);
};
class ShenandoahTraversalUpdateRefsClosure: public OopClosure {
private:
ShenandoahHeap* const _heap;
ShenandoahHeapRegionSet* const _traversal_set;
public:
inline ShenandoahTraversalUpdateRefsClosure();
inline void do_oop(oop* p);
inline void do_oop(narrowOop* p);
private:
template <class T>
inline void do_oop_work(T* p);
};
class ShenandoahEvacuateUpdateRootsClosure: public BasicOopIterateClosure {
private:
ShenandoahHeap* _heap;

View File

@ -26,6 +26,7 @@
#include "gc/shenandoah/shenandoahAsserts.hpp"
#include "gc/shenandoah/shenandoahClosures.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahTraversalGC.hpp"
#include "oops/compressedOops.inline.hpp"
#include "runtime/thread.hpp"
@ -78,6 +79,29 @@ void ShenandoahUpdateRefsClosure::do_oop_work(T* p) {
void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); }
void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }
ShenandoahTraversalUpdateRefsClosure::ShenandoahTraversalUpdateRefsClosure() :
_heap(ShenandoahHeap::heap()),
_traversal_set(ShenandoahHeap::heap()->traversal_gc()->traversal_set()) {
assert(_heap->is_traversal_mode(), "Why we here?");
}
template <class T>
void ShenandoahTraversalUpdateRefsClosure::do_oop_work(T* p) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
if (_heap->in_collection_set(obj) || _traversal_set->is_in((HeapWord*)obj)) {
obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
RawAccess<IS_NOT_NULL>::oop_store(p, obj);
} else {
shenandoah_assert_not_forwarded(p, obj);
}
}
}
void ShenandoahTraversalUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); }
void ShenandoahTraversalUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }
ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() :
_heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
}

View File

@ -319,13 +319,20 @@ public:
};
void ShenandoahConcurrentMark::update_thread_roots(ShenandoahPhaseTimings::Phase root_phase) {
WorkGang* workers = _heap->workers();
bool is_par = workers->active_workers() > 1;
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
ShenandoahGCPhase phase(root_phase);
#if COMPILER2_OR_JVMCI
DerivedPointerTable::clear();
#endif
WorkGang* workers = _heap->workers();
bool is_par = workers->active_workers() > 1;
ShenandoahUpdateThreadRootsTask task(is_par, root_phase);
workers->run_task(&task);
#if COMPILER2_OR_JVMCI
DerivedPointerTable::update_pointers();
#endif

View File

@ -1493,31 +1493,36 @@ void ShenandoahHeap::op_final_mark() {
stop_concurrent_marking();
// All allocations past TAMS are implicitly live, adjust the region data.
// Bitmaps/TAMS are swapped at this point, so we need to poll complete bitmap.
{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::complete_liveness);
// All allocations past TAMS are implicitly live, adjust the region data.
// Bitmaps/TAMS are swapped at this point, so we need to poll complete bitmap.
ShenandoahCompleteLivenessClosure cl;
parallel_heap_region_iterate(&cl);
}
// Force the threads to reacquire their TLABs outside the collection set.
{
ShenandoahGCPhase prepare_evac(ShenandoahPhaseTimings::prepare_evac);
ShenandoahGCPhase phase(ShenandoahPhaseTimings::retire_tlabs);
make_parsable(true);
}
// Trash the collection set left over from previous cycle, if any.
{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::trash_cset);
trash_cset_regions();
}
{
ShenandoahHeapLocker locker(lock());
_collection_set->clear();
_free_set->clear();
{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::prepare_evac);
heuristics()->choose_collection_set(_collection_set);
ShenandoahHeapLocker locker(lock());
_collection_set->clear();
_free_set->clear();
_free_set->rebuild();
}
heuristics()->choose_collection_set(_collection_set);
_free_set->rebuild();
}
// If collection set has candidates, start evacuation.
@ -1580,7 +1585,10 @@ void ShenandoahHeap::op_final_evac() {
set_evacuation_in_progress(false);
retire_and_reset_gclabs();
{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_evac_retire_gclabs);
retire_and_reset_gclabs();
}
if (ShenandoahVerify) {
verifier()->verify_after_evacuation();
@ -1902,7 +1910,7 @@ void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) {
}
void ShenandoahHeap::set_concurrent_traversal_in_progress(bool in_progress) {
set_gc_state_mask(TRAVERSAL | HAS_FORWARDED | UPDATEREFS, in_progress);
set_gc_state_mask(TRAVERSAL, in_progress);
ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress);
}
@ -2034,11 +2042,19 @@ void ShenandoahHeap::stw_process_weak_roots(bool full_gc) {
// Cleanup weak roots
ShenandoahGCPhase phase(timing_phase);
if (has_forwarded_objects()) {
ShenandoahForwardedIsAliveClosure is_alive;
ShenandoahUpdateRefsClosure keep_alive;
ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahUpdateRefsClosure>
cleaning_task(&is_alive, &keep_alive, num_workers);
_workers->run_task(&cleaning_task);
if (is_traversal_mode()) {
ShenandoahForwardedIsAliveClosure is_alive;
ShenandoahTraversalUpdateRefsClosure keep_alive;
ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalUpdateRefsClosure>
cleaning_task(&is_alive, &keep_alive, num_workers);
_workers->run_task(&cleaning_task);
} else {
ShenandoahForwardedIsAliveClosure is_alive;
ShenandoahUpdateRefsClosure keep_alive;
ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahUpdateRefsClosure>
cleaning_task(&is_alive, &keep_alive, num_workers);
_workers->run_task(&cleaning_task);
}
} else {
ShenandoahIsAliveClosure is_alive;
#ifdef ASSERT
@ -2060,7 +2076,12 @@ void ShenandoahHeap::parallel_cleaning(bool full_gc) {
}
void ShenandoahHeap::set_has_forwarded_objects(bool cond) {
set_gc_state_mask(HAS_FORWARDED, cond);
if (is_traversal_mode()) {
set_gc_state_mask(HAS_FORWARDED | UPDATEREFS, cond);
} else {
set_gc_state_mask(HAS_FORWARDED, cond);
}
}
void ShenandoahHeap::set_process_references(bool pr) {
@ -2229,7 +2250,10 @@ void ShenandoahHeap::op_init_updaterefs() {
set_evacuation_in_progress(false);
retire_and_reset_gclabs();
{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_retire_gclabs);
retire_and_reset_gclabs();
}
if (ShenandoahVerify) {
if (!is_degenerated_gc_in_progress()) {
@ -2239,14 +2263,19 @@ void ShenandoahHeap::op_init_updaterefs() {
}
set_update_refs_in_progress(true);
make_parsable(true);
for (uint i = 0; i < num_regions(); i++) {
ShenandoahHeapRegion* r = get_region(i);
r->set_concurrent_iteration_safe_limit(r->top());
}
// Reset iterator.
_update_refs_iterator.reset();
{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_prepare);
make_parsable(true);
for (uint i = 0; i < num_regions(); i++) {
ShenandoahHeapRegion* r = get_region(i);
r->set_concurrent_iteration_safe_limit(r->top());
}
// Reset iterator.
_update_refs_iterator.reset();
}
if (ShenandoahPacing) {
pacer()->setup_for_updaterefs();
@ -2258,7 +2287,7 @@ void ShenandoahHeap::op_final_updaterefs() {
// Check if there is left-over work, and finish it
if (_update_refs_iterator.has_next()) {
ShenandoahGCPhase final_work(ShenandoahPhaseTimings::final_update_refs_finish_work);
ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work);
// Finish updating references where we left off.
clear_cancelled_gc();
@ -2287,9 +2316,11 @@ void ShenandoahHeap::op_final_updaterefs() {
verifier()->verify_roots_in_to_space();
}
ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle);
{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset);
trash_cset_regions();
}
trash_cset_regions();
set_has_forwarded_objects(false);
set_update_refs_in_progress(false);

View File

@ -41,6 +41,9 @@ public:
ShenandoahLock() : _state(unlocked), _owner(NULL) {};
void lock() {
#ifdef ASSERT
assert(_owner != Thread::current(), "reentrant locking attempt, would deadlock");
#endif
Thread::SpinAcquire(&_state, "Shenandoah Heap Lock");
#ifdef ASSERT
assert(_state == locked, "must be locked");

View File

@ -100,8 +100,9 @@ class outputStream;
f(purge_par, " Parallel Cleanup") \
f(purge_cldg, " CLDG") \
f(complete_liveness, " Complete Liveness") \
f(retire_tlabs, " Retire TLABs") \
f(trash_cset, " Trash CSet") \
f(prepare_evac, " Prepare Evacuation") \
f(recycle_regions, " Recycle regions") \
\
/* Per-thread timer block, should have "roots" counters in consistent order */ \
f(init_evac, " Initial Evacuation") \
@ -127,9 +128,12 @@ class outputStream;
\
f(final_evac_gross, "Pause Final Evac (G)") \
f(final_evac, "Pause Final Evac (N)") \
f(final_evac_retire_gclabs, " Retire GCLABs") \
\
f(init_update_refs_gross, "Pause Init Update Refs (G)") \
f(init_update_refs, "Pause Init Update Refs (N)") \
f(init_update_refs_retire_gclabs, " Retire GCLABs") \
f(init_update_refs_prepare, " Prepare") \
\
f(final_update_refs_gross, "Pause Final Update Refs (G)") \
f(final_update_refs, "Pause Final Update Refs (N)") \
@ -157,7 +161,7 @@ class outputStream;
f(final_update_refs_string_dedup_queue_roots, " UR: Dedup Queue Roots") \
f(final_update_refs_finish_queues, " UR: Finish Queues") \
\
f(final_update_refs_recycle, " Recycle") \
f(final_update_refs_trash_cset, " Trash CSet") \
\
f(degen_gc_gross, "Pause Degenerated GC (G)") \
f(degen_gc, "Pause Degenerated GC (N)") \

View File

@ -189,6 +189,18 @@ ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimi
_thread_roots(n_workers > 1) {
}
void ShenandoahRootUpdater::strong_roots_do(uint worker_id, OopClosure* oops_cl) {
CodeBlobToOopClosure update_blobs(oops_cl, CodeBlobToOopClosure::FixRelocations);
CLDToOopClosure clds(oops_cl, ClassLoaderData::_claim_strong);
_serial_roots.oops_do(oops_cl, worker_id);
_vm_roots.oops_do(oops_cl, worker_id);
_thread_roots.oops_do(oops_cl, NULL, worker_id);
_cld_roots.cld_do(&clds, worker_id);
_code_roots.code_blobs_do(&update_blobs, worker_id);
}
ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
ShenandoahRootProcessor(phase),
_thread_roots(n_workers > 1) {

View File

@ -304,6 +304,8 @@ public:
template<typename IsAlive, typename KeepAlive>
void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
void strong_roots_do(uint worker_id, OopClosure* oops_cl);
};
// Adjuster all roots at a safepoint during full gc

View File

@ -390,6 +390,7 @@ void ShenandoahTraversalGC::init_traversal_collection() {
}
_heap->set_concurrent_traversal_in_progress(true);
_heap->set_has_forwarded_objects(true);
bool process_refs = _heap->process_references();
if (process_refs) {
@ -601,11 +602,14 @@ void ShenandoahTraversalGC::final_traversal_collection() {
TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
// No more marking expected
_heap->set_concurrent_traversal_in_progress(false);
_heap->mark_complete_marking_context();
fixup_roots();
_heap->parallel_cleaning(false);
_heap->set_has_forwarded_objects(false);
// Resize metaspace
MetaspaceGC::compute_new_size();
@ -651,7 +655,6 @@ void ShenandoahTraversalGC::final_traversal_collection() {
}
assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
_heap->set_concurrent_traversal_in_progress(false);
assert(!_heap->cancelled_gc(), "must not be cancelled when getting out here");
if (ShenandoahVerify) {
@ -697,8 +700,7 @@ public:
void work(uint worker_id) {
ShenandoahParallelWorkerSession worker_session(worker_id);
ShenandoahTraversalFixRootsClosure cl;
ShenandoahForwardedIsAliveClosure is_alive;
_rp->roots_do<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalFixRootsClosure>(worker_id, &is_alive, &cl);
_rp->strong_roots_do(worker_id, &cl);
}
};

View File

@ -191,6 +191,13 @@ JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throw
JNIEXPORT void JNICALL
JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo);
/*
* java.lang.NullPointerException
*/
JNIEXPORT jstring JNICALL
JVM_GetExtendedNPEMessage(JNIEnv *env, jthrowable throwable);
/*
* java.lang.StackWalker
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019 SAP SE. 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.
*
*/
#ifndef SHARE_INTERPRETER_BYTECODEUTILS_HPP
#define SHARE_INTERPRETER_BYTECODEUTILS_HPP
#include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp"
class Method;
class outputStream;
class BytecodeUtils : public AllStatic {
public:
// NPE extended message. Return true if string is printed.
static bool get_NPE_message_at(outputStream* ss, Method* method, int bci);
};
#endif // SHARE_INTERPRETER_BYTECODEUTILS_HPP

View File

@ -2497,10 +2497,18 @@ void InstanceKlass::unload_class(InstanceKlass* ik) {
#endif
}
static void method_release_C_heap_structures(Method* m) {
m->release_C_heap_structures();
}
void InstanceKlass::release_C_heap_structures(InstanceKlass* ik) {
// Clean up C heap
ik->release_C_heap_structures();
ik->constants()->release_C_heap_structures();
// Deallocate and call destructors for MDO mutexes
ik->methods_do(method_release_C_heap_structures);
}
void InstanceKlass::release_C_heap_structures() {

View File

@ -118,11 +118,6 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags) {
void Method::deallocate_contents(ClassLoaderData* loader_data) {
MetadataFactory::free_metadata(loader_data, constMethod());
set_constMethod(NULL);
#if INCLUDE_JVMCI
if (method_data()) {
FailedSpeculation::free_failed_speculations(method_data()->get_failed_speculations_address());
}
#endif
MetadataFactory::free_metadata(loader_data, method_data());
set_method_data(NULL);
MetadataFactory::free_metadata(loader_data, method_counters());
@ -131,6 +126,16 @@ void Method::deallocate_contents(ClassLoaderData* loader_data) {
if (code() != NULL) _code = NULL;
}
void Method::release_C_heap_structures() {
if (method_data()) {
#if INCLUDE_JVMCI
FailedSpeculation::free_failed_speculations(method_data()->get_failed_speculations_address());
#endif
// Destroy MethodData
method_data()->~MethodData();
}
}
address Method::get_i2c_entry() {
assert(adapter() != NULL, "must have");
return adapter()->get_i2c_entry();

View File

@ -1006,6 +1006,8 @@ public:
// Deallocation function for redefine classes or if an error occurs
void deallocate_contents(ClassLoaderData* loader_data);
void release_C_heap_structures();
Method* get_new_method() const {
InstanceKlass* holder = method_holder();
Method* new_method = holder->method_with_idnum(orig_method_idnum());

View File

@ -2445,7 +2445,7 @@ public:
virtual void metaspace_pointers_do(MetaspaceClosure* iter);
virtual MetaspaceObj::Type type() const { return MethodDataType; }
// Deallocation support - no pointer fields to deallocate
// Deallocation support - no metaspace pointer fields to deallocate
void deallocate_contents(ClassLoaderData* loader_data) {}
// GC support

View File

@ -38,6 +38,7 @@
#include "classfile/vmSymbols.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/bytecodeUtils.hpp"
#include "jfr/jfrEvents.hpp"
#include "logging/log.hpp"
#include "memory/heapShared.hpp"
@ -531,13 +532,37 @@ JVM_END
// java.lang.Throwable //////////////////////////////////////////////////////
JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver))
JVMWrapper("JVM_FillInStackTrace");
Handle exception(thread, JNIHandles::resolve_non_null(receiver));
java_lang_Throwable::fill_in_stack_trace(exception);
JVM_END
// java.lang.NullPointerException ///////////////////////////////////////////
JVM_ENTRY(jstring, JVM_GetExtendedNPEMessage(JNIEnv *env, jthrowable throwable))
if (!ShowCodeDetailsInExceptionMessages) return NULL;
oop exc = JNIHandles::resolve_non_null(throwable);
Method* method;
int bci;
if (!java_lang_Throwable::get_top_method_and_bci(exc, &method, &bci)) {
return NULL;
}
if (method->is_native()) {
return NULL;
}
stringStream ss;
bool ok = BytecodeUtils::get_NPE_message_at(&ss, method, bci);
if (ok) {
oop result = java_lang_String::create_oop_from_str(ss.base(), CHECK_0);
return (jstring) JNIHandles::make_local(env, result);
} else {
return NULL;
}
JVM_END
// java.lang.StackTraceElement //////////////////////////////////////////////

View File

@ -295,7 +295,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
// Reallocate the non-escaping objects and restore their fields. Then
// relock objects if synchronization on them was eliminated.
if (jvmci_enabled || ((DoEscapeAnalysis || EliminateNestedLocks) && EliminateAllocations)) {
if (jvmci_enabled || (DoEscapeAnalysis && EliminateAllocations)) {
realloc_failures = eliminate_allocations(thread, exec_mode, cm, deoptee, map, chunk);
}
#endif // COMPILER2_OR_JVMCI

View File

@ -643,6 +643,10 @@ const size_t minimumSymbolTableSize = 1024;
product(bool, OmitStackTraceInFastThrow, true, \
"Omit backtraces for some 'hot' exceptions in optimized code") \
\
manageable(bool, ShowCodeDetailsInExceptionMessages, false, \
"Show exception messages from RuntimeExceptions that contain " \
"snippets of the failing code. Disable this to improve privacy.") \
\
product(bool, PrintWarnings, true, \
"Print JVM warnings to output stream") \
\

View File

@ -47,8 +47,6 @@ class frame;
// OS services (time, I/O) as well as other functionality with system-
// dependent code.
typedef void (*dll_func)(...);
class Thread;
class JavaThread;
class NativeCallStack;
@ -195,14 +193,9 @@ class os: AllStatic {
// The "virtual time" of a thread is the amount of time a thread has
// actually run. The first function indicates whether the OS supports
// this functionality for the current thread, and if so:
// * the second enables vtime tracking (if that is required).
// * the third tells whether vtime is enabled.
// * the fourth returns the elapsed virtual time for the current
// thread.
// this functionality for the current thread, and if so the second
// returns the elapsed virtual time for the current thread.
static bool supports_vtime();
static bool enable_vtime();
static bool vtime_enabled();
static double elapsedVTime();
// Return current local time in a string (YYYY-MM-DD HH:MM:SS).
@ -254,14 +247,6 @@ class os: AllStatic {
return _initial_active_processor_count;
}
// Bind processes to processors.
// This is a two step procedure:
// first you generate a distribution of processes to processors,
// then you bind processes according to that distribution.
// Compute a distribution for number of processes to processors.
// Stores the processor id's into the distribution array argument.
// Returns true if it worked, false if it didn't.
static bool distribute_processes(uint length, uint* distribution);
// Binds the current process to a processor.
// Returns true if it worked, false if it didn't.
static bool bind_to_processor(uint processor_id);
@ -496,7 +481,6 @@ class os: AllStatic {
static void verify_stack_alignment() PRODUCT_RETURN;
static bool message_box(const char* title, const char* message);
static char* do_you_want_to_debug(const char* message);
// run cmd in a separate process and return its exit code; or -1 on failures
static int fork_and_exec(char *cmd, bool use_vfork_if_available = false);
@ -520,7 +504,6 @@ class os: AllStatic {
static void die();
// File i/o operations
static const int default_file_open_flags();
static int open(const char *path, int oflag, int mode);
static FILE* open(int fd, const char* mode);
static FILE* fopen(const char* path, const char* mode);
@ -668,9 +651,6 @@ class os: AllStatic {
// Will not change the value of errno.
static const char* errno_name(int e);
// Determines whether the calling process is being debugged by a user-mode debugger.
static bool is_debugger_attached();
// wait for a key press if PauseAtExit is set
static void wait_for_keypress_at_exit(void);
@ -966,10 +946,6 @@ class os: AllStatic {
return _state == SR_RUNNING;
}
bool is_suspend_request() const {
return _state == SR_SUSPEND_REQUEST;
}
bool is_suspended() const {
return _state == SR_SUSPENDED;
}

View File

@ -151,7 +151,13 @@ template <> void DCmdArgument<bool>::parse_value(const char* str,
ResourceMark rm;
char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
PRAGMA_DIAG_PUSH
PRAGMA_STRINGOP_TRUNCATION_IGNORED
// This code can incorrectly cause a "stringop-truncation" warning with gcc
strncpy(buf, str, len);
PRAGMA_DIAG_POP
buf[len] = '\0';
Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
"Boolean parsing error in command argument '%s'. Could not parse: %s.\n", _name, buf);

View File

@ -62,4 +62,8 @@
#define PRAGMA_FORMAT_IGNORED
#endif
#ifndef PRAGMA_STRINGOP_TRUNCATION_IGNORED
#define PRAGMA_STRINGOP_TRUNCATION_IGNORED
#endif
#endif // SHARE_UTILITIES_COMPILERWARNINGS_HPP

View File

@ -50,6 +50,12 @@
#define PRAGMA_FORMAT_IGNORED PRAGMA_DISABLE_GCC_WARNING("-Wformat")
// Disable -Wstringop-truncation which is introduced in GCC 8.
// https://gcc.gnu.org/gcc-8/changes.html
#if !defined(__clang_major__) && (__GNUC__ >= 8)
#define PRAGMA_STRINGOP_TRUNCATION_IGNORED PRAGMA_DISABLE_GCC_WARNING("-Wstringop-truncation")
#endif
#if defined(__clang_major__) && \
(__clang_major__ >= 4 || \
(__clang_major__ >= 3 && __clang_minor__ >= 1)) || \

View File

@ -367,12 +367,22 @@ public final class FilePermission extends Permission implements Serializable {
this.mask = mask;
if (cpath.equals("<<ALL FILES>>")) {
allFiles = true;
directory = true;
recursive = true;
cpath = "";
return;
}
// Validate path by platform's default file system
try {
String name = cpath.endsWith("*") ? cpath.substring(0, cpath.length() - 1) + "-" : cpath;
builtInFS.getPath(new File(name).getPath());
} catch (InvalidPathException ipe) {
invalid = true;
return;
}
// store only the canonical cpath if possible
cpath = AccessController.doPrivileged(new PrivilegedAction<>() {
public String run() {
@ -463,13 +473,16 @@ public final class FilePermission extends Permission implements Serializable {
* <P>
* The default value of the {@code jdk.io.permissionsUseCanonicalPath}
* system property is {@code false} in this implementation.
* <p>
* The value can also be set with a security property using the same name,
* but setting a system property will override the security property value.
*
* @param path the pathname of the file/directory.
* @param actions the action string.
*
* @throws IllegalArgumentException
* If actions is {@code null}, empty or contains an action
* other than the specified possible actions.
* @throws IllegalArgumentException if actions is {@code null}, empty,
* malformed or contains an action other than the specified
* possible actions
*/
public FilePermission(String path, String actions) {
super(path);
@ -573,19 +586,19 @@ public final class FilePermission extends Permission implements Serializable {
* @return the effective mask
*/
boolean impliesIgnoreMask(FilePermission that) {
if (this == that) {
return true;
}
if (allFiles) {
return true;
}
if (this.invalid || that.invalid) {
return false;
}
if (that.allFiles) {
return false;
}
if (FilePermCompat.nb) {
if (this == that) {
return true;
}
if (allFiles) {
return true;
}
if (this.invalid || that.invalid) {
return false;
}
if (that.allFiles) {
return false;
}
// Left at least same level of wildness as right
if ((this.recursive && that.recursive) != that.recursive
|| (this.directory && that.directory) != that.directory) {
@ -783,10 +796,10 @@ public final class FilePermission extends Permission implements Serializable {
FilePermission that = (FilePermission) obj;
if (this.invalid || that.invalid) {
return false;
}
if (FilePermCompat.nb) {
if (this.invalid || that.invalid) {
return false;
}
return (this.mask == that.mask) &&
(this.allFiles == that.allFiles) &&
this.npath.equals(that.npath) &&
@ -795,6 +808,7 @@ public final class FilePermission extends Permission implements Serializable {
(this.recursive == that.recursive);
} else {
return (this.mask == that.mask) &&
(this.allFiles == that.allFiles) &&
this.cpath.equals(that.cpath) &&
(this.directory == that.directory) &&
(this.recursive == that.recursive);
@ -921,17 +935,18 @@ public final class FilePermission extends Permission implements Serializable {
}
// make sure we didn't just match the tail of a word
// like "ackbarfaccept". Also, skip to the comma.
// like "ackbarfdelete". Also, skip to the comma.
boolean seencomma = false;
while (i >= matchlen && !seencomma) {
switch(a[i-matchlen]) {
case ',':
seencomma = true;
break;
switch (c = a[i-matchlen]) {
case ' ': case '\r': case '\n':
case '\f': case '\t':
break;
default:
if (c == ',' && i > matchlen) {
seencomma = true;
break;
}
throw new IllegalArgumentException(
"invalid permission: " + actions);
}
@ -1127,10 +1142,10 @@ final class FilePermissionCollection extends PermissionCollection
*
* @param permission the Permission object to add.
*
* @throws IllegalArgumentException - if the permission is not a
* @throws IllegalArgumentException if the permission is not a
* FilePermission
*
* @throws SecurityException - if this FilePermissionCollection object
* @throws SecurityException if this FilePermissionCollection object
* has been marked readonly
*/
@Override

View File

@ -70,4 +70,35 @@ class NullPointerException extends RuntimeException {
public NullPointerException(String s) {
super(s);
}
/**
* Returns the detail message string of this throwable.
*
* <p> If a non-null message was supplied in a constructor it is
* returned. Otherwise, an implementation specific message or
* {@code null} is returned.
*
* @implNote
* If no explicit message was passed to the constructor, and as
* long as certain internal information is available, a verbose
* description of the null reference is returned.
* The internal information is not available in deserialized
* NullPointerExceptions.
*
* @return the detail message string, which may be {@code null}.
*/
public String getMessage() {
String message = super.getMessage();
if (message == null) {
return getExtendedNPEMessage();
}
return message;
}
/**
* Get an extended exception message. This returns a string describing
* the location and cause of the exception. It returns null for
* exceptions where this is not applicable.
*/
private native String getExtendedNPEMessage();
}

View File

@ -145,6 +145,15 @@ import java.util.StringTokenizer;
* </tr>
*
* <tr>
* <th scope="row">setSocketImpl</th>
* <td>The ability to create a sub-class of Socket or ServerSocket with a
* user specified SocketImpl.</td>
* <td>Malicious user-defined SocketImpls can change the behavior of
* Socket and ServerSocket in surprising ways, by virtue of their
* ability to access the protected fields of SocketImpl.</td>
* </tr>
*
* <tr>
* <th scope="row">specifyStreamHandler</th>
* <td>The ability
* to specify a stream handler when constructing a URL</td>

View File

@ -32,6 +32,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.Collections;
import sun.security.util.SecurityConstants;
import sun.net.PlatformSocketImpl;
/**
@ -73,13 +74,25 @@ class ServerSocket implements java.io.Closeable {
*
* @throws NullPointerException if impl is {@code null}.
*
* @throws SecurityException if a security manager is set and
* its {@code checkPermission} method doesn't allow
* {@code NetPermission("setSocketImpl")}.
* @since 12
*/
protected ServerSocket(SocketImpl impl) {
Objects.requireNonNull(impl);
checkPermission();
this.impl = impl;
}
private static Void checkPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
}
return null;
}
/**
* Creates an unbound server socket.
*

View File

@ -25,6 +25,8 @@
package java.net;
import sun.security.util.SecurityConstants;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
@ -182,12 +184,28 @@ class Socket implements java.io.Closeable {
*
* @throws SocketException if there is an error in the underlying protocol,
* such as a TCP error.
*
* @throws SecurityException if {@code impl} is non-null and a security manager is set
* and its {@code checkPermission} method doesn't allow {@code NetPermission("setSocketImpl")}.
*
* @since 1.1
*/
protected Socket(SocketImpl impl) throws SocketException {
checkPermission(impl);
this.impl = impl;
}
private static Void checkPermission(SocketImpl impl) {
if (impl == null) {
return null;
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
}
return null;
}
/**
* Creates a stream socket and connects it to the specified port
* number on the named host.

View File

@ -287,6 +287,11 @@ public final class SocketPermission extends Permission
* @param host the hostname or IP address of the computer, optionally
* including a colon followed by a port or port range.
* @param action the action string.
*
* @throws NullPointerException if any parameters are null
* @throws IllegalArgumentException if the format of {@code host} is
* invalid, or if the {@code action} string is empty, malformed, or
* contains an action other than the specified possible actions
*/
public SocketPermission(String host, String action) {
super(getHost(host));
@ -589,14 +594,15 @@ public final class SocketPermission extends Permission
// like "ackbarfaccept". Also, skip to the comma.
boolean seencomma = false;
while (i >= matchlen && !seencomma) {
switch(a[i-matchlen]) {
case ',':
seencomma = true;
break;
switch (c = a[i-matchlen]) {
case ' ': case '\r': case '\n':
case '\f': case '\t':
break;
default:
if (c == ',' && i > matchlen) {
seencomma = true;
break;
}
throw new IllegalArgumentException(
"invalid permission: " + action);
}
@ -1361,10 +1367,10 @@ final class SocketPermissionCollection extends PermissionCollection
*
* @param permission the Permission object to add.
*
* @throws IllegalArgumentException - if the permission is not a
* @throws IllegalArgumentException if the permission is not a
* SocketPermission
*
* @throws SecurityException - if this SocketPermissionCollection object
* @throws SecurityException if this SocketPermissionCollection object
* has been marked readonly
*/
@Override

View File

@ -484,6 +484,16 @@ public final class URL implements java.io.Serializable {
throw new MalformedURLException(s);
}
}
if ("jar".equalsIgnoreCase(protocol)) {
if (handler instanceof sun.net.www.protocol.jar.Handler) {
// URL.openConnection() would throw a confusing exception
// so generate a better exception here instead.
String s = ((sun.net.www.protocol.jar.Handler) handler).checkNestedProtocol(file);
if (s != null) {
throw new MalformedURLException(s);
}
}
}
}
/**

View File

@ -178,10 +178,10 @@ final class AllPermissionCollection
*
* @param permission the Permission object to add.
*
* @throws IllegalArgumentException - if the permission is not a
* @throws IllegalArgumentException if the permission is not an
* AllPermission
*
* @throws SecurityException - if this AllPermissionCollection object
* @throws SecurityException if this AllPermissionCollection object
* has been marked readonly
*/

View File

@ -349,13 +349,13 @@ final class BasicPermissionCollection
*
* @param permission the Permission object to add.
*
* @throws IllegalArgumentException - if the permission is not a
* @throws IllegalArgumentException if the permission is not a
* BasicPermission, or if
* the permission is not of the
* same Class as the other
* permissions in this collection.
*
* @throws SecurityException - if this BasicPermissionCollection object
* @throws SecurityException if this BasicPermissionCollection object
* has been marked readonly
*/
@Override

View File

@ -107,9 +107,9 @@ public abstract class PermissionCollection implements java.io.Serializable {
*
* @param permission the Permission object to add.
*
* @throws SecurityException - if this PermissionCollection object
* @throws SecurityException if this PermissionCollection object
* has been marked readonly
* @throws IllegalArgumentException - if this PermissionCollection
* @throws IllegalArgumentException if this PermissionCollection
* object is a homogeneous collection and the permission
* is not of the correct type.
*/

View File

@ -837,7 +837,7 @@ public abstract class Policy {
*
* @param permission the Permission object to add.
*
* @throws SecurityException - if this PermissionCollection object
* @throws SecurityException if this PermissionCollection object
* has been marked readonly
*/
@Override public void add(Permission permission) {

View File

@ -2756,7 +2756,10 @@ public class DecimalFormat extends NumberFormat {
/**
* Return the grouping size. Grouping size is the number of digits between
* grouping separators in the integer portion of a number. For example,
* in the number "123,456.78", the grouping size is 3.
* in the number "123,456.78", the grouping size is 3. Grouping size of
* zero designates that grouping is not used, which provides the same
* formatting as if calling {@link #setGroupingUsed(boolean)
* setGroupingUsed(false)}.
*
* @return the grouping size
* @see #setGroupingSize
@ -2770,16 +2773,28 @@ public class DecimalFormat extends NumberFormat {
/**
* Set the grouping size. Grouping size is the number of digits between
* grouping separators in the integer portion of a number. For example,
* in the number "123,456.78", the grouping size is 3.
* <br>
* in the number "123,456.78", the grouping size is 3. Grouping size of
* zero designates that grouping is not used, which provides the same
* formatting as if calling {@link #setGroupingUsed(boolean)
* setGroupingUsed(false)}.
* <p>
* The value passed in is converted to a byte, which may lose information.
* Values that are negative or greater than
* {@link java.lang.Byte#MAX_VALUE Byte.MAX_VALUE}, will throw an
* {@code IllegalArgumentException}.
*
* @param newValue the new grouping size
* @see #getGroupingSize
* @see java.text.NumberFormat#setGroupingUsed
* @see java.text.DecimalFormatSymbols#setGroupingSeparator
* @throws IllegalArgumentException if {@code newValue} is negative or
* greater than {@link java.lang.Byte#MAX_VALUE Byte.MAX_VALUE}
*/
public void setGroupingSize (int newValue) {
if (newValue < 0 || newValue > Byte.MAX_VALUE) {
throw new IllegalArgumentException(
"newValue is out of valid range. value: " + newValue);
}
groupingSize = (byte)newValue;
fastPathCheckNeeded = true;
}
@ -3906,6 +3921,12 @@ public class DecimalFormat extends NumberFormat {
// Didn't have exponential fields
useExponentialNotation = false;
}
// Restore the invariant value if groupingSize is invalid.
if (groupingSize < 0) {
groupingSize = 3;
}
serialVersionOnStream = currentSerialVersion;
}
@ -4009,14 +4030,15 @@ public class DecimalFormat extends NumberFormat {
/**
* The number of digits between grouping separators in the integer
* portion of a number. Must be greater than 0 if
* portion of a number. Must be non-negative and less than or equal to
* {@link java.lang.Byte#MAX_VALUE Byte.MAX_VALUE} if
* {@code NumberFormat.groupingUsed} is true.
*
* @serial
* @see #getGroupingSize
* @see java.text.NumberFormat#isGroupingUsed
*/
private byte groupingSize = 3; // invariant, > 0 if useThousands
private byte groupingSize = 3; // invariant, 0 - 127, if groupingUsed
/**
* If true, forces the decimal separator to always appear in a formatted

View File

@ -463,10 +463,10 @@ final class PropertyPermissionCollection extends PermissionCollection
*
* @param permission the Permission object to add.
*
* @throws IllegalArgumentException - if the permission is not a
* @throws IllegalArgumentException if the permission is not a
* PropertyPermission
*
* @throws SecurityException - if this PropertyPermissionCollection
* @throws SecurityException if this PropertyPermissionCollection
* object has been marked readonly
*/
@Override

View File

@ -100,6 +100,7 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E>
private static final long serialVersionUID = -817911632652898426L;
/** The queued items */
@SuppressWarnings("serial") // Conditionally serializable
final Object[] items;
/** items index for next take, poll, peek or remove */
@ -120,9 +121,11 @@ public class ArrayBlockingQueue<E> extends AbstractQueue<E>
final ReentrantLock lock;
/** Condition for waiting takes */
@SuppressWarnings("serial") // Classes implementing Condition may be serializable.
private final Condition notEmpty;
/** Condition for waiting puts */
@SuppressWarnings("serial") // Classes implementing Condition may be serializable.
private final Condition notFull;
/**

View File

@ -4584,6 +4584,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
public static class KeySetView<K,V> extends CollectionView<K,V,K>
implements Set<K>, java.io.Serializable {
private static final long serialVersionUID = 7249069246763182397L;
@SuppressWarnings("serial") // Conditionally serializable
private final V value;
KeySetView(ConcurrentHashMap<K,V> map, V value) { // non-public
super(map);

View File

@ -334,6 +334,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
* nested classes.)
* @serial
*/
@SuppressWarnings("serial") // Conditionally serializable
final Comparator<? super K> comparator;
/** Lazily initialized topmost index of the skiplist. */
@ -2375,8 +2376,10 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
/** Underlying map */
final ConcurrentSkipListMap<K,V> m;
/** lower bound key, or null if from start */
@SuppressWarnings("serial") // Conditionally serializable
private final K lo;
/** upper bound key, or null if to end */
@SuppressWarnings("serial") // Conditionally serializable
private final K hi;
/** inclusion flag for lo */
private final boolean loInclusive;

View File

@ -103,6 +103,7 @@ public class ConcurrentSkipListSet<E>
* element. This field is declared final for the sake of thread
* safety, which entails some ugliness in clone().
*/
@SuppressWarnings("serial") // Conditionally serializable
private final ConcurrentNavigableMap<E,Object> m;
/**

View File

@ -1374,7 +1374,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
*/
static final class AdaptedRunnable<T> extends ForkJoinTask<T>
implements RunnableFuture<T> {
@SuppressWarnings("serial") // Conditionally serializable
final Runnable runnable;
@SuppressWarnings("serial") // Conditionally serializable
T result;
AdaptedRunnable(Runnable runnable, T result) {
if (runnable == null) throw new NullPointerException();
@ -1396,6 +1398,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
*/
static final class AdaptedRunnableAction extends ForkJoinTask<Void>
implements RunnableFuture<Void> {
@SuppressWarnings("serial") // Conditionally serializable
final Runnable runnable;
AdaptedRunnableAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
@ -1415,6 +1418,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* Adapter for Runnables in which failure forces worker exception.
*/
static final class RunnableExecuteAction extends ForkJoinTask<Void> {
@SuppressWarnings("serial") // Conditionally serializable
final Runnable runnable;
RunnableExecuteAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
@ -1434,7 +1438,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
*/
static final class AdaptedCallable<T> extends ForkJoinTask<T>
implements RunnableFuture<T> {
@SuppressWarnings("serial") // Conditionally serializable
final Callable<? extends T> callable;
@SuppressWarnings("serial") // Conditionally serializable
T result;
AdaptedCallable(Callable<? extends T> callable) {
if (callable == null) throw new NullPointerException();

View File

@ -159,9 +159,11 @@ public class LinkedBlockingDeque<E>
final ReentrantLock lock = new ReentrantLock();
/** Condition for waiting takes */
@SuppressWarnings("serial") // Classes implementing Condition may be serializable.
private final Condition notEmpty = lock.newCondition();
/** Condition for waiting puts */
@SuppressWarnings("serial") // Classes implementing Condition may be serializable.
private final Condition notFull = lock.newCondition();
/**

View File

@ -156,12 +156,14 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
private final ReentrantLock takeLock = new ReentrantLock();
/** Wait queue for waiting takes */
@SuppressWarnings("serial") // Classes implementing Condition may be serializable.
private final Condition notEmpty = takeLock.newCondition();
/** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock();
/** Wait queue for waiting puts */
@SuppressWarnings("serial") // Classes implementing Condition may be serializable.
private final Condition notFull = putLock.newCondition();
/**

View File

@ -173,6 +173,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
/**
* Condition for blocking when empty.
*/
@SuppressWarnings("serial") // Classes implementing Condition may be serializable.
private final Condition notEmpty = lock.newCondition();
/**

View File

@ -71,6 +71,7 @@ public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
/**
* The result of the computation.
*/
@SuppressWarnings("serial") // Conditionally serializable
V result;
/**

View File

@ -604,8 +604,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
private static final long serialVersionUID = 6138294804551838833L;
/** Thread this worker is running in. Null if factory fails. */
@SuppressWarnings("serial") // Unlikely to be serializable
final Thread thread;
/** Initial task to run. Possibly null. */
@SuppressWarnings("serial") // Not statically typed as Serializable
Runnable firstTask;
/** Per-thread task counter */
volatile long completedTasks;

View File

@ -60,6 +60,7 @@ public class AtomicReference<V> implements java.io.Serializable {
}
}
@SuppressWarnings("serial") // Conditionally serializable
private volatile V value;
/**

View File

@ -55,6 +55,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
private static final long serialVersionUID = -6209656149925076980L;
private static final VarHandle AA
= MethodHandles.arrayElementVarHandle(Object[].class);
@SuppressWarnings("serial") // Conditionally serializable
private final Object[] array; // must have exact type Object[]
/**

View File

@ -84,6 +84,7 @@ import java.util.function.DoubleBinaryOperator;
public class DoubleAccumulator extends Striped64 implements Serializable {
private static final long serialVersionUID = 7249069246863182397L;
@SuppressWarnings("serial") // Not statically typed as Serializable
private final DoubleBinaryOperator function;
private final long identity; // use long representation
@ -245,6 +246,7 @@ public class DoubleAccumulator extends Striped64 implements Serializable {
* The function used for updates.
* @serial
*/
@SuppressWarnings("serial") // Not statically typed as Serializable
private final DoubleBinaryOperator function;
/**

View File

@ -82,6 +82,7 @@ import java.util.function.LongBinaryOperator;
public class LongAccumulator extends Striped64 implements Serializable {
private static final long serialVersionUID = 7249069246863182397L;
@SuppressWarnings("serial") // Not statically typed as Serializable
private final LongBinaryOperator function;
private final long identity;
@ -239,6 +240,7 @@ public class LongAccumulator extends Striped64 implements Serializable {
* The function used for updates.
* @serial
*/
@SuppressWarnings("serial") // Not statically typed as Serializable
private final LongBinaryOperator function;
/**

View File

@ -1427,7 +1427,11 @@ public final class Pattern
localTCNCount = 0;
if (!pattern.isEmpty()) {
compile();
try {
compile();
} catch (StackOverflowError soe) {
throw error("Stack overflow during pattern compilation");
}
} else {
root = new Start(lastAccept);
matchRoot = lastAccept;
@ -1965,6 +1969,10 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
int ch = temp[cursor++];
while (ch != 0 && !isLineSeparator(ch))
ch = temp[cursor++];
if (ch == 0 && cursor > patternLength) {
cursor = patternLength;
ch = temp[cursor++];
}
return ch;
}
@ -1975,6 +1983,10 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
int ch = temp[++cursor];
while (ch != 0 && !isLineSeparator(ch))
ch = temp[++cursor];
if (ch == 0 && cursor > patternLength) {
cursor = patternLength;
ch = temp[cursor];
}
return ch;
}
@ -3415,9 +3427,10 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
private int N() {
if (read() == '{') {
int i = cursor;
while (cursor < patternLength && read() != '}') {}
if (cursor > patternLength)
throw error("Unclosed character name escape sequence");
while (read() != '}') {
if (cursor >= patternLength)
throw error("Unclosed character name escape sequence");
}
String name = new String(temp, i, cursor - i - 1);
try {
return Character.codePointOf(name);

View File

@ -2171,6 +2171,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
} while (retryTunnel < maxRedirects);
if (retryTunnel >= maxRedirects || (respCode != HTTP_OK)) {
if (respCode != HTTP_PROXY_AUTH) {
// remove all but authenticate responses
responses.reset();
}
throw new IOException("Unable to tunnel through proxy."+
" Proxy returns \"" +
statusLine + "\"");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019, 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
@ -121,6 +121,13 @@ public class Handler extends java.net.URLStreamHandler {
return h;
}
public String checkNestedProtocol(String spec) {
if (spec.regionMatches(true, 0, "jar:", 0, 4)) {
return "Nested JAR URLs are not supported";
} else {
return null;
}
}
@Override
@SuppressWarnings("deprecation")
@ -146,6 +153,12 @@ public class Handler extends java.net.URLStreamHandler {
: false;
spec = spec.substring(start, limit);
String exceptionMessage = checkNestedProtocol(spec);
if (exceptionMessage != null) {
// NPE will be transformed into MalformedURLException by the caller
throw new NullPointerException(exceptionMessage);
}
if (absoluteSpec) {
file = parseAbsoluteSpec(spec);
} else if (!refOnly) {

View File

@ -37,6 +37,9 @@ import java.net.StandardSocketOptions;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Set;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ -59,7 +62,12 @@ class ServerSocketAdaptor // package-private
private volatile int timeout;
static ServerSocket create(ServerSocketChannelImpl ssc) {
return new ServerSocketAdaptor(ssc);
PrivilegedExceptionAction<ServerSocket> pa = () -> new ServerSocketAdaptor(ssc);
try {
return AccessController.doPrivileged(pa);
} catch (PrivilegedActionException pae) {
throw new InternalError("Should not reach here", pae);
}
}
private ServerSocketAdaptor(ServerSocketChannelImpl ssc) {

View File

@ -36,6 +36,9 @@ import java.net.SocketException;
import java.net.SocketOption;
import java.net.StandardSocketOptions;
import java.nio.channels.SocketChannel;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Set;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ -61,10 +64,11 @@ class SocketAdaptor
}
static Socket create(SocketChannelImpl sc) {
PrivilegedExceptionAction<Socket> pa = () -> new SocketAdaptor(sc);
try {
return new SocketAdaptor(sc);
} catch (SocketException e) {
throw new InternalError("Should not reach here");
return AccessController.doPrivileged(pa);
} catch (PrivilegedActionException pae) {
throw new InternalError("Should not reach here", pae);
}
}

View File

@ -201,7 +201,7 @@ final class SupportedGroupsExtension {
// Primary XDH (RFC 7748) curves
NamedGroup.X25519,
// Primary NIST curves (e.g. used in TLSv1.3)
// Primary NIST Suite B curves
NamedGroup.SECP256_R1,
NamedGroup.SECP384_R1,
NamedGroup.SECP521_R1,
@ -209,17 +209,6 @@ final class SupportedGroupsExtension {
// Secondary XDH curves
NamedGroup.X448,
// Secondary NIST curves
NamedGroup.SECT283_K1,
NamedGroup.SECT283_R1,
NamedGroup.SECT409_K1,
NamedGroup.SECT409_R1,
NamedGroup.SECT571_K1,
NamedGroup.SECT571_R1,
// non-NIST curves
NamedGroup.SECP256_K1,
// FFDHE (RFC 7919)
NamedGroup.FFDHE_2048,
NamedGroup.FFDHE_3072,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, 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,8 +42,11 @@ public class FilePermCompat {
public static final boolean compat;
static {
String flag = GetPropertyAction.privilegedGetProperty(
"jdk.io.permissionsUseCanonicalPath", "false");
String flag = SecurityProperties.privilegedGetOverridable(
"jdk.io.permissionsUseCanonicalPath");
if (flag == null) {
flag = "false";
}
switch (flag) {
case "true":
nb = false;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2019, 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
@ -97,6 +97,10 @@ public final class SecurityConstants {
public static final NetPermission GET_RESPONSECACHE_PERMISSION =
new NetPermission("getResponseCache");
// java.net.ServerSocket, java.net.Socket
public static final NetPermission SET_SOCKETIMPL_PERMISSION =
new NetPermission("setSocketImpl");
// java.lang.SecurityManager, sun.applet.AppletPanel
public static final RuntimePermission CREATE_CLASSLOADER_PERMISSION =
new RuntimePermission("createClassLoader");

View File

@ -1213,3 +1213,51 @@ jdk.sasl.disabledMechanisms=
# if this property is not enabled.
#
jdk.security.caDistrustPolicies=SYMANTEC_TLS
#
# FilePermission path canonicalization
#
# This security property dictates how the path argument is processed and stored
# while constructing a FilePermission object. If the value is set to true, the
# path argument is canonicalized and FilePermission methods (such as implies,
# equals, and hashCode) are implemented based on this canonicalized result.
# Otherwise, the path argument is not canonicalized and FilePermission methods are
# implemented based on the original input. See the implementation note of the
# FilePermission class for more details.
#
# If a system property of the same name is also specified, it supersedes the
# security property value defined here.
#
# The default value for this property is false.
#
jdk.io.permissionsUseCanonicalPath=false
#
# Policies for the proxy_impersonator Kerberos ccache configuration entry
#
# The proxy_impersonator ccache configuration entry indicates that the ccache
# is a synthetic delegated credential for use with S4U2Proxy by an intermediate
# server. The ccache file should also contain the TGT of this server and
# an evidence ticket from the default principal of the ccache to this server.
#
# This security property determines how Java uses this configuration entry.
# There are 3 possible values:
#
# no-impersonate - Ignore this configuration entry, and always act as
# the owner of the TGT (if it exists).
#
# try-impersonate - Try impersonation when this configuration entry exists.
# If no matching TGT or evidence ticket is found,
# fallback to no-impersonate.
#
# always-impersonate - Always impersonate when this configuration entry exists.
# If no matching TGT or evidence ticket is found,
# no initial credential is read from the ccache.
#
# The default value is "always-impersonate".
#
# If a system property of the same name is also specified, it supersedes the
# security property value defined here.
#
#jdk.security.krb5.default.initiate.credential=always-impersonate

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019 SAP SE. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
#include "jni.h"
#include "jvm.h"
#include "java_lang_NullPointerException.h"
JNIEXPORT jstring JNICALL
Java_java_lang_NullPointerException_getExtendedNPEMessage(JNIEnv *env, jobject throwable)
{
return JVM_GetExtendedNPEMessage(env, throwable);
}

View File

@ -38,6 +38,7 @@ import java.lang.ProcessBuilder.Redirect;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
@ -46,6 +47,8 @@ import java.util.regex.Pattern;
import jdk.internal.access.JavaIOFileDescriptorAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
/* This class is for the exclusive use of ProcessBuilder.start() to
* create new processes.
@ -209,12 +212,15 @@ final class ProcessImpl extends Process {
private static final int VERIFICATION_CMD_BAT = 0;
private static final int VERIFICATION_WIN32 = 1;
private static final int VERIFICATION_LEGACY = 2;
private static final int VERIFICATION_WIN32_SAFE = 2; // inside quotes not allowed
private static final int VERIFICATION_LEGACY = 3;
// See Command shell overview for documentation of special characters.
// https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490954(v=technet.10)
private static final char ESCAPE_VERIFICATION[][] = {
// We guarantee the only command file execution for implicit [cmd.exe] run.
// http://technet.microsoft.com/en-us/library/bb490954.aspx
{' ', '\t', '<', '>', '&', '|', '^'},
{' ', '\t', '<', '>'},
{' ', '\t', '<', '>'},
{' ', '\t'}
};
@ -231,8 +237,25 @@ final class ProcessImpl extends Process {
cmdbuf.append(' ');
String s = cmd[i];
if (needsEscaping(verificationType, s)) {
cmdbuf.append('"').append(s);
cmdbuf.append('"');
if (verificationType == VERIFICATION_WIN32_SAFE) {
// Insert the argument, adding '\' to quote any interior quotes
int length = s.length();
for (int j = 0; j < length; j++) {
char c = s.charAt(j);
if (c == DOUBLEQUOTE) {
int count = countLeadingBackslash(verificationType, s, j);
while (count-- > 0) {
cmdbuf.append(BACKSLASH); // double the number of backslashes
}
cmdbuf.append(BACKSLASH); // backslash to quote the quote
}
cmdbuf.append(c);
}
} else {
cmdbuf.append(s);
}
// The code protects the [java.exe] and console command line
// parser, that interprets the [\"] combination as an escape
// sequence for the ["] char.
@ -245,8 +268,9 @@ final class ProcessImpl extends Process {
// command line parser. The case of the [""] tail escape
// sequence could not be realized due to the argument validation
// procedure.
if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
cmdbuf.append('\\');
int count = countLeadingBackslash(verificationType, s, s.length());
while (count-- > 0) {
cmdbuf.append(BACKSLASH); // double the number of backslashes
}
cmdbuf.append('"');
} else {
@ -256,26 +280,16 @@ final class ProcessImpl extends Process {
return cmdbuf.toString();
}
private static boolean isQuoted(boolean noQuotesInside, String arg,
String errorMessage) {
int lastPos = arg.length() - 1;
if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
// The argument has already been quoted.
if (noQuotesInside) {
if (arg.indexOf('"', 1) != lastPos) {
// There is ["] inside.
throw new IllegalArgumentException(errorMessage);
}
}
return true;
}
if (noQuotesInside) {
if (arg.indexOf('"') >= 0) {
// There is ["] inside.
throw new IllegalArgumentException(errorMessage);
}
}
return false;
/**
* Return the argument without quotes (1st and last) if present, else the arg.
* @param str a string
* @return the string without 1st and last quotes
*/
private static String unQuote(String str) {
int len = str.length();
return (len >= 2 && str.charAt(0) == DOUBLEQUOTE && str.charAt(len - 1) == DOUBLEQUOTE)
? str.substring(1, len - 1)
: str;
}
private static boolean needsEscaping(int verificationType, String arg) {
@ -286,9 +300,26 @@ final class ProcessImpl extends Process {
// For [.exe] or [.com] file the unpaired/internal ["]
// in the argument is not a problem.
boolean argIsQuoted = isQuoted(
(verificationType == VERIFICATION_CMD_BAT),
arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
String unquotedArg = unQuote(arg);
boolean argIsQuoted = !arg.equals(unquotedArg);
boolean embeddedQuote = unquotedArg.indexOf(DOUBLEQUOTE) >= 0;
switch (verificationType) {
case VERIFICATION_CMD_BAT:
if (embeddedQuote) {
throw new IllegalArgumentException("Argument has embedded quote, " +
"use the explicit CMD.EXE call.");
}
break; // break determine whether to quote
case VERIFICATION_WIN32_SAFE:
if (argIsQuoted && embeddedQuote) {
throw new IllegalArgumentException("Malformed argument has embedded quote: "
+ unquotedArg);
}
break;
default:
break;
}
if (!argIsQuoted) {
char testEscape[] = ESCAPE_VERIFICATION[verificationType];
@ -304,13 +335,13 @@ final class ProcessImpl extends Process {
private static String getExecutablePath(String path)
throws IOException
{
boolean pathIsQuoted = isQuoted(true, path,
"Executable name has embedded quote, split the arguments");
String name = unQuote(path);
if (name.indexOf(DOUBLEQUOTE) >= 0) {
throw new IllegalArgumentException("Executable name has embedded quote, " +
"split the arguments: " + name);
}
// Win32 CreateProcess requires path to be normalized
File fileToRun = new File(pathIsQuoted
? path.substring(1, path.length() - 1)
: path);
File fileToRun = new File(name);
// From the [CreateProcess] function documentation:
//
@ -325,13 +356,26 @@ final class ProcessImpl extends Process {
// sequence:..."
//
// In practice ANY non-existent path is extended by [.exe] extension
// in the [CreateProcess] funcion with the only exception:
// in the [CreateProcess] function with the only exception:
// the path ends by (.)
return fileToRun.getPath();
}
/**
* An executable is any program that is an EXE or does not have an extension
* and the Windows createProcess will be looking for .exe.
* The comparison is case insensitive based on the name.
* @param executablePath the executable file
* @return true if the path ends in .exe or does not have an extension.
*/
private boolean isExe(String executablePath) {
File file = new File(executablePath);
String upName = file.getName().toUpperCase(Locale.ROOT);
return (upName.endsWith(".EXE") || upName.indexOf('.') < 0);
}
// Old version that can be bypassed
private boolean isShellFile(String executablePath) {
String upPath = executablePath.toUpperCase();
return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
@ -342,6 +386,21 @@ final class ProcessImpl extends Process {
return argbuf.append('"').append(arg).append('"').toString();
}
// Count backslashes before start index of string.
// .bat files don't include backslashes as part of the quote
private static int countLeadingBackslash(int verificationType,
CharSequence input, int start) {
if (verificationType == VERIFICATION_CMD_BAT)
return 0;
int j;
for (j = start - 1; j >= 0 && input.charAt(j) == BACKSLASH; j--) {
// just scanning backwards
}
return (start - 1) - j; // number of BACKSLASHES
}
private static final char DOUBLEQUOTE = '\"';
private static final char BACKSLASH = '\\';
private final long handle;
private final ProcessHandle processHandle;
@ -358,15 +417,13 @@ final class ProcessImpl extends Process {
throws IOException
{
String cmdstr;
SecurityManager security = System.getSecurityManager();
boolean allowAmbiguousCommands = false;
if (security == null) {
allowAmbiguousCommands = true;
String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
if (value != null)
allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
}
if (allowAmbiguousCommands) {
final SecurityManager security = System.getSecurityManager();
final String value = GetPropertyAction.
privilegedGetProperty("jdk.lang.Process.allowAmbiguousCommands",
(security == null ? "true" : "false"));
final boolean allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
if (allowAmbiguousCommands && security == null) {
// Legacy mode.
// Normalize path if possible.
@ -413,11 +470,12 @@ final class ProcessImpl extends Process {
// Quotation protects from interpretation of the [path] argument as
// start of longer path with spaces. Quotation has no influence to
// [.exe] extension heuristic.
boolean isShell = allowAmbiguousCommands ? isShellFile(executablePath)
: !isExe(executablePath);
cmdstr = createCommandLine(
// We need the extended verification procedure for CMD files.
isShellFile(executablePath)
? VERIFICATION_CMD_BAT
: VERIFICATION_WIN32,
// We need the extended verification procedures
isShell ? VERIFICATION_CMD_BAT
: (allowAmbiguousCommands ? VERIFICATION_WIN32 : VERIFICATION_WIN32_SAFE),
quoteString(executablePath),
cmd);
}

View File

@ -1929,6 +1929,7 @@ public class Font implements java.io.Serializable
// value is the default.
if (fRequestedAttributes != null) {
try {
values = getAttributeValues(); // init
AttributeValues extras =
AttributeValues.fromSerializableHashtable(fRequestedAttributes);
@ -1938,10 +1939,13 @@ public class Font implements java.io.Serializable
values = getAttributeValues().merge(extras);
this.nonIdentityTx = values.anyNonDefault(EXTRA_MASK);
this.hasLayoutAttributes = values.anyNonDefault(LAYOUT_MASK);
} catch (Throwable t) {
throw new IOException(t);
} finally {
fRequestedAttributes = null; // don't need it any more
}
}
}
/**
* Returns the number of glyphs in this {@code Font}. Glyph codes

View File

@ -130,7 +130,7 @@ abstract class CMap {
static final char noSuchChar = (char)0xfffd;
static final int SHORTMASK = 0x0000ffff;
static final int INTMASK = 0xffffffff;
static final int INTMASK = 0x7fffffff;
static final char[][] converterMaps = new char[7][];
@ -919,7 +919,11 @@ abstract class CMap {
bbuffer.position(12);
bbuffer.get(is32);
nGroups = bbuffer.getInt();
nGroups = bbuffer.getInt() & INTMASK;
// A map group record is three uint32's making for 12 bytes total
if (bbuffer.remaining() < (12 * (long)nGroups)) {
throw new RuntimeException("Format 8 table exceeded");
}
startCharCode = new int[nGroups];
endCharCode = new int[nGroups];
startGlyphID = new int[nGroups];
@ -947,9 +951,13 @@ abstract class CMap {
CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
bbuffer.position(offset+12);
firstCode = bbuffer.getInt() & INTMASK;
entryCount = bbuffer.getInt() & INTMASK;
bbuffer.position(offset+20);
// each glyph is a uint16, so 2 bytes per value.
if (bbuffer.remaining() < (2 * (long)entryCount)) {
throw new RuntimeException("Format 10 table exceeded");
}
CharBuffer buffer = bbuffer.asCharBuffer();
glyphIdArray = new char[entryCount];
for (int i=0; i< entryCount; i++) {
@ -989,11 +997,15 @@ abstract class CMap {
throw new RuntimeException("xlat array for cmap fmt=12");
}
numGroups = buffer.getInt(offset+12);
buffer.position(offset+12);
numGroups = buffer.getInt() & INTMASK;
// A map group record is three uint32's making for 12 bytes total
if (buffer.remaining() < (12 * (long)numGroups)) {
throw new RuntimeException("Format 12 table exceeded");
}
startCharCode = new long[numGroups];
endCharCode = new long[numGroups];
startGlyphID = new int[numGroups];
buffer.position(offset+16);
buffer = buffer.slice();
IntBuffer ibuffer = buffer.asIntBuffer();
for (int i=0; i<numGroups; i++) {
@ -1110,7 +1122,13 @@ abstract class CMap {
char[][] glyphID;
UVS(ByteBuffer buffer, int offset) {
numSelectors = buffer.getInt(offset+6);
buffer.position(offset+6);
numSelectors = buffer.getInt() & INTMASK;
// A variation selector record is one 3 byte int + two int32's
// making for 11 bytes per record.
if (buffer.remaining() < (11 * (long)numSelectors)) {
throw new RuntimeException("Variations exceed buffer");
}
selector = new int[numSelectors];
numUVSMapping = new int[numSelectors];
unicodeValue = new int[numSelectors][];
@ -1131,6 +1149,11 @@ abstract class CMap {
} else if (tableOffset > 0) {
buffer.position(offset+tableOffset);
numUVSMapping[i] = buffer.getInt() & INTMASK;
// a UVS mapping record is one 3 byte int + uint16
// making for 5 bytes per record.
if (buffer.remaining() < (5 * (long)numUVSMapping[i])) {
throw new RuntimeException("Variations exceed buffer");
}
unicodeValue[i] = new int[numUVSMapping[i]];
glyphID[i] = new char[numUVSMapping[i]];

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