--- old/src/cpu/zero/vm/stack_zero.cpp 2015-02-24 17:14:33.794605237 +0100 +++ new/src/cpu/zero/vm/stack_zero.cpp 2015-02-24 17:14:33.743606062 +0100 @@ -30,7 +30,9 @@ int ZeroStack::suggest_size(Thread *thread) const { assert(needs_setup(), "already set up"); - return align_size_down(abi_stack_available(thread) / 2, wordSize); + int abi_available = abi_stack_available(thread); + assert(abi_available >= 0, "available abi stack must be >= 0"); + return align_size_down(abi_available / 2, wordSize); } void ZeroStack::handle_overflow(TRAPS) { --- old/src/cpu/zero/vm/stack_zero.inline.hpp 2015-02-24 17:14:35.608575907 +0100 +++ new/src/cpu/zero/vm/stack_zero.inline.hpp 2015-02-24 17:14:35.557576732 +0100 @@ -48,9 +48,11 @@ // to use under normal circumstances. Note that the returned // value can be negative. inline int ZeroStack::abi_stack_available(Thread *thread) const { - int stack_used = thread->stack_base() - (address) &stack_used; + guarantee(Thread::current() == thread, "should run in the same thread"); + int stack_used = thread->stack_base() - (address) &stack_used + + (StackYellowPages+StackRedPages+StackShadowPages) * os::vm_page_size(); int stack_free = thread->stack_size() - stack_used; - return stack_free - shadow_pages_size(); + return stack_free; } #endif // CPU_ZERO_VM_STACK_ZERO_INLINE_HPP --- old/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp 2015-02-24 17:14:36.562560482 +0100 +++ new/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp 2015-02-24 17:14:36.510561323 +0100 @@ -238,7 +238,13 @@ // operation. Note that some platforms only support this with the // limitation that the only valid value to store is the immediate // constant 1. There is a test for this in JNI_CreateJavaVM(). - return __sync_lock_test_and_set (dest, exchange_value); + jint result = __sync_lock_test_and_set (dest, exchange_value); + // All atomic operations are expected to be full memory barriers + // (see atomic.hpp). However, __sync_lock_test_and_set is not + // a full memory barrier, but an acquire barrier. Hence, this added + // barrier. + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } @@ -251,7 +257,9 @@ #ifdef M68K return m68k_lock_test_and_set(dest, exchange_value); #else - return __sync_lock_test_and_set (dest, exchange_value); + intptr_t result = __sync_lock_test_and_set (dest, exchange_value); + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } --- old/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp 2015-02-24 17:14:37.348547774 +0100 +++ new/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp 2015-02-24 17:14:37.297548599 +0100 @@ -232,7 +232,13 @@ // operation. Note that some platforms only support this with the // limitation that the only valid value to store is the immediate // constant 1. There is a test for this in JNI_CreateJavaVM(). - return __sync_lock_test_and_set (dest, exchange_value); + jint result = __sync_lock_test_and_set (dest, exchange_value); + // All atomic operations are expected to be full memory barriers + // (see atomic.hpp). However, __sync_lock_test_and_set is not + // a full memory barrier, but an acquire barrier. Hence, this added + // barrier. + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } @@ -245,7 +251,9 @@ #ifdef M68K return m68k_lock_test_and_set(dest, exchange_value); #else - return __sync_lock_test_and_set (dest, exchange_value); + intptr_t result = __sync_lock_test_and_set (dest, exchange_value); + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } --- old/src/share/vm/interpreter/interpreterRuntime.cpp 2015-02-24 17:14:38.268532899 +0100 +++ new/src/share/vm/interpreter/interpreterRuntime.cpp 2015-02-24 17:14:38.214533772 +0100 @@ -407,7 +407,11 @@ // during deoptimization so the interpreter needs to skip it when // the frame is popped. thread->set_do_not_unlock_if_synchronized(true); +#ifdef CC_INTERP + return (address) -1; +#else return Interpreter::remove_activation_entry(); +#endif } // Need to do this check first since when _do_not_unlock_if_synchronized