Merge
This commit is contained in:
commit
c2c3f0fe72
hotspot
build/windows/makefiles
src
@ -44,6 +44,10 @@ CPP=cl.exe
|
|||||||
# /Od Disable all optimizations
|
# /Od Disable all optimizations
|
||||||
#
|
#
|
||||||
# NOTE: Normally following any of the above with a '-' will turn off that flag
|
# NOTE: Normally following any of the above with a '-' will turn off that flag
|
||||||
|
#
|
||||||
|
# 6655385: For VS2003/2005 we now specify /Oy- (disable frame pointer
|
||||||
|
# omission.) This has little to no effect on performance while vastly
|
||||||
|
# improving the quality of crash log stack traces involving jvm.dll.
|
||||||
|
|
||||||
# These are always used in all compiles
|
# These are always used in all compiles
|
||||||
CPP_FLAGS=/nologo /W3 /WX
|
CPP_FLAGS=/nologo /W3 /WX
|
||||||
@ -141,14 +145,14 @@ DEBUG_OPT_OPTION = /Od
|
|||||||
!endif
|
!endif
|
||||||
|
|
||||||
!if "$(COMPILER_NAME)" == "VS2003"
|
!if "$(COMPILER_NAME)" == "VS2003"
|
||||||
PRODUCT_OPT_OPTION = /O2
|
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||||
FASTDEBUG_OPT_OPTION = /O2
|
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||||
DEBUG_OPT_OPTION = /Od
|
DEBUG_OPT_OPTION = /Od
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
!if "$(COMPILER_NAME)" == "VS2005"
|
!if "$(COMPILER_NAME)" == "VS2005"
|
||||||
PRODUCT_OPT_OPTION = /O2
|
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||||
FASTDEBUG_OPT_OPTION = /O2
|
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||||
DEBUG_OPT_OPTION = /Od
|
DEBUG_OPT_OPTION = /Od
|
||||||
GX_OPTION = /EHsc
|
GX_OPTION = /EHsc
|
||||||
# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
|
# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
|
||||||
@ -165,8 +169,8 @@ CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
|
|||||||
|
|
||||||
# Compile for space above time.
|
# Compile for space above time.
|
||||||
!if "$(Variant)" == "kernel"
|
!if "$(Variant)" == "kernel"
|
||||||
PRODUCT_OPT_OPTION = /O1
|
PRODUCT_OPT_OPTION = /O1 /Oy-
|
||||||
FASTDEBUG_OPT_OPTION = /O1
|
FASTDEBUG_OPT_OPTION = /O1 /Oy-
|
||||||
DEBUG_OPT_OPTION = /Od
|
DEBUG_OPT_OPTION = /Od
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
|
@ -1261,19 +1261,13 @@ jlong os::elapsed_frequency() {
|
|||||||
return (1000 * 1000);
|
return (1000 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong os::timeofday() {
|
jlong os::javaTimeMillis() {
|
||||||
timeval time;
|
timeval time;
|
||||||
int status = gettimeofday(&time, NULL);
|
int status = gettimeofday(&time, NULL);
|
||||||
assert(status != -1, "linux error");
|
assert(status != -1, "linux error");
|
||||||
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
|
|
||||||
// _use_global_time is only set if CacheTimeMillis is true
|
|
||||||
jlong os::javaTimeMillis() {
|
|
||||||
return (_use_global_time ? read_global_time() : timeofday());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CLOCK_MONOTONIC
|
#ifndef CLOCK_MONOTONIC
|
||||||
#define CLOCK_MONOTONIC (1)
|
#define CLOCK_MONOTONIC (1)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1691,19 +1691,14 @@ jlong getTimeMillis() {
|
|||||||
return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
|
return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong os::timeofday() {
|
// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
|
||||||
|
jlong os::javaTimeMillis() {
|
||||||
timeval t;
|
timeval t;
|
||||||
if (gettimeofday( &t, NULL) == -1)
|
if (gettimeofday( &t, NULL) == -1)
|
||||||
fatal1("timeofday: gettimeofday (%s)", strerror(errno));
|
fatal1("os::javaTimeMillis: gettimeofday (%s)", strerror(errno));
|
||||||
return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
|
return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
|
|
||||||
// _use_global_time is only set if CacheTimeMillis is true
|
|
||||||
jlong os::javaTimeMillis() {
|
|
||||||
return (_use_global_time ? read_global_time() : timeofday());
|
|
||||||
}
|
|
||||||
|
|
||||||
jlong os::javaTimeNanos() {
|
jlong os::javaTimeNanos() {
|
||||||
return (jlong)getTimeNanos();
|
return (jlong)getTimeNanos();
|
||||||
}
|
}
|
||||||
@ -2785,16 +2780,15 @@ char* os::Solaris::mmap_chunk(char *addr, size_t size, int flags, int prot) {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) {
|
||||||
os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
|
char* addr = requested_addr;
|
||||||
char* addr = NULL;
|
int flags = MAP_PRIVATE | MAP_NORESERVE;
|
||||||
int flags;
|
|
||||||
|
|
||||||
flags = MAP_PRIVATE | MAP_NORESERVE;
|
assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap");
|
||||||
if (requested_addr != NULL) {
|
|
||||||
flags |= MAP_FIXED;
|
if (fixed) {
|
||||||
addr = requested_addr;
|
flags |= MAP_FIXED;
|
||||||
} else if (has_map_align && alignment_hint > (size_t) vm_page_size()) {
|
} else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) {
|
||||||
flags |= MAP_ALIGN;
|
flags |= MAP_ALIGN;
|
||||||
addr = (char*) alignment_hint;
|
addr = (char*) alignment_hint;
|
||||||
}
|
}
|
||||||
@ -2802,11 +2796,14 @@ os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
|
|||||||
// Map uncommitted pages PROT_NONE so we fail early if we touch an
|
// Map uncommitted pages PROT_NONE so we fail early if we touch an
|
||||||
// uncommitted page. Otherwise, the read/write might succeed if we
|
// uncommitted page. Otherwise, the read/write might succeed if we
|
||||||
// have enough swap space to back the physical page.
|
// have enough swap space to back the physical page.
|
||||||
addr = Solaris::mmap_chunk(addr, bytes, flags, PROT_NONE);
|
return mmap_chunk(addr, bytes, flags, PROT_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
|
||||||
|
char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL));
|
||||||
|
|
||||||
guarantee(requested_addr == NULL || requested_addr == addr,
|
guarantee(requested_addr == NULL || requested_addr == addr,
|
||||||
"OS failed to return requested mmap address.");
|
"OS failed to return requested mmap address.");
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2832,6 +2829,31 @@ char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
|
|||||||
// in one of the methods further up the call chain. See bug 5044738.
|
// in one of the methods further up the call chain. See bug 5044738.
|
||||||
assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
|
assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
|
||||||
|
|
||||||
|
// Since snv_84, Solaris attempts to honor the address hint - see 5003415.
|
||||||
|
// Give it a try, if the kernel honors the hint we can return immediately.
|
||||||
|
char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false);
|
||||||
|
volatile int err = errno;
|
||||||
|
if (addr == requested_addr) {
|
||||||
|
return addr;
|
||||||
|
} else if (addr != NULL) {
|
||||||
|
unmap_memory(addr, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PrintMiscellaneous && Verbose) {
|
||||||
|
char buf[256];
|
||||||
|
buf[0] = '\0';
|
||||||
|
if (addr == NULL) {
|
||||||
|
jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
|
||||||
|
}
|
||||||
|
warning("attempt_reserve_memory_at: couldn't reserve %d bytes at "
|
||||||
|
PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
|
||||||
|
"%s", bytes, requested_addr, addr, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Address hint method didn't work. Fall back to the old method.
|
||||||
|
// In theory, once SNV becomes our oldest supported platform, this
|
||||||
|
// code will no longer be needed.
|
||||||
|
//
|
||||||
// Repeatedly allocate blocks until the block is allocated at the
|
// Repeatedly allocate blocks until the block is allocated at the
|
||||||
// right spot. Give up after max_tries.
|
// right spot. Give up after max_tries.
|
||||||
int i;
|
int i;
|
||||||
|
@ -156,6 +156,7 @@ class Solaris {
|
|||||||
static int get_dev_zero_fd() { return _dev_zero_fd; }
|
static int get_dev_zero_fd() { return _dev_zero_fd; }
|
||||||
static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; }
|
static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; }
|
||||||
static char* mmap_chunk(char *addr, size_t size, int flags, int prot);
|
static char* mmap_chunk(char *addr, size_t size, int flags, int prot);
|
||||||
|
static char* anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed);
|
||||||
static bool mpss_sanity_check(bool warn, size_t * page_size);
|
static bool mpss_sanity_check(bool warn, size_t * page_size);
|
||||||
static bool ism_sanity_check (bool warn, size_t * page_size);
|
static bool ism_sanity_check (bool warn, size_t * page_size);
|
||||||
|
|
||||||
|
@ -737,20 +737,13 @@ FILETIME java_to_windows_time(jlong l) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong os::timeofday() {
|
|
||||||
FILETIME wt;
|
|
||||||
GetSystemTimeAsFileTime(&wt);
|
|
||||||
return windows_to_java_time(wt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
|
|
||||||
// _use_global_time is only set if CacheTimeMillis is true
|
|
||||||
jlong os::javaTimeMillis() {
|
jlong os::javaTimeMillis() {
|
||||||
if (UseFakeTimers) {
|
if (UseFakeTimers) {
|
||||||
return fake_time++;
|
return fake_time++;
|
||||||
} else {
|
} else {
|
||||||
return (_use_global_time ? read_global_time() : timeofday());
|
FILETIME wt;
|
||||||
|
GetSystemTimeAsFileTime(&wt);
|
||||||
|
return windows_to_java_time(wt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1499,9 +1499,12 @@ bool DepChange::ContextStream::next() {
|
|||||||
// fall through:
|
// fall through:
|
||||||
_change_type = Change_new_sub;
|
_change_type = Change_new_sub;
|
||||||
case Change_new_sub:
|
case Change_new_sub:
|
||||||
_klass = instanceKlass::cast(_klass)->super();
|
// 6598190: brackets workaround Sun Studio C++ compiler bug 6629277
|
||||||
if (_klass != NULL) {
|
{
|
||||||
return true;
|
_klass = instanceKlass::cast(_klass)->super();
|
||||||
|
if (_klass != NULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// else set up _ti_limit and fall through:
|
// else set up _ti_limit and fall through:
|
||||||
_ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length();
|
_ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length();
|
||||||
|
@ -1279,12 +1279,10 @@ void Arguments::set_aggressive_opts_flags() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (AggressiveOpts) {
|
if (AggressiveOpts) {
|
||||||
NOT_WINDOWS(
|
// Sample flag setting code
|
||||||
// No measured benefit on Windows
|
// if (FLAG_IS_DEFAULT(EliminateZeroing)) {
|
||||||
if (FLAG_IS_DEFAULT(CacheTimeMillis)) {
|
// FLAG_SET_DEFAULT(EliminateZeroing, true);
|
||||||
FLAG_SET_DEFAULT(CacheTimeMillis, true);
|
// }
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,11 @@ static void enable_biased_locking(klassOop k) {
|
|||||||
|
|
||||||
class VM_EnableBiasedLocking: public VM_Operation {
|
class VM_EnableBiasedLocking: public VM_Operation {
|
||||||
public:
|
public:
|
||||||
VM_EnableBiasedLocking() {}
|
VM_EnableBiasedLocking() {}
|
||||||
VMOp_Type type() const { return VMOp_EnableBiasedLocking; }
|
VMOp_Type type() const { return VMOp_EnableBiasedLocking; }
|
||||||
|
Mode evaluation_mode() const { return _async_safepoint; }
|
||||||
|
bool is_cheap_allocated() const { return true; }
|
||||||
|
|
||||||
void doit() {
|
void doit() {
|
||||||
// Iterate the system dictionary enabling biased locking for all
|
// Iterate the system dictionary enabling biased locking for all
|
||||||
// currently loaded classes
|
// currently loaded classes
|
||||||
@ -62,8 +65,10 @@ class EnableBiasedLockingTask : public PeriodicTask {
|
|||||||
EnableBiasedLockingTask(size_t interval_time) : PeriodicTask(interval_time) {}
|
EnableBiasedLockingTask(size_t interval_time) : PeriodicTask(interval_time) {}
|
||||||
|
|
||||||
virtual void task() {
|
virtual void task() {
|
||||||
VM_EnableBiasedLocking op;
|
// Use async VM operation to avoid blocking the Watcher thread.
|
||||||
VMThread::execute(&op);
|
// VM Thread will free C heap storage.
|
||||||
|
VM_EnableBiasedLocking *op = new VM_EnableBiasedLocking();
|
||||||
|
VMThread::execute(op);
|
||||||
|
|
||||||
// Reclaim our storage and disenroll ourself
|
// Reclaim our storage and disenroll ourself
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -344,12 +344,6 @@ class CommandLineFlags {
|
|||||||
product(bool, ForceTimeHighResolution, false, \
|
product(bool, ForceTimeHighResolution, false, \
|
||||||
"Using high time resolution(For Win32 only)") \
|
"Using high time resolution(For Win32 only)") \
|
||||||
\
|
\
|
||||||
product(bool, CacheTimeMillis, false, \
|
|
||||||
"Cache os::javaTimeMillis with CacheTimeMillisGranularity") \
|
|
||||||
\
|
|
||||||
diagnostic(uintx, CacheTimeMillisGranularity, 50, \
|
|
||||||
"Granularity for CacheTimeMillis") \
|
|
||||||
\
|
|
||||||
develop(bool, TraceItables, false, \
|
develop(bool, TraceItables, false, \
|
||||||
"Trace initialization and use of itables") \
|
"Trace initialization and use of itables") \
|
||||||
\
|
\
|
||||||
|
@ -390,11 +390,6 @@ void before_exit(JavaThread * thread) {
|
|||||||
StatSampler::disengage();
|
StatSampler::disengage();
|
||||||
StatSampler::destroy();
|
StatSampler::destroy();
|
||||||
|
|
||||||
// shut down the TimeMillisUpdateTask
|
|
||||||
if (CacheTimeMillis) {
|
|
||||||
TimeMillisUpdateTask::disengage();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SERIALGC
|
#ifndef SERIALGC
|
||||||
// stop CMS threads
|
// stop CMS threads
|
||||||
if (UseConcMarkSweepGC) {
|
if (UseConcMarkSweepGC) {
|
||||||
|
@ -1119,10 +1119,15 @@ Monitor::~Monitor() {
|
|||||||
assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ;
|
assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Monitor::ClearMonitor (Monitor * m) {
|
void Monitor::ClearMonitor (Monitor * m, const char *name) {
|
||||||
m->_owner = NULL ;
|
m->_owner = NULL ;
|
||||||
m->_snuck = false ;
|
m->_snuck = false ;
|
||||||
m->_name = "UNKNOWN" ;
|
if (name == NULL) {
|
||||||
|
strcpy(m->_name, "UNKNOWN") ;
|
||||||
|
} else {
|
||||||
|
strncpy(m->_name, name, MONITOR_NAME_LEN - 1);
|
||||||
|
m->_name[MONITOR_NAME_LEN - 1] = '\0';
|
||||||
|
}
|
||||||
m->_LockWord.FullWord = 0 ;
|
m->_LockWord.FullWord = 0 ;
|
||||||
m->_EntryList = NULL ;
|
m->_EntryList = NULL ;
|
||||||
m->_OnDeck = NULL ;
|
m->_OnDeck = NULL ;
|
||||||
@ -1133,7 +1138,7 @@ void Monitor::ClearMonitor (Monitor * m) {
|
|||||||
Monitor::Monitor() { ClearMonitor(this); }
|
Monitor::Monitor() { ClearMonitor(this); }
|
||||||
|
|
||||||
Monitor::Monitor (int Rank, const char * name, bool allow_vm_block) {
|
Monitor::Monitor (int Rank, const char * name, bool allow_vm_block) {
|
||||||
ClearMonitor (this) ;
|
ClearMonitor (this, name) ;
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
_allow_vm_block = allow_vm_block;
|
_allow_vm_block = allow_vm_block;
|
||||||
_rank = Rank ;
|
_rank = Rank ;
|
||||||
@ -1145,7 +1150,7 @@ Mutex::~Mutex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Mutex (int Rank, const char * name, bool allow_vm_block) {
|
Mutex::Mutex (int Rank, const char * name, bool allow_vm_block) {
|
||||||
ClearMonitor ((Monitor *) this) ;
|
ClearMonitor ((Monitor *) this, name) ;
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
_allow_vm_block = allow_vm_block;
|
_allow_vm_block = allow_vm_block;
|
||||||
_rank = Rank ;
|
_rank = Rank ;
|
||||||
|
@ -82,6 +82,9 @@ class ParkEvent ;
|
|||||||
// *in that order*. If their implementations change such that these
|
// *in that order*. If their implementations change such that these
|
||||||
// assumptions are violated, a whole lot of code will break.
|
// assumptions are violated, a whole lot of code will break.
|
||||||
|
|
||||||
|
// The default length of monitor name is choosen to be 64 to avoid false sharing.
|
||||||
|
static const int MONITOR_NAME_LEN = 64;
|
||||||
|
|
||||||
class Monitor : public CHeapObj {
|
class Monitor : public CHeapObj {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -126,9 +129,8 @@ class Monitor : public CHeapObj {
|
|||||||
volatile intptr_t _WaitLock [1] ; // Protects _WaitSet
|
volatile intptr_t _WaitLock [1] ; // Protects _WaitSet
|
||||||
ParkEvent * volatile _WaitSet ; // LL of ParkEvents
|
ParkEvent * volatile _WaitSet ; // LL of ParkEvents
|
||||||
volatile bool _snuck; // Used for sneaky locking (evil).
|
volatile bool _snuck; // Used for sneaky locking (evil).
|
||||||
const char * _name; // Name of mutex
|
|
||||||
int NotifyCount ; // diagnostic assist
|
int NotifyCount ; // diagnostic assist
|
||||||
double pad [8] ; // avoid false sharing
|
char _name[MONITOR_NAME_LEN]; // Name of mutex
|
||||||
|
|
||||||
// Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
|
// Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
@ -170,7 +172,7 @@ class Monitor : public CHeapObj {
|
|||||||
int ILocked () ;
|
int ILocked () ;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void ClearMonitor (Monitor * m) ;
|
static void ClearMonitor (Monitor * m, const char* name = NULL) ;
|
||||||
Monitor() ;
|
Monitor() ;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -188,10 +188,6 @@ void mutex_init() {
|
|||||||
|
|
||||||
def(Safepoint_lock , Monitor, safepoint, true ); // locks SnippetCache_lock/Threads_lock
|
def(Safepoint_lock , Monitor, safepoint, true ); // locks SnippetCache_lock/Threads_lock
|
||||||
|
|
||||||
if (!UseMembar) {
|
|
||||||
def(SerializePage_lock , Monitor, leaf, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
def(Threads_lock , Monitor, barrier, true );
|
def(Threads_lock , Monitor, barrier, true );
|
||||||
|
|
||||||
def(VMOperationQueue_lock , Monitor, nonleaf, true ); // VM_thread allowed to block on these
|
def(VMOperationQueue_lock , Monitor, nonleaf, true ); // VM_thread allowed to block on these
|
||||||
|
@ -52,7 +52,6 @@ extern Mutex* DerivedPointerTableGC_lock; // a lock to protect the derive
|
|||||||
extern Monitor* VMOperationQueue_lock; // a lock on queue of vm_operations waiting to execute
|
extern Monitor* VMOperationQueue_lock; // a lock on queue of vm_operations waiting to execute
|
||||||
extern Monitor* VMOperationRequest_lock; // a lock on Threads waiting for a vm_operation to terminate
|
extern Monitor* VMOperationRequest_lock; // a lock on Threads waiting for a vm_operation to terminate
|
||||||
extern Monitor* Safepoint_lock; // a lock used by the safepoint abstraction
|
extern Monitor* Safepoint_lock; // a lock used by the safepoint abstraction
|
||||||
extern Monitor* SerializePage_lock; // a lock used when VMThread changing serialize memory page permission during safepoint
|
|
||||||
extern Monitor* Threads_lock; // a lock on the Threads table of active Java threads
|
extern Monitor* Threads_lock; // a lock on the Threads table of active Java threads
|
||||||
// (also used by Safepoints too to block threads creation/destruction)
|
// (also used by Safepoints too to block threads creation/destruction)
|
||||||
extern Monitor* CGC_lock; // used for coordination between
|
extern Monitor* CGC_lock; // used for coordination between
|
||||||
|
@ -33,9 +33,6 @@ volatile int32_t* os::_mem_serialize_page = NULL;
|
|||||||
uintptr_t os::_serialize_page_mask = 0;
|
uintptr_t os::_serialize_page_mask = 0;
|
||||||
long os::_rand_seed = 1;
|
long os::_rand_seed = 1;
|
||||||
int os::_processor_count = 0;
|
int os::_processor_count = 0;
|
||||||
volatile jlong os::_global_time = 0;
|
|
||||||
volatile int os::_global_time_lock = 0;
|
|
||||||
bool os::_use_global_time = false;
|
|
||||||
size_t os::_page_sizes[os::page_sizes_max];
|
size_t os::_page_sizes[os::page_sizes_max];
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
@ -44,74 +41,6 @@ size_t os::alloc_bytes = 0; // # of bytes allocated
|
|||||||
int os::num_frees = 0; // # of calls to free
|
int os::num_frees = 0; // # of calls to free
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Atomic read of a jlong is assured by a seqlock; see update_global_time()
|
|
||||||
jlong os::read_global_time() {
|
|
||||||
#ifdef _LP64
|
|
||||||
return _global_time;
|
|
||||||
#else
|
|
||||||
volatile int lock;
|
|
||||||
volatile jlong current_time;
|
|
||||||
int ctr = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
lock = _global_time_lock;
|
|
||||||
|
|
||||||
// spin while locked
|
|
||||||
while ((lock & 0x1) != 0) {
|
|
||||||
++ctr;
|
|
||||||
if ((ctr & 0xFFF) == 0) {
|
|
||||||
// Guarantee writer progress. Can't use yield; yield is advisory
|
|
||||||
// and has almost no effect on some platforms. Don't need a state
|
|
||||||
// transition - the park call will return promptly.
|
|
||||||
assert(Thread::current() != NULL, "TLS not initialized");
|
|
||||||
assert(Thread::current()->_ParkEvent != NULL, "sync not initialized");
|
|
||||||
Thread::current()->_ParkEvent->park(1);
|
|
||||||
}
|
|
||||||
lock = _global_time_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderAccess::loadload();
|
|
||||||
current_time = _global_time;
|
|
||||||
OrderAccess::loadload();
|
|
||||||
|
|
||||||
// ratify seqlock value
|
|
||||||
if (lock == _global_time_lock) {
|
|
||||||
return current_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// NOTE - Assumes only one writer thread!
|
|
||||||
//
|
|
||||||
// We use a seqlock to guarantee that jlong _global_time is updated
|
|
||||||
// atomically on 32-bit platforms. A locked value is indicated by
|
|
||||||
// the lock variable LSB == 1. Readers will initially read the lock
|
|
||||||
// value, spinning until the LSB == 0. They then speculatively read
|
|
||||||
// the global time value, then re-read the lock value to ensure that
|
|
||||||
// it hasn't changed. If the lock value has changed, the entire read
|
|
||||||
// sequence is retried.
|
|
||||||
//
|
|
||||||
// Writers simply set the LSB = 1 (i.e. increment the variable),
|
|
||||||
// update the global time, then release the lock and bump the version
|
|
||||||
// number (i.e. increment the variable again.) In this case we don't
|
|
||||||
// even need a CAS since we ensure there's only one writer.
|
|
||||||
//
|
|
||||||
void os::update_global_time() {
|
|
||||||
#ifdef _LP64
|
|
||||||
_global_time = timeofday();
|
|
||||||
#else
|
|
||||||
assert((_global_time_lock & 0x1) == 0, "multiple writers?");
|
|
||||||
jlong current_time = timeofday();
|
|
||||||
_global_time_lock++; // lock
|
|
||||||
OrderAccess::storestore();
|
|
||||||
_global_time = current_time;
|
|
||||||
OrderAccess::storestore();
|
|
||||||
_global_time_lock++; // unlock
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in buffer with current local time as an ISO-8601 string.
|
// Fill in buffer with current local time as an ISO-8601 string.
|
||||||
// E.g., yyyy-mm-ddThh:mm:ss-zzzz.
|
// E.g., yyyy-mm-ddThh:mm:ss-zzzz.
|
||||||
// Returns buffer, or NULL if it failed.
|
// Returns buffer, or NULL if it failed.
|
||||||
@ -138,7 +67,7 @@ char* os::iso8601_time(char* buffer, size_t buffer_length) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// Get the current time
|
// Get the current time
|
||||||
jlong milliseconds_since_19700101 = timeofday();
|
jlong milliseconds_since_19700101 = javaTimeMillis();
|
||||||
const int milliseconds_per_microsecond = 1000;
|
const int milliseconds_per_microsecond = 1000;
|
||||||
const time_t seconds_since_19700101 =
|
const time_t seconds_since_19700101 =
|
||||||
milliseconds_since_19700101 / milliseconds_per_microsecond;
|
milliseconds_since_19700101 / milliseconds_per_microsecond;
|
||||||
@ -956,7 +885,6 @@ bool os::set_boot_path(char fileSep, char pathSep) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void os::set_memory_serialize_page(address page) {
|
void os::set_memory_serialize_page(address page) {
|
||||||
int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64);
|
int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64);
|
||||||
_mem_serialize_page = (volatile int32_t *)page;
|
_mem_serialize_page = (volatile int32_t *)page;
|
||||||
@ -967,6 +895,8 @@ void os::set_memory_serialize_page(address page) {
|
|||||||
set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t)));
|
set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static volatile intptr_t SerializePageLock = 0;
|
||||||
|
|
||||||
// This method is called from signal handler when SIGSEGV occurs while the current
|
// This method is called from signal handler when SIGSEGV occurs while the current
|
||||||
// thread tries to store to the "read-only" memory serialize page during state
|
// thread tries to store to the "read-only" memory serialize page during state
|
||||||
// transition.
|
// transition.
|
||||||
@ -974,15 +904,14 @@ void os::block_on_serialize_page_trap() {
|
|||||||
if (TraceSafepoint) {
|
if (TraceSafepoint) {
|
||||||
tty->print_cr("Block until the serialize page permission restored");
|
tty->print_cr("Block until the serialize page permission restored");
|
||||||
}
|
}
|
||||||
// When VMThread is holding the SerializePage_lock during modifying the
|
// When VMThread is holding the SerializePageLock during modifying the
|
||||||
// access permission of the memory serialize page, the following call
|
// access permission of the memory serialize page, the following call
|
||||||
// will block until the permission of that page is restored to rw.
|
// will block until the permission of that page is restored to rw.
|
||||||
// Generally, it is unsafe to manipulate locks in signal handlers, but in
|
// Generally, it is unsafe to manipulate locks in signal handlers, but in
|
||||||
// this case, it's OK as the signal is synchronous and we know precisely when
|
// this case, it's OK as the signal is synchronous and we know precisely when
|
||||||
// it can occur. SerializePage_lock is a transiently-held leaf lock, so
|
// it can occur.
|
||||||
// lock_without_safepoint_check should be safe.
|
Thread::muxAcquire(&SerializePageLock, "set_memory_serialize_page");
|
||||||
SerializePage_lock->lock_without_safepoint_check();
|
Thread::muxRelease(&SerializePageLock);
|
||||||
SerializePage_lock->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize all thread state variables
|
// Serialize all thread state variables
|
||||||
@ -990,14 +919,12 @@ void os::serialize_thread_states() {
|
|||||||
// On some platforms such as Solaris & Linux, the time duration of the page
|
// On some platforms such as Solaris & Linux, the time duration of the page
|
||||||
// permission restoration is observed to be much longer than expected due to
|
// permission restoration is observed to be much longer than expected due to
|
||||||
// scheduler starvation problem etc. To avoid the long synchronization
|
// scheduler starvation problem etc. To avoid the long synchronization
|
||||||
// time and expensive page trap spinning, 'SerializePage_lock' is used to block
|
// time and expensive page trap spinning, 'SerializePageLock' is used to block
|
||||||
// the mutator thread if such case is encountered. Since this method is always
|
// the mutator thread if such case is encountered. See bug 6546278 for details.
|
||||||
// called by VMThread during safepoint, lock_without_safepoint_check is used
|
Thread::muxAcquire(&SerializePageLock, "serialize_thread_states");
|
||||||
// instead. See bug 6546278.
|
|
||||||
SerializePage_lock->lock_without_safepoint_check();
|
|
||||||
os::protect_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
|
os::protect_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
|
||||||
os::unguard_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
|
os::unguard_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
|
||||||
SerializePage_lock->unlock();
|
Thread::muxRelease(&SerializePageLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the current stack pointer is above the stack shadow
|
// Returns true if the current stack pointer is above the stack shadow
|
||||||
|
@ -66,9 +66,6 @@ class os: AllStatic {
|
|||||||
static address _polling_page;
|
static address _polling_page;
|
||||||
static volatile int32_t * _mem_serialize_page;
|
static volatile int32_t * _mem_serialize_page;
|
||||||
static uintptr_t _serialize_page_mask;
|
static uintptr_t _serialize_page_mask;
|
||||||
static volatile jlong _global_time;
|
|
||||||
static volatile int _global_time_lock;
|
|
||||||
static bool _use_global_time;
|
|
||||||
static size_t _page_sizes[page_sizes_max];
|
static size_t _page_sizes[page_sizes_max];
|
||||||
|
|
||||||
static void init_page_sizes(size_t default_page_size) {
|
static void init_page_sizes(size_t default_page_size) {
|
||||||
@ -88,11 +85,6 @@ class os: AllStatic {
|
|||||||
static bool getenv(const char* name, char* buffer, int len);
|
static bool getenv(const char* name, char* buffer, int len);
|
||||||
static bool have_special_privileges();
|
static bool have_special_privileges();
|
||||||
|
|
||||||
static jlong timeofday();
|
|
||||||
static void enable_global_time() { _use_global_time = true; }
|
|
||||||
static void disable_global_time() { _use_global_time = false; }
|
|
||||||
static jlong read_global_time();
|
|
||||||
static void update_global_time();
|
|
||||||
static jlong javaTimeMillis();
|
static jlong javaTimeMillis();
|
||||||
static jlong javaTimeNanos();
|
static jlong javaTimeNanos();
|
||||||
static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
|
static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
|
||||||
|
@ -1486,11 +1486,9 @@ char* SharedRuntime::generate_class_cast_message(
|
|||||||
const char* desc = " cannot be cast to ";
|
const char* desc = " cannot be cast to ";
|
||||||
size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1;
|
size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1;
|
||||||
|
|
||||||
char* message = NEW_C_HEAP_ARRAY(char, msglen);
|
char* message = NEW_RESOURCE_ARRAY(char, msglen);
|
||||||
if (NULL == message) {
|
if (NULL == message) {
|
||||||
// out of memory - can't use a detailed message. Since caller is
|
// Shouldn't happen, but don't cause even more problems if it does
|
||||||
// using a resource mark to free memory, returning this should be
|
|
||||||
// safe (caller won't explicitly delete it).
|
|
||||||
message = const_cast<char*>(objName);
|
message = const_cast<char*>(objName);
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(message, msglen, "%s%s%s", objName, desc, targetKlassName);
|
jio_snprintf(message, msglen, "%s%s%s", objName, desc, targetKlassName);
|
||||||
|
@ -107,25 +107,3 @@ void PeriodicTask::disenroll() {
|
|||||||
_tasks[index] = _tasks[index+1];
|
_tasks[index] = _tasks[index+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeMillisUpdateTask* TimeMillisUpdateTask::_task = NULL;
|
|
||||||
|
|
||||||
void TimeMillisUpdateTask::task() {
|
|
||||||
os::update_global_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeMillisUpdateTask::engage() {
|
|
||||||
assert(_task == NULL, "init twice?");
|
|
||||||
os::update_global_time(); // initial update
|
|
||||||
os::enable_global_time();
|
|
||||||
_task = new TimeMillisUpdateTask(CacheTimeMillisGranularity);
|
|
||||||
_task->enroll();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeMillisUpdateTask::disengage() {
|
|
||||||
assert(_task != NULL, "uninit twice?");
|
|
||||||
os::disable_global_time();
|
|
||||||
_task->disenroll();
|
|
||||||
delete _task;
|
|
||||||
_task = NULL;
|
|
||||||
}
|
|
||||||
|
@ -113,13 +113,3 @@ class PeriodicTask: public CHeapObj {
|
|||||||
// The task to perform at each period
|
// The task to perform at each period
|
||||||
virtual void task() = 0;
|
virtual void task() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimeMillisUpdateTask : public PeriodicTask {
|
|
||||||
private:
|
|
||||||
static TimeMillisUpdateTask* _task;
|
|
||||||
public:
|
|
||||||
TimeMillisUpdateTask(int interval) : PeriodicTask(interval) {}
|
|
||||||
void task();
|
|
||||||
static void engage();
|
|
||||||
static void disengage();
|
|
||||||
};
|
|
||||||
|
@ -3085,7 +3085,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
|||||||
if (MemProfiling) MemProfiler::engage();
|
if (MemProfiling) MemProfiler::engage();
|
||||||
StatSampler::engage();
|
StatSampler::engage();
|
||||||
if (CheckJNICalls) JniPeriodicChecker::engage();
|
if (CheckJNICalls) JniPeriodicChecker::engage();
|
||||||
if (CacheTimeMillis) TimeMillisUpdateTask::engage();
|
|
||||||
|
|
||||||
BiasedLocking::init();
|
BiasedLocking::init();
|
||||||
|
|
||||||
|
@ -170,7 +170,8 @@ static void print_bug_submit_message(outputStream *out, Thread *thread) {
|
|||||||
out->print_raw_cr(Arguments::java_vendor_url_bug());
|
out->print_raw_cr(Arguments::java_vendor_url_bug());
|
||||||
// If the crash is in native code, encourage user to submit a bug to the
|
// If the crash is in native code, encourage user to submit a bug to the
|
||||||
// provider of that code.
|
// provider of that code.
|
||||||
if (thread && thread->is_Java_thread()) {
|
if (thread && thread->is_Java_thread() &&
|
||||||
|
!thread->is_hidden_from_external_view()) {
|
||||||
JavaThread* jt = (JavaThread*)thread;
|
JavaThread* jt = (JavaThread*)thread;
|
||||||
if (jt->thread_state() == _thread_in_native) {
|
if (jt->thread_state() == _thread_in_native) {
|
||||||
out->print_cr("# The crash happened outside the Java Virtual Machine in native code.\n# See problematic frame for where to report the bug.");
|
out->print_cr("# The crash happened outside the Java Virtual Machine in native code.\n# See problematic frame for where to report the bug.");
|
||||||
@ -249,10 +250,10 @@ void VMError::report(outputStream* st) {
|
|||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
STEP(10, "(printing unexpected error message)")
|
STEP(10, "(printing fatal error message)")
|
||||||
|
|
||||||
st->print_cr("#");
|
st->print_cr("#");
|
||||||
st->print_cr("# An unexpected error has been detected by Java Runtime Environment:");
|
st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
|
||||||
|
|
||||||
STEP(15, "(printing type of error)")
|
STEP(15, "(printing type of error)")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user