You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2006/12/17 03:16:08 UTC
svn commit: r487928 - in /harmony/enhanced/drlvm/trunk/vm/vmcore:
include/Class.h src/class_support/Prepare.cpp src/jni/jni_array.cpp
src/jvmti/jvmti_object.cpp src/object/vm_arrays.cpp
src/thread/object_generic.cpp src/util/vm_strings.cpp
Author: gshimansky
Date: Sat Dec 16 18:16:07 2006
New Revision: 487928
URL: http://svn.apache.org/viewvc?view=rev&rev=487928
Log:
Applied HARMONY-2529 [drlvm] crash, very large arrays used incorrectly
I had to make a change to make this patch compile on win32: in Class.h:1681 length was changed to (unsigned)length. Attached test passes after this patch.
Tests passed on Ubuntu6 x86, WindowsXP and SuSE9 x86_64
Modified:
harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_array.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_object.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/vm_arrays.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/object_generic.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h?view=diff&rev=487928&r1=487927&r2=487928
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h Sat Dec 16 18:16:07 2006
@@ -930,6 +930,9 @@
// size of element of array; equals zero, if this class is not an array
unsigned int m_array_element_size;
+ // shift corresponding to size of element of array, undefined for non-arrays
+ unsigned int m_array_element_shift;
+
// type descriptor for array element class
TypeDesc* m_array_element_type_desc;
@@ -1656,18 +1659,35 @@
* @param[in] length - the length of the array
* @return The size of the array of specified length in bytes.*/
unsigned calculate_array_size(int length) const {
+ if (length < 0) {
+ return 0;
+ }
+
+ assert(m_array_element_size);
assert(length >= 0);
assert(is_array());
- assert(m_array_element_size);
unsigned first_elem_offset;
- if(m_array_element_size < 8) {
+ if(m_array_element_shift < 3) {
first_elem_offset = VM_VECTOR_FIRST_ELEM_OFFSET_1_2_4;
} else {
first_elem_offset = VM_VECTOR_FIRST_ELEM_OFFSET_8;
}
- unsigned size = first_elem_offset + length*m_array_element_size;
+
+ // check overflow, we need:
+ // first_elem_offset + (length << m_array_element_shift)
+ // + GC_OBJECT_ALIGNMENT < NEXT_TO_HIGH_BIT_CLEAR_MASK
+ //
+ if (((NEXT_TO_HIGH_BIT_CLEAR_MASK - GC_OBJECT_ALIGNMENT - first_elem_offset)
+ >> m_array_element_shift) < (unsigned)length) {
+ // zero means overflow
+ return 0;
+ }
+
+
+ unsigned size = first_elem_offset + (length << m_array_element_shift);
size = (((size + (GC_OBJECT_ALIGNMENT - 1)) & (~(GC_OBJECT_ALIGNMENT - 1))));
assert((size % GC_OBJECT_ALIGNMENT) == 0);
+ assert((size & NEXT_TO_HIGH_BIT_SET_MASK) == 0);
return size;
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp?view=diff&rev=487928&r1=487927&r2=487928
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp Sat Dec 16 18:16:07 2006
@@ -109,38 +109,38 @@
// Given a class that is a primitive array returns the size
// of an element in an instance of the class
// NOTE: the class is not fully formed at this time
-unsigned sizeof_primitive_array_element(Class *p_class)
+unsigned shift_of_primitive_array_element(Class *p_class)
{
const String *elt_type = p_class->get_name();
char elt = elt_type->bytes[1];
unsigned int sz;
switch (elt) {
case 'C':
- sz = 2;
+ sz = 1;
break;
case 'B':
- sz = 1;
+ sz = 0;
break;
case 'D':
- sz = 8;
+ sz = 3;
break;
case 'F':
- sz = 4;
+ sz = 2;
break;
case 'I':
- sz = 4;
+ sz = 2;
break;
case 'J':
- sz = 8;
+ sz = 3;
break;
case 'S':
- sz = 2;
+ sz = 1;
break;
case 'Z': // boolean
- sz = 1;
+ sz = 0;
break;
case '[':
- sz = 4; // This works for the H32, V64, R32 version.
+ sz = 2; // This works for the H32, V64, R32 version.
assert(OBJECT_REF_SIZE == 4);
break;
default:
@@ -148,7 +148,7 @@
return 0;
}
return sz;
-} //sizeof_primitive_array_element
+} //shift_of_primitive_array_element
//
@@ -1396,9 +1396,11 @@
if(is_array()) {
m_array_element_size = (vm_references_are_compressed()
? sizeof(COMPRESSED_REFERENCE) : sizeof(RAW_REFERENCE));
+ m_array_element_shift = m_array_element_size == 8 ? 3 : 2;
m_vtable->class_properties |= CL_PROP_ARRAY_MASK;
if(is_vector_of_primitives(this)) {
- m_array_element_size = sizeof_primitive_array_element(this);
+ m_array_element_shift = shift_of_primitive_array_element(this);
+ m_array_element_size = 1 << m_array_element_shift;
m_vtable->class_properties |= CL_PROP_NON_REF_ARRAY_MASK;
}
m_vtable->array_element_size = (unsigned short)m_array_element_size;
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_array.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_array.cpp?view=diff&rev=487928&r1=487927&r2=487928
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_array.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_array.cpp Sat Dec 16 18:16:07 2006
@@ -239,6 +239,8 @@
Class *clss = vm_env->ArrayOfBoolean_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
Vector_Handle array = gc_alloc(sz, clss->get_allocation_handle(),
@@ -274,6 +276,8 @@
Class *clss = vm_env->ArrayOfByte_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
Vector_Handle array = gc_alloc(sz, clss->get_allocation_handle(),
@@ -309,6 +313,8 @@
Class *clss = vm_env->ArrayOfChar_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
Vector_Handle array = gc_alloc(sz, clss->get_allocation_handle(),
@@ -344,6 +350,8 @@
Class *clss = vm_env->ArrayOfShort_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
@@ -380,6 +388,8 @@
Class *clss = vm_env->ArrayOfInt_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
Vector_Handle array = gc_alloc(sz, clss->get_allocation_handle(),
@@ -415,6 +425,8 @@
Class *clss = vm_env->ArrayOfLong_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
Vector_Handle array = gc_alloc(sz, clss->get_allocation_handle(),
@@ -450,6 +462,8 @@
Class *clss = vm_env->ArrayOfFloat_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
Vector_Handle array = gc_alloc(sz, clss->get_allocation_handle(),
@@ -485,6 +499,8 @@
Class *clss = vm_env->ArrayOfDouble_Class;
unsigned sz = clss->calculate_array_size(length);
+ if (sz == 0) return NULL;
+
tmn_suspend_disable(); //---------------------------------v
ObjectHandle h = oh_allocate_local_handle();
Vector_Handle array = gc_alloc(sz, clss->get_allocation_handle(),
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_object.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_object.cpp?view=diff&rev=487928&r1=487927&r2=487928
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_object.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_object.cpp Sat Dec 16 18:16:07 2006
@@ -79,6 +79,7 @@
*size_ptr = object_clss->calculate_array_size(get_vector_length((Vector_Handle)mo));
else
*size_ptr = class_get_boxed_data_size(object_clss);
+ assert(*size_ptr > 0);
tmn_suspend_enable();
return JVMTI_ERROR_NONE;
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/vm_arrays.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/vm_arrays.cpp?view=diff&rev=487928&r1=487927&r2=487928
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/vm_arrays.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/vm_arrays.cpp Sat Dec 16 18:16:07 2006
@@ -71,25 +71,22 @@
assert(!hythread_is_suspend_enabled());
assert(!arr_clss->is_array_of_primitives());
- if (length < 0) {
- tmn_suspend_enable();
- exn_raise_by_name("java/lang/NegativeArraySizeException");
- tmn_suspend_disable();
- return NULL;
- }
-
unsigned sz = arr_clss->calculate_array_size(length);
-
- if ((length & TWO_HIGHEST_BITS_SET_MASK) || (sz & TWO_HIGHEST_BITS_SET_MASK)) {
- // VM does not support arrays of length >= MAXINT>>2
- // GC does not support objects of length >= 1Gb
+ if (sz == 0) {
tmn_suspend_enable();
- exn_raise_by_name("java/lang/OutOfMemoryError",
- "VM doesn't support arrays of the requested size");
+
+ if (length < 0) {
+ exn_raise_by_name("java/lang/NegativeArraySizeException");
+ } else {
+ exn_raise_by_name("java/lang/OutOfMemoryError",
+ "VM doesn't support arrays of the requested size");
+ }
tmn_suspend_disable();
return NULL;
}
+ assert((sz & NEXT_TO_HIGH_BIT_SET_MASK) == 0);
+
Vector_Handle object_array = (Vector_Handle )gc_alloc(sz,
arr_clss->get_allocation_handle(), vm_get_gc_thread_local());
#ifdef VM_STATS
@@ -121,20 +118,21 @@
Vector_Handle vm_new_vector_primitive(Class *vector_class, int length) {
ASSERT_RAISE_AREA;
assert(!hythread_is_suspend_enabled());
- // VM does not support arrays of length >= MAXINT>>2
- if (length & TWO_HIGHEST_BITS_SET_MASK) {
+ assert(vector_class->is_array_of_primitives());
+ unsigned sz = vector_class->calculate_array_size(length);
+
+ if (sz == 0) {
tmn_suspend_enable();
if (length < 0) {
exn_raise_by_name("java/lang/NegativeArraySizeException");
} else {
exn_raise_by_name("java/lang/OutOfMemoryError",
- "VM doesn't support arrays of the requested size");
+ "VM doesn't support arrays of the requested size");
}
tmn_suspend_disable();
return NULL;
}
- assert(vector_class->is_array_of_primitives());
- unsigned sz = vector_class->calculate_array_size(length);
+
Vector_Handle vector = (Vector_Handle)gc_alloc(sz,
vector_class->get_allocation_handle(), vm_get_gc_thread_local());
#ifdef VM_STATS
@@ -184,6 +182,7 @@
if (0 != (length&TWO_HIGHEST_BITS_SET_MASK)) return;
VTable *vector_vtable = ManagedObject::allocation_handle_to_vtable(vector_handle);
unsigned sz = vector_vtable->clss->calculate_array_size(length);
+ assert(sz > 0);
vector_vtable->clss->instance_allocated(sz);
if((vector_vtable->class_properties & CL_PROP_NON_REF_ARRAY_MASK) == 0)
{
@@ -196,21 +195,22 @@
Vector_Handle vm_new_vector_using_vtable_and_thread_pointer(int length, Allocation_Handle vector_handle, void *tp)
{
assert( ! hythread_is_suspend_enabled());
- // VM does not support arrays of length >= MAXINT>>2
- if (length & TWO_HIGHEST_BITS_SET_MASK) {
+
+ VTable *vector_vtable = ManagedObject::allocation_handle_to_vtable(vector_handle);
+ unsigned sz = vector_vtable->clss->calculate_array_size(length);
+ if (sz == 0) {
tmn_suspend_enable();
if (length < 0) {
exn_raise_by_name("java/lang/NegativeArraySizeException");
} else {
exn_raise_by_name("java/lang/OutOfMemoryError",
- "VM doesn't support arrays of the requested size");
+ "VM doesn't support arrays of the requested size");
}
tmn_suspend_disable();
return NULL;
}
- VTable *vector_vtable = ManagedObject::allocation_handle_to_vtable(vector_handle);
- unsigned sz = vector_vtable->clss->calculate_array_size(length);
+
#ifdef VM_STATSxxx // Functionality moved into vm_new_vector_update_stats().
vector_vtable->clss->instance_allocated(sz);
#endif //VM_STATS
@@ -233,14 +233,13 @@
Vector_Handle vm_new_vector_or_null_using_vtable_and_thread_pointer(int length, Allocation_Handle vector_handle, void *tp)
{
- // VM does not support arrays of length >= MAXINT>>2
- if (0 != (length&TWO_HIGHEST_BITS_SET_MASK)) {
- // exception wiil be thown from other method
- return NULL;
- }
-
VTable *vector_vtable = ManagedObject::allocation_handle_to_vtable(vector_handle);
unsigned sz = vector_vtable->clss->calculate_array_size(length);
+
+ if (sz == 0) {
+ // Unsupported size
+ return NULL;
+ }
Vector_Handle vector = (Vector_Handle)gc_alloc_fast(sz, vector_handle, tp);
if (vector == NULL)
{
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/object_generic.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/object_generic.cpp?view=diff&rev=487928&r1=487927&r2=487928
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/object_generic.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/object_generic.cpp Sat Dec 16 18:16:07 2006
@@ -129,6 +129,7 @@
// clone an array
int32 length = get_vector_length((Vector_Handle) h->object);
size = vt->clss->calculate_array_size(length);
+ assert(size > 0);
result = (ManagedObject*)
vm_new_vector_using_vtable_and_thread_pointer(length,
vt->clss->get_allocation_handle(), vm_get_gc_thread_local());
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp?view=diff&rev=487928&r1=487927&r2=487928
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp Sat Dec 16 18:16:07 2006
@@ -244,6 +244,13 @@
assert(clss);
unsigned sz = clss->calculate_array_size(unicode_length);
+ if (sz == 0) {
+ // string too long
+ *str = NULL;
+ exn_raise_object(VM_Global_State::loader_env->java_lang_OutOfMemoryError);
+ return;
+ }
+
Vector_Handle array = vm_alloc_and_report_ti(sz, clss->get_allocation_handle(),
vm_get_gc_thread_local(), clss);
if(!array) { // OutOfMemory should be thrown