# HG changeset patch # User kmo # Date 1359047176 28800 # Node ID 274a29bf56828919a367f950b80053b67463b6f6 # Parent d754ef7b93526aeaa202db236f268ccb9801b049# Parent 22ead76da3f470a4a6a0b8bd82488c731b0e630c Merge diff -r 22ead76da3f4 -r 274a29bf5682 agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Thu Jan 24 02:03:38 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Thu Jan 24 09:06:16 2013 -0800 @@ -53,6 +53,7 @@ private static int HIGH_OFFSET; private static int FIELD_SLOTS; private static short FIELDINFO_TAG_SIZE; + private static short FIELDINFO_TAG_MASK; private static short FIELDINFO_TAG_OFFSET; // ClassState constants @@ -102,6 +103,7 @@ HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue(); FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue(); FIELDINFO_TAG_SIZE = db.lookupIntConstant("FIELDINFO_TAG_SIZE").shortValue(); + FIELDINFO_TAG_MASK = db.lookupIntConstant("FIELDINFO_TAG_MASK").shortValue(); FIELDINFO_TAG_OFFSET = db.lookupIntConstant("FIELDINFO_TAG_OFFSET").shortValue(); // read ClassState constants @@ -321,7 +323,7 @@ U2Array fields = getFields(); short lo = fields.at(index * FIELD_SLOTS + LOW_OFFSET); short hi = fields.at(index * FIELD_SLOTS + HIGH_OFFSET); - if ((lo & FIELDINFO_TAG_SIZE) == FIELDINFO_TAG_OFFSET) { + if ((lo & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET) { return VM.getVM().buildIntFromShorts(lo, hi) >> FIELDINFO_TAG_SIZE; } throw new RuntimeException("should not reach here"); diff -r 22ead76da3f4 -r 274a29bf5682 make/bsd/makefiles/mapfile-vers-debug --- a/make/bsd/makefiles/mapfile-vers-debug Thu Jan 24 02:03:38 2013 -0800 +++ b/make/bsd/makefiles/mapfile-vers-debug Thu Jan 24 09:06:16 2013 -0800 @@ -3,7 +3,7 @@ # # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 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 @@ -205,7 +205,6 @@ JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff -r 22ead76da3f4 -r 274a29bf5682 make/bsd/makefiles/mapfile-vers-product --- a/make/bsd/makefiles/mapfile-vers-product Thu Jan 24 02:03:38 2013 -0800 +++ b/make/bsd/makefiles/mapfile-vers-product Thu Jan 24 09:06:16 2013 -0800 @@ -3,7 +3,7 @@ # # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 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 @@ -205,7 +205,6 @@ JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff -r 22ead76da3f4 -r 274a29bf5682 make/linux/makefiles/mapfile-vers-debug --- a/make/linux/makefiles/mapfile-vers-debug Thu Jan 24 02:03:38 2013 -0800 +++ b/make/linux/makefiles/mapfile-vers-debug Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 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 @@ -201,7 +201,6 @@ JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff -r 22ead76da3f4 -r 274a29bf5682 make/linux/makefiles/mapfile-vers-product --- a/make/linux/makefiles/mapfile-vers-product Thu Jan 24 02:03:38 2013 -0800 +++ b/make/linux/makefiles/mapfile-vers-product Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 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 @@ -201,7 +201,6 @@ JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff -r 22ead76da3f4 -r 274a29bf5682 make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Thu Jan 24 02:03:38 2013 -0800 +++ b/make/solaris/makefiles/mapfile-vers Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 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 @@ -201,7 +201,6 @@ JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff -r 22ead76da3f4 -r 274a29bf5682 src/cpu/x86/vm/jni_x86.h --- a/src/cpu/x86/vm/jni_x86.h Thu Jan 24 02:03:38 2013 -0800 +++ b/src/cpu/x86/vm/jni_x86.h Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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. * * This code is free software; you can redistribute it and/or modify it @@ -38,14 +38,9 @@ #define JNICALL typedef int jint; -#if defined(_LP64) && !defined(__APPLE__) +#if defined(_LP64) typedef long jlong; #else - /* - * On _LP64 __APPLE__ "long" and "long long" are both 64 bits, - * but we use the "long long" typedef to avoid complaints from - * the __APPLE__ compiler about fprintf formats. - */ typedef long long jlong; #endif diff -r 22ead76da3f4 -r 274a29bf5682 src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/bsd/vm/os_bsd.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -243,29 +243,32 @@ int mib[2]; size_t len; int cpu_val; - u_long mem_val; + julong mem_val; /* get processors count via hw.ncpus sysctl */ mib[0] = CTL_HW; mib[1] = HW_NCPU; len = sizeof(cpu_val); if (sysctl(mib, 2, &cpu_val, &len, NULL, 0) != -1 && cpu_val >= 1) { + assert(len == sizeof(cpu_val), "unexpected data size"); set_processor_count(cpu_val); } else { set_processor_count(1); // fallback } - /* get physical memory via hw.usermem sysctl (hw.usermem is used - * instead of hw.physmem because we need size of allocatable memory + /* get physical memory via hw.memsize sysctl (hw.memsize is used + * since it returns a 64 bit value) */ mib[0] = CTL_HW; - mib[1] = HW_USERMEM; + mib[1] = HW_MEMSIZE; len = sizeof(mem_val); - if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) + if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) { + assert(len == sizeof(mem_val), "unexpected data size"); _physical_memory = mem_val; - else + } else { _physical_memory = 256*1024*1024; // fallback (XXXBSD?) + } #ifdef __OpenBSD__ { @@ -4091,11 +4094,12 @@ } -- _nParked ; - // In theory we could move the ST of 0 into _Event past the unlock(), - // but then we'd need a MEMBAR after the ST. _Event = 0 ; status = pthread_mutex_unlock(_mutex); assert_status(status == 0, status, "mutex_unlock"); + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other. + OrderAccess::fence(); } guarantee (_Event >= 0, "invariant") ; } @@ -4158,40 +4162,44 @@ status = pthread_mutex_unlock(_mutex); assert_status(status == 0, status, "mutex_unlock"); assert (_nParked == 0, "invariant") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other. + OrderAccess::fence(); return ret; } void os::PlatformEvent::unpark() { - int v, AnyWaiters ; - for (;;) { - v = _Event ; - if (v > 0) { - // The LD of _Event could have reordered or be satisfied - // by a read-aside from this processor's write buffer. - // To avoid problems execute a barrier and then - // ratify the value. - OrderAccess::fence() ; - if (_Event == v) return ; - continue ; - } - if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; + // Transitions for _Event: + // 0 :=> 1 + // 1 :=> 1 + // -1 :=> either 0 or 1; must signal target thread + // That is, we can safely transition _Event from -1 to either + // 0 or 1. Forcing 1 is slightly more efficient for back-to-back + // unpark() calls. + // See also: "Semaphores in Plan 9" by Mullender & Cox + // + // Note: Forcing a transition from "-1" to "1" on an unpark() means + // that it will take two back-to-back park() calls for the owning + // thread to block. This has the benefit of forcing a spurious return + // from the first park() call after an unpark() call which will help + // shake out uses of park() and unpark() without condition variables. + + if (Atomic::xchg(1, &_Event) >= 0) return; + + // Wait for the thread associated with the event to vacate + int status = pthread_mutex_lock(_mutex); + assert_status(status == 0, status, "mutex_lock"); + int AnyWaiters = _nParked; + assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); + if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { + AnyWaiters = 0; + pthread_cond_signal(_cond); } - if (v < 0) { - // Wait for the thread associated with the event to vacate - int status = pthread_mutex_lock(_mutex); - assert_status(status == 0, status, "mutex_lock"); - AnyWaiters = _nParked ; - assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; - if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { - AnyWaiters = 0 ; - pthread_cond_signal (_cond); - } - status = pthread_mutex_unlock(_mutex); - assert_status(status == 0, status, "mutex_unlock"); - if (AnyWaiters != 0) { - status = pthread_cond_signal(_cond); - assert_status(status == 0, status, "cond_signal"); - } + status = pthread_mutex_unlock(_mutex); + assert_status(status == 0, status, "mutex_unlock"); + if (AnyWaiters != 0) { + status = pthread_cond_signal(_cond); + assert_status(status == 0, status, "cond_signal"); } // Note that we signal() _after dropping the lock for "immortal" Events. @@ -4277,13 +4285,14 @@ } void Parker::park(bool isAbsolute, jlong time) { + // Ideally we'd do something useful while spinning, such + // as calling unpackTime(). + // Optional fast-path check: // Return immediately if a permit is available. - if (_counter > 0) { - _counter = 0 ; - OrderAccess::fence(); - return ; - } + // We depend on Atomic::xchg() having full barrier semantics + // since we are doing a lock-free update to _counter. + if (Atomic::xchg(0, &_counter) > 0) return; Thread* thread = Thread::current(); assert(thread->is_Java_thread(), "Must be JavaThread"); @@ -4324,6 +4333,8 @@ _counter = 0; status = pthread_mutex_unlock(_mutex); assert (status == 0, "invariant") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other and Java-level accesses. OrderAccess::fence(); return; } @@ -4360,12 +4371,14 @@ _counter = 0 ; status = pthread_mutex_unlock(_mutex) ; assert_status(status == 0, status, "invariant") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other and Java-level accesses. + OrderAccess::fence(); + // If externally suspended while waiting, re-suspend if (jt->handle_special_suspend_equivalent_condition()) { jt->java_suspend_self(); } - - OrderAccess::fence(); } void Parker::unpark() { diff -r 22ead76da3f4 -r 274a29bf5682 src/os/bsd/vm/os_bsd.inline.hpp --- a/src/os/bsd/vm/os_bsd.inline.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/bsd/vm/os_bsd.inline.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -59,14 +59,6 @@ return ":"; } -inline const char* os::jlong_format_specifier() { - return "%lld"; -} - -inline const char* os::julong_format_specifier() { - return "%llu"; -} - // File names are case-sensitive on windows only inline int os::file_name_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); diff -r 22ead76da3f4 -r 274a29bf5682 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/linux/vm/os_linux.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -5001,11 +5001,12 @@ } -- _nParked ; - // In theory we could move the ST of 0 into _Event past the unlock(), - // but then we'd need a MEMBAR after the ST. _Event = 0 ; status = pthread_mutex_unlock(_mutex); assert_status(status == 0, status, "mutex_unlock"); + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other. + OrderAccess::fence(); } guarantee (_Event >= 0, "invariant") ; } @@ -5068,40 +5069,44 @@ status = pthread_mutex_unlock(_mutex); assert_status(status == 0, status, "mutex_unlock"); assert (_nParked == 0, "invariant") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other. + OrderAccess::fence(); return ret; } void os::PlatformEvent::unpark() { - int v, AnyWaiters ; - for (;;) { - v = _Event ; - if (v > 0) { - // The LD of _Event could have reordered or be satisfied - // by a read-aside from this processor's write buffer. - // To avoid problems execute a barrier and then - // ratify the value. - OrderAccess::fence() ; - if (_Event == v) return ; - continue ; - } - if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; - } - if (v < 0) { - // Wait for the thread associated with the event to vacate - int status = pthread_mutex_lock(_mutex); - assert_status(status == 0, status, "mutex_lock"); - AnyWaiters = _nParked ; - assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; - if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { - AnyWaiters = 0 ; - pthread_cond_signal (_cond); - } - status = pthread_mutex_unlock(_mutex); - assert_status(status == 0, status, "mutex_unlock"); - if (AnyWaiters != 0) { - status = pthread_cond_signal(_cond); - assert_status(status == 0, status, "cond_signal"); - } + // Transitions for _Event: + // 0 :=> 1 + // 1 :=> 1 + // -1 :=> either 0 or 1; must signal target thread + // That is, we can safely transition _Event from -1 to either + // 0 or 1. Forcing 1 is slightly more efficient for back-to-back + // unpark() calls. + // See also: "Semaphores in Plan 9" by Mullender & Cox + // + // Note: Forcing a transition from "-1" to "1" on an unpark() means + // that it will take two back-to-back park() calls for the owning + // thread to block. This has the benefit of forcing a spurious return + // from the first park() call after an unpark() call which will help + // shake out uses of park() and unpark() without condition variables. + + if (Atomic::xchg(1, &_Event) >= 0) return; + + // Wait for the thread associated with the event to vacate + int status = pthread_mutex_lock(_mutex); + assert_status(status == 0, status, "mutex_lock"); + int AnyWaiters = _nParked; + assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); + if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { + AnyWaiters = 0; + pthread_cond_signal(_cond); + } + status = pthread_mutex_unlock(_mutex); + assert_status(status == 0, status, "mutex_unlock"); + if (AnyWaiters != 0) { + status = pthread_cond_signal(_cond); + assert_status(status == 0, status, "cond_signal"); } // Note that we signal() _after dropping the lock for "immortal" Events. @@ -5187,13 +5192,14 @@ } void Parker::park(bool isAbsolute, jlong time) { + // Ideally we'd do something useful while spinning, such + // as calling unpackTime(). + // Optional fast-path check: // Return immediately if a permit is available. - if (_counter > 0) { - _counter = 0 ; - OrderAccess::fence(); - return ; - } + // We depend on Atomic::xchg() having full barrier semantics + // since we are doing a lock-free update to _counter. + if (Atomic::xchg(0, &_counter) > 0) return; Thread* thread = Thread::current(); assert(thread->is_Java_thread(), "Must be JavaThread"); @@ -5234,6 +5240,8 @@ _counter = 0; status = pthread_mutex_unlock(_mutex); assert (status == 0, "invariant") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other and Java-level accesses. OrderAccess::fence(); return; } @@ -5270,12 +5278,14 @@ _counter = 0 ; status = pthread_mutex_unlock(_mutex) ; assert_status(status == 0, status, "invariant") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other and Java-level accesses. + OrderAccess::fence(); + // If externally suspended while waiting, re-suspend if (jt->handle_special_suspend_equivalent_condition()) { jt->java_suspend_self(); } - - OrderAccess::fence(); } void Parker::unpark() { diff -r 22ead76da3f4 -r 274a29bf5682 src/os/linux/vm/os_linux.inline.hpp --- a/src/os/linux/vm/os_linux.inline.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/linux/vm/os_linux.inline.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -68,14 +68,6 @@ return ":"; } -inline const char* os::jlong_format_specifier() { - return "%lld"; -} - -inline const char* os::julong_format_specifier() { - return "%llu"; -} - // File names are case-sensitive on windows only inline int os::file_name_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); diff -r 22ead76da3f4 -r 274a29bf5682 src/os/posix/launcher/java_md.c --- a/src/os/posix/launcher/java_md.c Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/posix/launcher/java_md.c Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1876,11 +1876,6 @@ } } -const char * -jlong_format_specifier() { - return "%lld"; -} - /* * Block current thread and continue execution in a new thread */ diff -r 22ead76da3f4 -r 274a29bf5682 src/os/posix/launcher/java_md.h --- a/src/os/posix/launcher/java_md.h Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/posix/launcher/java_md.h Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -64,6 +64,12 @@ #define Counter2Micros(counts) (1) #endif /* HAVE_GETHRTIME */ +#ifdef _LP64 +#define JLONG_FORMAT "%ld" +#else +#define JLONG_FORMAT "%lld" +#endif + /* * Function prototypes. */ diff -r 22ead76da3f4 -r 274a29bf5682 src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/solaris/vm/os_solaris.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -6014,6 +6014,9 @@ _Event = 0 ; status = os::Solaris::mutex_unlock(_mutex); assert_status(status == 0, status, "mutex_unlock"); + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other. + OrderAccess::fence(); } } @@ -6055,51 +6058,43 @@ _Event = 0 ; status = os::Solaris::mutex_unlock(_mutex); assert_status(status == 0, status, "mutex_unlock"); + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other. + OrderAccess::fence(); return ret; } void os::PlatformEvent::unpark() { - int v, AnyWaiters; - - // Increment _Event. - // Another acceptable implementation would be to simply swap 1 - // into _Event: - // if (Swap (&_Event, 1) < 0) { - // mutex_lock (_mutex) ; AnyWaiters = nParked; mutex_unlock (_mutex) ; - // if (AnyWaiters) cond_signal (_cond) ; - // } - - for (;;) { - v = _Event ; - if (v > 0) { - // The LD of _Event could have reordered or be satisfied - // by a read-aside from this processor's write buffer. - // To avoid problems execute a barrier and then - // ratify the value. A degenerate CAS() would also work. - // Viz., CAS (v+0, &_Event, v) == v). - OrderAccess::fence() ; - if (_Event == v) return ; - continue ; - } - if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; - } + // Transitions for _Event: + // 0 :=> 1 + // 1 :=> 1 + // -1 :=> either 0 or 1; must signal target thread + // That is, we can safely transition _Event from -1 to either + // 0 or 1. Forcing 1 is slightly more efficient for back-to-back + // unpark() calls. + // See also: "Semaphores in Plan 9" by Mullender & Cox + // + // Note: Forcing a transition from "-1" to "1" on an unpark() means + // that it will take two back-to-back park() calls for the owning + // thread to block. This has the benefit of forcing a spurious return + // from the first park() call after an unpark() call which will help + // shake out uses of park() and unpark() without condition variables. + + if (Atomic::xchg(1, &_Event) >= 0) return; // If the thread associated with the event was parked, wake it. - if (v < 0) { - int status ; - // Wait for the thread assoc with the PlatformEvent to vacate. - status = os::Solaris::mutex_lock(_mutex); - assert_status(status == 0, status, "mutex_lock"); - AnyWaiters = _nParked ; - status = os::Solaris::mutex_unlock(_mutex); - assert_status(status == 0, status, "mutex_unlock"); - guarantee (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; - if (AnyWaiters != 0) { - // We intentional signal *after* dropping the lock - // to avoid a common class of futile wakeups. - status = os::Solaris::cond_signal(_cond); - assert_status(status == 0, status, "cond_signal"); - } + // Wait for the thread assoc with the PlatformEvent to vacate. + int status = os::Solaris::mutex_lock(_mutex); + assert_status(status == 0, status, "mutex_lock"); + int AnyWaiters = _nParked; + status = os::Solaris::mutex_unlock(_mutex); + assert_status(status == 0, status, "mutex_unlock"); + guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); + if (AnyWaiters != 0) { + // We intentional signal *after* dropping the lock + // to avoid a common class of futile wakeups. + status = os::Solaris::cond_signal(_cond); + assert_status(status == 0, status, "cond_signal"); } } @@ -6177,14 +6172,14 @@ } void Parker::park(bool isAbsolute, jlong time) { + // Ideally we'd do something useful while spinning, such + // as calling unpackTime(). // Optional fast-path check: // Return immediately if a permit is available. - if (_counter > 0) { - _counter = 0 ; - OrderAccess::fence(); - return ; - } + // We depend on Atomic::xchg() having full barrier semantics + // since we are doing a lock-free update to _counter. + if (Atomic::xchg(0, &_counter) > 0) return; // Optional fast-exit: Check interrupt before trying to wait Thread* thread = Thread::current(); @@ -6226,6 +6221,8 @@ _counter = 0; status = os::Solaris::mutex_unlock(_mutex); assert (status == 0, "invariant") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other and Java-level accesses. OrderAccess::fence(); return; } @@ -6267,12 +6264,14 @@ _counter = 0 ; status = os::Solaris::mutex_unlock(_mutex); assert_status(status == 0, status, "mutex_unlock") ; + // Paranoia to ensure our locked and lock-free paths interact + // correctly with each other and Java-level accesses. + OrderAccess::fence(); // If externally suspended while waiting, re-suspend if (jt->handle_special_suspend_equivalent_condition()) { jt->java_suspend_self(); } - OrderAccess::fence(); } void Parker::unpark() { diff -r 22ead76da3f4 -r 274a29bf5682 src/os/solaris/vm/os_solaris.inline.hpp --- a/src/os/solaris/vm/os_solaris.inline.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/solaris/vm/os_solaris.inline.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -50,9 +50,6 @@ inline const char* os::line_separator() { return "\n"; } inline const char* os::path_separator() { return ":"; } -inline const char* os::jlong_format_specifier() { return "%lld"; } -inline const char* os::julong_format_specifier() { return "%llu"; } - // File names are case-sensitive on windows only inline int os::file_name_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); diff -r 22ead76da3f4 -r 274a29bf5682 src/os/windows/launcher/java_md.c --- a/src/os/windows/launcher/java_md.c Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/windows/launcher/java_md.c Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1323,11 +1323,6 @@ } } -const char * -jlong_format_specifier() { - return "%I64d"; -} - /* * Block current thread and continue execution in a new thread */ diff -r 22ead76da3f4 -r 274a29bf5682 src/os/windows/launcher/java_md.h --- a/src/os/windows/launcher/java_md.h Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/windows/launcher/java_md.h Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -69,6 +69,8 @@ extern int _main(int argc, char **argv); #endif +#define JLONG_FORMAT "%I64d" + /* * Function prototypes. */ diff -r 22ead76da3f4 -r 274a29bf5682 src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/windows/vm/os_windows.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -1874,8 +1874,22 @@ } return TRUE; break; + case CTRL_LOGOFF_EVENT: { + // Don't terminate JVM if it is running in a non-interactive session, + // such as a service process. + USEROBJECTFLAGS flags; + HANDLE handle = GetProcessWindowStation(); + if (handle != NULL && + GetUserObjectInformation(handle, UOI_FLAGS, &flags, + sizeof( USEROBJECTFLAGS), NULL)) { + // If it is a non-interactive session, let next handler to deal + // with it. + if ((flags.dwFlags & WSF_VISIBLE) == 0) { + return FALSE; + } + } + } case CTRL_CLOSE_EVENT: - case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: os::signal_raise(SIGTERM); return TRUE; @@ -2946,7 +2960,7 @@ } if( Verbose && PrintMiscellaneous ) { reserveTimer.stop(); - tty->print_cr("reserve_memory of %Ix bytes took %ld ms (%ld ticks)", bytes, + tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes, reserveTimer.milliseconds(), reserveTimer.ticks()); } } @@ -4305,7 +4319,7 @@ if (hFile == NULL) { if (PrintMiscellaneous && Verbose) { DWORD err = GetLastError(); - tty->print_cr("CreateFile() failed: GetLastError->%ld."); + tty->print_cr("CreateFile() failed: GetLastError->%ld.", err); } return NULL; } @@ -4355,7 +4369,7 @@ if (hMap == NULL) { if (PrintMiscellaneous && Verbose) { DWORD err = GetLastError(); - tty->print_cr("CreateFileMapping() failed: GetLastError->%ld."); + tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err); } CloseHandle(hFile); return NULL; @@ -4565,6 +4579,7 @@ } v = _Event ; _Event = 0 ; + // see comment at end of os::PlatformEvent::park() below: OrderAccess::fence() ; // If we encounter a nearly simultanous timeout expiry and unpark() // we return OS_OK indicating we awoke via unpark(). @@ -4602,25 +4617,25 @@ void os::PlatformEvent::unpark() { guarantee (_ParkHandle != NULL, "Invariant") ; - int v ; - for (;;) { - v = _Event ; // Increment _Event if it's < 1. - if (v > 0) { - // If it's already signaled just return. - // The LD of _Event could have reordered or be satisfied - // by a read-aside from this processor's write buffer. - // To avoid problems execute a barrier and then - // ratify the value. A degenerate CAS() would also work. - // Viz., CAS (v+0, &_Event, v) == v). - OrderAccess::fence() ; - if (_Event == v) return ; - continue ; - } - if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; - } - if (v < 0) { - ::SetEvent (_ParkHandle) ; - } + + // Transitions for _Event: + // 0 :=> 1 + // 1 :=> 1 + // -1 :=> either 0 or 1; must signal target thread + // That is, we can safely transition _Event from -1 to either + // 0 or 1. Forcing 1 is slightly more efficient for back-to-back + // unpark() calls. + // See also: "Semaphores in Plan 9" by Mullender & Cox + // + // Note: Forcing a transition from "-1" to "1" on an unpark() means + // that it will take two back-to-back park() calls for the owning + // thread to block. This has the benefit of forcing a spurious return + // from the first park() call after an unpark() call which will help + // shake out uses of park() and unpark() without condition variables. + + if (Atomic::xchg(1, &_Event) >= 0) return; + + ::SetEvent(_ParkHandle); } diff -r 22ead76da3f4 -r 274a29bf5682 src/os/windows/vm/os_windows.inline.hpp --- a/src/os/windows/vm/os_windows.inline.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/os/windows/vm/os_windows.inline.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, 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. * * This code is free software; you can redistribute it and/or modify it @@ -38,9 +38,6 @@ inline const char* os::path_separator() { return ";"; } inline const char* os::dll_file_extension() { return ".dll"; } -inline const char* os::jlong_format_specifier() { return "%I64d"; } -inline const char* os::julong_format_specifier() { return "%I64u"; } - inline const int os::default_file_open_flags() { return O_BINARY | O_NOINHERIT;} // File names are case-insensitive on windows only diff -r 22ead76da3f4 -r 274a29bf5682 src/share/tools/launcher/java.c --- a/src/share/tools/launcher/java.c Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/tools/launcher/java.c Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -808,7 +808,7 @@ static int parse_stack_size(const char *s, jlong *result) { jlong n = 0; - int args_read = sscanf(s, jlong_format_specifier(), &n); + int args_read = sscanf(s, JLONG_FORMAT, &n); if (args_read != 1) { return 0; } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/tools/launcher/java.h --- a/src/share/tools/launcher/java.h Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/tools/launcher/java.h Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -86,7 +86,6 @@ jboolean RemovableMachineDependentOption(char * option); void PrintMachineDependentOptions(); -const char *jlong_format_specifier(); /* * Block current thread and continue execution in new thread */ diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/c1/c1_InstructionPrinter.cpp --- a/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -360,7 +360,7 @@ ValueType* t = x->type(); switch (t->tag()) { case intTag : output()->print("%d" , t->as_IntConstant ()->value()); break; - case longTag : output()->print(os::jlong_format_specifier(), t->as_LongConstant()->value()); output()->print("L"); break; + case longTag : output()->print(JLONG_FORMAT, t->as_LongConstant()->value()); output()->print("L"); break; case floatTag : output()->print("%g" , t->as_FloatConstant ()->value()); break; case doubleTag : output()->print("%gD" , t->as_DoubleConstant()->value()); break; case objectTag : print_object(x); break; diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/c1/c1_LIR.cpp --- a/src/share/vm/c1/c1_LIR.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/c1/c1_LIR.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -1563,7 +1563,7 @@ switch (type()) { case T_ADDRESS:out->print("address:%d",as_jint()); break; case T_INT: out->print("int:%d", as_jint()); break; - case T_LONG: out->print("lng:%lld", as_jlong()); break; + case T_LONG: out->print("lng:" JLONG_FORMAT, as_jlong()); break; case T_FLOAT: out->print("flt:%f", as_jfloat()); break; case T_DOUBLE: out->print("dbl:%f", as_jdouble()); break; case T_OBJECT: out->print("obj:0x%x", as_jobject()); break; diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/ci/ciReplay.cpp --- a/src/share/vm/ci/ciReplay.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/ci/ciReplay.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +/* 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 @@ -645,7 +645,7 @@ java_mirror->bool_field_put(fd.offset(), value); } else if (strcmp(field_signature, "J") == 0) { jlong value; - if (sscanf(string_value, INT64_FORMAT, &value) != 1) { + if (sscanf(string_value, JLONG_FORMAT, &value) != 1) { fprintf(stderr, "Error parsing long: %s\n", string_value); return; } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/classfile/javaClasses.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -911,7 +911,6 @@ // Write the thread status value to threadStatus field in java.lang.Thread java class. void java_lang_Thread::set_thread_status(oop java_thread, java_lang_Thread::ThreadStatus status) { - assert(JavaThread::current()->thread_state() == _thread_in_vm, "Java Thread is not running in vm"); // The threadStatus is only present starting in 1.5 if (_thread_status_offset > 0) { java_thread->int_field_put(_thread_status_offset, status); @@ -1145,179 +1144,43 @@ } } -// Print stack trace element to resource allocated buffer -char* java_lang_Throwable::print_stack_element_to_buffer(Method* method, int bci) { - // Get strings and string lengths - InstanceKlass* klass = method->method_holder(); - const char* klass_name = klass->external_name(); - int buf_len = (int)strlen(klass_name); - char* source_file_name; - if (klass->source_file_name() == NULL) { - source_file_name = NULL; +// After this many redefines, the stack trace is unreliable. +const int MAX_VERSION = USHRT_MAX; + +// Helper backtrace functions to store bci|version together. +static inline int merge_bci_and_version(int bci, int version) { + // only store u2 for version, checking for overflow. + if (version > USHRT_MAX || version < 0) version = MAX_VERSION; + assert((jushort)bci == bci, "bci should be short"); + return build_int_from_shorts(version, bci); +} + +static inline int bci_at(unsigned int merged) { + return extract_high_short_from_int(merged); +} +static inline int version_at(unsigned int merged) { + return extract_low_short_from_int(merged); +} + +static inline bool version_matches(Method* method, int version) { + return (method->constants()->version() == version && version < MAX_VERSION); +} + +static inline int get_line_number(Method* method, int bci) { + int line_number = 0; + if (method->is_native()) { + // Negative value different from -1 below, enabling Java code in + // class java.lang.StackTraceElement to distinguish "native" from + // "no LineNumberTable". JDK tests for -2. + line_number = -2; } else { - source_file_name = klass->source_file_name()->as_C_string(); - buf_len += (int)strlen(source_file_name); - } - char* method_name = method->name()->as_C_string(); - buf_len += (int)strlen(method_name); - - // Allocate temporary buffer with extra space for formatting and line number - char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); - - // Print stack trace line in buffer - sprintf(buf, "\tat %s.%s", klass_name, method_name); - if (method->is_native()) { - strcat(buf, "(Native Method)"); - } else { - int line_number = method->line_number_from_bci(bci); - if (source_file_name != NULL && (line_number != -1)) { - // Sourcename and linenumber - sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); - } else if (source_file_name != NULL) { - // Just sourcename - sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); - } else { - // Neither soucename and linenumber - sprintf(buf + (int)strlen(buf), "(Unknown Source)"); - } - nmethod* nm = method->code(); - if (WizardMode && nm != NULL) { - sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); + // Returns -1 if no LineNumberTable, and otherwise actual line number + line_number = method->line_number_from_bci(bci); + if (line_number == -1 && ShowHiddenFrames) { + line_number = bci + 1000000; } } - - return buf; -} - - -void java_lang_Throwable::print_stack_element(Handle stream, Method* method, int bci) { - ResourceMark rm; - char* buf = print_stack_element_to_buffer(method, bci); - print_to_stream(stream, buf); -} - -void java_lang_Throwable::print_stack_element(outputStream *st, Method* method, int bci) { - ResourceMark rm; - char* buf = print_stack_element_to_buffer(method, bci); - st->print_cr("%s", buf); -} - -void java_lang_Throwable::print_to_stream(Handle stream, const char* str) { - if (stream.is_null()) { - tty->print_cr("%s", str); - } else { - EXCEPTION_MARK; - JavaValue result(T_VOID); - Handle arg (THREAD, oopFactory::new_charArray(str, THREAD)); - if (!HAS_PENDING_EXCEPTION) { - JavaCalls::call_virtual(&result, - stream, - KlassHandle(THREAD, stream->klass()), - vmSymbols::println_name(), - vmSymbols::char_array_void_signature(), - arg, - THREAD); - } - // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. - if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION; - } - -} - - -const char* java_lang_Throwable::no_stack_trace_message() { - return "\t<>"; -} - - -// Currently used only for exceptions occurring during startup -void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { - Thread *THREAD = Thread::current(); - Handle h_throwable(THREAD, throwable); - while (h_throwable.not_null()) { - objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); - if (result.is_null()) { - st->print_cr(no_stack_trace_message()); - return; - } - - while (result.not_null()) { - typeArrayHandle methods (THREAD, - typeArrayOop(result->obj_at(trace_methods_offset))); - typeArrayHandle bcis (THREAD, - typeArrayOop(result->obj_at(trace_bcis_offset))); - - if (methods.is_null() || bcis.is_null()) { - st->print_cr(no_stack_trace_message()); - return; - } - - int length = methods()->length(); - for (int index = 0; index < length; index++) { - Method* method = ((Method*)methods()->metadata_at(index)); - if (method == NULL) goto handle_cause; - int bci = bcis->ushort_at(index); - print_stack_element(st, method, bci); - } - result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); - } - handle_cause: - { - EXCEPTION_MARK; - JavaValue result(T_OBJECT); - JavaCalls::call_virtual(&result, - h_throwable, - KlassHandle(THREAD, h_throwable->klass()), - vmSymbols::getCause_name(), - vmSymbols::void_throwable_signature(), - THREAD); - // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - h_throwable = Handle(); - } else { - h_throwable = Handle(THREAD, (oop) result.get_jobject()); - if (h_throwable.not_null()) { - st->print("Caused by: "); - print(h_throwable, st); - st->cr(); - } - } - } - } -} - - -void java_lang_Throwable::print_stack_trace(oop throwable, oop print_stream) { - // Note: this is no longer used in Merlin, but we support it for compatibility. - Thread *thread = Thread::current(); - Handle stream(thread, print_stream); - objArrayHandle result (thread, objArrayOop(backtrace(throwable))); - if (result.is_null()) { - print_to_stream(stream, no_stack_trace_message()); - return; - } - - while (result.not_null()) { - typeArrayHandle methods(thread, - typeArrayOop(result->obj_at(trace_methods_offset))); - typeArrayHandle bcis (thread, - typeArrayOop(result->obj_at(trace_bcis_offset))); - - if (methods.is_null() || bcis.is_null()) { - print_to_stream(stream, no_stack_trace_message()); - return; - } - - int length = methods()->length(); - for (int index = 0; index < length; index++) { - Method* method = ((Method*)methods()->metadata_at(index)); - if (method == NULL) return; - int bci = bcis->ushort_at(index); - print_stack_element(stream, method, bci); - } - result = objArrayHandle(thread, objArrayOop(result->obj_at(trace_next_offset))); - } + return line_number; } // This class provides a simple wrapper over the internal structure of @@ -1337,13 +1200,30 @@ enum { trace_methods_offset = java_lang_Throwable::trace_methods_offset, - trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, + trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, trace_next_offset = java_lang_Throwable::trace_next_offset, trace_size = java_lang_Throwable::trace_size, trace_chunk_size = java_lang_Throwable::trace_chunk_size }; + // get info out of chunks + static typeArrayOop get_methods(objArrayHandle chunk) { + typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); + assert(methods != NULL, "method array should be initialized in backtrace"); + return methods; + } + static typeArrayOop get_bcis(objArrayHandle chunk) { + typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); + assert(bcis != NULL, "bci array should be initialized in backtrace"); + return bcis; + } + static objArrayOop get_mirrors(objArrayHandle chunk) { + objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset)); + assert(mirrors != NULL, "mirror array should be initialized in backtrace"); + return mirrors; + } + // constructor for new backtrace BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) { expand(CHECK); @@ -1351,6 +1231,19 @@ _index = 0; } + BacktraceBuilder(objArrayHandle backtrace) { + _methods = get_methods(backtrace); + _bcis = get_bcis(backtrace); + _mirrors = get_mirrors(backtrace); + assert(_methods->length() == _bcis->length() && + _methods->length() == _mirrors->length(), + "method and source information arrays should match"); + + // head is the preallocated backtrace + _backtrace = _head = backtrace(); + _index = 0; + } + void expand(TRAPS) { objArrayHandle old_head(THREAD, _head); Pause_No_Safepoint_Verifier pnsv(&_nsv); @@ -1358,10 +1251,10 @@ objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK); objArrayHandle new_head(THREAD, head); - typeArrayOop methods = oopFactory::new_metaDataArray(trace_chunk_size, CHECK); + typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK); typeArrayHandle new_methods(THREAD, methods); - typeArrayOop bcis = oopFactory::new_shortArray(trace_chunk_size, CHECK); + typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK); typeArrayHandle new_bcis(THREAD, bcis); objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); @@ -1376,7 +1269,7 @@ _head = new_head(); _methods = new_methods(); - _bcis = new_bcis(); + _bcis = new_bcis(); _mirrors = new_mirrors(); _index = 0; } @@ -1390,7 +1283,6 @@ // shorts. The later line number lookup would just smear the -1 // to a 0 even if it could be recorded. if (bci == SynchronizationEntryBCI) bci = 0; - assert(bci == (jushort)bci, "doesn't fit"); if (_index >= trace_chunk_size) { methodHandle mhandle(THREAD, method); @@ -1398,26 +1290,148 @@ method = mhandle(); } - _methods->metadata_at_put(_index, method); - _bcis->ushort_at_put(_index, bci); - // we need to save the mirrors in the backtrace to keep the methods from - // being unloaded if their class loader is unloaded while we still have - // this stack trace. + _methods->short_at_put(_index, method->method_idnum()); + _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version())); + + // We need to save the mirrors in the backtrace to keep the class + // from being unloaded while we still have this stack trace. + assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); _index++; } - Method* current_method() { - assert(_index >= 0 && _index < trace_chunk_size, "out of range"); - return ((Method*)_methods->metadata_at(_index)); +}; + +// Print stack trace element to resource allocated buffer +char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror, + int method_id, int version, int bci) { + + // Get strings and string lengths + InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); + const char* klass_name = holder->external_name(); + int buf_len = (int)strlen(klass_name); + + // pushing to the stack trace added one. + Method* method = holder->method_with_idnum(method_id); + char* method_name = method->name()->as_C_string(); + buf_len += (int)strlen(method_name); + + char* source_file_name = NULL; + if (version_matches(method, version)) { + Symbol* source = holder->source_file_name(); + if (source != NULL) { + source_file_name = source->as_C_string(); + buf_len += (int)strlen(source_file_name); + } + } + + // Allocate temporary buffer with extra space for formatting and line number + char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); + + // Print stack trace line in buffer + sprintf(buf, "\tat %s.%s", klass_name, method_name); + + if (!version_matches(method, version)) { + strcat(buf, "(Redefined)"); + } else { + int line_number = get_line_number(method, bci); + if (line_number == -2) { + strcat(buf, "(Native Method)"); + } else { + if (source_file_name != NULL && (line_number != -1)) { + // Sourcename and linenumber + sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); + } else if (source_file_name != NULL) { + // Just sourcename + sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); + } else { + // Neither sourcename nor linenumber + sprintf(buf + (int)strlen(buf), "(Unknown Source)"); + } + nmethod* nm = method->code(); + if (WizardMode && nm != NULL) { + sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); + } + } } - jushort current_bci() { - assert(_index >= 0 && _index < trace_chunk_size, "out of range"); - return _bcis->ushort_at(_index); + return buf; +} + +void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, + int method_id, int version, int bci) { + ResourceMark rm; + char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci); + st->print_cr("%s", buf); +} + +void java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) { + Handle mirror = method->method_holder()->java_mirror(); + int method_id = method->method_idnum(); + int version = method->constants()->version(); + print_stack_element(st, mirror, method_id, version, bci); +} + +const char* java_lang_Throwable::no_stack_trace_message() { + return "\t<>"; +} + + +// Currently used only for exceptions occurring during startup +void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { + Thread *THREAD = Thread::current(); + Handle h_throwable(THREAD, throwable); + while (h_throwable.not_null()) { + objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); + if (result.is_null()) { + st->print_cr(no_stack_trace_message()); + return; + } + + while (result.not_null()) { + + // Get method id, bci, version and mirror from chunk + typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); + typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); + objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); + + int length = methods()->length(); + for (int index = 0; index < length; index++) { + Handle mirror(THREAD, mirrors->obj_at(index)); + // NULL mirror means end of stack trace + if (mirror.is_null()) goto handle_cause; + int method = methods->short_at(index); + int version = version_at(bcis->int_at(index)); + int bci = bci_at(bcis->int_at(index)); + print_stack_element(st, mirror, method, version, bci); + } + result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); + } + handle_cause: + { + EXCEPTION_MARK; + JavaValue cause(T_OBJECT); + JavaCalls::call_virtual(&cause, + h_throwable, + KlassHandle(THREAD, h_throwable->klass()), + vmSymbols::getCause_name(), + vmSymbols::void_throwable_signature(), + THREAD); + // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + h_throwable = Handle(); + } else { + h_throwable = Handle(THREAD, (oop) cause.get_jobject()); + if (h_throwable.not_null()) { + st->print("Caused by: "); + print(h_throwable, st); + st->cr(); + } + } + } } -}; - +} void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) { if (!StackTraceInThrowable) return; @@ -1578,21 +1592,8 @@ // No-op if stack trace is disabled if (!StackTraceInThrowable) return; - - objArrayOop h_oop = oopFactory::new_objectArray(trace_size, CHECK); - objArrayHandle backtrace (THREAD, h_oop); - typeArrayOop m_oop = oopFactory::new_metaDataArray(trace_chunk_size, CHECK); - typeArrayHandle methods (THREAD, m_oop); - typeArrayOop b = oopFactory::new_shortArray(trace_chunk_size, CHECK); - typeArrayHandle bcis(THREAD, b); - objArrayOop mirror_oop = oopFactory::new_objectArray(trace_chunk_size, CHECK); - objArrayHandle mirrors (THREAD, mirror_oop); - - // backtrace has space for one chunk (next is NULL) - backtrace->obj_at_put(trace_methods_offset, methods()); - backtrace->obj_at_put(trace_bcis_offset, bcis()); - backtrace->obj_at_put(trace_mirrors_offset, mirrors()); - set_backtrace(throwable(), backtrace()); + BacktraceBuilder bt(CHECK); // creates a backtrace + set_backtrace(throwable(), bt.backtrace()); } @@ -1604,48 +1605,26 @@ assert(throwable->is_a(SystemDictionary::Throwable_klass()), "sanity check"); - objArrayOop backtrace = (objArrayOop)java_lang_Throwable::backtrace(throwable()); - assert(backtrace != NULL, "backtrace not preallocated"); - - oop m = backtrace->obj_at(trace_methods_offset); - typeArrayOop methods = typeArrayOop(m); - assert(methods != NULL && methods->length() > 0, "method array not preallocated"); - - oop b = backtrace->obj_at(trace_bcis_offset); - typeArrayOop bcis = typeArrayOop(b); - assert(bcis != NULL, "bci array not preallocated"); - - oop mr = backtrace->obj_at(trace_mirrors_offset); - objArrayOop mirrors = objArrayOop(mr); - assert(mirrors != NULL, "bci array not preallocated"); - - assert(methods->length() == bcis->length() && - methods->length() == mirrors->length(), - "method and bci arrays should match"); - - JavaThread* thread = JavaThread::current(); - ResourceMark rm(thread); - vframeStream st(thread); + JavaThread* THREAD = JavaThread::current(); + + objArrayHandle backtrace (THREAD, (objArrayOop)java_lang_Throwable::backtrace(throwable())); + assert(backtrace.not_null(), "backtrace should have been preallocated"); + + ResourceMark rm(THREAD); + vframeStream st(THREAD); + + BacktraceBuilder bt(backtrace); // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init // methods as preallocated errors aren't created by "java" code. // fill in as much stack trace as possible + typeArrayOop methods = BacktraceBuilder::get_methods(backtrace); int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth); int chunk_count = 0; for (;!st.at_end(); st.next()) { - // Add entry and smear the -1 bci to 0 since the array only holds - // unsigned shorts. The later line number lookup would just smear - // the -1 to a 0 even if it could be recorded. - int bci = st.bci(); - if (bci == SynchronizationEntryBCI) bci = 0; - assert(bci == (jushort)bci, "doesn't fit"); - bcis->ushort_at_put(chunk_count, bci); - methods->metadata_at_put(chunk_count, st.method()); - mirrors->obj_at_put(chunk_count, - st.method()->method_holder()->java_mirror()); - + bt.push(st.method(), st.bci(), CHECK); chunk_count++; // Bail-out for deep stacks @@ -1659,7 +1638,6 @@ java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace()); assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized"); } - } @@ -1678,12 +1656,12 @@ chunk = next; } assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check"); - // Count element in remaining partial chunk - typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); - typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); - assert(methods != NULL && bcis != NULL, "sanity check"); - for (int i = 0; i < methods->length(); i++) { - if (methods->metadata_at(i) == NULL) break; + // Count element in remaining partial chunk. NULL value for mirror + // marks the end of the stack trace elements that are saved. + objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); + assert(mirrors != NULL, "sanity check"); + for (int i = 0; i < mirrors->length(); i++) { + if (mirrors->obj_at(i) == NULL) break; depth++; } } @@ -1709,25 +1687,28 @@ if (chunk == NULL) { THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); } - // Get method,bci from chunk - typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); - typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); - assert(methods != NULL && bcis != NULL, "sanity check"); - methodHandle method(THREAD, ((Method*)methods->metadata_at(chunk_index))); - int bci = bcis->ushort_at(chunk_index); + // Get method id, bci, version and mirror from chunk + typeArrayOop methods = BacktraceBuilder::get_methods(chunk); + typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk); + objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); + + assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); + + int method = methods->short_at(chunk_index); + int version = version_at(bcis->int_at(chunk_index)); + int bci = bci_at(bcis->int_at(chunk_index)); + Handle mirror(THREAD, mirrors->obj_at(chunk_index)); + // Chunk can be partial full - if (method.is_null()) { + if (mirror.is_null()) { THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); } - oop element = java_lang_StackTraceElement::create(method, bci, CHECK_0); + oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, CHECK_0); return element; } -oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { - // SystemDictionary::stackTraceElement_klass() will be null for pre-1.4 JDKs - assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4"); - +oop java_lang_StackTraceElement::create(Handle mirror, int method_id, int version, int bci, TRAPS) { // Allocate java.lang.StackTraceElement instance Klass* k = SystemDictionary::StackTraceElement_klass(); assert(k != NULL, "must be loaded in 1.4+"); @@ -1739,37 +1720,39 @@ Handle element = ik->allocate_instance_handle(CHECK_0); // Fill in class name ResourceMark rm(THREAD); - const char* str = method->method_holder()->external_name(); + InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); + const char* str = holder->external_name(); oop classname = StringTable::intern((char*) str, CHECK_0); java_lang_StackTraceElement::set_declaringClass(element(), classname); + // Fill in method name + Method* method = holder->method_with_idnum(method_id); oop methodname = StringTable::intern(method->name(), CHECK_0); java_lang_StackTraceElement::set_methodName(element(), methodname); - // Fill in source file name - Symbol* source = method->method_holder()->source_file_name(); - if (ShowHiddenFrames && source == NULL) - source = vmSymbols::unknown_class_name(); - oop filename = StringTable::intern(source, CHECK_0); - java_lang_StackTraceElement::set_fileName(element(), filename); - // File in source line number - int line_number; - if (method->is_native()) { - // Negative value different from -1 below, enabling Java code in - // class java.lang.StackTraceElement to distinguish "native" from - // "no LineNumberTable". - line_number = -2; + + if (!version_matches(method, version)) { + // The method was redefined, accurate line number information isn't available + java_lang_StackTraceElement::set_fileName(element(), NULL); + java_lang_StackTraceElement::set_lineNumber(element(), -1); } else { - // Returns -1 if no LineNumberTable, and otherwise actual line number - line_number = method->line_number_from_bci(bci); - if (line_number == -1 && ShowHiddenFrames) { - line_number = bci + 1000000; - } + // Fill in source file name and line number. + Symbol* source = holder->source_file_name(); + if (ShowHiddenFrames && source == NULL) + source = vmSymbols::unknown_class_name(); + oop filename = StringTable::intern(source, CHECK_0); + java_lang_StackTraceElement::set_fileName(element(), filename); + + int line_number = get_line_number(method, bci); + java_lang_StackTraceElement::set_lineNumber(element(), line_number); } - java_lang_StackTraceElement::set_lineNumber(element(), line_number); - return element(); } +oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { + Handle mirror (THREAD, method->method_holder()->java_mirror()); + int method_id = method->method_idnum(); + return create(mirror, method_id, method->constants()->version(), bci, THREAD); +} void java_lang_reflect_AccessibleObject::compute_offsets() { Klass* k = SystemDictionary::reflect_AccessibleObject_klass(); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/classfile/javaClasses.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -463,8 +463,7 @@ static int static_unassigned_stacktrace_offset; // Printing - static char* print_stack_element_to_buffer(Method* method, int bci); - static void print_to_stream(Handle stream, const char* str); + static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci); // StackTrace (programmatic access, new since 1.4) static void clear_stacktrace(oop throwable); // No stack trace available @@ -484,12 +483,9 @@ static oop message(oop throwable); static oop message(Handle throwable); static void set_message(oop throwable, oop value); - // Print stack trace stored in exception by call-back to Java - // Note: this is no longer used in Merlin, but we still suppport - // it for compatibility. - static void print_stack_trace(oop throwable, oop print_stream); - static void print_stack_element(Handle stream, Method* method, int bci); - static void print_stack_element(outputStream *st, Method* method, int bci); + static void print_stack_element(outputStream *st, Handle mirror, int method, + int version, int bci); + static void print_stack_element(outputStream *st, methodHandle method, int bci); static void print_stack_usage(Handle stream); // Allocate space for backtrace (created but stack trace not filled in) @@ -1257,7 +1253,8 @@ static void set_lineNumber(oop element, int value); // Create an instance of StackTraceElement - static oop create(methodHandle m, int bci, TRAPS); + static oop create(Handle mirror, int method, int version, int bci, TRAPS); + static oop create(methodHandle method, int bci, TRAPS); // Debugging friend class JavaClasses; diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -554,7 +554,7 @@ reportIndexedFreeListStatistics(); size_t total_size = totalSizeInIndexedFreeLists() + _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())); - gclog_or_tty->print(" free=%ld frag=%1.4f\n", total_size, flsFrag()); + gclog_or_tty->print(" free=" SIZE_FORMAT " frag=%1.4f\n", total_size, flsFrag()); } } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -3338,7 +3338,7 @@ if (Verbose && PrintGC) { size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size - bytes; - gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK", + gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", name(), old_mem_size/K, bytes/K, new_mem_size/K); } } @@ -9203,7 +9203,7 @@ if (Verbose && PrintGCDetails) { size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size + bytes; - gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK", + gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", name(), old_mem_size/K, bytes/K, new_mem_size/K); } } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp --- a/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -131,17 +131,23 @@ #ifndef PRODUCT +template <> const int WorkerDataArray::_uninitialized = -1; +template <> const double WorkerDataArray::_uninitialized = -1.0; +template <> const size_t WorkerDataArray::_uninitialized = (size_t)-1; + template void WorkerDataArray::reset() { for (uint i = 0; i < _length; i++) { - _data[i] = (T)-1; + _data[i] = (T)_uninitialized; } } template void WorkerDataArray::verify() { for (uint i = 0; i < _length; i++) { - assert(_data[i] >= (T)0, err_msg("Invalid data for worker %d", i)); + assert(_data[i] != _uninitialized, + err_msg("Invalid data for worker " UINT32_FORMAT ", data: %lf, uninitialized: %lf", + i, (double)_data[i], (double)_uninitialized)); } } @@ -201,20 +207,20 @@ _last_termination_attempts.verify(); _last_gc_worker_end_times_ms.verify(); - for (uint i = 0; i < _active_gc_threads; i++) { - double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i); - _last_gc_worker_times_ms.set(i, worker_time); + for (uint i = 0; i < _active_gc_threads; i++) { + double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i); + _last_gc_worker_times_ms.set(i, worker_time); - double worker_known_time = _last_ext_root_scan_times_ms.get(i) + - _last_satb_filtering_times_ms.get(i) + - _last_update_rs_times_ms.get(i) + - _last_scan_rs_times_ms.get(i) + - _last_obj_copy_times_ms.get(i) + - _last_termination_times_ms.get(i); + double worker_known_time = _last_ext_root_scan_times_ms.get(i) + + _last_satb_filtering_times_ms.get(i) + + _last_update_rs_times_ms.get(i) + + _last_scan_rs_times_ms.get(i) + + _last_obj_copy_times_ms.get(i) + + _last_termination_times_ms.get(i); - double worker_other_time = worker_time - worker_known_time; - _last_gc_worker_other_times_ms.set(i, worker_other_time); - } + double worker_other_time = worker_time - worker_known_time; + _last_gc_worker_other_times_ms.set(i, worker_other_time); + } _last_gc_worker_times_ms.verify(); _last_gc_worker_other_times_ms.verify(); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp --- a/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -35,6 +35,8 @@ const char* _print_format; bool _print_sum; + NOT_PRODUCT(static const T _uninitialized;) + // We are caching the sum and average to only have to calculate them once. // This is not done in an MT-safe way. It is intetened to allow single // threaded code to call sum() and average() multiple times in any order diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -529,7 +529,7 @@ if (PrintTenuringDistribution) { gclog_or_tty->cr(); - gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)", + gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max %u)", size_policy->calculated_survivor_size_in_bytes(), _tenuring_threshold, MaxTenuringThreshold); } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/gc_implementation/shared/ageTable.cpp --- a/src/share/vm/gc_implementation/shared/ageTable.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/ageTable.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, 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. * * This code is free software; you can redistribute it and/or modify it @@ -96,7 +96,7 @@ if (PrintTenuringDistribution) { gclog_or_tty->cr(); - gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)", + gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max %u)", desired_survivor_size*oopSize, result, MaxTenuringThreshold); } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/memory/universe.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -228,7 +228,7 @@ if (size < alignment || size % alignment != 0) { ResourceMark rm; stringStream st; - st.print("Size of %s (%ld bytes) must be aligned to %ld bytes", name, size, alignment); + st.print("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment); char* error = st.as_string(); vm_exit_during_initialization(error); } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/oops/constantPool.cpp --- a/src/share/vm/oops/constantPool.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/oops/constantPool.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ set_pool_holder(NULL); set_flags(0); // only set to non-zero if constant pool is merged by RedefineClasses - set_orig_length(0); + set_version(0); set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock")); // all fields are initialized; needed for GC set_on_stack(false); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/oops/constantPool.hpp --- a/src/share/vm/oops/constantPool.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/oops/constantPool.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -103,8 +103,8 @@ union { // set for CDS to restore resolved references int _resolved_reference_length; - // only set to non-zero if constant pool is merged by RedefineClasses - int _orig_length; + // keeps version number for redefined classes (used in backtrace) + int _version; } _saved; Monitor* _lock; @@ -784,8 +784,11 @@ static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS); static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS); int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS); - int orig_length() const { return _saved._orig_length; } - void set_orig_length(int orig_length) { _saved._orig_length = orig_length; } + int version() const { return _saved._version; } + void set_version(int version) { _saved._version = version; } + void increment_and_save_version(int version) { + _saved._version = version >= 0 ? (version + 1) : version; // keep overflow + } void set_resolved_reference_length(int length) { _saved._resolved_reference_length = length; } int resolved_reference_length() const { return _saved._resolved_reference_length; } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/opto/idealGraphPrinter.cpp --- a/src/share/vm/opto/idealGraphPrinter.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/opto/idealGraphPrinter.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -547,7 +547,7 @@ // max. 2 chars allowed if (value >= -9 && value <= 99) { - sprintf(buffer, INT64_FORMAT, value); + sprintf(buffer, JLONG_FORMAT, value); print_prop(short_name, buffer); } else { print_prop(short_name, "L"); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/opto/type.cpp --- a/src/share/vm/opto/type.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/opto/type.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -1542,10 +1542,10 @@ static const char* longnamenear(jlong x, const char* xname, char* buf, jlong n) { if (n > x) { if (n >= x + 10000) return NULL; - sprintf(buf, "%s+" INT64_FORMAT, xname, n - x); + sprintf(buf, "%s+" JLONG_FORMAT, xname, n - x); } else if (n < x) { if (n <= x - 10000) return NULL; - sprintf(buf, "%s-" INT64_FORMAT, xname, x - n); + sprintf(buf, "%s-" JLONG_FORMAT, xname, x - n); } else { return xname; } @@ -1557,11 +1557,11 @@ if (n == min_jlong) return "min"; else if (n < min_jlong + 10000) - sprintf(buf, "min+" INT64_FORMAT, n - min_jlong); + sprintf(buf, "min+" JLONG_FORMAT, n - min_jlong); else if (n == max_jlong) return "max"; else if (n > max_jlong - 10000) - sprintf(buf, "max-" INT64_FORMAT, max_jlong - n); + sprintf(buf, "max-" JLONG_FORMAT, max_jlong - n); else if ((str = longnamenear(max_juint, "maxuint", buf, n)) != NULL) return str; else if ((str = longnamenear(max_jint, "maxint", buf, n)) != NULL) @@ -1569,7 +1569,7 @@ else if ((str = longnamenear(min_jint, "minint", buf, n)) != NULL) return str; else - sprintf(buf, INT64_FORMAT, n); + sprintf(buf, JLONG_FORMAT, n); return buf; } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/prims/jvm.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -484,15 +484,6 @@ JVM_END -JVM_ENTRY(void, JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable)) - JVMWrapper("JVM_PrintStackTrace"); - // Note: This is no longer used in Merlin, but we still support it for compatibility. - oop exception = JNIHandles::resolve_non_null(receiver); - oop stream = JNIHandles::resolve_non_null(printable); - java_lang_Throwable::print_stack_trace(exception, stream); -JVM_END - - JVM_ENTRY(jint, JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)) JVMWrapper("JVM_GetStackTraceDepth"); oop exception = JNIHandles::resolve(throwable); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/prims/jvm.h Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -212,9 +212,6 @@ JNIEXPORT void JNICALL JVM_FillInStackTrace(JNIEnv *env, jobject throwable); -JNIEXPORT void JNICALL -JVM_PrintStackTrace(JNIEnv *env, jobject throwable, jobject printable); - JNIEXPORT jint JNICALL JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -1334,20 +1334,8 @@ return JVMTI_ERROR_INTERNAL; } - int orig_length = old_cp->orig_length(); - if (orig_length == 0) { - // This old_cp is an actual original constant pool. We save - // the original length in the merged constant pool so that - // merge_constant_pools() can be more efficient. If a constant - // pool has a non-zero orig_length() value, then that constant - // pool was created by a merge operation in RedefineClasses. - merge_cp->set_orig_length(old_cp->length()); - } else { - // This old_cp is a merged constant pool from a previous - // RedefineClasses() calls so just copy the orig_length() - // value. - merge_cp->set_orig_length(old_cp->orig_length()); - } + // Update the version number of the constant pool + merge_cp->increment_and_save_version(old_cp->version()); ResourceMark rm(THREAD); _index_map_count = 0; @@ -2417,18 +2405,19 @@ int scratch_cp_length, TRAPS) { assert(scratch_cp->length() >= scratch_cp_length, "sanity check"); - // scratch_cp is a merged constant pool and has enough space for a - // worst case merge situation. We want to associate the minimum - // sized constant pool with the klass to save space. - constantPoolHandle smaller_cp(THREAD, - ConstantPool::allocate(loader_data, scratch_cp_length, - THREAD)); - // preserve orig_length() value in the smaller copy - int orig_length = scratch_cp->orig_length(); - assert(orig_length != 0, "sanity check"); - smaller_cp->set_orig_length(orig_length); - scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); - scratch_cp = smaller_cp; + // scratch_cp is a merged constant pool and has enough space for a + // worst case merge situation. We want to associate the minimum + // sized constant pool with the klass to save space. + constantPoolHandle smaller_cp(THREAD, + ConstantPool::allocate(loader_data, scratch_cp_length, THREAD)); + + // preserve version() value in the smaller copy + int version = scratch_cp->version(); + assert(version != 0, "sanity check"); + smaller_cp->set_version(version); + + scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); + scratch_cp = smaller_cp; // attach new constant pool to klass scratch_cp->set_pool_holder(scratch_class()); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/aprofiler.cpp --- a/src/share/vm/runtime/aprofiler.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/aprofiler.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -129,7 +129,7 @@ assert(!is_active(), "AllocationProfiler cannot be active while printing profile"); tty->cr(); - tty->print_cr("Allocation profile (sizes in bytes, cutoff = %ld bytes):", cutoff * BytesPerWord); + tty->print_cr("Allocation profile (sizes in bytes, cutoff = " SIZE_FORMAT " bytes):", cutoff * BytesPerWord); tty->cr(); // Print regular instance klasses and basic type array klasses diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/arguments.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -532,7 +532,7 @@ // Parses a memory size specification string. static bool atomull(const char *s, julong* result) { julong n = 0; - int args_read = sscanf(s, os::julong_format_specifier(), &n); + int args_read = sscanf(s, JULONG_FORMAT, &n); if (args_read != 1) { return false; } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/objectMonitor.cpp --- a/src/share/vm/runtime/objectMonitor.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/objectMonitor.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -653,8 +653,7 @@ assert (_succ != Self, "invariant") ; if (_Responsible == Self) { _Responsible = NULL ; - // Dekker pivot-point. - // Consider OrderAccess::storeload() here + OrderAccess::fence(); // Dekker pivot-point // We may leave threads on cxq|EntryList without a designated // "Responsible" thread. This is benign. When this thread subsequently @@ -674,10 +673,6 @@ // // The MEMBAR, above, prevents the LD of cxq|EntryList in the subsequent // exit operation from floating above the ST Responsible=null. - // - // In *practice* however, EnterI() is always followed by some atomic - // operation such as the decrement of _count in ::enter(). Those atomics - // obviate the need for the explicit MEMBAR, above. } // We've acquired ownership with CAS(). diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/objectMonitor.inline.hpp --- a/src/share/vm/runtime/objectMonitor.inline.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/objectMonitor.inline.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -101,10 +101,12 @@ return _count; } +// Do NOT set _count = 0. There is a race such that _count could +// be set while inflating prior to setting _owner +// Just use Atomic::inc/dec and assert 0 when monitor put on free list inline void ObjectMonitor::set_owner(void* owner) { _owner = owner; _recursions = 0; - _count = 0; } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/os.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -641,10 +641,6 @@ static struct hostent* get_host_by_name(char* name); - // Printing 64 bit integers - static const char* jlong_format_specifier(); - static const char* julong_format_specifier(); - // Support for signals (see JVM_RaiseSignal, JVM_RegisterSignal) static void signal_init(); static void signal_init_pd(); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/perfData.cpp --- a/src/share/vm/runtime/perfData.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/perfData.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -192,7 +192,7 @@ } int PerfLong::format(char* buffer, int length) { - return jio_snprintf(buffer, length,"%lld", *(jlong*)_valuep); + return jio_snprintf(buffer, length, JLONG_FORMAT, *(jlong*)_valuep); } PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u, diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/synchronizer.cpp --- a/src/share/vm/runtime/synchronizer.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/synchronizer.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -333,7 +333,9 @@ void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { TEVENT (jni_exit) ; if (UseBiasedLocking) { - BiasedLocking::revoke_and_rebias(obj, false, THREAD); + Handle h_obj(THREAD, obj); + BiasedLocking::revoke_and_rebias(h_obj, false, THREAD); + obj = h_obj(); } assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/virtualspace.cpp --- a/src/share/vm/runtime/virtualspace.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/virtualspace.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -868,8 +868,8 @@ tty->print ("Virtual space:"); if (special()) tty->print(" (pinned in memory)"); tty->cr(); - tty->print_cr(" - committed: %ld", committed_size()); - tty->print_cr(" - reserved: %ld", reserved_size()); + tty->print_cr(" - committed: " SIZE_FORMAT, committed_size()); + tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/vmStructs.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -2291,6 +2291,7 @@ /*************************************/ \ \ declare_preprocessor_constant("FIELDINFO_TAG_SIZE", FIELDINFO_TAG_SIZE) \ + declare_preprocessor_constant("FIELDINFO_TAG_MASK", FIELDINFO_TAG_MASK) \ declare_preprocessor_constant("FIELDINFO_TAG_OFFSET", FIELDINFO_TAG_OFFSET) \ \ /************************************************/ \ diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/runtime/vmThread.cpp --- a/src/share/vm/runtime/vmThread.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/runtime/vmThread.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -570,7 +570,11 @@ if (!t->is_VM_thread()) { SkipGCALot sgcalot(t); // avoid re-entrant attempts to gc-a-lot // JavaThread or WatcherThread - t->check_for_valid_safepoint_state(true); + bool concurrent = op->evaluate_concurrently(); + // only blocking VM operations need to verify the caller's safepoint state: + if (!concurrent) { + t->check_for_valid_safepoint_state(true); + } // New request from Java thread, evaluate prologue if (!op->doit_prologue()) { @@ -582,7 +586,6 @@ // It does not make sense to execute the epilogue, if the VM operation object is getting // deallocated by the VM thread. - bool concurrent = op->evaluate_concurrently(); bool execute_epilog = !op->is_cheap_allocated(); assert(!concurrent || op->is_cheap_allocated(), "concurrent => cheap_allocated"); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/services/diagnosticArgument.cpp --- a/src/share/vm/services/diagnosticArgument.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/services/diagnosticArgument.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,7 @@ template <> void DCmdArgument::parse_value(const char* str, size_t len, TRAPS) { - if (str == NULL || sscanf(str, INT64_FORMAT, &_value) != 1) { + if (str == NULL || sscanf(str, JLONG_FORMAT, &_value) != 1) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Integer parsing error in diagnostic command arguments\n"); } @@ -171,7 +171,7 @@ "Integer parsing error nanotime value: syntax error"); } - int argc = sscanf(str, INT64_FORMAT , &_value._time); + int argc = sscanf(str, JLONG_FORMAT, &_value._time); if (argc != 1) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Integer parsing error nanotime value: syntax error"); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/services/heapDumper.cpp --- a/src/share/vm/services/heapDumper.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/services/heapDumper.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, 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. * * This code is free software; you can redistribute it and/or modify it @@ -1866,7 +1866,7 @@ if (error() == NULL) { char msg[256]; sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]", - os::jlong_format_specifier(), timer()->seconds()); + JLONG_FORMAT, timer()->seconds()); tty->print_cr(msg, writer.bytes_written()); } else { tty->print_cr("Dump file is incomplete: %s", writer.error()); diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/services/lowMemoryDetector.cpp --- a/src/share/vm/services/lowMemoryDetector.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/services/lowMemoryDetector.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -353,7 +353,7 @@ #ifndef PRODUCT void SensorInfo::print() { - tty->print_cr("%s count = %ld pending_triggers = %ld pending_clears = %ld", + tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %ld pending_clears = %ld", (_sensor_on ? "on" : "off"), _sensor_count, _pending_trigger_count, _pending_clear_count); } diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/utilities/globalDefinitions.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -1250,6 +1250,14 @@ #define PTR64_FORMAT "0x%016" PRIx64 +// Format jlong, if necessary +#ifndef JLONG_FORMAT +#define JLONG_FORMAT INT64_FORMAT +#endif +#ifndef JULONG_FORMAT +#define JULONG_FORMAT UINT64_FORMAT +#endif + // Format pointers which change size between 32- and 64-bit. #ifdef _LP64 #define INTPTR_FORMAT "0x%016" PRIxPTR diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/utilities/globalDefinitions_gcc.hpp --- a/src/share/vm/utilities/globalDefinitions_gcc.hpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/utilities/globalDefinitions_gcc.hpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -306,4 +306,8 @@ #endif #define offsetof(klass,field) offset_of(klass,field) +#if defined(_LP64) && defined(__APPLE__) +#define JLONG_FORMAT "%ld" +#endif // _LP64 && __APPLE__ + #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/utilities/ostream.cpp --- a/src/share/vm/utilities/ostream.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/utilities/ostream.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -243,13 +243,11 @@ } void outputStream::print_jlong(jlong value) { - // N.B. Same as INT64_FORMAT - print(os::jlong_format_specifier(), value); + print(JLONG_FORMAT, value); } void outputStream::print_julong(julong value) { - // N.B. Same as UINT64_FORMAT - print(os::julong_format_specifier(), value); + print(JULONG_FORMAT, value); } /** diff -r 22ead76da3f4 -r 274a29bf5682 src/share/vm/utilities/taskqueue.cpp --- a/src/share/vm/utilities/taskqueue.cpp Thu Jan 24 02:03:38 2013 -0800 +++ b/src/share/vm/utilities/taskqueue.cpp Thu Jan 24 09:06:16 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, 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. * * This code is free software; you can redistribute it and/or modify it @@ -239,8 +239,8 @@ #ifdef TRACESPINNING void ParallelTaskTerminator::print_termination_counts() { - gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: %lld " - "Total spins: %lld Total peeks: %lld", + gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: " UINT32_FORMAT + " Total spins: " UINT32_FORMAT " Total peeks: " UINT32_FORMAT, total_yields(), total_spins(), total_peeks()); diff -r 22ead76da3f4 -r 274a29bf5682 test/Makefile --- a/test/Makefile Thu Jan 24 02:03:38 2013 -0800 +++ b/test/Makefile Thu Jan 24 09:06:16 2013 -0800 @@ -189,9 +189,9 @@ $(JTREG) -a -v:fail,error \ $(JTREG_KEY_OPTION) \ $(EXTRA_JTREG_OPTIONS) \ - -r:$(ABS_TEST_OUTPUT_DIR)/JTreport \ - -w:$(ABS_TEST_OUTPUT_DIR)/JTwork \ - -jdk:$(PRODUCT_HOME) \ + -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport \ + -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTwork \ + -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \ $(JAVA_OPTIONS:%=-vmoption:%) \ $(JTREG_TESTDIRS) \ || $(BUNDLE_UP_FAILED)