提交 c96183fb 编写于 作者: C coleenp

Merge

......@@ -67,7 +67,7 @@
#define JAVA_CLASSFILE_MAGIC 0xCAFEBABE
#define JAVA_MIN_SUPPORTED_VERSION 45
#define JAVA_MAX_SUPPORTED_VERSION 51
#define JAVA_MAX_SUPPORTED_VERSION 52
#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
// Used for two backward compatibility reasons:
......
......@@ -413,8 +413,7 @@ char* java_lang_String::as_utf8_string(oop java_string, int start, int len) {
}
bool java_lang_String::equals(oop java_string, jchar* chars, int len) {
assert(SharedSkipVerify ||
java_string->klass() == SystemDictionary::String_klass(),
assert(java_string->klass() == SystemDictionary::String_klass(),
"must be java_string");
typeArrayOop value = java_lang_String::value(java_string);
int offset = java_lang_String::offset(java_string);
......
......@@ -92,6 +92,26 @@ void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flag
return res;
}
void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_constant,
allocation_type type, MEMFLAGS flags) {
//should only call this with std::nothrow, use other operator new() otherwise
address res;
switch (type) {
case C_HEAP:
res = (address)AllocateHeap(size, flags, CALLER_PC, AllocFailStrategy::RETURN_NULL);
DEBUG_ONLY(if (res!= NULL) set_allocation_type(res, C_HEAP);)
break;
case RESOURCE_AREA:
// new(size) sets allocation type RESOURCE_AREA.
res = (address)operator new(size, std::nothrow);
break;
default:
ShouldNotReachHere();
}
return res;
}
void ResourceObj::operator delete(void* p) {
assert(((ResourceObj *)p)->allocated_on_C_heap(),
"delete only allowed for C_HEAP objects");
......@@ -506,7 +526,7 @@ void Arena::signal_out_of_memory(size_t sz, const char* whence) const {
}
// Grow a new Chunk
void* Arena::grow( size_t x ) {
void* Arena::grow(size_t x, AllocFailType alloc_failmode) {
// Get minimal required size. Either real big, or even bigger for giant objs
size_t len = MAX2(x, (size_t) Chunk::size);
......@@ -514,7 +534,10 @@ void* Arena::grow( size_t x ) {
_chunk = new (len) Chunk(len);
if (_chunk == NULL) {
signal_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
if (alloc_failmode == AllocFailStrategy::EXIT_OOM) {
signal_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
}
return NULL;
}
if (k) k->set_next(_chunk); // Append new chunk to end of linked list
else _first = _chunk;
......@@ -529,13 +552,16 @@ void* Arena::grow( size_t x ) {
// Reallocate storage in Arena.
void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size) {
void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFailType alloc_failmode) {
assert(new_size >= 0, "bad size");
if (new_size == 0) return NULL;
#ifdef ASSERT
if (UseMallocOnly) {
// always allocate a new object (otherwise we'll free this one twice)
char* copy = (char*)Amalloc(new_size);
char* copy = (char*)Amalloc(new_size, alloc_failmode);
if (copy == NULL) {
return NULL;
}
size_t n = MIN2(old_size, new_size);
if (n > 0) memcpy(copy, old_ptr, n);
Afree(old_ptr,old_size); // Mostly done to keep stats accurate
......@@ -561,7 +587,10 @@ void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size) {
}
// Oops, got to relocate guts
void *new_ptr = Amalloc(new_size);
void *new_ptr = Amalloc(new_size, alloc_failmode);
if (new_ptr == NULL) {
return NULL;
}
memcpy( new_ptr, c_old, old_size );
Afree(c_old,old_size); // Mostly done to keep stats accurate
return new_ptr;
......
......@@ -53,6 +53,12 @@
#endif
#endif
class AllocFailStrategy {
public:
enum AllocFailEnum { EXIT_OOM, RETURN_NULL };
};
typedef AllocFailStrategy::AllocFailEnum AllocFailType;
// All classes in the virtual machine must be subclassed
// by one of the following allocation classes:
//
......@@ -315,7 +321,8 @@ protected:
Chunk *_first; // First chunk
Chunk *_chunk; // current chunk
char *_hwm, *_max; // High water mark and max in current chunk
void* grow(size_t x); // Get a new Chunk of at least size x
// Get a new Chunk of at least size x
void* grow(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
size_t _size_in_bytes; // Size of arena (used for native memory tracking)
NOT_PRODUCT(static julong _bytes_allocated;) // total #bytes allocated since start
......@@ -350,14 +357,14 @@ protected:
void operator delete(void* p);
// Fast allocate in the arena. Common case is: pointer test + increment.
void* Amalloc(size_t x) {
void* Amalloc(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
x = ARENA_ALIGN(x);
debug_only(if (UseMallocOnly) return malloc(x);)
check_for_overflow(x, "Arena::Amalloc");
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x);
return grow(x, alloc_failmode);
} else {
char *old = _hwm;
_hwm += x;
......@@ -365,13 +372,13 @@ protected:
}
}
// Further assume size is padded out to words
void *Amalloc_4(size_t x) {
void *Amalloc_4(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
debug_only(if (UseMallocOnly) return malloc(x);)
check_for_overflow(x, "Arena::Amalloc_4");
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x);
return grow(x, alloc_failmode);
} else {
char *old = _hwm;
_hwm += x;
......@@ -381,7 +388,7 @@ protected:
// Allocate with 'double' alignment. It is 8 bytes on sparc.
// In other cases Amalloc_D() should be the same as Amalloc_4().
void* Amalloc_D(size_t x) {
void* Amalloc_D(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
debug_only(if (UseMallocOnly) return malloc(x);)
#if defined(SPARC) && !defined(_LP64)
......@@ -392,7 +399,7 @@ protected:
check_for_overflow(x, "Arena::Amalloc_D");
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x); // grow() returns a result aligned >= 8 bytes.
return grow(x, alloc_failmode); // grow() returns a result aligned >= 8 bytes.
} else {
char *old = _hwm;
_hwm += x;
......@@ -412,7 +419,8 @@ protected:
if (((char*)ptr) + size == _hwm) _hwm = (char*)ptr;
}
void *Arealloc( void *old_ptr, size_t old_size, size_t new_size );
void *Arealloc( void *old_ptr, size_t old_size, size_t new_size,
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
// Move contents of this arena into an empty arena
Arena *move_contents(Arena *empty_arena);
......@@ -458,9 +466,12 @@ private:
//%note allocation_1
extern char* resource_allocate_bytes(size_t size);
extern char* resource_allocate_bytes(Thread* thread, size_t size);
extern char* resource_reallocate_bytes( char *old, size_t old_size, size_t new_size);
extern char* resource_allocate_bytes(size_t size,
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
extern char* resource_allocate_bytes(Thread* thread, size_t size,
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
extern char* resource_reallocate_bytes( char *old, size_t old_size, size_t new_size,
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
extern void resource_free_bytes( char *old, size_t size );
//----------------------------------------------------------------------
......@@ -496,6 +507,8 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
public:
void* operator new(size_t size, allocation_type type, MEMFLAGS flags);
void* operator new(size_t size, const std::nothrow_t& nothrow_constant,
allocation_type type, MEMFLAGS flags);
void* operator new(size_t size, Arena *arena) {
address res = (address)arena->Amalloc(size);
DEBUG_ONLY(set_allocation_type(res, ARENA);)
......@@ -506,6 +519,13 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
return res;
}
void* operator new(size_t size, const std::nothrow_t& nothrow_constant) {
address res = (address)resource_allocate_bytes(size, AllocFailStrategy::RETURN_NULL);
DEBUG_ONLY(if (res != NULL) set_allocation_type(res, RESOURCE_AREA);)
return res;
}
void operator delete(void* p);
};
......
......@@ -48,7 +48,8 @@ inline void inc_stat_counter(volatile julong* dest, julong add_value) {
#endif
// allocate using malloc; will fail if no memory available
inline char* AllocateHeap(size_t size, MEMFLAGS flags, address pc = 0) {
inline char* AllocateHeap(size_t size, MEMFLAGS flags, address pc = 0,
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
if (pc == 0) {
pc = CURRENT_PC;
}
......@@ -56,16 +57,17 @@ inline char* AllocateHeap(size_t size, MEMFLAGS flags, address pc = 0) {
#ifdef ASSERT
if (PrintMallocFree) trace_heap_malloc(size, "AllocateHeap", p);
#endif
if (p == NULL) vm_exit_out_of_memory(size, "AllocateHeap");
if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) vm_exit_out_of_memory(size, "AllocateHeap");
return p;
}
inline char* ReallocateHeap(char *old, size_t size, MEMFLAGS flags) {
inline char* ReallocateHeap(char *old, size_t size, MEMFLAGS flags,
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
char* p = (char*) os::realloc(old, size, flags, CURRENT_PC);
#ifdef ASSERT
if (PrintMallocFree) trace_heap_malloc(size, "ReallocateHeap", p);
#endif
if (p == NULL) vm_exit_out_of_memory(size, "ReallocateHeap");
if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) vm_exit_out_of_memory(size, "ReallocateHeap");
return p;
}
......@@ -91,11 +93,13 @@ template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size,
template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
const std::nothrow_t& nothrow_constant, address caller_pc) {
#ifdef ASSERT
void* p = os::malloc(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
AllocFailStrategy::RETURN_NULL);
if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
return p;
#else
return os::malloc(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
return (void *) AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
AllocFailStrategy::RETURN_NULL);
#endif
}
......
......@@ -45,15 +45,15 @@ debug_only(int ResourceArea::_warned;) // to suppress multiple warnings
// The following routines are declared in allocation.hpp and used everywhere:
// Allocation in thread-local resource area
extern char* resource_allocate_bytes(size_t size) {
return Thread::current()->resource_area()->allocate_bytes(size);
extern char* resource_allocate_bytes(size_t size, AllocFailType alloc_failmode) {
return Thread::current()->resource_area()->allocate_bytes(size, alloc_failmode);
}
extern char* resource_allocate_bytes(Thread* thread, size_t size) {
return thread->resource_area()->allocate_bytes(size);
extern char* resource_allocate_bytes(Thread* thread, size_t size, AllocFailType alloc_failmode) {
return thread->resource_area()->allocate_bytes(size, alloc_failmode);
}
extern char* resource_reallocate_bytes( char *old, size_t old_size, size_t new_size){
return (char*)Thread::current()->resource_area()->Arealloc(old, old_size, new_size);
extern char* resource_reallocate_bytes( char *old, size_t old_size, size_t new_size, AllocFailType alloc_failmode){
return (char*)Thread::current()->resource_area()->Arealloc(old, old_size, new_size, alloc_failmode);
}
extern void resource_free_bytes( char *old, size_t size ) {
......
......@@ -68,7 +68,7 @@ public:
debug_only(_nesting = 0;);
}
char* allocate_bytes(size_t size) {
char* allocate_bytes(size_t size, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
#ifdef ASSERT
if (_nesting < 1 && !_warned++)
fatal("memory leak: allocating without ResourceMark");
......@@ -78,7 +78,7 @@ public:
return (*save = (char*)os::malloc(size, mtThread));
}
#endif
return (char*)Amalloc(size);
return (char*)Amalloc(size, alloc_failmode);
}
debug_only(int nesting() const { return _nesting; });
......
......@@ -1268,10 +1268,6 @@ void Universe::print_heap_after_gc(outputStream* st, bool ignore_extended) {
}
void Universe::verify(bool silent, VerifyOption option) {
if (SharedSkipVerify) {
return;
}
// The use of _verify_in_progress is a temporary work around for
// 6320749. Don't bother with a creating a class to set and clear
// it since it is only used in this method and the control flow is
......
......@@ -356,12 +356,11 @@ void Klass::set_next_sibling(Klass* s) {
}
void Klass::append_to_sibling_list() {
debug_only(if (!SharedSkipVerify) verify();)
debug_only(verify();)
// add ourselves to superklass' subklass list
InstanceKlass* super = superklass();
if (super == NULL) return; // special case: class Object
assert(SharedSkipVerify ||
(!super->is_interface() // interfaces cannot be supers
assert((!super->is_interface() // interfaces cannot be supers
&& (super->superklass() == NULL || !is_interface())),
"an interface can only be a subklass of Object");
Klass* prev_first_subklass = super->subklass_oop();
......@@ -371,7 +370,7 @@ void Klass::append_to_sibling_list() {
}
// make ourselves the superklass' first subklass
super->set_subklass(this);
debug_only(if (!SharedSkipVerify) verify();)
debug_only(verify();)
}
void Klass::remove_from_sibling_list() {
......
......@@ -1135,7 +1135,7 @@ static jint invoke_primitive_field_callback_for_static_fields
// get offset and field value
int offset = field->field_offset();
address addr = (address)klass + offset;
address addr = (address)klass->java_mirror() + offset;
jvalue value;
copy_to_jvalue(&value, addr, value_type);
......
......@@ -3539,10 +3539,6 @@ class CommandLineFlags {
product(uintx, SharedDummyBlockSize, 0, \
"Size of dummy block used to shift heap addresses (in bytes)") \
\
diagnostic(bool, SharedSkipVerify, false, \
"Skip assert() and verify() which page-in unwanted shared " \
"objects. ") \
\
diagnostic(bool, EnableInvokeDynamic, true, \
"support JSR 292 (method handles, invokedynamic, " \
"anonymous classes") \
......
......@@ -48,7 +48,7 @@
oop* HandleArea::allocate_handle(oop obj) {
assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark");
assert(_no_handle_mark_nesting == 0, "allocating handle inside NoHandleMark");
assert(SharedSkipVerify || obj->is_oop(), "sanity check");
assert(obj->is_oop(), "sanity check");
return real_allocate_handle(obj);
}
......
......@@ -110,11 +110,11 @@ class Handle VALUE_OBJ_CLASS_SPEC {
/* Constructors */ \
type##Handle () : Handle() {} \
type##Handle (type##Oop obj) : Handle((oop)obj) { \
assert(SharedSkipVerify || is_null() || ((oop)obj)->is_a(), \
assert(is_null() || ((oop)obj)->is_a(), \
"illegal type"); \
} \
type##Handle (Thread* thread, type##Oop obj) : Handle(thread, (oop)obj) { \
assert(SharedSkipVerify || is_null() || ((oop)obj)->is_a(), "illegal type"); \
assert(is_null() || ((oop)obj)->is_a(), "illegal type"); \
} \
\
/* Operators for ease of use */ \
......@@ -201,11 +201,11 @@ class instanceKlassHandle : public KlassHandle {
/* Constructors */
instanceKlassHandle () : KlassHandle() {}
instanceKlassHandle (const Klass* k) : KlassHandle(k) {
assert(SharedSkipVerify || k == NULL || k->oop_is_instance(),
assert(k == NULL || k->oop_is_instance(),
"illegal type");
}
instanceKlassHandle (Thread* thread, const Klass* k) : KlassHandle(thread, k) {
assert(SharedSkipVerify || k == NULL || k->oop_is_instance(),
assert(k == NULL || k->oop_is_instance(),
"illegal type");
}
/* Access to klass part */
......
......@@ -177,7 +177,8 @@ void* Thread::allocate(size_t size, bool throw_excpt, MEMFLAGS flags) {
const int alignment = markOopDesc::biased_lock_alignment;
size_t aligned_size = size + (alignment - sizeof(intptr_t));
void* real_malloc_addr = throw_excpt? AllocateHeap(aligned_size, flags, CURRENT_PC)
: os::malloc(aligned_size, flags, CURRENT_PC);
: AllocateHeap(aligned_size, flags, CURRENT_PC,
AllocFailStrategy::RETURN_NULL);
void* aligned_addr = (void*) align_size_up((intptr_t) real_malloc_addr, alignment);
assert(((uintptr_t) aligned_addr + (uintptr_t) size) <=
((uintptr_t) real_malloc_addr + (uintptr_t) aligned_size),
......@@ -191,7 +192,7 @@ void* Thread::allocate(size_t size, bool throw_excpt, MEMFLAGS flags) {
return aligned_addr;
} else {
return throw_excpt? AllocateHeap(size, flags, CURRENT_PC)
: os::malloc(size, flags, CURRENT_PC);
: AllocateHeap(size, flags, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
}
}
......
......@@ -110,7 +110,7 @@ class Thread: public ThreadShadow {
void* _real_malloc_address;
public:
void* operator new(size_t size) { return allocate(size, true); }
void* operator new(size_t size, std::nothrow_t& nothrow_constant) { return allocate(size, false); }
void* operator new(size_t size, const std::nothrow_t& nothrow_constant) { return allocate(size, false); }
void operator delete(void* p);
protected:
......
......@@ -4,6 +4,7 @@
## @test Test6929067.sh
## @bug 6929067
## @summary Stack guard pages should be removed when thread is detached
## @compile T.java
## @run shell Test6929067.sh
##
......@@ -33,31 +34,97 @@ case "$OS" in
;;
esac
# Choose arch: i386 or amd64 (test is Linux-specific)
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1
# Bitness:
# Cannot simply look at TESTVMOPTS as -d64 is not
# passed if there is only a 64-bit JVM available.
${TESTJAVA}/bin/java ${TESTVMOPTS} -version 2>1 | grep "64-Bit" >/dev/null
grep "64-Bit" vm_version.out > ${NULL}
if [ "$?" = "0" ]
then
ARCH=amd64
COMP_FLAG="-m64"
else
ARCH=i386
COMP_FLAG="-m32"
fi
LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${ARCH}/client:/usr/openwin/lib:/usr/dt/lib:/usr/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
THIS_DIR=`pwd`
# Architecture:
# Translate uname output to JVM directory name, but permit testing
# 32-bit x86 on an x64 platform.
ARCH=`uname -m`
case "$ARCH" in
x86_64)
if [ "$COMP_FLAG" = "-m32" ]; then
ARCH=i386
else
ARCH=amd64
fi
;;
ppc64)
if [ "$COMP_FLAG" = "-m32" ]; then
ARCH=ppc
else
ARCH=ppc64
fi
;;
sparc64)
if [ "$COMP_FLAG" = "-m32" ]; then
ARCH=sparc
else
ARCH=sparc64
fi
;;
arm*)
# 32-bit ARM machine: compiler may not recognise -m32
COMP_FLAG=""
ARCH=arm
;;
aarch64)
# 64-bit arm machine, could be testing 32 or 64-bit:
if [ "$COMP_FLAG" = "-m32" ]; then
ARCH=arm
else
ARCH=aarch64
fi
;;
i586)
ARCH=i386
;;
i686)
ARCH=i386
;;
# Assuming other ARCH values need no translation
esac
cp ${TESTSRC}${FS}invoke.c ${THIS_DIR}
cp ${TESTSRC}${FS}T.java ${THIS_DIR}
# VM type: need to know server or client
VMTYPE=client
grep Server vm_version.out > ${NULL}
if [ "$?" = "0" ]
then
VMTYPE=server
fi
LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
cp ${TESTSRC}${FS}invoke.c .
# Copy the result of our @compile action:
cp ${TESTCLASSES}${FS}T.class .
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
${TESTJAVA}${FS}bin${FS}javac T.java
echo "Architecture: ${ARCH}"
echo "Compilation flag: ${COMP_FLAG}"
echo "VM type: ${VMTYPE}"
gcc -DLINUX ${COMP_FLAG} -o invoke \
-I${TESTJAVA}/include -I${TESTJAVA}/include/linux \
-L${TESTJAVA}/jre/lib/${ARCH}/${VMTYPE} \
-ljvm -lpthread invoke.c
gcc -o invoke -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c ${TESTJAVA}/jre/lib/${ARCH}/client/libjvm.so
./invoke
exit $?
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册