Merge
This commit is contained in:
commit
593a00095a
@ -132,12 +132,12 @@ static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Part of the class sharing workaround
|
// Part of the class sharing workaround
|
||||||
static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
|
static void add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
|
||||||
uintptr_t vaddr, size_t memsz) {
|
uintptr_t vaddr, size_t memsz) {
|
||||||
map_info* map;
|
map_info* map;
|
||||||
if ((map = allocate_init_map(ph->core->classes_jsa_fd,
|
if ((map = allocate_init_map(ph->core->classes_jsa_fd,
|
||||||
offset, vaddr, memsz)) == NULL) {
|
offset, vaddr, memsz)) == NULL) {
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
map->next = ph->core->class_share_maps;
|
map->next = ph->core->class_share_maps;
|
||||||
|
@ -168,12 +168,12 @@ endif
|
|||||||
# conversions which might affect the values. To avoid that, we need to turn
|
# conversions which might affect the values. To avoid that, we need to turn
|
||||||
# it off explicitly.
|
# it off explicitly.
|
||||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||||
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wsign-compare
|
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
|
||||||
else
|
else
|
||||||
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
|
WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS)
|
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
|
||||||
# Special cases
|
# Special cases
|
||||||
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
|
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
|
||||||
# XXXDARWIN: for _dyld_bind_fully_image_containing_address
|
# XXXDARWIN: for _dyld_bind_fully_image_containing_address
|
||||||
|
@ -69,7 +69,7 @@ ifeq ($(INCLUDE_CDS), false)
|
|||||||
CXXFLAGS += -DINCLUDE_CDS=0
|
CXXFLAGS += -DINCLUDE_CDS=0
|
||||||
CFLAGS += -DINCLUDE_CDS=0
|
CFLAGS += -DINCLUDE_CDS=0
|
||||||
|
|
||||||
Src_Files_EXCLUDE += metaspaceShared.cpp
|
Src_Files_EXCLUDE += filemap.cpp metaspaceShared.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(INCLUDE_ALL_GCS), false)
|
ifeq ($(INCLUDE_ALL_GCS), false)
|
||||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
|
|||||||
|
|
||||||
HS_MAJOR_VER=25
|
HS_MAJOR_VER=25
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=22
|
HS_BUILD_NUMBER=23
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=8
|
JDK_MINOR_VER=8
|
||||||
|
@ -131,12 +131,12 @@ WARNINGS_ARE_ERRORS = -Werror
|
|||||||
# conversions which might affect the values. To avoid that, we need to turn
|
# conversions which might affect the values. To avoid that, we need to turn
|
||||||
# it off explicitly.
|
# it off explicitly.
|
||||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||||
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wsign-compare
|
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
|
||||||
else
|
else
|
||||||
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
|
WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS)
|
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
|
||||||
# Special cases
|
# Special cases
|
||||||
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
|
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
|
||||||
|
|
||||||
|
@ -118,8 +118,8 @@ endif
|
|||||||
# Compiler warnings are treated as errors
|
# Compiler warnings are treated as errors
|
||||||
WARNINGS_ARE_ERRORS = -Werror
|
WARNINGS_ARE_ERRORS = -Werror
|
||||||
# Enable these warnings. See 'info gcc' about details on these options
|
# Enable these warnings. See 'info gcc' about details on these options
|
||||||
ADDITIONAL_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
|
WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
|
||||||
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ADDITIONAL_WARNINGS)
|
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
|
||||||
# Special cases
|
# Special cases
|
||||||
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
|
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
|
||||||
|
|
||||||
|
@ -2194,7 +2194,8 @@ int AbstractInterpreter::layout_activation(Method* method,
|
|||||||
int callee_locals_size,
|
int callee_locals_size,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
frame* interpreter_frame,
|
frame* interpreter_frame,
|
||||||
bool is_top_frame) {
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame) {
|
||||||
|
|
||||||
assert(popframe_extra_args == 0, "NEED TO FIX");
|
assert(popframe_extra_args == 0, "NEED TO FIX");
|
||||||
// NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
|
// NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
|
||||||
|
@ -1581,7 +1581,8 @@ int AbstractInterpreter::layout_activation(Method* method,
|
|||||||
int callee_local_count,
|
int callee_local_count,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
frame* interpreter_frame,
|
frame* interpreter_frame,
|
||||||
bool is_top_frame) {
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame) {
|
||||||
// Note: This calculation must exactly parallel the frame setup
|
// Note: This calculation must exactly parallel the frame setup
|
||||||
// in InterpreterGenerator::generate_fixed_frame.
|
// in InterpreterGenerator::generate_fixed_frame.
|
||||||
// If f!=NULL, set up the following variables:
|
// If f!=NULL, set up the following variables:
|
||||||
@ -1664,6 +1665,15 @@ int AbstractInterpreter::layout_activation(Method* method,
|
|||||||
int delta = local_words - parm_words;
|
int delta = local_words - parm_words;
|
||||||
int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
|
int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
|
||||||
*interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
|
*interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
|
||||||
|
if (!is_bottom_frame) {
|
||||||
|
// Llast_SP is set below for the current frame to SP (with the
|
||||||
|
// extra space for the callee's locals). Here we adjust
|
||||||
|
// Llast_SP for the caller's frame, removing the extra space
|
||||||
|
// for the current method's locals.
|
||||||
|
*caller->register_addr(Llast_SP) = *interpreter_frame->register_addr(I5_savedSP);
|
||||||
|
} else {
|
||||||
|
assert(*caller->register_addr(Llast_SP) >= *interpreter_frame->register_addr(I5_savedSP), "strange Llast_SP");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
|
assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
|
||||||
// Don't have Lesp available; lay out locals block in the caller
|
// Don't have Lesp available; lay out locals block in the caller
|
||||||
|
@ -2361,7 +2361,8 @@ int AbstractInterpreter::layout_activation(Method* method,
|
|||||||
int callee_locals,
|
int callee_locals,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
frame* interpreter_frame,
|
frame* interpreter_frame,
|
||||||
bool is_top_frame) {
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame) {
|
||||||
|
|
||||||
assert(popframe_extra_args == 0, "FIX ME");
|
assert(popframe_extra_args == 0, "FIX ME");
|
||||||
// NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
|
// NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
|
||||||
|
@ -356,7 +356,7 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
|
|||||||
// Verifies the calculated original PC of a deoptimization PC for the
|
// Verifies the calculated original PC of a deoptimization PC for the
|
||||||
// given unextended SP. The unextended SP might also be the saved SP
|
// given unextended SP. The unextended SP might also be the saved SP
|
||||||
// for MethodHandle call sites.
|
// for MethodHandle call sites.
|
||||||
#if ASSERT
|
#ifdef ASSERT
|
||||||
void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
|
void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
|
||||||
frame fr;
|
frame fr;
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@
|
|||||||
return (intptr_t*) addr_at(offset);
|
return (intptr_t*) addr_at(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ASSERT
|
#ifdef ASSERT
|
||||||
// Used in frame::sender_for_{interpreter,compiled}_frame
|
// Used in frame::sender_for_{interpreter,compiled}_frame
|
||||||
static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
|
static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
|
||||||
static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {
|
static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {
|
||||||
|
@ -1585,7 +1585,8 @@ int AbstractInterpreter::layout_activation(Method* method,
|
|||||||
int callee_locals,
|
int callee_locals,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
frame* interpreter_frame,
|
frame* interpreter_frame,
|
||||||
bool is_top_frame) {
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame) {
|
||||||
// Note: This calculation must exactly parallel the frame setup
|
// Note: This calculation must exactly parallel the frame setup
|
||||||
// in AbstractInterpreterGenerator::generate_method_entry.
|
// in AbstractInterpreterGenerator::generate_method_entry.
|
||||||
// If interpreter_frame!=NULL, set up the method, locals, and monitors.
|
// If interpreter_frame!=NULL, set up the method, locals, and monitors.
|
||||||
|
@ -1599,7 +1599,8 @@ int AbstractInterpreter::layout_activation(Method* method,
|
|||||||
int callee_locals,
|
int callee_locals,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
frame* interpreter_frame,
|
frame* interpreter_frame,
|
||||||
bool is_top_frame) {
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame) {
|
||||||
// Note: This calculation must exactly parallel the frame setup
|
// Note: This calculation must exactly parallel the frame setup
|
||||||
// in AbstractInterpreterGenerator::generate_method_entry.
|
// in AbstractInterpreterGenerator::generate_method_entry.
|
||||||
// If interpreter_frame!=NULL, set up the method, locals, and monitors.
|
// If interpreter_frame!=NULL, set up the method, locals, and monitors.
|
||||||
|
@ -919,7 +919,8 @@ int AbstractInterpreter::layout_activation(Method* method,
|
|||||||
int callee_locals,
|
int callee_locals,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
frame* interpreter_frame,
|
frame* interpreter_frame,
|
||||||
bool is_top_frame) {
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame) {
|
||||||
assert(popframe_extra_args == 0, "what to do?");
|
assert(popframe_extra_args == 0, "what to do?");
|
||||||
assert(!is_top_frame || (!callee_locals && !callee_param_count),
|
assert(!is_top_frame || (!callee_locals && !callee_param_count),
|
||||||
"top frame should have no caller");
|
"top frame should have no caller");
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "runtime/threadCritical.hpp"
|
#include "runtime/threadCritical.hpp"
|
||||||
#include "runtime/timer.hpp"
|
#include "runtime/timer.hpp"
|
||||||
#include "services/attachListener.hpp"
|
#include "services/attachListener.hpp"
|
||||||
|
#include "services/memTracker.hpp"
|
||||||
#include "services/runtimeService.hpp"
|
#include "services/runtimeService.hpp"
|
||||||
#include "utilities/decoder.hpp"
|
#include "utilities/decoder.hpp"
|
||||||
#include "utilities/defaultStream.hpp"
|
#include "utilities/defaultStream.hpp"
|
||||||
@ -2275,13 +2276,25 @@ char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The memory is committed
|
||||||
|
address pc = CALLER_PC;
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc);
|
||||||
|
MemTracker::record_virtual_memory_commit((address)addr, bytes, pc);
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool os::release_memory_special(char* base, size_t bytes) {
|
bool os::release_memory_special(char* base, size_t bytes) {
|
||||||
// detaching the SHM segment will also delete it, see reserve_memory_special()
|
// detaching the SHM segment will also delete it, see reserve_memory_special()
|
||||||
int rslt = shmdt(base);
|
int rslt = shmdt(base);
|
||||||
return rslt == 0;
|
if (rslt == 0) {
|
||||||
|
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
|
||||||
|
MemTracker::record_virtual_memory_release((address)base, bytes);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t os::large_page_size() {
|
size_t os::large_page_size() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -40,6 +40,9 @@
|
|||||||
product(bool, UseHugeTLBFS, false, \
|
product(bool, UseHugeTLBFS, false, \
|
||||||
"Use MAP_HUGETLB for large pages") \
|
"Use MAP_HUGETLB for large pages") \
|
||||||
\
|
\
|
||||||
|
product(bool, LoadExecStackDllInVMThread, true, \
|
||||||
|
"Load DLLs with executable-stack attribute in the VM Thread") \
|
||||||
|
\
|
||||||
product(bool, UseSHM, false, \
|
product(bool, UseSHM, false, \
|
||||||
"Use SYSV shared memory for large pages")
|
"Use SYSV shared memory for large pages")
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "runtime/extendedPC.hpp"
|
#include "runtime/extendedPC.hpp"
|
||||||
#include "runtime/globals.hpp"
|
#include "runtime/globals.hpp"
|
||||||
#include "runtime/interfaceSupport.hpp"
|
#include "runtime/interfaceSupport.hpp"
|
||||||
|
#include "runtime/init.hpp"
|
||||||
#include "runtime/java.hpp"
|
#include "runtime/java.hpp"
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
@ -57,10 +58,12 @@
|
|||||||
#include "runtime/threadCritical.hpp"
|
#include "runtime/threadCritical.hpp"
|
||||||
#include "runtime/timer.hpp"
|
#include "runtime/timer.hpp"
|
||||||
#include "services/attachListener.hpp"
|
#include "services/attachListener.hpp"
|
||||||
|
#include "services/memTracker.hpp"
|
||||||
#include "services/runtimeService.hpp"
|
#include "services/runtimeService.hpp"
|
||||||
#include "utilities/decoder.hpp"
|
#include "utilities/decoder.hpp"
|
||||||
#include "utilities/defaultStream.hpp"
|
#include "utilities/defaultStream.hpp"
|
||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
|
#include "utilities/elfFile.hpp"
|
||||||
#include "utilities/growableArray.hpp"
|
#include "utilities/growableArray.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
|
|
||||||
@ -1796,9 +1799,93 @@ bool os::dll_address_to_library_name(address addr, char* buf,
|
|||||||
// in case of error it checks if .dll/.so was built for the
|
// in case of error it checks if .dll/.so was built for the
|
||||||
// same architecture as Hotspot is running on
|
// same architecture as Hotspot is running on
|
||||||
|
|
||||||
|
|
||||||
|
// Remember the stack's state. The Linux dynamic linker will change
|
||||||
|
// the stack to 'executable' at most once, so we must safepoint only once.
|
||||||
|
bool os::Linux::_stack_is_executable = false;
|
||||||
|
|
||||||
|
// VM operation that loads a library. This is necessary if stack protection
|
||||||
|
// of the Java stacks can be lost during loading the library. If we
|
||||||
|
// do not stop the Java threads, they can stack overflow before the stacks
|
||||||
|
// are protected again.
|
||||||
|
class VM_LinuxDllLoad: public VM_Operation {
|
||||||
|
private:
|
||||||
|
const char *_filename;
|
||||||
|
void *_lib;
|
||||||
|
public:
|
||||||
|
VM_LinuxDllLoad(const char *fn) :
|
||||||
|
_filename(fn), _lib(NULL) {}
|
||||||
|
VMOp_Type type() const { return VMOp_LinuxDllLoad; }
|
||||||
|
void doit() {
|
||||||
|
_lib = os::Linux::dll_load_inner(_filename);
|
||||||
|
os::Linux::_stack_is_executable = true;
|
||||||
|
}
|
||||||
|
void* loaded_library() { return _lib; }
|
||||||
|
};
|
||||||
|
|
||||||
void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
|
void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
|
||||||
{
|
{
|
||||||
void * result= ::dlopen(filename, RTLD_LAZY);
|
void * result = NULL;
|
||||||
|
bool load_attempted = false;
|
||||||
|
|
||||||
|
// Check whether the library to load might change execution rights
|
||||||
|
// of the stack. If they are changed, the protection of the stack
|
||||||
|
// guard pages will be lost. We need a safepoint to fix this.
|
||||||
|
//
|
||||||
|
// See Linux man page execstack(8) for more info.
|
||||||
|
if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) {
|
||||||
|
ElfFile ef(filename);
|
||||||
|
if (!ef.specifies_noexecstack()) {
|
||||||
|
if (!is_init_completed()) {
|
||||||
|
os::Linux::_stack_is_executable = true;
|
||||||
|
// This is OK - No Java threads have been created yet, and hence no
|
||||||
|
// stack guard pages to fix.
|
||||||
|
//
|
||||||
|
// This should happen only when you are building JDK7 using a very
|
||||||
|
// old version of JDK6 (e.g., with JPRT) and running test_gamma.
|
||||||
|
//
|
||||||
|
// Dynamic loader will make all stacks executable after
|
||||||
|
// this function returns, and will not do that again.
|
||||||
|
assert(Threads::first() == NULL, "no Java threads should exist yet.");
|
||||||
|
} else {
|
||||||
|
warning("You have loaded library %s which might have disabled stack guard. "
|
||||||
|
"The VM will try to fix the stack guard now.\n"
|
||||||
|
"It's highly recommended that you fix the library with "
|
||||||
|
"'execstack -c <libfile>', or link it with '-z noexecstack'.",
|
||||||
|
filename);
|
||||||
|
|
||||||
|
assert(Thread::current()->is_Java_thread(), "must be Java thread");
|
||||||
|
JavaThread *jt = JavaThread::current();
|
||||||
|
if (jt->thread_state() != _thread_in_native) {
|
||||||
|
// This happens when a compiler thread tries to load a hsdis-<arch>.so file
|
||||||
|
// that requires ExecStack. Cannot enter safe point. Let's give up.
|
||||||
|
warning("Unable to fix stack guard. Giving up.");
|
||||||
|
} else {
|
||||||
|
if (!LoadExecStackDllInVMThread) {
|
||||||
|
// This is for the case where the DLL has an static
|
||||||
|
// constructor function that executes JNI code. We cannot
|
||||||
|
// load such DLLs in the VMThread.
|
||||||
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadInVMfromNative tiv(jt);
|
||||||
|
debug_only(VMNativeEntryWrapper vew;)
|
||||||
|
|
||||||
|
VM_LinuxDllLoad op(filename);
|
||||||
|
VMThread::execute(&op);
|
||||||
|
if (LoadExecStackDllInVMThread) {
|
||||||
|
result = op.loaded_library();
|
||||||
|
}
|
||||||
|
load_attempted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!load_attempted) {
|
||||||
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
|
}
|
||||||
|
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
// Successful loading
|
// Successful loading
|
||||||
return result;
|
return result;
|
||||||
@ -1952,6 +2039,38 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void * os::Linux::dll_load_inner(const char *filename) {
|
||||||
|
void * result = NULL;
|
||||||
|
if (LoadExecStackDllInVMThread) {
|
||||||
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a
|
||||||
|
// library that requires an executable stack, or which does not have this
|
||||||
|
// stack attribute set, dlopen changes the stack attribute to executable. The
|
||||||
|
// read protection of the guard pages gets lost.
|
||||||
|
//
|
||||||
|
// Need to check _stack_is_executable again as multiple VM_LinuxDllLoad
|
||||||
|
// may have been queued at the same time.
|
||||||
|
|
||||||
|
if (!_stack_is_executable) {
|
||||||
|
JavaThread *jt = Threads::first();
|
||||||
|
|
||||||
|
while (jt) {
|
||||||
|
if (!jt->stack_guard_zone_unused() && // Stack not yet fully initialized
|
||||||
|
jt->stack_yellow_zone_enabled()) { // No pending stack overflow exceptions
|
||||||
|
if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(),
|
||||||
|
jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) {
|
||||||
|
warning("Attempt to reguard stack yellow zone failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jt = jt->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* glibc-2.0 libdl is not MT safe. If you are building with any glibc,
|
* glibc-2.0 libdl is not MT safe. If you are building with any glibc,
|
||||||
* chances are you might want to run the generated bits against glibc-2.0
|
* chances are you might want to run the generated bits against glibc-2.0
|
||||||
@ -3094,13 +3213,24 @@ char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
|
|||||||
numa_make_global(addr, bytes);
|
numa_make_global(addr, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The memory is committed
|
||||||
|
address pc = CALLER_PC;
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc);
|
||||||
|
MemTracker::record_virtual_memory_commit((address)addr, bytes, pc);
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool os::release_memory_special(char* base, size_t bytes) {
|
bool os::release_memory_special(char* base, size_t bytes) {
|
||||||
// detaching the SHM segment will also delete it, see reserve_memory_special()
|
// detaching the SHM segment will also delete it, see reserve_memory_special()
|
||||||
int rslt = shmdt(base);
|
int rslt = shmdt(base);
|
||||||
return rslt == 0;
|
if (rslt == 0) {
|
||||||
|
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
|
||||||
|
MemTracker::record_virtual_memory_release((address)base, bytes);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t os::large_page_size() {
|
size_t os::large_page_size() {
|
||||||
|
@ -94,6 +94,9 @@ class Linux {
|
|||||||
static void print_libversion_info(outputStream* st);
|
static void print_libversion_info(outputStream* st);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static bool _stack_is_executable;
|
||||||
|
static void *dll_load_inner(const char *name);
|
||||||
|
|
||||||
static void init_thread_fpu_state();
|
static void init_thread_fpu_state();
|
||||||
static int get_fpu_control_word();
|
static int get_fpu_control_word();
|
||||||
static void set_fpu_control_word(int fpu_control);
|
static void set_fpu_control_word(int fpu_control);
|
||||||
|
@ -2945,7 +2945,7 @@ char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info
|
|||||||
while (p < (uint64_t)end) {
|
while (p < (uint64_t)end) {
|
||||||
addrs[0] = p;
|
addrs[0] = p;
|
||||||
size_t addrs_count = 1;
|
size_t addrs_count = 1;
|
||||||
while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] < (uint64_t)end) {
|
while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] + page_size < (uint64_t)end) {
|
||||||
addrs[addrs_count] = addrs[addrs_count - 1] + page_size;
|
addrs[addrs_count] = addrs[addrs_count - 1] + page_size;
|
||||||
addrs_count++;
|
addrs_count++;
|
||||||
}
|
}
|
||||||
@ -3420,13 +3420,25 @@ char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
|
|||||||
if ((retAddr != NULL) && UseNUMAInterleaving) {
|
if ((retAddr != NULL) && UseNUMAInterleaving) {
|
||||||
numa_make_global(retAddr, size);
|
numa_make_global(retAddr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The memory is committed
|
||||||
|
address pc = CALLER_PC;
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)retAddr, size, pc);
|
||||||
|
MemTracker::record_virtual_memory_commit((address)retAddr, size, pc);
|
||||||
|
|
||||||
return retAddr;
|
return retAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool os::release_memory_special(char* base, size_t bytes) {
|
bool os::release_memory_special(char* base, size_t bytes) {
|
||||||
// detaching the SHM segment will also delete it, see reserve_memory_special()
|
// detaching the SHM segment will also delete it, see reserve_memory_special()
|
||||||
int rslt = shmdt(base);
|
int rslt = shmdt(base);
|
||||||
return rslt == 0;
|
if (rslt == 0) {
|
||||||
|
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
|
||||||
|
MemTracker::record_virtual_memory_release((address)base, bytes);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t os::large_page_size() {
|
size_t os::large_page_size() {
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#include "runtime/threadCritical.hpp"
|
#include "runtime/threadCritical.hpp"
|
||||||
#include "runtime/timer.hpp"
|
#include "runtime/timer.hpp"
|
||||||
#include "services/attachListener.hpp"
|
#include "services/attachListener.hpp"
|
||||||
|
#include "services/memTracker.hpp"
|
||||||
#include "services/runtimeService.hpp"
|
#include "services/runtimeService.hpp"
|
||||||
#include "utilities/decoder.hpp"
|
#include "utilities/decoder.hpp"
|
||||||
#include "utilities/defaultStream.hpp"
|
#include "utilities/defaultStream.hpp"
|
||||||
@ -2836,7 +2837,7 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
|
|||||||
PAGE_READWRITE);
|
PAGE_READWRITE);
|
||||||
// If reservation failed, return NULL
|
// If reservation failed, return NULL
|
||||||
if (p_buf == NULL) return NULL;
|
if (p_buf == NULL) return NULL;
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);
|
||||||
os::release_memory(p_buf, bytes + chunk_size);
|
os::release_memory(p_buf, bytes + chunk_size);
|
||||||
|
|
||||||
// we still need to round up to a page boundary (in case we are using large pages)
|
// we still need to round up to a page boundary (in case we are using large pages)
|
||||||
@ -2898,6 +2899,11 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
|
|||||||
if (next_alloc_addr > p_buf) {
|
if (next_alloc_addr > p_buf) {
|
||||||
// Some memory was committed so release it.
|
// Some memory was committed so release it.
|
||||||
size_t bytes_to_release = bytes - bytes_remaining;
|
size_t bytes_to_release = bytes - bytes_remaining;
|
||||||
|
// NMT has yet to record any individual blocks, so it
|
||||||
|
// need to create a dummy 'reserve' record to match
|
||||||
|
// the release.
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)p_buf,
|
||||||
|
bytes_to_release, CALLER_PC);
|
||||||
os::release_memory(p_buf, bytes_to_release);
|
os::release_memory(p_buf, bytes_to_release);
|
||||||
}
|
}
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
@ -2909,10 +2915,19 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
|
|||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_remaining -= bytes_to_rq;
|
bytes_remaining -= bytes_to_rq;
|
||||||
next_alloc_addr += bytes_to_rq;
|
next_alloc_addr += bytes_to_rq;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
// Although the memory is allocated individually, it is returned as one.
|
||||||
|
// NMT records it as one block.
|
||||||
|
address pc = CALLER_PC;
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, pc);
|
||||||
|
if ((flags & MEM_COMMIT) != 0) {
|
||||||
|
MemTracker::record_virtual_memory_commit((address)p_buf, bytes, pc);
|
||||||
|
}
|
||||||
|
|
||||||
// made it this far, success
|
// made it this far, success
|
||||||
return p_buf;
|
return p_buf;
|
||||||
}
|
}
|
||||||
@ -3099,11 +3114,20 @@ char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
|
|||||||
// normal policy just allocate it all at once
|
// normal policy just allocate it all at once
|
||||||
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
|
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
|
||||||
char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot);
|
char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot);
|
||||||
|
if (res != NULL) {
|
||||||
|
address pc = CALLER_PC;
|
||||||
|
MemTracker::record_virtual_memory_reserve((address)res, bytes, pc);
|
||||||
|
MemTracker::record_virtual_memory_commit((address)res, bytes, pc);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool os::release_memory_special(char* base, size_t bytes) {
|
bool os::release_memory_special(char* base, size_t bytes) {
|
||||||
|
assert(base != NULL, "Sanity check");
|
||||||
|
// Memory allocated via reserve_memory_special() is committed
|
||||||
|
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
|
||||||
return release_memory(base, bytes);
|
return release_memory(base, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@ JVM_handle_bsd_signal(int sig,
|
|||||||
// here if the underlying file has been truncated.
|
// here if the underlying file has been truncated.
|
||||||
// Do not crash the VM in such a case.
|
// Do not crash the VM in such a case.
|
||||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||||
nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
|
nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
|
||||||
if (nm != NULL && nm->has_unsafe_access()) {
|
if (nm != NULL && nm->has_unsafe_access()) {
|
||||||
stub = StubRoutines::handler_for_unsafe_access();
|
stub = StubRoutines::handler_for_unsafe_access();
|
||||||
}
|
}
|
||||||
|
@ -410,6 +410,11 @@ inline static bool checkOverflow(sigcontext* uc,
|
|||||||
// to handle_unexpected_exception way down below.
|
// to handle_unexpected_exception way down below.
|
||||||
thread->disable_stack_red_zone();
|
thread->disable_stack_red_zone();
|
||||||
tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
|
tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
|
||||||
|
|
||||||
|
// This is a likely cause, but hard to verify. Let's just print
|
||||||
|
// it as a hint.
|
||||||
|
tty->print_raw_cr("Please check if any of your loaded .so files has "
|
||||||
|
"enabled executable stack (see man page execstack(8))");
|
||||||
} else {
|
} else {
|
||||||
// Accessing stack address below sp may cause SEGV if current
|
// Accessing stack address below sp may cause SEGV if current
|
||||||
// thread has MAP_GROWSDOWN stack. This should only happen when
|
// thread has MAP_GROWSDOWN stack. This should only happen when
|
||||||
|
@ -305,6 +305,11 @@ JVM_handle_linux_signal(int sig,
|
|||||||
// to handle_unexpected_exception way down below.
|
// to handle_unexpected_exception way down below.
|
||||||
thread->disable_stack_red_zone();
|
thread->disable_stack_red_zone();
|
||||||
tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
|
tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
|
||||||
|
|
||||||
|
// This is a likely cause, but hard to verify. Let's just print
|
||||||
|
// it as a hint.
|
||||||
|
tty->print_raw_cr("Please check if any of your loaded .so files has "
|
||||||
|
"enabled executable stack (see man page execstack(8))");
|
||||||
} else {
|
} else {
|
||||||
// Accessing stack address below sp may cause SEGV if current
|
// Accessing stack address below sp may cause SEGV if current
|
||||||
// thread has MAP_GROWSDOWN stack. This should only happen when
|
// thread has MAP_GROWSDOWN stack. This should only happen when
|
||||||
|
@ -2375,7 +2375,7 @@ class LIR_OpVisitState: public StackObj {
|
|||||||
// collects all register operands of the instruction
|
// collects all register operands of the instruction
|
||||||
void visit(LIR_Op* op);
|
void visit(LIR_Op* op);
|
||||||
|
|
||||||
#if ASSERT
|
#ifdef ASSERT
|
||||||
// check that an operation has no operands
|
// check that an operation has no operands
|
||||||
bool no_operands(LIR_Op* op);
|
bool no_operands(LIR_Op* op);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2540,7 +2540,7 @@ void ciTypeFlow::build_loop_tree(Block* blk) {
|
|||||||
} else if (innermost->head() == blk) {
|
} else if (innermost->head() == blk) {
|
||||||
// If loop header, complete the tree pointers
|
// If loop header, complete the tree pointers
|
||||||
if (blk->loop() != innermost) {
|
if (blk->loop() != innermost) {
|
||||||
#if ASSERT
|
#ifdef ASSERT
|
||||||
assert(blk->loop()->head() == innermost->head(), "same head");
|
assert(blk->loop()->head() == innermost->head(), "same head");
|
||||||
Loop* dl;
|
Loop* dl;
|
||||||
for (dl = innermost; dl != NULL && dl != blk->loop(); dl = dl->parent());
|
for (dl = innermost; dl != NULL && dl != blk->loop(); dl = dl->parent());
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,6 +34,7 @@
|
|||||||
#include "classfile/symbolTable.hpp"
|
#include "classfile/symbolTable.hpp"
|
||||||
|
|
||||||
class FieldAllocationCount;
|
class FieldAllocationCount;
|
||||||
|
class FieldLayoutInfo;
|
||||||
|
|
||||||
|
|
||||||
// Parser for for .class files
|
// Parser for for .class files
|
||||||
@ -47,6 +48,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
u2 _major_version;
|
u2 _major_version;
|
||||||
u2 _minor_version;
|
u2 _minor_version;
|
||||||
Symbol* _class_name;
|
Symbol* _class_name;
|
||||||
|
ClassLoaderData* _loader_data;
|
||||||
KlassHandle _host_klass;
|
KlassHandle _host_klass;
|
||||||
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
|
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
|
||||||
|
|
||||||
@ -58,33 +60,59 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
|
|
||||||
// class attributes parsed before the instance klass is created:
|
// class attributes parsed before the instance klass is created:
|
||||||
bool _synthetic_flag;
|
bool _synthetic_flag;
|
||||||
|
int _sde_length;
|
||||||
|
char* _sde_buffer;
|
||||||
Symbol* _sourcefile;
|
Symbol* _sourcefile;
|
||||||
Symbol* _generic_signature;
|
Symbol* _generic_signature;
|
||||||
char* _sde_buffer;
|
|
||||||
int _sde_length;
|
// Metadata created before the instance klass is created. Must be deallocated
|
||||||
Array<u2>* _inner_classes;
|
// if not transferred to the InstanceKlass upon successful class loading
|
||||||
|
// in which case these pointers have been set to NULL.
|
||||||
|
instanceKlassHandle _super_klass;
|
||||||
|
ConstantPool* _cp;
|
||||||
|
Array<u2>* _fields;
|
||||||
|
Array<Method*>* _methods;
|
||||||
|
Array<u2>* _inner_classes;
|
||||||
|
Array<Klass*>* _local_interfaces;
|
||||||
|
Array<Klass*>* _transitive_interfaces;
|
||||||
AnnotationArray* _annotations;
|
AnnotationArray* _annotations;
|
||||||
AnnotationArray* _type_annotations;
|
AnnotationArray* _type_annotations;
|
||||||
|
Array<AnnotationArray*>* _fields_annotations;
|
||||||
|
Array<AnnotationArray*>* _fields_type_annotations;
|
||||||
|
InstanceKlass* _klass; // InstanceKlass once created.
|
||||||
|
|
||||||
void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
|
void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
|
||||||
void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
|
void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
|
||||||
void set_class_generic_signature(Symbol* x) { _generic_signature = x; }
|
void set_class_generic_signature(Symbol* x) { _generic_signature = x; }
|
||||||
void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
|
void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
|
||||||
void set_class_inner_classes(Array<u2>* x) { _inner_classes = x; }
|
|
||||||
void set_class_annotations(AnnotationArray* x) { _annotations = x; }
|
void init_parsed_class_attributes(ClassLoaderData* loader_data) {
|
||||||
void set_class_type_annotations(AnnotationArray* x) { _type_annotations = x; }
|
_loader_data = loader_data;
|
||||||
void init_parsed_class_attributes() {
|
|
||||||
_synthetic_flag = false;
|
_synthetic_flag = false;
|
||||||
_sourcefile = NULL;
|
_sourcefile = NULL;
|
||||||
_generic_signature = NULL;
|
_generic_signature = NULL;
|
||||||
_sde_buffer = NULL;
|
_sde_buffer = NULL;
|
||||||
_sde_length = 0;
|
_sde_length = 0;
|
||||||
_annotations = _type_annotations = NULL;
|
|
||||||
// initialize the other flags too:
|
// initialize the other flags too:
|
||||||
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
|
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
|
||||||
_max_bootstrap_specifier_index = -1;
|
_max_bootstrap_specifier_index = -1;
|
||||||
|
clear_class_metadata();
|
||||||
|
_klass = NULL;
|
||||||
}
|
}
|
||||||
void apply_parsed_class_attributes(instanceKlassHandle k); // update k
|
void apply_parsed_class_attributes(instanceKlassHandle k); // update k
|
||||||
|
void apply_parsed_class_metadata(instanceKlassHandle k, int fields_count, TRAPS);
|
||||||
|
void clear_class_metadata() {
|
||||||
|
// metadata created before the instance klass is created. Must be
|
||||||
|
// deallocated if classfile parsing returns an error.
|
||||||
|
_cp = NULL;
|
||||||
|
_fields = NULL;
|
||||||
|
_methods = NULL;
|
||||||
|
_inner_classes = NULL;
|
||||||
|
_local_interfaces = NULL;
|
||||||
|
_transitive_interfaces = NULL;
|
||||||
|
_annotations = _type_annotations = NULL;
|
||||||
|
_fields_annotations = _fields_type_annotations = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
class AnnotationCollector {
|
class AnnotationCollector {
|
||||||
public:
|
public:
|
||||||
@ -124,11 +152,27 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
void set_contended(bool contended) { set_annotation(_sun_misc_Contended); }
|
void set_contended(bool contended) { set_annotation(_sun_misc_Contended); }
|
||||||
bool is_contended() { return has_annotation(_sun_misc_Contended); }
|
bool is_contended() { return has_annotation(_sun_misc_Contended); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This class also doubles as a holder for metadata cleanup.
|
||||||
class FieldAnnotationCollector: public AnnotationCollector {
|
class FieldAnnotationCollector: public AnnotationCollector {
|
||||||
|
ClassLoaderData* _loader_data;
|
||||||
|
AnnotationArray* _field_annotations;
|
||||||
|
AnnotationArray* _field_type_annotations;
|
||||||
public:
|
public:
|
||||||
FieldAnnotationCollector() : AnnotationCollector(_in_field) { }
|
FieldAnnotationCollector(ClassLoaderData* loader_data) :
|
||||||
|
AnnotationCollector(_in_field),
|
||||||
|
_loader_data(loader_data),
|
||||||
|
_field_annotations(NULL),
|
||||||
|
_field_type_annotations(NULL) {}
|
||||||
void apply_to(FieldInfo* f);
|
void apply_to(FieldInfo* f);
|
||||||
|
~FieldAnnotationCollector();
|
||||||
|
AnnotationArray* field_annotations() { return _field_annotations; }
|
||||||
|
AnnotationArray* field_type_annotations() { return _field_type_annotations; }
|
||||||
|
|
||||||
|
void set_field_annotations(AnnotationArray* a) { _field_annotations = a; }
|
||||||
|
void set_field_type_annotations(AnnotationArray* a) { _field_type_annotations = a; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MethodAnnotationCollector: public AnnotationCollector {
|
class MethodAnnotationCollector: public AnnotationCollector {
|
||||||
public:
|
public:
|
||||||
MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
|
MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
|
||||||
@ -152,38 +196,30 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
void set_stream(ClassFileStream* st) { _stream = st; }
|
void set_stream(ClassFileStream* st) { _stream = st; }
|
||||||
|
|
||||||
// Constant pool parsing
|
// Constant pool parsing
|
||||||
void parse_constant_pool_entries(ClassLoaderData* loader_data,
|
void parse_constant_pool_entries(int length, TRAPS);
|
||||||
constantPoolHandle cp, int length, TRAPS);
|
|
||||||
|
|
||||||
constantPoolHandle parse_constant_pool(ClassLoaderData* loader_data, TRAPS);
|
constantPoolHandle parse_constant_pool(TRAPS);
|
||||||
|
|
||||||
// Interface parsing
|
// Interface parsing
|
||||||
Array<Klass*>* parse_interfaces(constantPoolHandle cp,
|
Array<Klass*>* parse_interfaces(int length,
|
||||||
int length,
|
|
||||||
ClassLoaderData* loader_data,
|
|
||||||
Handle protection_domain,
|
Handle protection_domain,
|
||||||
Symbol* class_name,
|
Symbol* class_name,
|
||||||
bool* has_default_methods,
|
bool* has_default_methods,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS);
|
void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS);
|
||||||
|
|
||||||
|
instanceKlassHandle parse_super_class(int super_class_index, TRAPS);
|
||||||
// Field parsing
|
// Field parsing
|
||||||
void parse_field_attributes(ClassLoaderData* loader_data,
|
void parse_field_attributes(u2 attributes_count,
|
||||||
constantPoolHandle cp, u2 attributes_count,
|
|
||||||
bool is_static, u2 signature_index,
|
bool is_static, u2 signature_index,
|
||||||
u2* constantvalue_index_addr,
|
u2* constantvalue_index_addr,
|
||||||
bool* is_synthetic_addr,
|
bool* is_synthetic_addr,
|
||||||
u2* generic_signature_index_addr,
|
u2* generic_signature_index_addr,
|
||||||
AnnotationArray** field_annotations,
|
|
||||||
AnnotationArray** field_type_annotations,
|
|
||||||
FieldAnnotationCollector* parsed_annotations,
|
FieldAnnotationCollector* parsed_annotations,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
Array<u2>* parse_fields(ClassLoaderData* loader_data,
|
Array<u2>* parse_fields(Symbol* class_name,
|
||||||
Symbol* class_name,
|
bool is_interface,
|
||||||
constantPoolHandle cp, bool is_interface,
|
|
||||||
FieldAllocationCount *fac,
|
FieldAllocationCount *fac,
|
||||||
Array<AnnotationArray*>** fields_annotations,
|
|
||||||
Array<AnnotationArray*>** fields_type_annotations,
|
|
||||||
u2* java_fields_count_ptr, TRAPS);
|
u2* java_fields_count_ptr, TRAPS);
|
||||||
|
|
||||||
void print_field_layout(Symbol* name,
|
void print_field_layout(Symbol* name,
|
||||||
@ -195,65 +231,52 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
int static_fields_end);
|
int static_fields_end);
|
||||||
|
|
||||||
// Method parsing
|
// Method parsing
|
||||||
methodHandle parse_method(ClassLoaderData* loader_data,
|
methodHandle parse_method(bool is_interface,
|
||||||
constantPoolHandle cp,
|
|
||||||
bool is_interface,
|
|
||||||
AccessFlags* promoted_flags,
|
AccessFlags* promoted_flags,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
Array<Method*>* parse_methods(ClassLoaderData* loader_data,
|
Array<Method*>* parse_methods(bool is_interface,
|
||||||
constantPoolHandle cp,
|
|
||||||
bool is_interface,
|
|
||||||
AccessFlags* promoted_flags,
|
AccessFlags* promoted_flags,
|
||||||
bool* has_final_method,
|
bool* has_final_method,
|
||||||
bool* has_default_method,
|
bool* has_default_method,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
Array<int>* sort_methods(ClassLoaderData* loader_data,
|
intArray* sort_methods(Array<Method*>* methods);
|
||||||
Array<Method*>* methods,
|
|
||||||
TRAPS);
|
u2* parse_exception_table(u4 code_length, u4 exception_table_length,
|
||||||
u2* parse_exception_table(ClassLoaderData* loader_data,
|
TRAPS);
|
||||||
u4 code_length, u4 exception_table_length,
|
|
||||||
constantPoolHandle cp, TRAPS);
|
|
||||||
void parse_linenumber_table(
|
void parse_linenumber_table(
|
||||||
u4 code_attribute_length, u4 code_length,
|
u4 code_attribute_length, u4 code_length,
|
||||||
CompressedLineNumberWriteStream** write_stream, TRAPS);
|
CompressedLineNumberWriteStream** write_stream, TRAPS);
|
||||||
u2* parse_localvariable_table(u4 code_length, u2 max_locals, u4 code_attribute_length,
|
u2* parse_localvariable_table(u4 code_length, u2 max_locals, u4 code_attribute_length,
|
||||||
constantPoolHandle cp, u2* localvariable_table_length,
|
u2* localvariable_table_length,
|
||||||
bool isLVTT, TRAPS);
|
bool isLVTT, TRAPS);
|
||||||
u2* parse_checked_exceptions(u2* checked_exceptions_length, u4 method_attribute_length,
|
u2* parse_checked_exceptions(u2* checked_exceptions_length, u4 method_attribute_length,
|
||||||
constantPoolHandle cp, TRAPS);
|
TRAPS);
|
||||||
void parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index,
|
void parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index,
|
||||||
u1* u1_array, u2* u2_array, constantPoolHandle cp, TRAPS);
|
u1* u1_array, u2* u2_array, TRAPS);
|
||||||
Array<u1>* parse_stackmap_table(ClassLoaderData* loader_data, u4 code_attribute_length, TRAPS);
|
u1* parse_stackmap_table(u4 code_attribute_length, TRAPS);
|
||||||
|
|
||||||
// Classfile attribute parsing
|
// Classfile attribute parsing
|
||||||
void parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS);
|
void parse_classfile_sourcefile_attribute(TRAPS);
|
||||||
void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
|
void parse_classfile_source_debug_extension_attribute(int length, TRAPS);
|
||||||
int length, TRAPS);
|
u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
|
||||||
u2 parse_classfile_inner_classes_attribute(ClassLoaderData* loader_data,
|
|
||||||
u1* inner_classes_attribute_start,
|
|
||||||
bool parsed_enclosingmethod_attribute,
|
bool parsed_enclosingmethod_attribute,
|
||||||
u2 enclosing_method_class_index,
|
u2 enclosing_method_class_index,
|
||||||
u2 enclosing_method_method_index,
|
u2 enclosing_method_method_index,
|
||||||
constantPoolHandle cp,
|
|
||||||
TRAPS);
|
TRAPS);
|
||||||
void parse_classfile_attributes(ClassLoaderData* loader_data,
|
void parse_classfile_attributes(ClassAnnotationCollector* parsed_annotations,
|
||||||
constantPoolHandle cp,
|
|
||||||
ClassAnnotationCollector* parsed_annotations,
|
|
||||||
TRAPS);
|
TRAPS);
|
||||||
void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS);
|
void parse_classfile_synthetic_attribute(TRAPS);
|
||||||
void parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS);
|
void parse_classfile_signature_attribute(TRAPS);
|
||||||
void parse_classfile_bootstrap_methods_attribute(ClassLoaderData* loader_data, constantPoolHandle cp, u4 attribute_length, TRAPS);
|
void parse_classfile_bootstrap_methods_attribute(u4 attribute_length, TRAPS);
|
||||||
|
|
||||||
// Annotations handling
|
// Annotations handling
|
||||||
AnnotationArray* assemble_annotations(ClassLoaderData* loader_data,
|
AnnotationArray* assemble_annotations(u1* runtime_visible_annotations,
|
||||||
u1* runtime_visible_annotations,
|
|
||||||
int runtime_visible_annotations_length,
|
int runtime_visible_annotations_length,
|
||||||
u1* runtime_invisible_annotations,
|
u1* runtime_invisible_annotations,
|
||||||
int runtime_invisible_annotations_length, TRAPS);
|
int runtime_invisible_annotations_length, TRAPS);
|
||||||
int skip_annotation(u1* buffer, int limit, int index);
|
int skip_annotation(u1* buffer, int limit, int index);
|
||||||
int skip_annotation_value(u1* buffer, int limit, int index);
|
int skip_annotation_value(u1* buffer, int limit, int index);
|
||||||
void parse_annotations(ClassLoaderData* loader_data,
|
void parse_annotations(u1* buffer, int limit,
|
||||||
u1* buffer, int limit, constantPoolHandle cp,
|
|
||||||
/* Results (currently, only one result is supported): */
|
/* Results (currently, only one result is supported): */
|
||||||
AnnotationCollector* result,
|
AnnotationCollector* result,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
@ -267,8 +290,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
int* nonstatic_oop_offsets,
|
int* nonstatic_oop_offsets,
|
||||||
unsigned int* nonstatic_oop_counts);
|
unsigned int* nonstatic_oop_counts);
|
||||||
void set_precomputed_flags(instanceKlassHandle k);
|
void set_precomputed_flags(instanceKlassHandle k);
|
||||||
Array<Klass*>* compute_transitive_interfaces(ClassLoaderData* loader_data,
|
Array<Klass*>* compute_transitive_interfaces(instanceKlassHandle super,
|
||||||
instanceKlassHandle super,
|
|
||||||
Array<Klass*>* local_ifs, TRAPS);
|
Array<Klass*>* local_ifs, TRAPS);
|
||||||
|
|
||||||
// Format checker methods
|
// Format checker methods
|
||||||
@ -318,7 +340,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
bool is_supported_version(u2 major, u2 minor);
|
bool is_supported_version(u2 major, u2 minor);
|
||||||
bool has_illegal_visibility(jint flags);
|
bool has_illegal_visibility(jint flags);
|
||||||
|
|
||||||
void verify_constantvalue(int constantvalue_index, int signature_index, constantPoolHandle cp, TRAPS);
|
void verify_constantvalue(int constantvalue_index, int signature_index, TRAPS);
|
||||||
void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS);
|
void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS);
|
||||||
void verify_legal_class_name(Symbol* name, TRAPS);
|
void verify_legal_class_name(Symbol* name, TRAPS);
|
||||||
void verify_legal_field_name(Symbol* name, TRAPS);
|
void verify_legal_field_name(Symbol* name, TRAPS);
|
||||||
@ -359,10 +381,17 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
// In older versions of the VM, Klass*s cannot sneak into early phases of
|
// In older versions of the VM, Klass*s cannot sneak into early phases of
|
||||||
// constant pool construction, but in later versions they can.
|
// constant pool construction, but in later versions they can.
|
||||||
// %%% Let's phase out the old is_klass_reference.
|
// %%% Let's phase out the old is_klass_reference.
|
||||||
bool is_klass_reference(constantPoolHandle cp, int index) {
|
bool valid_klass_reference_at(int index) {
|
||||||
return (EnableInvokeDynamic
|
return _cp->is_within_bounds(index) &&
|
||||||
? cp->tag_at(index).is_klass_or_reference()
|
(EnableInvokeDynamic
|
||||||
: cp->tag_at(index).is_klass_reference());
|
? _cp->tag_at(index).is_klass_or_reference()
|
||||||
|
: _cp->tag_at(index).is_klass_reference());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks that the cpool index is in range and is a utf8
|
||||||
|
bool valid_symbol_at(int cpool_index) {
|
||||||
|
return (_cp->is_within_bounds(cpool_index) &&
|
||||||
|
_cp->tag_at(cpool_index).is_utf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_localvariable_table(ConstMethod* cm, int lvt_cnt,
|
void copy_localvariable_table(ConstMethod* cm, int lvt_cnt,
|
||||||
@ -373,8 +402,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
u2** localvariable_type_table_start,
|
u2** localvariable_type_table_start,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
|
||||||
void copy_method_annotations(ClassLoaderData* loader_data,
|
void copy_method_annotations(ConstMethod* cm,
|
||||||
ConstMethod* cm,
|
|
||||||
u1* runtime_visible_annotations,
|
u1* runtime_visible_annotations,
|
||||||
int runtime_visible_annotations_length,
|
int runtime_visible_annotations_length,
|
||||||
u1* runtime_invisible_annotations,
|
u1* runtime_invisible_annotations,
|
||||||
@ -391,9 +419,15 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||||||
int annotation_default_length,
|
int annotation_default_length,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
|
||||||
|
// lays out fields in class and returns the total oopmap count
|
||||||
|
void layout_fields(Handle class_loader, FieldAllocationCount* fac,
|
||||||
|
ClassAnnotationCollector* parsed_annotations,
|
||||||
|
FieldLayoutInfo* info, TRAPS);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
ClassFileParser(ClassFileStream* st) { set_stream(st); }
|
ClassFileParser(ClassFileStream* st) { set_stream(st); }
|
||||||
|
~ClassFileParser();
|
||||||
|
|
||||||
// Parse .class file and return new Klass*. The Klass* is not hooked up
|
// Parse .class file and return new Klass*. The Klass* is not hooked up
|
||||||
// to the system dictionary or any other structures, so a .class file can
|
// to the system dictionary or any other structures, so a .class file can
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -49,18 +49,17 @@ Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS
|
|||||||
|
|
||||||
Symbol* sym;
|
Symbol* sym;
|
||||||
|
|
||||||
if (c_heap) {
|
if (DumpSharedSpaces) {
|
||||||
|
// Allocate all symbols to CLD shared metaspace
|
||||||
|
sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
|
||||||
|
} else if (c_heap) {
|
||||||
// refcount starts as 1
|
// refcount starts as 1
|
||||||
assert(!DumpSharedSpaces, "never allocate to C heap");
|
|
||||||
sym = new (len, THREAD) Symbol(name, len, 1);
|
sym = new (len, THREAD) Symbol(name, len, 1);
|
||||||
assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
|
assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
|
||||||
} else {
|
} else {
|
||||||
if (DumpSharedSpaces) {
|
// Allocate to global arena
|
||||||
sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
|
|
||||||
} else {
|
|
||||||
sym = new (len, arena(), THREAD) Symbol(name, len, -1);
|
sym = new (len, arena(), THREAD) Symbol(name, len, -1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ void CompressedWriteStream::write_int_mb(jint value) {
|
|||||||
// for this block (a matching directive turns it back on later).
|
// for this block (a matching directive turns it back on later).
|
||||||
// These directives can be removed once the MS VS.NET 2005
|
// These directives can be removed once the MS VS.NET 2005
|
||||||
// compiler stack overflow is fixed.
|
// compiler stack overflow is fixed.
|
||||||
#if _MSC_VER >=1400 && !defined(_WIN64)
|
#if defined(_MSC_VER) && _MSC_VER >=1400 && !defined(_WIN64)
|
||||||
#pragma optimize("", off)
|
#pragma optimize("", off)
|
||||||
#pragma warning(disable: 4748)
|
#pragma warning(disable: 4748)
|
||||||
#endif
|
#endif
|
||||||
@ -276,7 +276,7 @@ void test_compressed_stream(int trace) {
|
|||||||
guarantee(fails == 0, "test failures");
|
guarantee(fails == 0, "test failures");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _MSC_VER >=1400 && !defined(_WIN64)
|
#if defined(_MSC_VER) &&_MSC_VER >=1400 && !defined(_WIN64)
|
||||||
#pragma warning(default: 4748)
|
#pragma warning(default: 4748)
|
||||||
#pragma optimize("", on)
|
#pragma optimize("", on)
|
||||||
#endif
|
#endif
|
||||||
|
@ -505,7 +505,7 @@ void CompileTask::log_task(xmlStream* log) {
|
|||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
|
|
||||||
// <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
|
// <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
|
||||||
if (_compile_id != 0) log->print(" compile_id='%d'", _compile_id);
|
log->print(" compile_id='%d'", _compile_id);
|
||||||
if (_osr_bci != CompileBroker::standard_entry_bci) {
|
if (_osr_bci != CompileBroker::standard_entry_bci) {
|
||||||
log->print(" compile_kind='osr'"); // same as nmethod::compile_kind
|
log->print(" compile_kind='osr'"); // same as nmethod::compile_kind
|
||||||
} // else compile_kind='c2c'
|
} // else compile_kind='c2c'
|
||||||
|
@ -2063,11 +2063,6 @@ void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
|
|||||||
// required.
|
// required.
|
||||||
_collectorState = FinalMarking;
|
_collectorState = FinalMarking;
|
||||||
}
|
}
|
||||||
if (PrintGCDetails &&
|
|
||||||
(_collectorState > Idling ||
|
|
||||||
!GCCause::is_user_requested_gc(GenCollectedHeap::heap()->gc_cause()))) {
|
|
||||||
gclog_or_tty->print(" (concurrent mode failure)");
|
|
||||||
}
|
|
||||||
collect_in_foreground(clear_all_soft_refs);
|
collect_in_foreground(clear_all_soft_refs);
|
||||||
|
|
||||||
// For a mark-sweep, compute_new_size() will be called
|
// For a mark-sweep, compute_new_size() will be called
|
||||||
@ -3400,10 +3395,10 @@ CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
|
|||||||
if (PrintCMSStatistics != 0) {
|
if (PrintCMSStatistics != 0) {
|
||||||
_collector->resetYields();
|
_collector->resetYields();
|
||||||
}
|
}
|
||||||
if (PrintGCDetails && PrintGCTimeStamps) {
|
if (PrintGCDetails) {
|
||||||
gclog_or_tty->date_stamp(PrintGCDateStamps);
|
gclog_or_tty->date_stamp(PrintGCDateStamps);
|
||||||
gclog_or_tty->stamp();
|
gclog_or_tty->stamp(PrintGCTimeStamps);
|
||||||
gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
|
gclog_or_tty->print_cr("[%s-concurrent-%s-start]",
|
||||||
_collector->cmsGen()->short_name(), _phase);
|
_collector->cmsGen()->short_name(), _phase);
|
||||||
}
|
}
|
||||||
_collector->resetTimer();
|
_collector->resetTimer();
|
||||||
|
@ -1310,11 +1310,6 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
|
|||||||
_markStack.expand();
|
_markStack.expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if VERIFY_OBJS_PROCESSED
|
|
||||||
_scan_obj_cl.objs_processed = 0;
|
|
||||||
ThreadLocalObjQueue::objs_enqueued = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
double now = os::elapsedTime();
|
double now = os::elapsedTime();
|
||||||
_remark_mark_times.add((mark_work_end - start) * 1000.0);
|
_remark_mark_times.add((mark_work_end - start) * 1000.0);
|
||||||
@ -2555,17 +2550,6 @@ void ConcurrentMark::checkpointRootsFinalWork() {
|
|||||||
guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant");
|
guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant");
|
||||||
|
|
||||||
print_stats();
|
print_stats();
|
||||||
|
|
||||||
#if VERIFY_OBJS_PROCESSED
|
|
||||||
if (_scan_obj_cl.objs_processed != ThreadLocalObjQueue::objs_enqueued) {
|
|
||||||
gclog_or_tty->print_cr("Processed = %d, enqueued = %d.",
|
|
||||||
_scan_obj_cl.objs_processed,
|
|
||||||
ThreadLocalObjQueue::objs_enqueued);
|
|
||||||
guarantee(_scan_obj_cl.objs_processed ==
|
|
||||||
ThreadLocalObjQueue::objs_enqueued,
|
|
||||||
"Different number of objs processed and enqueued.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
@ -4111,7 +4095,7 @@ void CMTask::do_marking_step(double time_target_ms,
|
|||||||
// bitmap knows by how much we need to move it as it knows its
|
// bitmap knows by how much we need to move it as it knows its
|
||||||
// granularity).
|
// granularity).
|
||||||
assert(_finger < _region_limit, "invariant");
|
assert(_finger < _region_limit, "invariant");
|
||||||
HeapWord* new_finger = _nextMarkBitMap->nextWord(_finger);
|
HeapWord* new_finger = _nextMarkBitMap->nextObject(_finger);
|
||||||
// Check if bitmap iteration was aborted while scanning the last object
|
// Check if bitmap iteration was aborted while scanning the last object
|
||||||
if (new_finger >= _region_limit) {
|
if (new_finger >= _region_limit) {
|
||||||
giveup_current_region();
|
giveup_current_region();
|
||||||
|
@ -97,7 +97,6 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
|
|||||||
HeapWord* limit = NULL) const;
|
HeapWord* limit = NULL) const;
|
||||||
|
|
||||||
// conversion utilities
|
// conversion utilities
|
||||||
// XXX Fix these so that offsets are size_t's...
|
|
||||||
HeapWord* offsetToHeapWord(size_t offset) const {
|
HeapWord* offsetToHeapWord(size_t offset) const {
|
||||||
return _bmStartWord + (offset << _shifter);
|
return _bmStartWord + (offset << _shifter);
|
||||||
}
|
}
|
||||||
@ -105,8 +104,13 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
|
|||||||
return pointer_delta(addr, _bmStartWord) >> _shifter;
|
return pointer_delta(addr, _bmStartWord) >> _shifter;
|
||||||
}
|
}
|
||||||
int heapWordDiffToOffsetDiff(size_t diff) const;
|
int heapWordDiffToOffsetDiff(size_t diff) const;
|
||||||
HeapWord* nextWord(HeapWord* addr) {
|
|
||||||
return offsetToHeapWord(heapWordToOffset(addr) + 1);
|
// The argument addr should be the start address of a valid object
|
||||||
|
HeapWord* nextObject(HeapWord* addr) {
|
||||||
|
oop obj = (oop) addr;
|
||||||
|
HeapWord* res = addr + obj->size();
|
||||||
|
assert(offsetToHeapWord(heapWordToOffset(res)) == res, "sanity");
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -252,12 +252,10 @@ inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
|
|||||||
|
|
||||||
start_offset = _bm.get_next_one_offset(start_offset, end_offset);
|
start_offset = _bm.get_next_one_offset(start_offset, end_offset);
|
||||||
while (start_offset < end_offset) {
|
while (start_offset < end_offset) {
|
||||||
HeapWord* obj_addr = offsetToHeapWord(start_offset);
|
|
||||||
oop obj = (oop) obj_addr;
|
|
||||||
if (!cl->do_bit(start_offset)) {
|
if (!cl->do_bit(start_offset)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HeapWord* next_addr = MIN2(obj_addr + obj->size(), end_addr);
|
HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
|
||||||
BitMap::idx_t next_offset = heapWordToOffset(next_addr);
|
BitMap::idx_t next_offset = heapWordToOffset(next_addr);
|
||||||
start_offset = _bm.get_next_one_offset(next_offset, end_offset);
|
start_offset = _bm.get_next_one_offset(next_offset, end_offset);
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate(
|
|||||||
// heap remains parsable.
|
// heap remains parsable.
|
||||||
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
|
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
|
||||||
const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
|
const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
|
||||||
assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
|
|
||||||
if (limit_exceeded && softrefs_clear) {
|
if (limit_exceeded && softrefs_clear) {
|
||||||
*gc_overhead_limit_was_exceeded = true;
|
*gc_overhead_limit_was_exceeded = true;
|
||||||
size_policy()->set_gc_overhead_limit_exceeded(false);
|
size_policy()->set_gc_overhead_limit_exceeded(false);
|
||||||
|
@ -948,6 +948,8 @@ void MutableNUMASpace::LGRPSpace::scan_pages(size_t page_size, size_t page_count
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (e != scan_end) {
|
if (e != scan_end) {
|
||||||
|
assert(e < scan_end, err_msg("e: " PTR_FORMAT " scan_end: " PTR_FORMAT, e, scan_end));
|
||||||
|
|
||||||
if ((page_expected.size != page_size || page_expected.lgrp_id != lgrp_id())
|
if ((page_expected.size != page_size || page_expected.lgrp_id != lgrp_id())
|
||||||
&& page_expected.size != 0) {
|
&& page_expected.size != 0) {
|
||||||
os::free_memory(s, pointer_delta(e, s, sizeof(char)), page_size);
|
os::free_memory(s, pointer_delta(e, s, sizeof(char)), page_size);
|
||||||
|
@ -186,7 +186,8 @@ class AbstractInterpreter: AllStatic {
|
|||||||
int caller_actual_parameters,
|
int caller_actual_parameters,
|
||||||
int callee_params,
|
int callee_params,
|
||||||
int callee_locals,
|
int callee_locals,
|
||||||
bool is_top_frame) {
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame) {
|
||||||
return layout_activation(method,
|
return layout_activation(method,
|
||||||
temps,
|
temps,
|
||||||
popframe_args,
|
popframe_args,
|
||||||
@ -196,7 +197,8 @@ class AbstractInterpreter: AllStatic {
|
|||||||
callee_locals,
|
callee_locals,
|
||||||
(frame*)NULL,
|
(frame*)NULL,
|
||||||
(frame*)NULL,
|
(frame*)NULL,
|
||||||
is_top_frame);
|
is_top_frame,
|
||||||
|
is_bottom_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int layout_activation(Method* method,
|
static int layout_activation(Method* method,
|
||||||
@ -208,7 +210,8 @@ class AbstractInterpreter: AllStatic {
|
|||||||
int callee_locals,
|
int callee_locals,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
frame* interpreter_frame,
|
frame* interpreter_frame,
|
||||||
bool is_top_frame);
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame);
|
||||||
|
|
||||||
// Runtime support
|
// Runtime support
|
||||||
static bool is_not_reached( methodHandle method, int bci);
|
static bool is_not_reached( methodHandle method, int bci);
|
||||||
|
@ -84,15 +84,13 @@ void Rewriter::make_constant_pool_cache(TRAPS) {
|
|||||||
const int length = _cp_cache_map.length();
|
const int length = _cp_cache_map.length();
|
||||||
ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
|
ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
|
||||||
ConstantPoolCache* cache =
|
ConstantPoolCache* cache =
|
||||||
ConstantPoolCache::allocate(loader_data, length, CHECK);
|
ConstantPoolCache::allocate(loader_data, length, _cp_cache_map,
|
||||||
|
_invokedynamic_references_map, CHECK);
|
||||||
|
|
||||||
// initialize object cache in constant pool
|
// initialize object cache in constant pool
|
||||||
_pool->initialize_resolved_references(loader_data, _resolved_references_map,
|
_pool->initialize_resolved_references(loader_data, _resolved_references_map,
|
||||||
_resolved_reference_limit,
|
_resolved_reference_limit,
|
||||||
CHECK);
|
CHECK);
|
||||||
|
|
||||||
No_Safepoint_Verifier nsv;
|
|
||||||
cache->initialize(_cp_cache_map, _invokedynamic_references_map);
|
|
||||||
_pool->set_cache(cache);
|
_pool->set_cache(cache);
|
||||||
cache->set_constant_pool(_pool());
|
cache->set_constant_pool(_pool());
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
|
|||||||
|
|
||||||
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
|
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
|
||||||
const bool softrefs_clear = all_soft_refs_clear();
|
const bool softrefs_clear = all_soft_refs_clear();
|
||||||
assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
|
|
||||||
if (limit_exceeded && softrefs_clear) {
|
if (limit_exceeded && softrefs_clear) {
|
||||||
*gc_overhead_limit_was_exceeded = true;
|
*gc_overhead_limit_was_exceeded = true;
|
||||||
size_policy()->set_gc_overhead_limit_exceeded(false);
|
size_policy()->set_gc_overhead_limit_exceeded(false);
|
||||||
|
@ -112,12 +112,19 @@ public:
|
|||||||
char* region_base(int i) { return _header._space[i]._base; }
|
char* region_base(int i) { return _header._space[i]._base; }
|
||||||
struct FileMapHeader* header() { return &_header; }
|
struct FileMapHeader* header() { return &_header; }
|
||||||
|
|
||||||
static void set_current_info(FileMapInfo* info) { _current_info = info; }
|
static void set_current_info(FileMapInfo* info) {
|
||||||
static FileMapInfo* current_info() { return _current_info; }
|
CDS_ONLY(_current_info = info;)
|
||||||
|
}
|
||||||
|
|
||||||
|
static FileMapInfo* current_info() {
|
||||||
|
CDS_ONLY(return _current_info;)
|
||||||
|
NOT_CDS(return NULL;)
|
||||||
|
}
|
||||||
|
|
||||||
static void assert_mark(bool check);
|
static void assert_mark(bool check);
|
||||||
|
|
||||||
// File manipulation.
|
// File manipulation.
|
||||||
bool initialize();
|
bool initialize() NOT_CDS_RETURN_(false);
|
||||||
bool open_for_read();
|
bool open_for_read();
|
||||||
void open_for_write();
|
void open_for_write();
|
||||||
void write_header();
|
void write_header();
|
||||||
@ -141,7 +148,7 @@ public:
|
|||||||
void fail_continue(const char *msg, ...);
|
void fail_continue(const char *msg, ...);
|
||||||
|
|
||||||
// Return true if given address is in the mapped shared space.
|
// Return true if given address is in the mapped shared space.
|
||||||
bool is_in_shared_space(const void* p);
|
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_MEMORY_FILEMAP_HPP
|
#endif // SHARE_VM_MEMORY_FILEMAP_HPP
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -52,7 +52,6 @@ const bool metaspace_slow_verify = false;
|
|||||||
const uint metadata_deallocate_a_lot_block = 10;
|
const uint metadata_deallocate_a_lot_block = 10;
|
||||||
const uint metadata_deallocate_a_lock_chunk = 3;
|
const uint metadata_deallocate_a_lock_chunk = 3;
|
||||||
size_t const allocation_from_dictionary_limit = 64 * K;
|
size_t const allocation_from_dictionary_limit = 64 * K;
|
||||||
const size_t metadata_deallocate = 0xf5f5f5f5;
|
|
||||||
|
|
||||||
MetaWord* last_allocated = 0;
|
MetaWord* last_allocated = 0;
|
||||||
|
|
||||||
@ -2440,7 +2439,8 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
|
|||||||
free_chunks_capacity_bytes / K,
|
free_chunks_capacity_bytes / K,
|
||||||
used_and_free / K,
|
used_and_free / K,
|
||||||
capacity_bytes / K);
|
capacity_bytes / K);
|
||||||
assert(used_and_free == capacity_bytes, "Accounting is wrong");
|
// Accounting can only be correct if we got the values during a safepoint
|
||||||
|
assert(!SafepointSynchronize::is_at_safepoint() || used_and_free == capacity_bytes, "Accounting is wrong");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print total fragmentation for class and data metaspaces separately
|
// Print total fragmentation for class and data metaspaces separately
|
||||||
|
@ -885,6 +885,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
|
|||||||
// the actual alignment depends on its size.
|
// the actual alignment depends on its size.
|
||||||
Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
|
Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
|
||||||
size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
|
size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
|
||||||
|
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
|
||||||
|
"heap size is too big for compressed oops");
|
||||||
char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
|
char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
|
||||||
|
|
||||||
ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr);
|
ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr);
|
||||||
|
@ -55,11 +55,24 @@ ConstMethod::ConstMethod(int byte_code_size,
|
|||||||
set_stackmap_data(NULL);
|
set_stackmap_data(NULL);
|
||||||
set_code_size(byte_code_size);
|
set_code_size(byte_code_size);
|
||||||
set_constMethod_size(size);
|
set_constMethod_size(size);
|
||||||
set_inlined_tables_length(sizes);
|
set_inlined_tables_length(sizes); // sets _flags
|
||||||
set_method_type(method_type);
|
set_method_type(method_type);
|
||||||
assert(this->size() == size, "wrong size for object");
|
assert(this->size() == size, "wrong size for object");
|
||||||
|
set_name_index(0);
|
||||||
|
set_signature_index(0);
|
||||||
|
set_constants(NULL);
|
||||||
|
set_max_stack(0);
|
||||||
|
set_max_locals(0);
|
||||||
|
set_method_idnum(0);
|
||||||
|
set_size_of_parameters(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accessor that copies to metadata.
|
||||||
|
void ConstMethod::copy_stackmap_data(ClassLoaderData* loader_data,
|
||||||
|
u1* sd, int length, TRAPS) {
|
||||||
|
_stackmap_data = MetadataFactory::new_array<u1>(loader_data, length, CHECK);
|
||||||
|
memcpy((void*)_stackmap_data->adr_at(0), (void*)sd, length);
|
||||||
|
}
|
||||||
|
|
||||||
// Deallocate metadata fields associated with ConstMethod*
|
// Deallocate metadata fields associated with ConstMethod*
|
||||||
void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {
|
void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {
|
||||||
|
@ -280,6 +280,7 @@ public:
|
|||||||
// stackmap table data
|
// stackmap table data
|
||||||
Array<u1>* stackmap_data() const { return _stackmap_data; }
|
Array<u1>* stackmap_data() const { return _stackmap_data; }
|
||||||
void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; }
|
void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; }
|
||||||
|
void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);
|
||||||
bool has_stackmap_table() const { return _stackmap_data != NULL; }
|
bool has_stackmap_table() const { return _stackmap_data != NULL; }
|
||||||
|
|
||||||
void init_fingerprint() {
|
void init_fingerprint() {
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
void ConstantPoolCacheEntry::initialize_entry(int index) {
|
void ConstantPoolCacheEntry::initialize_entry(int index) {
|
||||||
assert(0 < index && index < 0x10000, "sanity check");
|
assert(0 < index && index < 0x10000, "sanity check");
|
||||||
_indices = index;
|
_indices = index;
|
||||||
|
_f1 = NULL;
|
||||||
|
_f2 = _flags = 0;
|
||||||
assert(constant_pool_index() == index, "");
|
assert(constant_pool_index() == index, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,13 +535,17 @@ void ConstantPoolCacheEntry::verify(outputStream* st) const {
|
|||||||
|
|
||||||
// Implementation of ConstantPoolCache
|
// Implementation of ConstantPoolCache
|
||||||
|
|
||||||
ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
|
ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
|
||||||
|
int length,
|
||||||
|
const intStack& index_map,
|
||||||
|
const intStack& invokedynamic_map, TRAPS) {
|
||||||
int size = ConstantPoolCache::size(length);
|
int size = ConstantPoolCache::size(length);
|
||||||
|
|
||||||
return new (loader_data, size, false, THREAD) ConstantPoolCache(length);
|
return new (loader_data, size, false, THREAD) ConstantPoolCache(length, index_map, invokedynamic_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
|
void ConstantPoolCache::initialize(const intArray& inverse_index_map,
|
||||||
|
const intArray& invokedynamic_references_map) {
|
||||||
assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
|
assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
|
||||||
for (int i = 0; i < length(); i++) {
|
for (int i = 0; i < length(); i++) {
|
||||||
ConstantPoolCacheEntry* e = entry_at(i);
|
ConstantPoolCacheEntry* e = entry_at(i);
|
||||||
|
@ -377,14 +377,21 @@ class ConstantPoolCache: public MetaspaceObj {
|
|||||||
debug_only(friend class ClassVerifier;)
|
debug_only(friend class ClassVerifier;)
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ConstantPoolCache(int length) : _length(length), _constant_pool(NULL) {
|
ConstantPoolCache(int length, const intStack& inverse_index_map,
|
||||||
|
const intStack& invokedynamic_references_map) :
|
||||||
|
_length(length), _constant_pool(NULL) {
|
||||||
|
initialize(inverse_index_map, invokedynamic_references_map);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
assert(entry_at(i)->is_f1_null(), "Failed to clear?");
|
assert(entry_at(i)->is_f1_null(), "Failed to clear?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
void initialize(const intArray& inverse_index_map, const intArray& invokedynamic_references_map);
|
||||||
public:
|
public:
|
||||||
static ConstantPoolCache* allocate(ClassLoaderData* loader_data, int length, TRAPS);
|
static ConstantPoolCache* allocate(ClassLoaderData* loader_data, int length,
|
||||||
|
const intStack& inverse_index_map,
|
||||||
|
const intStack& invokedynamic_references_map, TRAPS);
|
||||||
bool is_constantPoolCache() const { return true; }
|
bool is_constantPoolCache() const { return true; }
|
||||||
|
|
||||||
int length() const { return _length; }
|
int length() const { return _length; }
|
||||||
@ -405,9 +412,6 @@ class ConstantPoolCache: public MetaspaceObj {
|
|||||||
friend class ConstantPoolCacheEntry;
|
friend class ConstantPoolCacheEntry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Initialization
|
|
||||||
void initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map);
|
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
void set_constant_pool(ConstantPool* pool) { _constant_pool = pool; }
|
void set_constant_pool(ConstantPool* pool) { _constant_pool = pool; }
|
||||||
ConstantPool* constant_pool() const { return _constant_pool; }
|
ConstantPool* constant_pool() const { return _constant_pool; }
|
||||||
|
@ -165,7 +165,8 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
|
|||||||
|
|
||||||
volatile int InstanceKlass::_total_instanceKlass_count = 0;
|
volatile int InstanceKlass::_total_instanceKlass_count = 0;
|
||||||
|
|
||||||
Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data,
|
InstanceKlass* InstanceKlass::allocate_instance_klass(
|
||||||
|
ClassLoaderData* loader_data,
|
||||||
int vtable_len,
|
int vtable_len,
|
||||||
int itable_len,
|
int itable_len,
|
||||||
int static_field_size,
|
int static_field_size,
|
||||||
@ -207,10 +208,35 @@ Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data,
|
|||||||
access_flags, is_anonymous);
|
access_flags, is_anonymous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for pending exception before adding to the loader data and incrementing
|
||||||
|
// class count. Can get OOM here.
|
||||||
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all classes to our internal class loader list here,
|
||||||
|
// including classes in the bootstrap (NULL) class loader.
|
||||||
|
loader_data->add_class(ik);
|
||||||
|
|
||||||
Atomic::inc(&_total_instanceKlass_count);
|
Atomic::inc(&_total_instanceKlass_count);
|
||||||
return ik;
|
return ik;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// copy method ordering from resource area to Metaspace
|
||||||
|
void InstanceKlass::copy_method_ordering(intArray* m, TRAPS) {
|
||||||
|
if (m != NULL) {
|
||||||
|
// allocate a new array and copy contents (memcpy?)
|
||||||
|
_method_ordering = MetadataFactory::new_array<int>(class_loader_data(), m->length(), CHECK);
|
||||||
|
for (int i = 0; i < m->length(); i++) {
|
||||||
|
_method_ordering->at_put(i, m->at(i));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_method_ordering = Universe::the_empty_int_array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
InstanceKlass::InstanceKlass(int vtable_len,
|
InstanceKlass::InstanceKlass(int vtable_len,
|
||||||
int itable_len,
|
int itable_len,
|
||||||
int static_field_size,
|
int static_field_size,
|
||||||
@ -220,72 +246,116 @@ InstanceKlass::InstanceKlass(int vtable_len,
|
|||||||
bool is_anonymous) {
|
bool is_anonymous) {
|
||||||
No_Safepoint_Verifier no_safepoint; // until k becomes parsable
|
No_Safepoint_Verifier no_safepoint; // until k becomes parsable
|
||||||
|
|
||||||
int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
|
int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
|
||||||
access_flags.is_interface(), is_anonymous);
|
access_flags.is_interface(), is_anonymous);
|
||||||
|
|
||||||
// The sizes of these these three variables are used for determining the
|
set_vtable_length(vtable_len);
|
||||||
// size of the instanceKlassOop. It is critical that these are set to the right
|
set_itable_length(itable_len);
|
||||||
// sizes before the first GC, i.e., when we allocate the mirror.
|
set_static_field_size(static_field_size);
|
||||||
this->set_vtable_length(vtable_len);
|
set_nonstatic_oop_map_size(nonstatic_oop_map_size);
|
||||||
this->set_itable_length(itable_len);
|
set_access_flags(access_flags);
|
||||||
this->set_static_field_size(static_field_size);
|
_misc_flags = 0; // initialize to zero
|
||||||
this->set_nonstatic_oop_map_size(nonstatic_oop_map_size);
|
set_is_anonymous(is_anonymous);
|
||||||
this->set_access_flags(access_flags);
|
assert(size() == iksize, "wrong size for object");
|
||||||
this->set_is_anonymous(is_anonymous);
|
|
||||||
assert(this->size() == size, "wrong size for object");
|
|
||||||
|
|
||||||
this->set_array_klasses(NULL);
|
set_array_klasses(NULL);
|
||||||
this->set_methods(NULL);
|
set_methods(NULL);
|
||||||
this->set_method_ordering(NULL);
|
set_method_ordering(NULL);
|
||||||
this->set_local_interfaces(NULL);
|
set_local_interfaces(NULL);
|
||||||
this->set_transitive_interfaces(NULL);
|
set_transitive_interfaces(NULL);
|
||||||
this->init_implementor();
|
init_implementor();
|
||||||
this->set_fields(NULL, 0);
|
set_fields(NULL, 0);
|
||||||
this->set_constants(NULL);
|
set_constants(NULL);
|
||||||
this->set_class_loader_data(NULL);
|
set_class_loader_data(NULL);
|
||||||
this->set_protection_domain(NULL);
|
set_protection_domain(NULL);
|
||||||
this->set_signers(NULL);
|
set_signers(NULL);
|
||||||
this->set_source_file_name(NULL);
|
set_source_file_name(NULL);
|
||||||
this->set_source_debug_extension(NULL, 0);
|
set_source_debug_extension(NULL, 0);
|
||||||
this->set_array_name(NULL);
|
set_array_name(NULL);
|
||||||
this->set_inner_classes(NULL);
|
set_inner_classes(NULL);
|
||||||
this->set_static_oop_field_count(0);
|
set_static_oop_field_count(0);
|
||||||
this->set_nonstatic_field_size(0);
|
set_nonstatic_field_size(0);
|
||||||
this->set_is_marked_dependent(false);
|
set_is_marked_dependent(false);
|
||||||
this->set_init_state(InstanceKlass::allocated);
|
set_init_state(InstanceKlass::allocated);
|
||||||
this->set_init_thread(NULL);
|
set_init_thread(NULL);
|
||||||
this->set_init_lock(NULL);
|
set_init_lock(NULL);
|
||||||
this->set_reference_type(rt);
|
set_reference_type(rt);
|
||||||
this->set_oop_map_cache(NULL);
|
set_oop_map_cache(NULL);
|
||||||
this->set_jni_ids(NULL);
|
set_jni_ids(NULL);
|
||||||
this->set_osr_nmethods_head(NULL);
|
set_osr_nmethods_head(NULL);
|
||||||
this->set_breakpoints(NULL);
|
set_breakpoints(NULL);
|
||||||
this->init_previous_versions();
|
init_previous_versions();
|
||||||
this->set_generic_signature(NULL);
|
set_generic_signature(NULL);
|
||||||
this->release_set_methods_jmethod_ids(NULL);
|
release_set_methods_jmethod_ids(NULL);
|
||||||
this->release_set_methods_cached_itable_indices(NULL);
|
release_set_methods_cached_itable_indices(NULL);
|
||||||
this->set_annotations(NULL);
|
set_annotations(NULL);
|
||||||
this->set_jvmti_cached_class_field_map(NULL);
|
set_jvmti_cached_class_field_map(NULL);
|
||||||
this->set_initial_method_idnum(0);
|
set_initial_method_idnum(0);
|
||||||
|
_dependencies = NULL;
|
||||||
|
set_jvmti_cached_class_field_map(NULL);
|
||||||
|
set_cached_class_file(NULL, 0);
|
||||||
|
set_initial_method_idnum(0);
|
||||||
|
set_minor_version(0);
|
||||||
|
set_major_version(0);
|
||||||
|
NOT_PRODUCT(_verify_count = 0;)
|
||||||
|
|
||||||
// initialize the non-header words to zero
|
// initialize the non-header words to zero
|
||||||
intptr_t* p = (intptr_t*)this;
|
intptr_t* p = (intptr_t*)this;
|
||||||
for (int index = InstanceKlass::header_size(); index < size; index++) {
|
for (int index = InstanceKlass::header_size(); index < iksize; index++) {
|
||||||
p[index] = NULL_WORD;
|
p[index] = NULL_WORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set temporary value until parseClassFile updates it with the real instance
|
// Set temporary value until parseClassFile updates it with the real instance
|
||||||
// size.
|
// size.
|
||||||
this->set_layout_helper(Klass::instance_layout_helper(0, true));
|
set_layout_helper(Klass::instance_layout_helper(0, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,
|
||||||
|
Array<Method*>* methods) {
|
||||||
|
if (methods != NULL && methods != Universe::the_empty_method_array()) {
|
||||||
|
for (int i = 0; i < methods->length(); i++) {
|
||||||
|
Method* method = methods->at(i);
|
||||||
|
if (method == NULL) continue; // maybe null if error processing
|
||||||
|
// Only want to delete methods that are not executing for RedefineClasses.
|
||||||
|
// The previous version will point to them so they're not totally dangling
|
||||||
|
assert (!method->on_stack(), "shouldn't be called with methods on stack");
|
||||||
|
MetadataFactory::free_metadata(loader_data, method);
|
||||||
|
}
|
||||||
|
MetadataFactory::free_array<Method*>(loader_data, methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstanceKlass::deallocate_interfaces(ClassLoaderData* loader_data,
|
||||||
|
Klass* super_klass,
|
||||||
|
Array<Klass*>* local_interfaces,
|
||||||
|
Array<Klass*>* transitive_interfaces) {
|
||||||
|
// Only deallocate transitive interfaces if not empty, same as super class
|
||||||
|
// or same as local interfaces. See code in parseClassFile.
|
||||||
|
Array<Klass*>* ti = transitive_interfaces;
|
||||||
|
if (ti != Universe::the_empty_klass_array() && ti != local_interfaces) {
|
||||||
|
// check that the interfaces don't come from super class
|
||||||
|
Array<Klass*>* sti = (super_klass == NULL) ? NULL :
|
||||||
|
InstanceKlass::cast(super_klass)->transitive_interfaces();
|
||||||
|
if (ti != sti) {
|
||||||
|
MetadataFactory::free_array<Klass*>(loader_data, ti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// local interfaces can be empty
|
||||||
|
if (local_interfaces != Universe::the_empty_klass_array()) {
|
||||||
|
MetadataFactory::free_array<Klass*>(loader_data, local_interfaces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This function deallocates the metadata and C heap pointers that the
|
// This function deallocates the metadata and C heap pointers that the
|
||||||
// InstanceKlass points to.
|
// InstanceKlass points to.
|
||||||
void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
||||||
|
|
||||||
// Orphan the mirror first, CMS thinks it's still live.
|
// Orphan the mirror first, CMS thinks it's still live.
|
||||||
java_lang_Class::set_klass(java_mirror(), NULL);
|
if (java_mirror() != NULL) {
|
||||||
|
java_lang_Class::set_klass(java_mirror(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Need to take this class off the class loader data list.
|
// Need to take this class off the class loader data list.
|
||||||
loader_data->remove_class(this);
|
loader_data->remove_class(this);
|
||||||
@ -300,17 +370,7 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||||||
// reference counting symbol names.
|
// reference counting symbol names.
|
||||||
release_C_heap_structures();
|
release_C_heap_structures();
|
||||||
|
|
||||||
Array<Method*>* ms = methods();
|
deallocate_methods(loader_data, methods());
|
||||||
if (ms != Universe::the_empty_method_array()) {
|
|
||||||
for (int i = 0; i <= methods()->length() -1 ; i++) {
|
|
||||||
Method* method = methods()->at(i);
|
|
||||||
// Only want to delete methods that are not executing for RedefineClasses.
|
|
||||||
// The previous version will point to them so they're not totally dangling
|
|
||||||
assert (!method->on_stack(), "shouldn't be called with methods on stack");
|
|
||||||
MetadataFactory::free_metadata(loader_data, method);
|
|
||||||
}
|
|
||||||
MetadataFactory::free_array<Method*>(loader_data, methods());
|
|
||||||
}
|
|
||||||
set_methods(NULL);
|
set_methods(NULL);
|
||||||
|
|
||||||
if (method_ordering() != Universe::the_empty_int_array()) {
|
if (method_ordering() != Universe::the_empty_int_array()) {
|
||||||
@ -327,24 +387,8 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||||||
}
|
}
|
||||||
set_secondary_supers(NULL);
|
set_secondary_supers(NULL);
|
||||||
|
|
||||||
// Only deallocate transitive interfaces if not empty, same as super class
|
deallocate_interfaces(loader_data, super(), local_interfaces(), transitive_interfaces());
|
||||||
// or same as local interfaces. See code in parseClassFile.
|
|
||||||
Array<Klass*>* ti = transitive_interfaces();
|
|
||||||
if (ti != Universe::the_empty_klass_array() && ti != local_interfaces()) {
|
|
||||||
// check that the interfaces don't come from super class
|
|
||||||
Array<Klass*>* sti = (super() == NULL) ? NULL :
|
|
||||||
InstanceKlass::cast(super())->transitive_interfaces();
|
|
||||||
if (ti != sti) {
|
|
||||||
MetadataFactory::free_array<Klass*>(loader_data, ti);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set_transitive_interfaces(NULL);
|
set_transitive_interfaces(NULL);
|
||||||
|
|
||||||
// local interfaces can be empty
|
|
||||||
Array<Klass*>* li = local_interfaces();
|
|
||||||
if (li != Universe::the_empty_klass_array()) {
|
|
||||||
MetadataFactory::free_array<Klass*>(loader_data, li);
|
|
||||||
}
|
|
||||||
set_local_interfaces(NULL);
|
set_local_interfaces(NULL);
|
||||||
|
|
||||||
MetadataFactory::free_array<jushort>(loader_data, fields());
|
MetadataFactory::free_array<jushort>(loader_data, fields());
|
||||||
@ -352,9 +396,11 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||||||
|
|
||||||
// If a method from a redefined class is using this constant pool, don't
|
// If a method from a redefined class is using this constant pool, don't
|
||||||
// delete it, yet. The new class's previous version will point to this.
|
// delete it, yet. The new class's previous version will point to this.
|
||||||
assert (!constants()->on_stack(), "shouldn't be called if anything is onstack");
|
if (constants() != NULL) {
|
||||||
MetadataFactory::free_metadata(loader_data, constants());
|
assert (!constants()->on_stack(), "shouldn't be called if anything is onstack");
|
||||||
set_constants(NULL);
|
MetadataFactory::free_metadata(loader_data, constants());
|
||||||
|
set_constants(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (inner_classes() != Universe::the_empty_short_array()) {
|
if (inner_classes() != Universe::the_empty_short_array()) {
|
||||||
MetadataFactory::free_array<jushort>(loader_data, inner_classes());
|
MetadataFactory::free_array<jushort>(loader_data, inner_classes());
|
||||||
@ -2785,7 +2831,7 @@ void InstanceKlass::print_on(outputStream* st) const {
|
|||||||
st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
|
st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
|
||||||
st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr();
|
st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr();
|
||||||
st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr();
|
st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr();
|
||||||
st->print(BULLET"init_lock: "); ((oop)init_lock())->print_value_on(st); st->cr();
|
st->print(BULLET"init_lock: "); ((oop)_init_lock)->print_value_on(st); st->cr();
|
||||||
if (source_file_name() != NULL) {
|
if (source_file_name() != NULL) {
|
||||||
st->print(BULLET"source file: ");
|
st->print(BULLET"source file: ");
|
||||||
source_file_name()->print_value_on(st);
|
source_file_name()->print_value_on(st);
|
||||||
|
@ -147,7 +147,8 @@ class InstanceKlass: public Klass {
|
|||||||
AccessFlags access_flags,
|
AccessFlags access_flags,
|
||||||
bool is_anonymous);
|
bool is_anonymous);
|
||||||
public:
|
public:
|
||||||
static Klass* allocate_instance_klass(ClassLoaderData* loader_data,
|
static InstanceKlass* allocate_instance_klass(
|
||||||
|
ClassLoaderData* loader_data,
|
||||||
int vtable_len,
|
int vtable_len,
|
||||||
int itable_len,
|
int itable_len,
|
||||||
int static_field_size,
|
int static_field_size,
|
||||||
@ -266,9 +267,10 @@ class InstanceKlass: public Klass {
|
|||||||
u1 _init_state; // state of class
|
u1 _init_state; // state of class
|
||||||
u1 _reference_type; // reference type
|
u1 _reference_type; // reference type
|
||||||
|
|
||||||
|
|
||||||
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
|
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
|
||||||
|
|
||||||
|
NOT_PRODUCT(int _verify_count;) // to avoid redundant verifies
|
||||||
|
|
||||||
// Method array.
|
// Method array.
|
||||||
Array<Method*>* _methods;
|
Array<Method*>* _methods;
|
||||||
// Interface (Klass*s) this class declares locally to implement.
|
// Interface (Klass*s) this class declares locally to implement.
|
||||||
@ -356,16 +358,19 @@ class InstanceKlass: public Klass {
|
|||||||
// method ordering
|
// method ordering
|
||||||
Array<int>* method_ordering() const { return _method_ordering; }
|
Array<int>* method_ordering() const { return _method_ordering; }
|
||||||
void set_method_ordering(Array<int>* m) { _method_ordering = m; }
|
void set_method_ordering(Array<int>* m) { _method_ordering = m; }
|
||||||
|
void copy_method_ordering(intArray* m, TRAPS);
|
||||||
|
|
||||||
// interfaces
|
// interfaces
|
||||||
Array<Klass*>* local_interfaces() const { return _local_interfaces; }
|
Array<Klass*>* local_interfaces() const { return _local_interfaces; }
|
||||||
void set_local_interfaces(Array<Klass*>* a) {
|
void set_local_interfaces(Array<Klass*>* a) {
|
||||||
guarantee(_local_interfaces == NULL || a == NULL, "Just checking");
|
guarantee(_local_interfaces == NULL || a == NULL, "Just checking");
|
||||||
_local_interfaces = a; }
|
_local_interfaces = a; }
|
||||||
|
|
||||||
Array<Klass*>* transitive_interfaces() const { return _transitive_interfaces; }
|
Array<Klass*>* transitive_interfaces() const { return _transitive_interfaces; }
|
||||||
void set_transitive_interfaces(Array<Klass*>* a) {
|
void set_transitive_interfaces(Array<Klass*>* a) {
|
||||||
guarantee(_transitive_interfaces == NULL || a == NULL, "Just checking");
|
guarantee(_transitive_interfaces == NULL || a == NULL, "Just checking");
|
||||||
_transitive_interfaces = a; }
|
_transitive_interfaces = a;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class fieldDescriptor;
|
friend class fieldDescriptor;
|
||||||
@ -381,10 +386,9 @@ class InstanceKlass: public Klass {
|
|||||||
int java_fields_count() const { return (int)_java_fields_count; }
|
int java_fields_count() const { return (int)_java_fields_count; }
|
||||||
|
|
||||||
Array<u2>* fields() const { return _fields; }
|
Array<u2>* fields() const { return _fields; }
|
||||||
|
|
||||||
void set_fields(Array<u2>* f, u2 java_fields_count) {
|
void set_fields(Array<u2>* f, u2 java_fields_count) {
|
||||||
guarantee(_fields == NULL || f == NULL, "Just checking");
|
guarantee(_fields == NULL || f == NULL, "Just checking");
|
||||||
_fields = f;
|
_fields = f;
|
||||||
_java_fields_count = java_fields_count;
|
_java_fields_count = java_fields_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +592,7 @@ class InstanceKlass: public Klass {
|
|||||||
|
|
||||||
// symbol unloading support (refcount already added)
|
// symbol unloading support (refcount already added)
|
||||||
Symbol* array_name() { return _array_name; }
|
Symbol* array_name() { return _array_name; }
|
||||||
void set_array_name(Symbol* name) { assert(_array_name == NULL, "name already created"); _array_name = name; }
|
void set_array_name(Symbol* name) { assert(_array_name == NULL || name == NULL, "name already created"); _array_name = name; }
|
||||||
|
|
||||||
// nonstatic oop-map blocks
|
// nonstatic oop-map blocks
|
||||||
static int nonstatic_oop_map_size(unsigned int oop_map_count) {
|
static int nonstatic_oop_map_size(unsigned int oop_map_count) {
|
||||||
@ -914,8 +918,15 @@ class InstanceKlass: public Klass {
|
|||||||
void clean_method_data(BoolObjectClosure* is_alive);
|
void clean_method_data(BoolObjectClosure* is_alive);
|
||||||
|
|
||||||
// Explicit metaspace deallocation of fields
|
// Explicit metaspace deallocation of fields
|
||||||
// For RedefineClasses, we need to deallocate instanceKlasses
|
// For RedefineClasses and class file parsing errors, we need to deallocate
|
||||||
|
// instanceKlasses and the metadata they point to.
|
||||||
void deallocate_contents(ClassLoaderData* loader_data);
|
void deallocate_contents(ClassLoaderData* loader_data);
|
||||||
|
static void deallocate_methods(ClassLoaderData* loader_data,
|
||||||
|
Array<Method*>* methods);
|
||||||
|
void static deallocate_interfaces(ClassLoaderData* loader_data,
|
||||||
|
Klass* super_klass,
|
||||||
|
Array<Klass*>* local_interfaces,
|
||||||
|
Array<Klass*>* transitive_interfaces);
|
||||||
|
|
||||||
// The constant pool is on stack if any of the methods are executing or
|
// The constant pool is on stack if any of the methods are executing or
|
||||||
// referenced by handles.
|
// referenced by handles.
|
||||||
|
@ -146,16 +146,16 @@ void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word
|
|||||||
Klass::Klass() {
|
Klass::Klass() {
|
||||||
Klass* k = this;
|
Klass* k = this;
|
||||||
|
|
||||||
{ // Preinitialize supertype information.
|
// Preinitialize supertype information.
|
||||||
// A later call to initialize_supers() may update these settings:
|
// A later call to initialize_supers() may update these settings:
|
||||||
set_super(NULL);
|
set_super(NULL);
|
||||||
for (juint i = 0; i < Klass::primary_super_limit(); i++) {
|
for (juint i = 0; i < Klass::primary_super_limit(); i++) {
|
||||||
_primary_supers[i] = NULL;
|
_primary_supers[i] = NULL;
|
||||||
}
|
|
||||||
set_secondary_supers(NULL);
|
|
||||||
_primary_supers[0] = k;
|
|
||||||
set_super_check_offset(in_bytes(primary_supers_offset()));
|
|
||||||
}
|
}
|
||||||
|
set_secondary_supers(NULL);
|
||||||
|
set_secondary_super_cache(NULL);
|
||||||
|
_primary_supers[0] = k;
|
||||||
|
set_super_check_offset(in_bytes(primary_supers_offset()));
|
||||||
|
|
||||||
set_java_mirror(NULL);
|
set_java_mirror(NULL);
|
||||||
set_modifier_flags(0);
|
set_modifier_flags(0);
|
||||||
|
@ -79,7 +79,6 @@
|
|||||||
// [last_biased_lock_bulk_revocation_time] (64 bits)
|
// [last_biased_lock_bulk_revocation_time] (64 bits)
|
||||||
// [prototype_header]
|
// [prototype_header]
|
||||||
// [biased_lock_revocation_count]
|
// [biased_lock_revocation_count]
|
||||||
// [verify_count ] - not in product
|
|
||||||
// [alloc_count ]
|
// [alloc_count ]
|
||||||
// [_modified_oops]
|
// [_modified_oops]
|
||||||
// [_accumulated_modified_oops]
|
// [_accumulated_modified_oops]
|
||||||
@ -172,10 +171,6 @@ class Klass : public Metadata {
|
|||||||
markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type
|
markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type
|
||||||
jint _biased_lock_revocation_count;
|
jint _biased_lock_revocation_count;
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
int _verify_count; // to avoid redundant verifies
|
|
||||||
#endif
|
|
||||||
|
|
||||||
juint _alloc_count; // allocation profiling support
|
juint _alloc_count; // allocation profiling support
|
||||||
|
|
||||||
TRACE_DEFINE_KLASS_TRACE_ID;
|
TRACE_DEFINE_KLASS_TRACE_ID;
|
||||||
|
@ -77,22 +77,19 @@ Method* Method::allocate(ClassLoaderData* loader_data,
|
|||||||
return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
|
return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Method::Method(ConstMethod* xconst,
|
Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
|
||||||
AccessFlags access_flags, int size) {
|
|
||||||
No_Safepoint_Verifier no_safepoint;
|
No_Safepoint_Verifier no_safepoint;
|
||||||
set_constMethod(xconst);
|
set_constMethod(xconst);
|
||||||
set_access_flags(access_flags);
|
set_access_flags(access_flags);
|
||||||
set_method_size(size);
|
set_method_size(size);
|
||||||
set_name_index(0);
|
|
||||||
set_signature_index(0);
|
|
||||||
#ifdef CC_INTERP
|
#ifdef CC_INTERP
|
||||||
set_result_index(T_VOID);
|
set_result_index(T_VOID);
|
||||||
#endif
|
#endif
|
||||||
set_constants(NULL);
|
|
||||||
set_max_stack(0);
|
|
||||||
set_max_locals(0);
|
|
||||||
set_intrinsic_id(vmIntrinsics::_none);
|
set_intrinsic_id(vmIntrinsics::_none);
|
||||||
set_jfr_towrite(false);
|
set_jfr_towrite(false);
|
||||||
|
set_force_inline(false);
|
||||||
|
set_hidden(false);
|
||||||
|
set_dont_inline(false);
|
||||||
set_method_data(NULL);
|
set_method_data(NULL);
|
||||||
set_interpreter_throwout_count(0);
|
set_interpreter_throwout_count(0);
|
||||||
set_vtable_index(Method::garbage_vtable_index);
|
set_vtable_index(Method::garbage_vtable_index);
|
||||||
|
@ -652,23 +652,25 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
|
|||||||
// Set the method back-pointer.
|
// Set the method back-pointer.
|
||||||
_method = method();
|
_method = method();
|
||||||
|
|
||||||
if (TieredCompilation) {
|
_invocation_counter.init();
|
||||||
_invocation_counter.init();
|
_backedge_counter.init();
|
||||||
_backedge_counter.init();
|
_invocation_counter_start = 0;
|
||||||
_invocation_counter_start = 0;
|
_backedge_counter_start = 0;
|
||||||
_backedge_counter_start = 0;
|
_num_loops = 0;
|
||||||
_num_loops = 0;
|
_num_blocks = 0;
|
||||||
_num_blocks = 0;
|
_highest_comp_level = 0;
|
||||||
_highest_comp_level = 0;
|
_highest_osr_comp_level = 0;
|
||||||
_highest_osr_comp_level = 0;
|
_would_profile = true;
|
||||||
_would_profile = true;
|
|
||||||
}
|
|
||||||
set_creation_mileage(mileage_of(method()));
|
set_creation_mileage(mileage_of(method()));
|
||||||
|
|
||||||
// Initialize flags and trap history.
|
// Initialize flags and trap history.
|
||||||
_nof_decompiles = 0;
|
_nof_decompiles = 0;
|
||||||
_nof_overflow_recompiles = 0;
|
_nof_overflow_recompiles = 0;
|
||||||
_nof_overflow_traps = 0;
|
_nof_overflow_traps = 0;
|
||||||
|
_eflags = 0;
|
||||||
|
_arg_local = 0;
|
||||||
|
_arg_stack = 0;
|
||||||
|
_arg_returned = 0;
|
||||||
assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
|
assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
|
||||||
Copy::zero_to_words((HeapWord*) &_trap_hist,
|
Copy::zero_to_words((HeapWord*) &_trap_hist,
|
||||||
sizeof(_trap_hist) / sizeof(HeapWord));
|
sizeof(_trap_hist) / sizeof(HeapWord));
|
||||||
@ -677,6 +679,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
|
|||||||
// corresponding data cells.
|
// corresponding data cells.
|
||||||
int data_size = 0;
|
int data_size = 0;
|
||||||
int empty_bc_count = 0; // number of bytecodes lacking data
|
int empty_bc_count = 0; // number of bytecodes lacking data
|
||||||
|
_data[0] = 0; // apparently not set below.
|
||||||
BytecodeStream stream(method);
|
BytecodeStream stream(method);
|
||||||
Bytecodes::Code c;
|
Bytecodes::Code c;
|
||||||
while ((c = stream.next()) >= 0) {
|
while ((c = stream.next()) >= 0) {
|
||||||
@ -710,6 +713,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
|
|||||||
post_initialize(&stream);
|
post_initialize(&stream);
|
||||||
|
|
||||||
set_size(object_size);
|
set_size(object_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a measure of how much mileage the method has on it.
|
// Get a measure of how much mileage the method has on it.
|
||||||
|
@ -187,31 +187,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------LRG_List---------------------------------------
|
|
||||||
// Map Node indices to Live RanGe indices.
|
|
||||||
// Array lookup in the optimized case.
|
|
||||||
class LRG_List : public ResourceObj {
|
|
||||||
friend class VMStructs;
|
|
||||||
uint _cnt, _max;
|
|
||||||
uint* _lidxs;
|
|
||||||
ReallocMark _nesting; // assertion check for reallocations
|
|
||||||
public:
|
|
||||||
LRG_List( uint max );
|
|
||||||
|
|
||||||
uint lookup( uint nidx ) const {
|
|
||||||
return _lidxs[nidx];
|
|
||||||
}
|
|
||||||
uint operator[] (uint nidx) const { return lookup(nidx); }
|
|
||||||
|
|
||||||
void map( uint nidx, uint lidx ) {
|
|
||||||
assert( nidx < _cnt, "oob" );
|
|
||||||
_lidxs[nidx] = lidx;
|
|
||||||
}
|
|
||||||
void extend( uint nidx, uint lidx );
|
|
||||||
|
|
||||||
uint Size() const { return _cnt; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------IFG--------------------------------------------
|
//------------------------------IFG--------------------------------------------
|
||||||
// InterFerence Graph
|
// InterFerence Graph
|
||||||
// An undirected graph implementation. Created with a fixed number of
|
// An undirected graph implementation. Created with a fixed number of
|
||||||
|
@ -892,7 +892,7 @@ Compile::Compile( ciEnv* ci_env,
|
|||||||
: Phase(Compiler),
|
: Phase(Compiler),
|
||||||
_env(ci_env),
|
_env(ci_env),
|
||||||
_log(ci_env->log()),
|
_log(ci_env->log()),
|
||||||
_compile_id(-1),
|
_compile_id(0),
|
||||||
_save_argument_registers(save_arg_registers),
|
_save_argument_registers(save_arg_registers),
|
||||||
_method(NULL),
|
_method(NULL),
|
||||||
_stub_name(stub_name),
|
_stub_name(stub_name),
|
||||||
|
@ -33,11 +33,35 @@
|
|||||||
#include "opto/regmask.hpp"
|
#include "opto/regmask.hpp"
|
||||||
|
|
||||||
class Block;
|
class Block;
|
||||||
class LRG_List;
|
|
||||||
class PhaseCFG;
|
class PhaseCFG;
|
||||||
class VectorSet;
|
class VectorSet;
|
||||||
class IndexSet;
|
class IndexSet;
|
||||||
|
|
||||||
|
//------------------------------LRG_List---------------------------------------
|
||||||
|
// Map Node indices to Live RanGe indices.
|
||||||
|
// Array lookup in the optimized case.
|
||||||
|
class LRG_List : public ResourceObj {
|
||||||
|
friend class VMStructs;
|
||||||
|
uint _cnt, _max;
|
||||||
|
uint* _lidxs;
|
||||||
|
ReallocMark _nesting; // assertion check for reallocations
|
||||||
|
public:
|
||||||
|
LRG_List( uint max );
|
||||||
|
|
||||||
|
uint lookup( uint nidx ) const {
|
||||||
|
return _lidxs[nidx];
|
||||||
|
}
|
||||||
|
uint operator[] (uint nidx) const { return lookup(nidx); }
|
||||||
|
|
||||||
|
void map( uint nidx, uint lidx ) {
|
||||||
|
assert( nidx < _cnt, "oob" );
|
||||||
|
_lidxs[nidx] = lidx;
|
||||||
|
}
|
||||||
|
void extend( uint nidx, uint lidx );
|
||||||
|
|
||||||
|
uint Size() const { return _cnt; }
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------PhaseLive--------------------------------------
|
//------------------------------PhaseLive--------------------------------------
|
||||||
// Compute live-in/live-out
|
// Compute live-in/live-out
|
||||||
class PhaseLive : public Phase {
|
class PhaseLive : public Phase {
|
||||||
|
@ -890,7 +890,7 @@ void JvmtiSuspendControl::print() {
|
|||||||
|
|
||||||
tty->print("Suspended Threads: [");
|
tty->print("Suspended Threads: [");
|
||||||
for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
|
for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
|
||||||
#if JVMTI_TRACE
|
#ifdef JVMTI_TRACE
|
||||||
const char *name = JvmtiTrace::safe_get_thread_name(thread);
|
const char *name = JvmtiTrace::safe_get_thread_name(thread);
|
||||||
#else
|
#else
|
||||||
const char *name = "";
|
const char *name = "";
|
||||||
|
@ -43,10 +43,10 @@
|
|||||||
|
|
||||||
// Support tracing except in product build on the client compiler
|
// Support tracing except in product build on the client compiler
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
#define JVMTI_TRACE 1
|
#define JVMTI_TRACE
|
||||||
#else
|
#else
|
||||||
#ifdef COMPILER2
|
#ifdef COMPILER2
|
||||||
#define JVMTI_TRACE 1
|
#define JVMTI_TRACE
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1381,6 +1381,40 @@ bool Arguments::should_auto_select_low_pause_collector() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Arguments::set_use_compressed_oops() {
|
||||||
|
#ifndef ZERO
|
||||||
|
#ifdef _LP64
|
||||||
|
// MaxHeapSize is not set up properly at this point, but
|
||||||
|
// the only value that can override MaxHeapSize if we are
|
||||||
|
// to use UseCompressedOops is InitialHeapSize.
|
||||||
|
size_t max_heap_size = MAX2(MaxHeapSize, InitialHeapSize);
|
||||||
|
|
||||||
|
if (max_heap_size <= max_heap_for_compressed_oops()) {
|
||||||
|
#if !defined(COMPILER1) || defined(TIERED)
|
||||||
|
if (FLAG_IS_DEFAULT(UseCompressedOops)) {
|
||||||
|
FLAG_SET_ERGO(bool, UseCompressedOops, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN64
|
||||||
|
if (UseLargePages && UseCompressedOops) {
|
||||||
|
// Cannot allocate guard pages for implicit checks in indexed addressing
|
||||||
|
// mode, when large pages are specified on windows.
|
||||||
|
// This flag could be switched ON if narrow oop base address is set to 0,
|
||||||
|
// see code in Universe::initialize_heap().
|
||||||
|
Universe::set_narrow_oop_use_implicit_null_checks(false);
|
||||||
|
}
|
||||||
|
#endif // _WIN64
|
||||||
|
} else {
|
||||||
|
if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
|
||||||
|
warning("Max heap size too large for Compressed Oops");
|
||||||
|
FLAG_SET_DEFAULT(UseCompressedOops, false);
|
||||||
|
FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // _LP64
|
||||||
|
#endif // ZERO
|
||||||
|
}
|
||||||
|
|
||||||
void Arguments::set_ergonomics_flags() {
|
void Arguments::set_ergonomics_flags() {
|
||||||
|
|
||||||
if (os::is_server_class_machine()) {
|
if (os::is_server_class_machine()) {
|
||||||
@ -1410,30 +1444,7 @@ void Arguments::set_ergonomics_flags() {
|
|||||||
|
|
||||||
#ifndef ZERO
|
#ifndef ZERO
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
// Check that UseCompressedOops can be set with the max heap size allocated
|
set_use_compressed_oops();
|
||||||
// by ergonomics.
|
|
||||||
if (MaxHeapSize <= max_heap_for_compressed_oops()) {
|
|
||||||
#if !defined(COMPILER1) || defined(TIERED)
|
|
||||||
if (FLAG_IS_DEFAULT(UseCompressedOops)) {
|
|
||||||
FLAG_SET_ERGO(bool, UseCompressedOops, true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN64
|
|
||||||
if (UseLargePages && UseCompressedOops) {
|
|
||||||
// Cannot allocate guard pages for implicit checks in indexed addressing
|
|
||||||
// mode, when large pages are specified on windows.
|
|
||||||
// This flag could be switched ON if narrow oop base address is set to 0,
|
|
||||||
// see code in Universe::initialize_heap().
|
|
||||||
Universe::set_narrow_oop_use_implicit_null_checks(false);
|
|
||||||
}
|
|
||||||
#endif // _WIN64
|
|
||||||
} else {
|
|
||||||
if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
|
|
||||||
warning("Max heap size too large for Compressed Oops");
|
|
||||||
FLAG_SET_DEFAULT(UseCompressedOops, false);
|
|
||||||
FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// UseCompressedOops must be on for UseCompressedKlassPointers to be on.
|
// UseCompressedOops must be on for UseCompressedKlassPointers to be on.
|
||||||
if (!UseCompressedOops) {
|
if (!UseCompressedOops) {
|
||||||
if (UseCompressedKlassPointers) {
|
if (UseCompressedKlassPointers) {
|
||||||
@ -1813,6 +1824,13 @@ void Arguments::check_deprecated_gcs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Arguments::check_deprecated_gc_flags() {
|
||||||
|
if (FLAG_IS_CMDLINE(MaxGCMinorPauseMillis)) {
|
||||||
|
warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated"
|
||||||
|
"and will likely be removed in future release");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check stack pages settings
|
// Check stack pages settings
|
||||||
bool Arguments::check_stack_pages()
|
bool Arguments::check_stack_pages()
|
||||||
{
|
{
|
||||||
@ -2273,10 +2291,12 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
}
|
}
|
||||||
#if !INCLUDE_JVMTI
|
#if !INCLUDE_JVMTI
|
||||||
if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
|
if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
|
||||||
warning("profiling and debugging agents are not supported in this VM");
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
} else
|
"Profiling and debugging agents are not supported in this VM\n");
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
#endif // !INCLUDE_JVMTI
|
#endif // !INCLUDE_JVMTI
|
||||||
add_init_library(name, options);
|
add_init_library(name, options);
|
||||||
}
|
}
|
||||||
// -agentlib and -agentpath
|
// -agentlib and -agentpath
|
||||||
} else if (match_option(option, "-agentlib:", &tail) ||
|
} else if (match_option(option, "-agentlib:", &tail) ||
|
||||||
@ -2293,16 +2313,19 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
}
|
}
|
||||||
#if !INCLUDE_JVMTI
|
#if !INCLUDE_JVMTI
|
||||||
if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
|
if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
|
||||||
warning("profiling and debugging agents are not supported in this VM");
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
} else
|
"Profiling and debugging agents are not supported in this VM\n");
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
#endif // !INCLUDE_JVMTI
|
#endif // !INCLUDE_JVMTI
|
||||||
add_init_agent(name, options, is_absolute_path);
|
add_init_agent(name, options, is_absolute_path);
|
||||||
|
|
||||||
}
|
}
|
||||||
// -javaagent
|
// -javaagent
|
||||||
} else if (match_option(option, "-javaagent:", &tail)) {
|
} else if (match_option(option, "-javaagent:", &tail)) {
|
||||||
#if !INCLUDE_JVMTI
|
#if !INCLUDE_JVMTI
|
||||||
warning("Instrumentation agents are not supported in this VM");
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
|
"Instrumentation agents are not supported in this VM\n");
|
||||||
|
return JNI_ERR;
|
||||||
#else
|
#else
|
||||||
if(tail != NULL) {
|
if(tail != NULL) {
|
||||||
char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail);
|
char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail);
|
||||||
@ -2443,8 +2466,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
#if INCLUDE_FPROF
|
#if INCLUDE_FPROF
|
||||||
_has_profile = true;
|
_has_profile = true;
|
||||||
#else // INCLUDE_FPROF
|
#else // INCLUDE_FPROF
|
||||||
// do we have to exit?
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
warning("Flat profiling is not supported in this VM.");
|
"Flat profiling is not supported in this VM.\n");
|
||||||
|
return JNI_ERR;
|
||||||
#endif // INCLUDE_FPROF
|
#endif // INCLUDE_FPROF
|
||||||
// -Xaprof
|
// -Xaprof
|
||||||
} else if (match_option(option, "-Xaprof", &tail)) {
|
} else if (match_option(option, "-Xaprof", &tail)) {
|
||||||
@ -2478,8 +2502,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
#if INCLUDE_MANAGEMENT
|
#if INCLUDE_MANAGEMENT
|
||||||
FLAG_SET_CMDLINE(bool, ManagementServer, true);
|
FLAG_SET_CMDLINE(bool, ManagementServer, true);
|
||||||
#else
|
#else
|
||||||
vm_exit_during_initialization(
|
jio_fprintf(defaultStream::output_stream(),
|
||||||
"-Dcom.sun.management is not supported in this VM.", NULL);
|
"-Dcom.sun.management is not supported in this VM.\n");
|
||||||
|
return JNI_ERR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// -Xint
|
// -Xint
|
||||||
@ -2492,16 +2517,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
} else if (match_option(option, "-Xcomp", &tail)) {
|
} else if (match_option(option, "-Xcomp", &tail)) {
|
||||||
// for testing the compiler; turn off all flags that inhibit compilation
|
// for testing the compiler; turn off all flags that inhibit compilation
|
||||||
set_mode_flags(_comp);
|
set_mode_flags(_comp);
|
||||||
|
|
||||||
// -Xshare:dump
|
// -Xshare:dump
|
||||||
} else if (match_option(option, "-Xshare:dump", &tail)) {
|
} else if (match_option(option, "-Xshare:dump", &tail)) {
|
||||||
#if !INCLUDE_CDS
|
|
||||||
vm_exit_during_initialization(
|
|
||||||
"Dumping a shared archive is not supported in this VM.", NULL);
|
|
||||||
#else
|
|
||||||
FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true);
|
FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true);
|
||||||
set_mode_flags(_int); // Prevent compilation, which creates objects
|
set_mode_flags(_int); // Prevent compilation, which creates objects
|
||||||
#endif
|
|
||||||
// -Xshare:on
|
// -Xshare:on
|
||||||
} else if (match_option(option, "-Xshare:on", &tail)) {
|
} else if (match_option(option, "-Xshare:on", &tail)) {
|
||||||
FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
|
FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
|
||||||
@ -2514,7 +2533,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
} else if (match_option(option, "-Xshare:off", &tail)) {
|
} else if (match_option(option, "-Xshare:off", &tail)) {
|
||||||
FLAG_SET_CMDLINE(bool, UseSharedSpaces, false);
|
FLAG_SET_CMDLINE(bool, UseSharedSpaces, false);
|
||||||
FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
|
FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
|
||||||
|
|
||||||
// -Xverify
|
// -Xverify
|
||||||
} else if (match_option(option, "-Xverify", &tail)) {
|
} else if (match_option(option, "-Xverify", &tail)) {
|
||||||
if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
|
if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
|
||||||
@ -2828,8 +2846,9 @@ SOLARIS_ONLY(
|
|||||||
FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true);
|
FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true);
|
||||||
#if !INCLUDE_MANAGEMENT
|
#if !INCLUDE_MANAGEMENT
|
||||||
} else if (match_option(option, "-XX:+ManagementServer", &tail)) {
|
} else if (match_option(option, "-XX:+ManagementServer", &tail)) {
|
||||||
vm_exit_during_initialization(
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
"ManagementServer is not supported in this VM.", NULL);
|
"ManagementServer is not supported in this VM.\n");
|
||||||
|
return JNI_ERR;
|
||||||
#endif // INCLUDE_MANAGEMENT
|
#endif // INCLUDE_MANAGEMENT
|
||||||
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
|
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
|
||||||
// Skip -XX:Flags= since that case has already been handled
|
// Skip -XX:Flags= since that case has already been handled
|
||||||
@ -3135,7 +3154,9 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
|||||||
#if INCLUDE_NMT
|
#if INCLUDE_NMT
|
||||||
MemTracker::init_tracking_options(tail);
|
MemTracker::init_tracking_options(tail);
|
||||||
#else
|
#else
|
||||||
warning("Native Memory Tracking is not supported in this VM");
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
|
"Native Memory Tracking is not supported in this VM\n");
|
||||||
|
return JNI_ERR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3254,6 +3275,16 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
|||||||
force_serial_gc();
|
force_serial_gc();
|
||||||
#endif // INCLUDE_ALL_GCS
|
#endif // INCLUDE_ALL_GCS
|
||||||
#if !INCLUDE_CDS
|
#if !INCLUDE_CDS
|
||||||
|
if (DumpSharedSpaces || RequireSharedSpaces) {
|
||||||
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
|
"Shared spaces are not supported in this VM\n");
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
if ((UseSharedSpaces && FLAG_IS_CMDLINE(UseSharedSpaces)) || PrintSharedSpaces) {
|
||||||
|
warning("Shared spaces are not supported in this VM");
|
||||||
|
FLAG_SET_DEFAULT(UseSharedSpaces, false);
|
||||||
|
FLAG_SET_DEFAULT(PrintSharedSpaces, false);
|
||||||
|
}
|
||||||
no_shared_spaces();
|
no_shared_spaces();
|
||||||
#endif // INCLUDE_CDS
|
#endif // INCLUDE_CDS
|
||||||
|
|
||||||
@ -3292,6 +3323,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
|||||||
set_g1_gc_flags();
|
set_g1_gc_flags();
|
||||||
}
|
}
|
||||||
check_deprecated_gcs();
|
check_deprecated_gcs();
|
||||||
|
check_deprecated_gc_flags();
|
||||||
#else // INCLUDE_ALL_GCS
|
#else // INCLUDE_ALL_GCS
|
||||||
assert(verify_serial_gc_flags(), "SerialGC unset");
|
assert(verify_serial_gc_flags(), "SerialGC unset");
|
||||||
#endif // INCLUDE_ALL_GCS
|
#endif // INCLUDE_ALL_GCS
|
||||||
|
@ -309,6 +309,7 @@ class Arguments : AllStatic {
|
|||||||
// Garbage-First (UseG1GC)
|
// Garbage-First (UseG1GC)
|
||||||
static void set_g1_gc_flags();
|
static void set_g1_gc_flags();
|
||||||
// GC ergonomics
|
// GC ergonomics
|
||||||
|
static void set_use_compressed_oops();
|
||||||
static void set_ergonomics_flags();
|
static void set_ergonomics_flags();
|
||||||
static void set_shared_spaces_flags();
|
static void set_shared_spaces_flags();
|
||||||
// Setup heap size
|
// Setup heap size
|
||||||
@ -414,6 +415,7 @@ class Arguments : AllStatic {
|
|||||||
// Check for consistency in the selection of the garbage collector.
|
// Check for consistency in the selection of the garbage collector.
|
||||||
static bool check_gc_consistency();
|
static bool check_gc_consistency();
|
||||||
static void check_deprecated_gcs();
|
static void check_deprecated_gcs();
|
||||||
|
static void check_deprecated_gc_flags();
|
||||||
// Check consistecy or otherwise of VM argument settings
|
// Check consistecy or otherwise of VM argument settings
|
||||||
static bool check_vm_args_consistency();
|
static bool check_vm_args_consistency();
|
||||||
// Check stack pages settings
|
// Check stack pages settings
|
||||||
|
@ -425,6 +425,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
|||||||
callee_parameters,
|
callee_parameters,
|
||||||
callee_locals,
|
callee_locals,
|
||||||
index == 0,
|
index == 0,
|
||||||
|
index == array->frames() - 1,
|
||||||
popframe_extra_args);
|
popframe_extra_args);
|
||||||
// This pc doesn't have to be perfect just good enough to identify the frame
|
// This pc doesn't have to be perfect just good enough to identify the frame
|
||||||
// as interpreted so the skeleton frame will be walkable
|
// as interpreted so the skeleton frame will be walkable
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -1289,6 +1289,7 @@ class JavaThread: public Thread {
|
|||||||
void enable_stack_red_zone();
|
void enable_stack_red_zone();
|
||||||
void disable_stack_red_zone();
|
void disable_stack_red_zone();
|
||||||
|
|
||||||
|
inline bool stack_guard_zone_unused();
|
||||||
inline bool stack_yellow_zone_disabled();
|
inline bool stack_yellow_zone_disabled();
|
||||||
inline bool stack_yellow_zone_enabled();
|
inline bool stack_yellow_zone_enabled();
|
||||||
|
|
||||||
@ -1759,6 +1760,10 @@ inline CompilerThread* JavaThread::as_CompilerThread() {
|
|||||||
return (CompilerThread*)this;
|
return (CompilerThread*)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool JavaThread::stack_guard_zone_unused() {
|
||||||
|
return _stack_guard_state == stack_guard_unused;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool JavaThread::stack_yellow_zone_disabled() {
|
inline bool JavaThread::stack_yellow_zone_disabled() {
|
||||||
return _stack_guard_state == stack_guard_yellow_disabled;
|
return _stack_guard_state == stack_guard_yellow_disabled;
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
|||||||
int callee_locals,
|
int callee_locals,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
bool is_top_frame,
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame,
|
||||||
int exec_mode) {
|
int exec_mode) {
|
||||||
JavaThread* thread = (JavaThread*) Thread::current();
|
JavaThread* thread = (JavaThread*) Thread::current();
|
||||||
|
|
||||||
@ -275,7 +276,8 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
|||||||
callee_locals,
|
callee_locals,
|
||||||
caller,
|
caller,
|
||||||
iframe(),
|
iframe(),
|
||||||
is_top_frame);
|
is_top_frame,
|
||||||
|
is_bottom_frame);
|
||||||
|
|
||||||
// Update the pc in the frame object and overwrite the temporary pc
|
// Update the pc in the frame object and overwrite the temporary pc
|
||||||
// we placed in the skeletal frame now that we finally know the
|
// we placed in the skeletal frame now that we finally know the
|
||||||
@ -420,6 +422,7 @@ int vframeArrayElement::on_stack_size(int caller_actual_parameters,
|
|||||||
int callee_parameters,
|
int callee_parameters,
|
||||||
int callee_locals,
|
int callee_locals,
|
||||||
bool is_top_frame,
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame,
|
||||||
int popframe_extra_stack_expression_els) const {
|
int popframe_extra_stack_expression_els) const {
|
||||||
assert(method()->max_locals() == locals()->size(), "just checking");
|
assert(method()->max_locals() == locals()->size(), "just checking");
|
||||||
int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors();
|
int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors();
|
||||||
@ -431,7 +434,8 @@ int vframeArrayElement::on_stack_size(int caller_actual_parameters,
|
|||||||
caller_actual_parameters,
|
caller_actual_parameters,
|
||||||
callee_parameters,
|
callee_parameters,
|
||||||
callee_locals,
|
callee_locals,
|
||||||
is_top_frame);
|
is_top_frame,
|
||||||
|
is_bottom_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -522,7 +526,7 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller
|
|||||||
|
|
||||||
// Do the unpacking of interpreter frames; the frame at index 0 represents the top activation, so it has no callee
|
// Do the unpacking of interpreter frames; the frame at index 0 represents the top activation, so it has no callee
|
||||||
// Unpack the frames from the oldest (frames() -1) to the youngest (0)
|
// Unpack the frames from the oldest (frames() -1) to the youngest (0)
|
||||||
frame caller_frame = me;
|
frame* caller_frame = &me;
|
||||||
for (index = frames() - 1; index >= 0 ; index--) {
|
for (index = frames() - 1; index >= 0 ; index--) {
|
||||||
vframeArrayElement* elem = element(index); // caller
|
vframeArrayElement* elem = element(index); // caller
|
||||||
int callee_parameters, callee_locals;
|
int callee_parameters, callee_locals;
|
||||||
@ -542,13 +546,14 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller
|
|||||||
elem->unpack_on_stack(caller_actual_parameters,
|
elem->unpack_on_stack(caller_actual_parameters,
|
||||||
callee_parameters,
|
callee_parameters,
|
||||||
callee_locals,
|
callee_locals,
|
||||||
&caller_frame,
|
caller_frame,
|
||||||
index == 0,
|
index == 0,
|
||||||
|
index == frames() - 1,
|
||||||
exec_mode);
|
exec_mode);
|
||||||
if (index == frames() - 1) {
|
if (index == frames() - 1) {
|
||||||
Deoptimization::unwind_callee_save_values(elem->iframe(), this);
|
Deoptimization::unwind_callee_save_values(elem->iframe(), this);
|
||||||
}
|
}
|
||||||
caller_frame = *elem->iframe();
|
caller_frame = elem->iframe();
|
||||||
caller_actual_parameters = callee_parameters;
|
caller_actual_parameters = callee_parameters;
|
||||||
}
|
}
|
||||||
deallocate_monitor_chunks();
|
deallocate_monitor_chunks();
|
||||||
|
@ -88,6 +88,7 @@ class vframeArrayElement : public _ValueObj {
|
|||||||
int on_stack_size(int caller_actual_parameters,
|
int on_stack_size(int caller_actual_parameters,
|
||||||
int callee_parameters,
|
int callee_parameters,
|
||||||
int callee_locals,
|
int callee_locals,
|
||||||
|
bool is_bottom_frame,
|
||||||
bool is_top_frame,
|
bool is_top_frame,
|
||||||
int popframe_extra_stack_expression_els) const;
|
int popframe_extra_stack_expression_els) const;
|
||||||
|
|
||||||
@ -97,6 +98,7 @@ class vframeArrayElement : public _ValueObj {
|
|||||||
int callee_locals,
|
int callee_locals,
|
||||||
frame* caller,
|
frame* caller,
|
||||||
bool is_top_frame,
|
bool is_top_frame,
|
||||||
|
bool is_bottom_frame,
|
||||||
int exec_mode);
|
int exec_mode);
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -336,7 +336,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
|||||||
nonstatic_field(Klass, _access_flags, AccessFlags) \
|
nonstatic_field(Klass, _access_flags, AccessFlags) \
|
||||||
nonstatic_field(Klass, _subklass, Klass*) \
|
nonstatic_field(Klass, _subklass, Klass*) \
|
||||||
nonstatic_field(Klass, _next_sibling, Klass*) \
|
nonstatic_field(Klass, _next_sibling, Klass*) \
|
||||||
nonproduct_nonstatic_field(Klass, _verify_count, int) \
|
|
||||||
nonstatic_field(Klass, _alloc_count, juint) \
|
nonstatic_field(Klass, _alloc_count, juint) \
|
||||||
nonstatic_field(MethodData, _size, int) \
|
nonstatic_field(MethodData, _size, int) \
|
||||||
nonstatic_field(MethodData, _method, Method*) \
|
nonstatic_field(MethodData, _method, Method*) \
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
template(ReportJavaOutOfMemory) \
|
template(ReportJavaOutOfMemory) \
|
||||||
template(JFRCheckpoint) \
|
template(JFRCheckpoint) \
|
||||||
template(Exit) \
|
template(Exit) \
|
||||||
|
template(LinuxDllLoad) \
|
||||||
|
|
||||||
class VM_Operation: public CHeapObj<mtInternal> {
|
class VM_Operation: public CHeapObj<mtInternal> {
|
||||||
public:
|
public:
|
||||||
|
@ -197,4 +197,28 @@ ElfStringTable* ElfFile::get_string_table(int index) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LINUX
|
||||||
|
bool ElfFile::specifies_noexecstack() {
|
||||||
|
Elf_Phdr phdr;
|
||||||
|
if (!m_file) return true;
|
||||||
|
|
||||||
|
if (!fseek(m_file, m_elfHdr.e_phoff, SEEK_SET)) {
|
||||||
|
for (int index = 0; index < m_elfHdr.e_phnum; index ++) {
|
||||||
|
if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, m_file) != 1) {
|
||||||
|
m_status = NullDecoder::file_invalid;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (phdr.p_type == PT_GNU_STACK) {
|
||||||
|
if (phdr.p_flags == (PF_R | PF_W)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // _WINDOWS
|
#endif // _WINDOWS
|
||||||
|
@ -43,6 +43,7 @@ typedef Elf64_Addr Elf_Addr;
|
|||||||
|
|
||||||
typedef Elf64_Ehdr Elf_Ehdr;
|
typedef Elf64_Ehdr Elf_Ehdr;
|
||||||
typedef Elf64_Shdr Elf_Shdr;
|
typedef Elf64_Shdr Elf_Shdr;
|
||||||
|
typedef Elf64_Phdr Elf_Phdr;
|
||||||
typedef Elf64_Sym Elf_Sym;
|
typedef Elf64_Sym Elf_Sym;
|
||||||
|
|
||||||
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
|
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
|
||||||
@ -59,6 +60,7 @@ typedef Elf32_Addr Elf_Addr;
|
|||||||
|
|
||||||
typedef Elf32_Ehdr Elf_Ehdr;
|
typedef Elf32_Ehdr Elf_Ehdr;
|
||||||
typedef Elf32_Shdr Elf_Shdr;
|
typedef Elf32_Shdr Elf_Shdr;
|
||||||
|
typedef Elf32_Phdr Elf_Phdr;
|
||||||
typedef Elf32_Sym Elf_Sym;
|
typedef Elf32_Sym Elf_Sym;
|
||||||
|
|
||||||
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
|
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
|
||||||
@ -123,6 +125,14 @@ protected:
|
|||||||
ElfFile* next() const { return m_next; }
|
ElfFile* next() const { return m_next; }
|
||||||
void set_next(ElfFile* file) { m_next = file; }
|
void set_next(ElfFile* file) { m_next = file; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Returns true if the elf file is marked NOT to require an executable stack,
|
||||||
|
// or if the file could not be opened.
|
||||||
|
// Returns false if the elf file requires an executable stack, the stack flag
|
||||||
|
// is not set at all, or if the file can not be read.
|
||||||
|
// On systems other than linux it always returns false.
|
||||||
|
bool specifies_noexecstack() NOT_LINUX({ return false; });
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ElfFile* m_next;
|
ElfFile* m_next;
|
||||||
|
|
||||||
|
255
hotspot/test/compiler/8009761/Test8009761.java
Normal file
255
hotspot/test/compiler/8009761/Test8009761.java
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8009761
|
||||||
|
* @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
|
||||||
|
* @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8009761
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Test8009761 {
|
||||||
|
|
||||||
|
static class UnloadedClass {
|
||||||
|
volatile int i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object m1(boolean deopt) {
|
||||||
|
// When running interpreted, on sparc, the caller's stack is
|
||||||
|
// extended for the locals and the caller's frame is restored
|
||||||
|
// on return.
|
||||||
|
long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12,
|
||||||
|
l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24,
|
||||||
|
l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36,
|
||||||
|
l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48,
|
||||||
|
l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60,
|
||||||
|
l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72,
|
||||||
|
l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84,
|
||||||
|
l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96,
|
||||||
|
l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107,
|
||||||
|
l108, l109, l110, l111, l112, l113, l114, l115, l116, l117,
|
||||||
|
l118, l119, l120, l121, l122, l123, l124, l125, l126, l127,
|
||||||
|
l128, l129, l130, l131, l132, l133, l134, l135, l136, l137,
|
||||||
|
l138, l139, l140, l141, l142, l143, l144, l145, l146, l147,
|
||||||
|
l148, l149, l150, l151, l152, l153, l154, l155, l156, l157,
|
||||||
|
l158, l159, l160, l161, l162, l163, l164, l165, l166, l167,
|
||||||
|
l168, l169, l170, l171, l172, l173, l174, l175, l176, l177,
|
||||||
|
l178, l179, l180, l181, l182, l183, l184, l185, l186, l187,
|
||||||
|
l188, l189, l190, l191, l192, l193, l194, l195, l196, l197,
|
||||||
|
l198, l199, l200, l201, l202, l203, l204, l205, l206, l207,
|
||||||
|
l208, l209, l210, l211, l212, l213, l214, l215, l216, l217,
|
||||||
|
l218, l219, l220, l221, l222, l223, l224, l225, l226, l227,
|
||||||
|
l228, l229, l230, l231, l232, l233, l234, l235, l236, l237,
|
||||||
|
l238, l239, l240, l241, l242, l243, l244, l245, l246, l247,
|
||||||
|
l248, l249, l250, l251, l252, l253, l254, l255, l256, l257,
|
||||||
|
l258, l259, l260, l261, l262, l263, l264, l265, l266, l267,
|
||||||
|
l268, l269, l270, l271, l272, l273, l274, l275, l276, l277,
|
||||||
|
l278, l279, l280, l281, l282, l283, l284, l285, l286, l287,
|
||||||
|
l288, l289, l290, l291, l292, l293, l294, l295, l296, l297,
|
||||||
|
l298, l299, l300, l301, l302, l303, l304, l305, l306, l307,
|
||||||
|
l308, l309, l310, l311, l312, l313, l314, l315, l316, l317,
|
||||||
|
l318, l319, l320, l321, l322, l323, l324, l325, l326, l327,
|
||||||
|
l328, l329, l330, l331, l332, l333, l334, l335, l336, l337,
|
||||||
|
l338, l339, l340, l341, l342, l343, l344, l345, l346, l347,
|
||||||
|
l348, l349, l350, l351, l352, l353, l354, l355, l356, l357,
|
||||||
|
l358, l359, l360, l361, l362, l363, l364, l365, l366, l367,
|
||||||
|
l368, l369, l370, l371, l372, l373, l374, l375, l376, l377,
|
||||||
|
l378, l379, l380, l381, l382, l383, l384, l385, l386, l387,
|
||||||
|
l388, l389, l390, l391, l392, l393, l394, l395, l396, l397,
|
||||||
|
l398, l399, l400, l401, l402, l403, l404, l405, l406, l407,
|
||||||
|
l408, l409, l410, l411, l412, l413, l414, l415, l416, l417,
|
||||||
|
l418, l419, l420, l421, l422, l423, l424, l425, l426, l427,
|
||||||
|
l428, l429, l430, l431, l432, l433, l434, l435, l436, l437,
|
||||||
|
l438, l439, l440, l441, l442, l443, l444, l445, l446, l447,
|
||||||
|
l448, l449, l450, l451, l452, l453, l454, l455, l456, l457,
|
||||||
|
l458, l459, l460, l461, l462, l463, l464, l465, l466, l467,
|
||||||
|
l468, l469, l470, l471, l472, l473, l474, l475, l476, l477,
|
||||||
|
l478, l479, l480, l481, l482, l483, l484, l485, l486, l487,
|
||||||
|
l488, l489, l490, l491, l492, l493, l494, l495, l496, l497,
|
||||||
|
l498, l499, l500, l501, l502, l503, l504, l505, l506, l507,
|
||||||
|
l508, l509, l510, l511;
|
||||||
|
|
||||||
|
long ll0, ll1, ll2, ll3, ll4, ll5, ll6, ll7, ll8, ll9, ll10, ll11, ll12,
|
||||||
|
ll13, ll14, ll15, ll16, ll17, ll18, ll19, ll20, ll21, ll22, ll23, ll24,
|
||||||
|
ll25, ll26, ll27, ll28, ll29, ll30, ll31, ll32, ll33, ll34, ll35, ll36,
|
||||||
|
ll37, ll38, ll39, ll40, ll41, ll42, ll43, ll44, ll45, ll46, ll47, ll48,
|
||||||
|
ll49, ll50, ll51, ll52, ll53, ll54, ll55, ll56, ll57, ll58, ll59, ll60,
|
||||||
|
ll61, ll62, ll63, ll64, ll65, ll66, ll67, ll68, ll69, ll70, ll71, ll72,
|
||||||
|
ll73, ll74, ll75, ll76, ll77, ll78, ll79, ll80, ll81, ll82, ll83, ll84,
|
||||||
|
ll85, ll86, ll87, ll88, ll89, ll90, ll91, ll92, ll93, ll94, ll95, ll96,
|
||||||
|
ll97, ll98, ll99, ll100, ll101, ll102, ll103, ll104, ll105, ll106, ll107,
|
||||||
|
ll108, ll109, ll110, ll111, ll112, ll113, ll114, ll115, ll116, ll117,
|
||||||
|
ll118, ll119, ll120, ll121, ll122, ll123, ll124, ll125, ll126, ll127,
|
||||||
|
ll128, ll129, ll130, ll131, ll132, ll133, ll134, ll135, ll136, ll137,
|
||||||
|
ll138, ll139, ll140, ll141, ll142, ll143, ll144, ll145, ll146, ll147,
|
||||||
|
ll148, ll149, ll150, ll151, ll152, ll153, ll154, ll155, ll156, ll157,
|
||||||
|
ll158, ll159, ll160, ll161, ll162, ll163, ll164, ll165, ll166, ll167,
|
||||||
|
ll168, ll169, ll170, ll171, ll172, ll173, ll174, ll175, ll176, ll177,
|
||||||
|
ll178, ll179, ll180, ll181, ll182, ll183, ll184, ll185, ll186, ll187,
|
||||||
|
ll188, ll189, ll190, ll191, ll192, ll193, ll194, ll195, ll196, ll197,
|
||||||
|
ll198, ll199, ll200, ll201, ll202, ll203, ll204, ll205, ll206, ll207,
|
||||||
|
ll208, ll209, ll210, ll211, ll212, ll213, ll214, ll215, ll216, ll217,
|
||||||
|
ll218, ll219, ll220, ll221, ll222, ll223, ll224, ll225, ll226, ll227,
|
||||||
|
ll228, ll229, ll230, ll231, ll232, ll233, ll234, ll235, ll236, ll237,
|
||||||
|
ll238, ll239, ll240, ll241, ll242, ll243, ll244, ll245, ll246, ll247,
|
||||||
|
ll248, ll249, ll250, ll251, ll252, ll253, ll254, ll255, ll256, ll257,
|
||||||
|
ll258, ll259, ll260, ll261, ll262, ll263, ll264, ll265, ll266, ll267,
|
||||||
|
ll268, ll269, ll270, ll271, ll272, ll273, ll274, ll275, ll276, ll277,
|
||||||
|
ll278, ll279, ll280, ll281, ll282, ll283, ll284, ll285, ll286, ll287,
|
||||||
|
ll288, ll289, ll290, ll291, ll292, ll293, ll294, ll295, ll296, ll297,
|
||||||
|
ll298, ll299, ll300, ll301, ll302, ll303, ll304, ll305, ll306, ll307,
|
||||||
|
ll308, ll309, ll310, ll311, ll312, ll313, ll314, ll315, ll316, ll317,
|
||||||
|
ll318, ll319, ll320, ll321, ll322, ll323, ll324, ll325, ll326, ll327,
|
||||||
|
ll328, ll329, ll330, ll331, ll332, ll333, ll334, ll335, ll336, ll337,
|
||||||
|
ll338, ll339, ll340, ll341, ll342, ll343, ll344, ll345, ll346, ll347,
|
||||||
|
ll348, ll349, ll350, ll351, ll352, ll353, ll354, ll355, ll356, ll357,
|
||||||
|
ll358, ll359, ll360, ll361, ll362, ll363, ll364, ll365, ll366, ll367,
|
||||||
|
ll368, ll369, ll370, ll371, ll372, ll373, ll374, ll375, ll376, ll377,
|
||||||
|
ll378, ll379, ll380, ll381, ll382, ll383, ll384, ll385, ll386, ll387,
|
||||||
|
ll388, ll389, ll390, ll391, ll392, ll393, ll394, ll395, ll396, ll397,
|
||||||
|
ll398, ll399, ll400, ll401, ll402, ll403, ll404, ll405, ll406, ll407,
|
||||||
|
ll408, ll409, ll410, ll411, ll412, ll413, ll414, ll415, ll416, ll417,
|
||||||
|
ll418, ll419, ll420, ll421, ll422, ll423, ll424, ll425, ll426, ll427,
|
||||||
|
ll428, ll429, ll430, ll431, ll432, ll433, ll434, ll435, ll436, ll437,
|
||||||
|
ll438, ll439, ll440, ll441, ll442, ll443, ll444, ll445, ll446, ll447,
|
||||||
|
ll448, ll449, ll450, ll451, ll452, ll453, ll454, ll455, ll456, ll457,
|
||||||
|
ll458, ll459, ll460, ll461, ll462, ll463, ll464, ll465, ll466, ll467,
|
||||||
|
ll468, ll469, ll470, ll471, ll472, ll473, ll474, ll475, ll476, ll477,
|
||||||
|
ll478, ll479, ll480, ll481, ll482, ll483, ll484, ll485, ll486, ll487,
|
||||||
|
ll488, ll489, ll490, ll491, ll492, ll493, ll494, ll495, ll496, ll497,
|
||||||
|
ll498, ll499, ll500, ll501, ll502, ll503, ll504, ll505, ll506, ll507,
|
||||||
|
ll508, ll509, ll510, ll511;
|
||||||
|
|
||||||
|
if (deopt) {
|
||||||
|
UnloadedClass res = new UnloadedClass(); // sufficient to force deopt with c2 but not c1
|
||||||
|
res.i = 0; // forces deopt with c1
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count = 0;
|
||||||
|
|
||||||
|
static void m2() {
|
||||||
|
// Will be called recursively until a stack overflow
|
||||||
|
// exception. Makes sure it has a lot of locals so that it's
|
||||||
|
// not called a sufficient number of times to trigger
|
||||||
|
// compilation.
|
||||||
|
|
||||||
|
long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12,
|
||||||
|
l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24,
|
||||||
|
l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36,
|
||||||
|
l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48,
|
||||||
|
l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60,
|
||||||
|
l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72,
|
||||||
|
l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84,
|
||||||
|
l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96,
|
||||||
|
l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107,
|
||||||
|
l108, l109, l110, l111, l112, l113, l114, l115, l116, l117,
|
||||||
|
l118, l119, l120, l121, l122, l123, l124, l125, l126, l127,
|
||||||
|
l128, l129, l130, l131, l132, l133, l134, l135, l136, l137,
|
||||||
|
l138, l139, l140, l141, l142, l143, l144, l145, l146, l147,
|
||||||
|
l148, l149, l150, l151, l152, l153, l154, l155, l156, l157,
|
||||||
|
l158, l159, l160, l161, l162, l163, l164, l165, l166, l167,
|
||||||
|
l168, l169, l170, l171, l172, l173, l174, l175, l176, l177,
|
||||||
|
l178, l179, l180, l181, l182, l183, l184, l185, l186, l187,
|
||||||
|
l188, l189, l190, l191, l192, l193, l194, l195, l196, l197,
|
||||||
|
l198, l199, l200, l201, l202, l203, l204, l205, l206, l207,
|
||||||
|
l208, l209, l210, l211, l212, l213, l214, l215, l216, l217,
|
||||||
|
l218, l219, l220, l221, l222, l223, l224, l225, l226, l227,
|
||||||
|
l228, l229, l230, l231, l232, l233, l234, l235, l236, l237,
|
||||||
|
l238, l239, l240, l241, l242, l243, l244, l245, l246, l247,
|
||||||
|
l248, l249, l250, l251, l252, l253, l254, l255, l256, l257,
|
||||||
|
l258, l259, l260, l261, l262, l263, l264, l265, l266, l267,
|
||||||
|
l268, l269, l270, l271, l272, l273, l274, l275, l276, l277,
|
||||||
|
l278, l279, l280, l281, l282, l283, l284, l285, l286, l287,
|
||||||
|
l288, l289, l290, l291, l292, l293, l294, l295, l296, l297,
|
||||||
|
l298, l299, l300, l301, l302, l303, l304, l305, l306, l307,
|
||||||
|
l308, l309, l310, l311, l312, l313, l314, l315, l316, l317,
|
||||||
|
l318, l319, l320, l321, l322, l323, l324, l325, l326, l327,
|
||||||
|
l328, l329, l330, l331, l332, l333, l334, l335, l336, l337,
|
||||||
|
l338, l339, l340, l341, l342, l343, l344, l345, l346, l347,
|
||||||
|
l348, l349, l350, l351, l352, l353, l354, l355, l356, l357,
|
||||||
|
l358, l359, l360, l361, l362, l363, l364, l365, l366, l367,
|
||||||
|
l368, l369, l370, l371, l372, l373, l374, l375, l376, l377,
|
||||||
|
l378, l379, l380, l381, l382, l383, l384, l385, l386, l387,
|
||||||
|
l388, l389, l390, l391, l392, l393, l394, l395, l396, l397,
|
||||||
|
l398, l399, l400, l401, l402, l403, l404, l405, l406, l407,
|
||||||
|
l408, l409, l410, l411, l412, l413, l414, l415, l416, l417,
|
||||||
|
l418, l419, l420, l421, l422, l423, l424, l425, l426, l427,
|
||||||
|
l428, l429, l430, l431, l432, l433, l434, l435, l436, l437,
|
||||||
|
l438, l439, l440, l441, l442, l443, l444, l445, l446, l447,
|
||||||
|
l448, l449, l450, l451, l452, l453, l454, l455, l456, l457,
|
||||||
|
l458, l459, l460, l461, l462, l463, l464, l465, l466, l467,
|
||||||
|
l468, l469, l470, l471, l472, l473, l474, l475, l476, l477,
|
||||||
|
l478, l479, l480, l481, l482, l483, l484, l485, l486, l487,
|
||||||
|
l488, l489, l490, l491, l492, l493, l494, l495, l496, l497,
|
||||||
|
l498, l499, l500, l501, l502, l503, l504, l505, l506, l507,
|
||||||
|
l508, l509, l510, l511;
|
||||||
|
|
||||||
|
count++;
|
||||||
|
m2();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object m3(boolean overflow_stack, boolean deopt) {
|
||||||
|
if (overflow_stack) {
|
||||||
|
m2();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Object o = m1(deopt);
|
||||||
|
if (deopt) {
|
||||||
|
m2();
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public void main(String[] args) {
|
||||||
|
int c1;
|
||||||
|
// Call m2 from m3 recursively until stack overflow. Count the number of recursive calls.
|
||||||
|
try {
|
||||||
|
m3(true, false);
|
||||||
|
} catch(StackOverflowError soe) {
|
||||||
|
}
|
||||||
|
c1 = count;
|
||||||
|
// Force the compilation of m3() that will inline m1()
|
||||||
|
for (int i = 0; i < 20000; i++) {
|
||||||
|
m3(false, false);
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
// Force deoptimization of m3() in m1(), then return from m1()
|
||||||
|
// to m3(), call recursively m2(). If deoptimization correctly
|
||||||
|
// built the interpreter stack for m3()/m1() then we should be
|
||||||
|
// able to call m2() recursively as many times as before.
|
||||||
|
try {
|
||||||
|
m3(false, true);
|
||||||
|
} catch(StackOverflowError soe) {
|
||||||
|
}
|
||||||
|
if (c1 != count) {
|
||||||
|
System.out.println("Failed: init recursive calls: " + c1 + ". After deopt " + count);
|
||||||
|
System.exit(97);
|
||||||
|
} else {
|
||||||
|
System.out.println("PASSED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
hotspot/test/runtime/7107135/Test.java
Normal file
65
hotspot/test/runtime/7107135/Test.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2011 SAP AG. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
static boolean loadLib(String libName){
|
||||||
|
try {
|
||||||
|
System.loadLibrary(libName);
|
||||||
|
System.out.println("Loaded library "+ libName + ".");
|
||||||
|
return true;
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int counter = 1;
|
||||||
|
|
||||||
|
static int Runner() {
|
||||||
|
counter = counter * -1;
|
||||||
|
int i = counter;
|
||||||
|
if(counter < 2) counter += Runner();
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int run() {
|
||||||
|
try{
|
||||||
|
Runner();
|
||||||
|
} catch (StackOverflowError e) {
|
||||||
|
System.out.println("Caught stack overflow error.");
|
||||||
|
return 0;
|
||||||
|
} catch (OutOfMemoryError e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String argv[]) {
|
||||||
|
loadLib(argv[0]);
|
||||||
|
System.exit(run());
|
||||||
|
}
|
||||||
|
}
|
98
hotspot/test/runtime/7107135/Test7107135.sh
Normal file
98
hotspot/test/runtime/7107135/Test7107135.sh
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
# Copyright (c) 2011 SAP AG. All Rights Reserved.
|
||||||
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
#
|
||||||
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License version 2 only, as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
# version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
# accompanied this code).
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License version
|
||||||
|
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
# or visit www.oracle.com if you need additional information or have any
|
||||||
|
# questions.
|
||||||
|
#
|
||||||
|
|
||||||
|
##
|
||||||
|
## @test Test7107135.sh
|
||||||
|
## @bug 7107135
|
||||||
|
## @summary Stack guard pages lost after loading library with executable stack.
|
||||||
|
## @run shell Test7107135.sh
|
||||||
|
##
|
||||||
|
|
||||||
|
if [ "${TESTSRC}" = "" ]
|
||||||
|
then TESTSRC=.
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${TESTJAVA}" = "" ]
|
||||||
|
then
|
||||||
|
PARENT=`dirname \`which java\``
|
||||||
|
TESTJAVA=`dirname ${PARENT}`
|
||||||
|
echo "TESTJAVA not set, selecting " ${TESTJAVA}
|
||||||
|
echo "If this is incorrect, try setting the variable manually."
|
||||||
|
fi
|
||||||
|
|
||||||
|
BIT_FLAG=""
|
||||||
|
|
||||||
|
# set platform-dependent variables
|
||||||
|
OS=`uname -s`
|
||||||
|
case "$OS" in
|
||||||
|
Linux)
|
||||||
|
NULL=/dev/null
|
||||||
|
PS=":"
|
||||||
|
FS="/"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
NULL=NUL
|
||||||
|
PS=";"
|
||||||
|
FS="\\"
|
||||||
|
echo "Test passed; only valid for Linux"
|
||||||
|
exit 0;
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ARCH=`uname -m`
|
||||||
|
|
||||||
|
THIS_DIR=`pwd`
|
||||||
|
|
||||||
|
cp ${TESTSRC}${FS}*.java ${THIS_DIR}
|
||||||
|
${TESTJAVA}${FS}bin${FS}javac *.java
|
||||||
|
|
||||||
|
gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c
|
||||||
|
ld -shared -z execstack -o libtest-rwx.so test.o
|
||||||
|
ld -shared -z noexecstack -o libtest-rw.so test.o
|
||||||
|
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH=${THIS_DIR}
|
||||||
|
echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH}
|
||||||
|
export LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
# This should not fail.
|
||||||
|
echo Check testprogram. Expected to pass:
|
||||||
|
echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw
|
||||||
|
${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo Test changing of stack protection:
|
||||||
|
echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw
|
||||||
|
${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx
|
||||||
|
|
||||||
|
if [ "$?" == "0" ]
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx
|
||||||
|
${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $?
|
85
hotspot/test/runtime/7107135/TestMT.java
Normal file
85
hotspot/test/runtime/7107135/TestMT.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2011 SAP AG. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class TestMT {
|
||||||
|
|
||||||
|
static boolean loadLib(String libName) {
|
||||||
|
try {
|
||||||
|
System.loadLibrary(libName);
|
||||||
|
System.out.println("Loaded library "+ libName + ".");
|
||||||
|
return true;
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int counter = 1;
|
||||||
|
static int Runner() {
|
||||||
|
counter = counter * -1;
|
||||||
|
int i = counter;
|
||||||
|
if (counter < 2) counter += Runner();
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int run(String msg) {
|
||||||
|
try {
|
||||||
|
Runner();
|
||||||
|
} catch (StackOverflowError e) {
|
||||||
|
System.out.println(msg + " caught stack overflow error.");
|
||||||
|
return 0;
|
||||||
|
} catch (OutOfMemoryError e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String argv[]) {
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
Thread t = new DoStackOverflow("SpawnedThread " + i);
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
run("Main thread");
|
||||||
|
loadLib("test-rwx");
|
||||||
|
run("Main thread");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DoStackOverflow extends Thread {
|
||||||
|
public DoStackOverflow(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
TestMT.run(getName());
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
hotspot/test/runtime/7107135/test.c
Normal file
39
hotspot/test/runtime/7107135/test.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2011 SAP AG. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "jni.h"
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_Test_someMethod(JNIEnv *env, jobject mainObject) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
302
hotspot/test/runtime/8003985/Test8003985.java
Normal file
302
hotspot/test/runtime/8003985/Test8003985.java
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.Class;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import sun.misc.Contended;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8003985
|
||||||
|
* @summary Support Contended Annotation - JEP 142
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:-RestrictContended Test8003985
|
||||||
|
*/
|
||||||
|
public class Test8003985 {
|
||||||
|
|
||||||
|
private static final Unsafe U;
|
||||||
|
private static int ADDRESS_SIZE;
|
||||||
|
private static int HEADER_SIZE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
// steal Unsafe
|
||||||
|
try {
|
||||||
|
Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
unsafe.setAccessible(true);
|
||||||
|
U = (Unsafe) unsafe.get(null);
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When running with CompressedOops on 64-bit platform, the address size
|
||||||
|
// reported by Unsafe is still 8, while the real reference fields are 4 bytes long.
|
||||||
|
// Try to guess the reference field size with this naive trick.
|
||||||
|
try {
|
||||||
|
long off1 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj1"));
|
||||||
|
long off2 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj2"));
|
||||||
|
ADDRESS_SIZE = (int) Math.abs(off2 - off1);
|
||||||
|
HEADER_SIZE = (int) Math.min(off1, off2);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
ADDRESS_SIZE = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CompressedOopsClass {
|
||||||
|
public Object obj1;
|
||||||
|
public Object obj2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean arePaddedPairwise(Class klass, String field1, String field2) throws Exception {
|
||||||
|
Field f1 = klass.getDeclaredField(field1);
|
||||||
|
Field f2 = klass.getDeclaredField(field2);
|
||||||
|
|
||||||
|
if (isStatic(f1) != isStatic(f2)) {
|
||||||
|
return true; // these guys are in naturally disjoint locations
|
||||||
|
}
|
||||||
|
|
||||||
|
int diff = offset(f1) - offset(f2);
|
||||||
|
if (diff < 0) {
|
||||||
|
// f1 is first
|
||||||
|
return (offset(f2) - (offset(f1) + getSize(f1))) > 64;
|
||||||
|
} else {
|
||||||
|
// f2 is first
|
||||||
|
return (offset(f1) - (offset(f2) + getSize(f2))) > 64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPadded(Class klass, String field1) throws Exception {
|
||||||
|
Field f1 = klass.getDeclaredField(field1);
|
||||||
|
|
||||||
|
if (isStatic(f1)) {
|
||||||
|
return offset(f1) > 128 + 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset(f1) > 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean sameLayout(Class klass1, Class klass2) throws Exception {
|
||||||
|
for (Field f1 : klass1.getDeclaredFields()) {
|
||||||
|
Field f2 = klass2.getDeclaredField(f1.getName());
|
||||||
|
if (offset(f1) != offset(f2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Field f2 : klass1.getDeclaredFields()) {
|
||||||
|
Field f1 = klass2.getDeclaredField(f2.getName());
|
||||||
|
if (offset(f1) != offset(f2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isStatic(Field field) {
|
||||||
|
return Modifier.isStatic(field.getModifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int offset(Field field) {
|
||||||
|
if (isStatic(field)) {
|
||||||
|
return (int) U.staticFieldOffset(field);
|
||||||
|
} else {
|
||||||
|
return (int) U.objectFieldOffset(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getSize(Field field) {
|
||||||
|
Class type = field.getType();
|
||||||
|
if (type == byte.class) { return 1; }
|
||||||
|
if (type == boolean.class) { return 1; }
|
||||||
|
if (type == short.class) { return 2; }
|
||||||
|
if (type == char.class) { return 2; }
|
||||||
|
if (type == int.class) { return 4; }
|
||||||
|
if (type == float.class) { return 4; }
|
||||||
|
if (type == long.class) { return 8; }
|
||||||
|
if (type == double.class) { return 8; }
|
||||||
|
return ADDRESS_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
boolean endResult = true;
|
||||||
|
|
||||||
|
// --------------- INSTANCE FIELDS ---------------------
|
||||||
|
|
||||||
|
if (arePaddedPairwise(Test1.class, "int1", "int2") ||
|
||||||
|
isPadded(Test1.class, "int1") ||
|
||||||
|
isPadded(Test1.class, "int2")) {
|
||||||
|
System.err.println("Test1 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arePaddedPairwise(Test2.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test2.class, "int1") ||
|
||||||
|
isPadded(Test2.class, "int2")) {
|
||||||
|
System.err.println("Test2 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arePaddedPairwise(Test3.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test3.class, "int1") ||
|
||||||
|
!isPadded(Test3.class, "int2")) {
|
||||||
|
System.err.println("Test3 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arePaddedPairwise(Test4.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test4.class, "int1") ||
|
||||||
|
!isPadded(Test4.class, "int2")) {
|
||||||
|
System.err.println("Test4 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arePaddedPairwise(Test5.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test5.class, "int1") ||
|
||||||
|
!isPadded(Test5.class, "int2")) {
|
||||||
|
System.err.println("Test5 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arePaddedPairwise(Test6.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test6.class, "int1") ||
|
||||||
|
!isPadded(Test6.class, "int2")) {
|
||||||
|
System.err.println("Test6 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arePaddedPairwise(Test7.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test7.class, "int1") ||
|
||||||
|
!isPadded(Test7.class, "int2")) {
|
||||||
|
System.err.println("Test7 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arePaddedPairwise(Test8.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test8.class, "int1") ||
|
||||||
|
!isPadded(Test8.class, "int2")) {
|
||||||
|
System.err.println("Test8 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arePaddedPairwise(Test9.class, "int1", "int2") ||
|
||||||
|
!isPadded(Test9.class, "int1") ||
|
||||||
|
!isPadded(Test9.class, "int2")) {
|
||||||
|
System.err.println("Test9 failed");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sameLayout(Test4.class, Test7.class)) {
|
||||||
|
System.err.println("Test4 and Test7 have different layouts");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sameLayout(Test5.class, Test6.class)) {
|
||||||
|
System.err.println("Test5 and Test6 have different layouts");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sameLayout(Test8.class, Test9.class)) {
|
||||||
|
System.err.println("Test8 and Test9 have different layouts");
|
||||||
|
endResult &= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(endResult ? "Test PASSES" : "Test FAILS");
|
||||||
|
if (!endResult) {
|
||||||
|
throw new Error("Test failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------- INSTANCE FIELDS -----------------------------------------
|
||||||
|
|
||||||
|
// naturally packed
|
||||||
|
public static class Test1 {
|
||||||
|
private int int1;
|
||||||
|
private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int1 is padded
|
||||||
|
public static class Test2 {
|
||||||
|
@Contended private int int1;
|
||||||
|
private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// both fields are padded
|
||||||
|
public static class Test3 {
|
||||||
|
@Contended private int int1;
|
||||||
|
@Contended private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fields are padded in the singular group
|
||||||
|
public static class Test4 {
|
||||||
|
@Contended("sameGroup") private int int1;
|
||||||
|
@Contended("sameGroup") private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fields are padded in disjoint groups
|
||||||
|
public static class Test5 {
|
||||||
|
@Contended("diffGroup1") private int int1;
|
||||||
|
@Contended("diffGroup2") private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fields are padded in disjoint groups
|
||||||
|
public static class Test6 {
|
||||||
|
@Contended private int int1;
|
||||||
|
@Contended("diffGroup2") private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fields are padded in the singular group
|
||||||
|
@Contended
|
||||||
|
public static class Test7 {
|
||||||
|
private int int1;
|
||||||
|
private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all fields are padded as the group, and one field is padded specifically
|
||||||
|
@Contended
|
||||||
|
public static class Test8 {
|
||||||
|
@Contended private int int1;
|
||||||
|
private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all fields are padded as the group, and one field is padded specifically
|
||||||
|
@Contended
|
||||||
|
public static class Test9 {
|
||||||
|
@Contended("group") private int int1;
|
||||||
|
private int int2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user