提交 b1caa4ad 编写于 作者: J jcoomes

6845368: large objects cause a crash or unexpected exception

Reviewed-by: jmasa, iveresov
上级 c1de0e1e
...@@ -766,16 +766,16 @@ enum FieldAllocationType { ...@@ -766,16 +766,16 @@ enum FieldAllocationType {
struct FieldAllocationCount { struct FieldAllocationCount {
int static_oop_count; unsigned int static_oop_count;
int static_byte_count; unsigned int static_byte_count;
int static_short_count; unsigned int static_short_count;
int static_word_count; unsigned int static_word_count;
int static_double_count; unsigned int static_double_count;
int nonstatic_oop_count; unsigned int nonstatic_oop_count;
int nonstatic_byte_count; unsigned int nonstatic_byte_count;
int nonstatic_short_count; unsigned int nonstatic_short_count;
int nonstatic_word_count; unsigned int nonstatic_word_count;
int nonstatic_double_count; unsigned int nonstatic_double_count;
}; };
typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface, typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface,
...@@ -2908,11 +2908,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -2908,11 +2908,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
} }
// end of "discovered" field compactibility fix // end of "discovered" field compactibility fix
int nonstatic_double_count = fac.nonstatic_double_count; unsigned int nonstatic_double_count = fac.nonstatic_double_count;
int nonstatic_word_count = fac.nonstatic_word_count; unsigned int nonstatic_word_count = fac.nonstatic_word_count;
int nonstatic_short_count = fac.nonstatic_short_count; unsigned int nonstatic_short_count = fac.nonstatic_short_count;
int nonstatic_byte_count = fac.nonstatic_byte_count; unsigned int nonstatic_byte_count = fac.nonstatic_byte_count;
int nonstatic_oop_count = fac.nonstatic_oop_count; unsigned int nonstatic_oop_count = fac.nonstatic_oop_count;
bool super_has_nonstatic_fields = bool super_has_nonstatic_fields =
(super_klass() != NULL && super_klass->has_nonstatic_fields()); (super_klass() != NULL && super_klass->has_nonstatic_fields());
...@@ -2922,26 +2922,26 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -2922,26 +2922,26 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
nonstatic_oop_count) != 0); nonstatic_oop_count) != 0);
// Prepare list of oops for oop maps generation. // Prepare list of oops for oop map generation.
u2* nonstatic_oop_offsets; int* nonstatic_oop_offsets;
u2* nonstatic_oop_counts; unsigned int* nonstatic_oop_counts;
int nonstatic_oop_map_count = 0; unsigned int nonstatic_oop_map_count = 0;
nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
THREAD, u2, nonstatic_oop_count+1); THREAD, int, nonstatic_oop_count + 1);
nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
THREAD, u2, nonstatic_oop_count+1); THREAD, unsigned int, nonstatic_oop_count + 1);
// Add fake fields for java.lang.Class instances (also see above). // Add fake fields for java.lang.Class instances (also see above).
// FieldsAllocationStyle and CompactFields values will be reset to default. // FieldsAllocationStyle and CompactFields values will be reset to default.
if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) { if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) {
java_lang_Class_fix_post(&next_nonstatic_field_offset); java_lang_Class_fix_post(&next_nonstatic_field_offset);
nonstatic_oop_offsets[0] = (u2)first_nonstatic_field_offset; nonstatic_oop_offsets[0] = first_nonstatic_field_offset;
int fake_oop_count = (( next_nonstatic_field_offset - const uint fake_oop_count = (next_nonstatic_field_offset -
first_nonstatic_field_offset ) / heapOopSize); first_nonstatic_field_offset) / heapOopSize;
nonstatic_oop_counts [0] = (u2)fake_oop_count; nonstatic_oop_counts[0] = fake_oop_count;
nonstatic_oop_map_count = 1; nonstatic_oop_map_count = 1;
nonstatic_oop_count -= fake_oop_count; nonstatic_oop_count -= fake_oop_count;
first_nonstatic_oop_offset = first_nonstatic_field_offset; first_nonstatic_oop_offset = first_nonstatic_field_offset;
} else { } else {
first_nonstatic_oop_offset = 0; // will be set for first oop field first_nonstatic_oop_offset = 0; // will be set for first oop field
...@@ -3119,12 +3119,14 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -3119,12 +3119,14 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// Update oop maps // Update oop maps
if( nonstatic_oop_map_count > 0 && if( nonstatic_oop_map_count > 0 &&
nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
(u2)(real_offset - nonstatic_oop_counts[nonstatic_oop_map_count - 1] * heapOopSize) ) { real_offset -
int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
heapOopSize ) {
// Extend current oop map // Extend current oop map
nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1; nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
} else { } else {
// Create new oop map // Create new oop map
nonstatic_oop_offsets[nonstatic_oop_map_count] = (u2)real_offset; nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
nonstatic_oop_counts [nonstatic_oop_map_count] = 1; nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
nonstatic_oop_map_count += 1; nonstatic_oop_map_count += 1;
if( first_nonstatic_oop_offset == 0 ) { // Undefined if( first_nonstatic_oop_offset == 0 ) { // Undefined
...@@ -3183,9 +3185,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -3183,9 +3185,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value"); assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value");
// Number of non-static oop map blocks allocated at end of klass. // Number of non-static oop map blocks allocated at end of klass.
int total_oop_map_count = compute_oop_map_count(super_klass, const unsigned int total_oop_map_count =
nonstatic_oop_map_count, compute_oop_map_count(super_klass, nonstatic_oop_map_count,
first_nonstatic_oop_offset); first_nonstatic_oop_offset);
// Compute reference type // Compute reference type
ReferenceType rt; ReferenceType rt;
...@@ -3196,10 +3198,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -3196,10 +3198,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
} }
// We can now create the basic klassOop for this klass // We can now create the basic klassOop for this klass
klassOop ik = oopFactory::new_instanceKlass( klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size,
vtable_size, itable_size, static_field_size,
static_field_size, total_oop_map_count, total_oop_map_count,
rt, CHECK_(nullHandle)); rt, CHECK_(nullHandle));
instanceKlassHandle this_klass (THREAD, ik); instanceKlassHandle this_klass (THREAD, ik);
assert(this_klass->static_field_size() == static_field_size, "sanity"); assert(this_klass->static_field_size() == static_field_size, "sanity");
...@@ -3378,10 +3380,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -3378,10 +3380,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
} }
int ClassFileParser::compute_oop_map_count(instanceKlassHandle super, unsigned int
int nonstatic_oop_map_count, ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
int first_nonstatic_oop_offset) { unsigned int nonstatic_oop_map_count,
int map_count = super.is_null() ? 0 : super->nonstatic_oop_map_count(); int first_nonstatic_oop_offset) {
unsigned int map_count =
super.is_null() ? 0 : super->nonstatic_oop_map_count();
if (nonstatic_oop_map_count > 0) { if (nonstatic_oop_map_count > 0) {
// We have oops to add to map // We have oops to add to map
if (map_count == 0) { if (map_count == 0) {
...@@ -3409,16 +3413,16 @@ int ClassFileParser::compute_oop_map_count(instanceKlassHandle super, ...@@ -3409,16 +3413,16 @@ int ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
void ClassFileParser::fill_oop_maps(instanceKlassHandle k, void ClassFileParser::fill_oop_maps(instanceKlassHandle k,
int nonstatic_oop_map_count, unsigned int nonstatic_oop_map_count,
u2* nonstatic_oop_offsets, int* nonstatic_oop_offsets,
u2* nonstatic_oop_counts) { unsigned int* nonstatic_oop_counts) {
OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps(); OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps();
const instanceKlass* const super = k->superklass(); const instanceKlass* const super = k->superklass();
const int super_count = super != NULL ? super->nonstatic_oop_map_count() : 0; const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0;
if (super_count > 0) { if (super_count > 0) {
// Copy maps from superklass // Copy maps from superklass
OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps(); OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps();
for (int i = 0; i < super_count; ++i) { for (unsigned int i = 0; i < super_count; ++i) {
*this_oop_map++ = *super_oop_map++; *this_oop_map++ = *super_oop_map++;
} }
} }
......
...@@ -125,10 +125,13 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { ...@@ -125,10 +125,13 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int runtime_invisible_annotations_length, TRAPS); int runtime_invisible_annotations_length, TRAPS);
// Final setup // Final setup
int compute_oop_map_count(instanceKlassHandle super, int nonstatic_oop_count, unsigned int compute_oop_map_count(instanceKlassHandle super,
int first_nonstatic_oop_offset); unsigned int nonstatic_oop_count,
void fill_oop_maps(instanceKlassHandle k, int nonstatic_oop_map_count, int first_nonstatic_oop_offset);
u2* nonstatic_oop_offsets, u2* nonstatic_oop_counts); void fill_oop_maps(instanceKlassHandle k,
unsigned int nonstatic_oop_map_count,
int* nonstatic_oop_offsets,
unsigned int* nonstatic_oop_counts);
void set_precomputed_flags(instanceKlassHandle k); void set_precomputed_flags(instanceKlassHandle k);
objArrayHandle compute_transitive_interfaces(instanceKlassHandle super, objArrayHandle compute_transitive_interfaces(instanceKlassHandle super,
objArrayHandle local_ifs, TRAPS); objArrayHandle local_ifs, TRAPS);
......
...@@ -98,8 +98,10 @@ constantPoolCacheOop oopFactory::new_constantPoolCache(int length, ...@@ -98,8 +98,10 @@ constantPoolCacheOop oopFactory::new_constantPoolCache(int length,
} }
klassOop oopFactory::new_instanceKlass(int vtable_len, int itable_len, int static_field_size, klassOop oopFactory::new_instanceKlass(int vtable_len, int itable_len,
int nonstatic_oop_map_count, ReferenceType rt, TRAPS) { int static_field_size,
unsigned int nonstatic_oop_map_count,
ReferenceType rt, TRAPS) {
instanceKlassKlass* ikk = instanceKlassKlass::cast(Universe::instanceKlassKlassObj()); instanceKlassKlass* ikk = instanceKlassKlass::cast(Universe::instanceKlassKlassObj());
return ikk->allocate_instance_klass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, rt, CHECK_NULL); return ikk->allocate_instance_klass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, rt, CHECK_NULL);
} }
......
...@@ -89,8 +89,10 @@ class oopFactory: AllStatic { ...@@ -89,8 +89,10 @@ class oopFactory: AllStatic {
TRAPS); TRAPS);
// Instance classes // Instance classes
static klassOop new_instanceKlass(int vtable_len, int itable_len, int static_field_size, static klassOop new_instanceKlass(int vtable_len, int itable_len,
int nonstatic_oop_map_count, ReferenceType rt, TRAPS); int static_field_size,
unsigned int nonstatic_oop_map_count,
ReferenceType rt, TRAPS);
// Methods // Methods
private: private:
......
...@@ -2223,7 +2223,8 @@ void instanceKlass::verify_class_klass_nonstatic_oop_maps(klassOop k) { ...@@ -2223,7 +2223,8 @@ void instanceKlass::verify_class_klass_nonstatic_oop_maps(klassOop k) {
int offset = java_lang_Class::klass_offset; int offset = java_lang_Class::klass_offset;
OopMapBlock* map = ik->start_of_nonstatic_oop_maps(); OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
guarantee(map->offset() == offset && map->count() == extra, "sanity"); guarantee(map->offset() == offset && map->count() == (unsigned int) extra,
"sanity");
} }
} }
......
...@@ -103,12 +103,12 @@ class FieldPrinter: public FieldClosure { ...@@ -103,12 +103,12 @@ class FieldPrinter: public FieldClosure {
class OopMapBlock VALUE_OBJ_CLASS_SPEC { class OopMapBlock VALUE_OBJ_CLASS_SPEC {
public: public:
// Byte offset of the first oop mapped by this block. // Byte offset of the first oop mapped by this block.
jushort offset() const { return _offset; } int offset() const { return _offset; }
void set_offset(jushort offset) { _offset = offset; } void set_offset(int offset) { _offset = offset; }
// Number of oops in this block. // Number of oops in this block.
jushort count() const { return _count; } uint count() const { return _count; }
void set_count(jushort count) { _count = count; } void set_count(uint count) { _count = count; }
// sizeof(OopMapBlock) in HeapWords. // sizeof(OopMapBlock) in HeapWords.
static const int size_in_words() { static const int size_in_words() {
...@@ -117,8 +117,8 @@ class OopMapBlock VALUE_OBJ_CLASS_SPEC { ...@@ -117,8 +117,8 @@ class OopMapBlock VALUE_OBJ_CLASS_SPEC {
} }
private: private:
jushort _offset; int _offset;
jushort _count; uint _count;
}; };
class instanceKlass: public Klass { class instanceKlass: public Klass {
...@@ -446,10 +446,10 @@ class instanceKlass: public Klass { ...@@ -446,10 +446,10 @@ class instanceKlass: public Klass {
void set_source_debug_extension(symbolOop n){ oop_store_without_check((oop*) &_source_debug_extension, (oop) n); } void set_source_debug_extension(symbolOop n){ oop_store_without_check((oop*) &_source_debug_extension, (oop) n); }
// nonstatic oop-map blocks // nonstatic oop-map blocks
static int nonstatic_oop_map_size(int oop_map_count) { static int nonstatic_oop_map_size(unsigned int oop_map_count) {
return oop_map_count * OopMapBlock::size_in_words(); return oop_map_count * OopMapBlock::size_in_words();
} }
int nonstatic_oop_map_count() const { unsigned int nonstatic_oop_map_count() const {
return _nonstatic_oop_map_size / OopMapBlock::size_in_words(); return _nonstatic_oop_map_size / OopMapBlock::size_in_words();
} }
int nonstatic_oop_map_size() const { return _nonstatic_oop_map_size; } int nonstatic_oop_map_size() const { return _nonstatic_oop_map_size; }
......
...@@ -405,7 +405,7 @@ int instanceKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, ...@@ -405,7 +405,7 @@ int instanceKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
klassOop klassOop
instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_len, instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_len,
int static_field_size, int static_field_size,
int nonstatic_oop_map_count, unsigned nonstatic_oop_map_count,
ReferenceType rt, TRAPS) { ReferenceType rt, TRAPS) {
const int nonstatic_oop_map_size = const int nonstatic_oop_map_size =
......
...@@ -39,7 +39,7 @@ class instanceKlassKlass : public klassKlass { ...@@ -39,7 +39,7 @@ class instanceKlassKlass : public klassKlass {
klassOop allocate_instance_klass(int vtable_len, klassOop allocate_instance_klass(int vtable_len,
int itable_len, int itable_len,
int static_field_size, int static_field_size,
int nonstatic_oop_map_count, unsigned int nonstatic_oop_map_count,
ReferenceType rt, ReferenceType rt,
TRAPS); TRAPS);
......
...@@ -407,7 +407,7 @@ void instanceRefKlass::update_nonstatic_oop_maps(klassOop k) { ...@@ -407,7 +407,7 @@ void instanceRefKlass::update_nonstatic_oop_maps(klassOop k) {
// Check that the current map is (2,4) - currently points at field with // Check that the current map is (2,4) - currently points at field with
// offset 2 (words) and has 4 map entries. // offset 2 (words) and has 4 map entries.
debug_only(int offset = java_lang_ref_Reference::referent_offset); debug_only(int offset = java_lang_ref_Reference::referent_offset);
debug_only(int count = ((java_lang_ref_Reference::discovered_offset - debug_only(unsigned int count = ((java_lang_ref_Reference::discovered_offset -
java_lang_ref_Reference::referent_offset)/heapOopSize) + 1); java_lang_ref_Reference::referent_offset)/heapOopSize) + 1);
if (UseSharedSpaces) { if (UseSharedSpaces) {
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册