mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
6703888: Compressed Oops: use the 32-bits gap after klass in a object
Use the gap also for a narrow oop field and a boxing object value. Reviewed-by: coleenp, never
This commit is contained in:
parent
76035424de
commit
e53e767d88
13 changed files with 67 additions and 72 deletions
|
@ -2556,7 +2556,6 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
|
||||||
int total_strings = 0;
|
int total_strings = 0;
|
||||||
int first_arg_to_pass = 0;
|
int first_arg_to_pass = 0;
|
||||||
int total_c_args = 0;
|
int total_c_args = 0;
|
||||||
int box_offset = java_lang_boxing_object::value_offset_in_bytes();
|
|
||||||
|
|
||||||
// Skip the receiver as dtrace doesn't want to see it
|
// Skip the receiver as dtrace doesn't want to see it
|
||||||
if( !method->is_static() ) {
|
if( !method->is_static() ) {
|
||||||
|
@ -2778,7 +2777,9 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
|
||||||
__ br_null(in_reg, true, Assembler::pn, skipUnbox);
|
__ br_null(in_reg, true, Assembler::pn, skipUnbox);
|
||||||
__ delayed()->mov(G0, tmp);
|
__ delayed()->mov(G0, tmp);
|
||||||
|
|
||||||
switch (out_sig_bt[c_arg]) {
|
BasicType bt = out_sig_bt[c_arg];
|
||||||
|
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
|
||||||
|
switch (bt) {
|
||||||
case T_BYTE:
|
case T_BYTE:
|
||||||
__ ldub(in_reg, box_offset, tmp); break;
|
__ ldub(in_reg, box_offset, tmp); break;
|
||||||
case T_SHORT:
|
case T_SHORT:
|
||||||
|
|
|
@ -5471,7 +5471,6 @@ instruct loadN(iRegN dst, memory mem) %{
|
||||||
// Load Klass Pointer
|
// Load Klass Pointer
|
||||||
instruct loadKlass(iRegP dst, memory mem) %{
|
instruct loadKlass(iRegP dst, memory mem) %{
|
||||||
match(Set dst (LoadKlass mem));
|
match(Set dst (LoadKlass mem));
|
||||||
predicate(!n->in(MemNode::Address)->bottom_type()->is_ptr_to_narrowoop());
|
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
size(4);
|
size(4);
|
||||||
|
|
||||||
|
@ -5490,6 +5489,7 @@ instruct loadKlass(iRegP dst, memory mem) %{
|
||||||
instruct loadNKlass(iRegN dst, memory mem) %{
|
instruct loadNKlass(iRegN dst, memory mem) %{
|
||||||
match(Set dst (LoadNKlass mem));
|
match(Set dst (LoadNKlass mem));
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
size(4);
|
||||||
|
|
||||||
format %{ "LDUW $mem,$dst\t! compressed klass ptr" %}
|
format %{ "LDUW $mem,$dst\t! compressed klass ptr" %}
|
||||||
|
|
||||||
|
|
|
@ -1920,7 +1920,6 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
|
||||||
int total_strings = 0;
|
int total_strings = 0;
|
||||||
int first_arg_to_pass = 0;
|
int first_arg_to_pass = 0;
|
||||||
int total_c_args = 0;
|
int total_c_args = 0;
|
||||||
int box_offset = java_lang_boxing_object::value_offset_in_bytes();
|
|
||||||
|
|
||||||
if( !method->is_static() ) { // Pass in receiver first
|
if( !method->is_static() ) { // Pass in receiver first
|
||||||
in_sig_bt[i++] = T_OBJECT;
|
in_sig_bt[i++] = T_OBJECT;
|
||||||
|
@ -2131,7 +2130,10 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
|
||||||
assert(dst.first()->is_stack() &&
|
assert(dst.first()->is_stack() &&
|
||||||
(!dst.second()->is_valid() || dst.second()->is_stack()),
|
(!dst.second()->is_valid() || dst.second()->is_stack()),
|
||||||
"value(s) must go into stack slots");
|
"value(s) must go into stack slots");
|
||||||
if ( out_sig_bt[c_arg] == T_LONG ) {
|
|
||||||
|
BasicType bt = out_sig_bt[c_arg];
|
||||||
|
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
|
||||||
|
if ( bt == T_LONG ) {
|
||||||
__ movl(rbx, Address(in_reg,
|
__ movl(rbx, Address(in_reg,
|
||||||
box_offset + VMRegImpl::stack_slot_size));
|
box_offset + VMRegImpl::stack_slot_size));
|
||||||
__ movl(Address(rsp, reg2offset_out(dst.second())), rbx);
|
__ movl(Address(rsp, reg2offset_out(dst.second())), rbx);
|
||||||
|
|
|
@ -1950,7 +1950,6 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
|
||||||
int total_strings = 0;
|
int total_strings = 0;
|
||||||
int first_arg_to_pass = 0;
|
int first_arg_to_pass = 0;
|
||||||
int total_c_args = 0;
|
int total_c_args = 0;
|
||||||
int box_offset = java_lang_boxing_object::value_offset_in_bytes();
|
|
||||||
|
|
||||||
// Skip the receiver as dtrace doesn't want to see it
|
// Skip the receiver as dtrace doesn't want to see it
|
||||||
if( !method->is_static() ) {
|
if( !method->is_static() ) {
|
||||||
|
@ -2197,8 +2196,10 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
|
||||||
__ testq(in_reg, in_reg);
|
__ testq(in_reg, in_reg);
|
||||||
__ jcc(Assembler::zero, skipUnbox);
|
__ jcc(Assembler::zero, skipUnbox);
|
||||||
|
|
||||||
|
BasicType bt = out_sig_bt[c_arg];
|
||||||
|
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
|
||||||
Address src1(in_reg, box_offset);
|
Address src1(in_reg, box_offset);
|
||||||
if ( out_sig_bt[c_arg] == T_LONG ) {
|
if ( bt == T_LONG ) {
|
||||||
__ movq(in_reg, src1);
|
__ movq(in_reg, src1);
|
||||||
__ movq(stack_dst, in_reg);
|
__ movq(stack_dst, in_reg);
|
||||||
assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
|
assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
|
||||||
|
@ -2460,8 +2461,10 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
|
||||||
Label skip;
|
Label skip;
|
||||||
__ testq(r, r);
|
__ testq(r, r);
|
||||||
__ jcc(Assembler::equal, skip);
|
__ jcc(Assembler::equal, skip);
|
||||||
|
BasicType bt = out_sig_bt[c_arg];
|
||||||
|
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
|
||||||
Address src1(r, box_offset);
|
Address src1(r, box_offset);
|
||||||
if ( out_sig_bt[c_arg] == T_LONG ) {
|
if ( bt == T_LONG ) {
|
||||||
__ movq(r, src1);
|
__ movq(r, src1);
|
||||||
} else {
|
} else {
|
||||||
__ movl(r, src1);
|
__ movl(r, src1);
|
||||||
|
|
|
@ -392,12 +392,12 @@ int ciInstanceKlass::compute_nonstatic_fields() {
|
||||||
assert(!is_java_lang_Object(), "bootstrap OK");
|
assert(!is_java_lang_Object(), "bootstrap OK");
|
||||||
|
|
||||||
// Size in bytes of my fields, including inherited fields.
|
// Size in bytes of my fields, including inherited fields.
|
||||||
int fsize = nonstatic_field_size() * wordSize;
|
int fsize = nonstatic_field_size() * heapOopSize;
|
||||||
|
|
||||||
ciInstanceKlass* super = this->super();
|
ciInstanceKlass* super = this->super();
|
||||||
GrowableArray<ciField*>* super_fields = NULL;
|
GrowableArray<ciField*>* super_fields = NULL;
|
||||||
if (super != NULL && super->has_nonstatic_fields()) {
|
if (super != NULL && super->has_nonstatic_fields()) {
|
||||||
int super_fsize = super->nonstatic_field_size() * wordSize;
|
int super_fsize = super->nonstatic_field_size() * heapOopSize;
|
||||||
int super_flen = super->nof_nonstatic_fields();
|
int super_flen = super->nof_nonstatic_fields();
|
||||||
super_fields = super->_nonstatic_fields;
|
super_fields = super->_nonstatic_fields;
|
||||||
assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
|
assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
|
||||||
|
@ -438,7 +438,7 @@ int ciInstanceKlass::compute_nonstatic_fields() {
|
||||||
// This is a minor inefficiency classFileParser.cpp.
|
// This is a minor inefficiency classFileParser.cpp.
|
||||||
last_offset = offset + size;
|
last_offset = offset + size;
|
||||||
}
|
}
|
||||||
assert(last_offset <= (int)sizeof(oopDesc) + fsize, "no overflow");
|
assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_nonstatic_fields = fields;
|
_nonstatic_fields = fields;
|
||||||
|
|
|
@ -2664,8 +2664,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
fac.static_byte_count ), wordSize );
|
fac.static_byte_count ), wordSize );
|
||||||
static_field_size = (next_static_type_offset -
|
static_field_size = (next_static_type_offset -
|
||||||
next_static_oop_offset) / wordSize;
|
next_static_oop_offset) / wordSize;
|
||||||
first_nonstatic_field_offset = (instanceOopDesc::header_size() +
|
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
|
||||||
nonstatic_field_size) * wordSize;
|
nonstatic_field_size * heapOopSize;
|
||||||
next_nonstatic_field_offset = first_nonstatic_field_offset;
|
next_nonstatic_field_offset = first_nonstatic_field_offset;
|
||||||
|
|
||||||
// Add fake fields for java.lang.Class instances (also see below)
|
// Add fake fields for java.lang.Class instances (also see below)
|
||||||
|
@ -2734,9 +2734,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
next_nonstatic_byte_offset = next_nonstatic_short_offset +
|
next_nonstatic_byte_offset = next_nonstatic_short_offset +
|
||||||
(nonstatic_short_count * BytesPerShort);
|
(nonstatic_short_count * BytesPerShort);
|
||||||
next_nonstatic_type_offset = align_size_up((next_nonstatic_byte_offset +
|
next_nonstatic_type_offset = align_size_up((next_nonstatic_byte_offset +
|
||||||
nonstatic_byte_count ), wordSize );
|
nonstatic_byte_count ), heapOopSize );
|
||||||
orig_nonstatic_field_size = nonstatic_field_size +
|
orig_nonstatic_field_size = nonstatic_field_size +
|
||||||
((next_nonstatic_type_offset - first_nonstatic_field_offset)/wordSize);
|
((next_nonstatic_type_offset - first_nonstatic_field_offset)/heapOopSize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
bool compact_fields = CompactFields;
|
bool compact_fields = CompactFields;
|
||||||
|
@ -2791,18 +2791,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
int nonstatic_short_space_offset;
|
int nonstatic_short_space_offset;
|
||||||
int nonstatic_byte_space_offset;
|
int nonstatic_byte_space_offset;
|
||||||
|
|
||||||
bool compact_into_header = (UseCompressedOops &&
|
if( nonstatic_double_count > 0 ) {
|
||||||
allocation_style == 1 && compact_fields &&
|
int offset = next_nonstatic_double_offset;
|
||||||
!super_has_nonstatic_fields);
|
|
||||||
|
|
||||||
if( compact_into_header || nonstatic_double_count > 0 ) {
|
|
||||||
int offset;
|
|
||||||
// Pack something in with the header if no super klass has done so.
|
|
||||||
if (compact_into_header) {
|
|
||||||
offset = oopDesc::klass_gap_offset_in_bytes();
|
|
||||||
} else {
|
|
||||||
offset = next_nonstatic_double_offset;
|
|
||||||
}
|
|
||||||
next_nonstatic_double_offset = align_size_up(offset, BytesPerLong);
|
next_nonstatic_double_offset = align_size_up(offset, BytesPerLong);
|
||||||
if( compact_fields && offset != next_nonstatic_double_offset ) {
|
if( compact_fields && offset != next_nonstatic_double_offset ) {
|
||||||
// Allocate available fields into the gap before double field.
|
// Allocate available fields into the gap before double field.
|
||||||
|
@ -2830,8 +2820,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
}
|
}
|
||||||
// Allocate oop field in the gap if there are no other fields for that.
|
// Allocate oop field in the gap if there are no other fields for that.
|
||||||
nonstatic_oop_space_offset = offset;
|
nonstatic_oop_space_offset = offset;
|
||||||
if(!compact_into_header && length >= heapOopSize &&
|
if( length >= heapOopSize && nonstatic_oop_count > 0 &&
|
||||||
nonstatic_oop_count > 0 &&
|
|
||||||
allocation_style != 0 ) { // when oop fields not first
|
allocation_style != 0 ) { // when oop fields not first
|
||||||
nonstatic_oop_count -= 1;
|
nonstatic_oop_count -= 1;
|
||||||
nonstatic_oop_space_count = 1; // Only one will fit
|
nonstatic_oop_space_count = 1; // Only one will fit
|
||||||
|
@ -2854,14 +2843,13 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
} else { // allocation_style == 1
|
} else { // allocation_style == 1
|
||||||
next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
|
next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
|
||||||
if( nonstatic_oop_count > 0 ) {
|
if( nonstatic_oop_count > 0 ) {
|
||||||
notaligned_offset = next_nonstatic_oop_offset;
|
|
||||||
next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
|
next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
|
||||||
}
|
}
|
||||||
notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
|
notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
|
||||||
}
|
}
|
||||||
next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
|
next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
|
||||||
nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
|
nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
|
||||||
- first_nonstatic_field_offset)/wordSize);
|
- first_nonstatic_field_offset)/heapOopSize);
|
||||||
|
|
||||||
// Iterate over fields again and compute correct offsets.
|
// Iterate over fields again and compute correct offsets.
|
||||||
// The field allocation type was temporarily stored in the offset slot.
|
// The field allocation type was temporarily stored in the offset slot.
|
||||||
|
@ -2962,9 +2950,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
// Size of instances
|
// Size of instances
|
||||||
int instance_size;
|
int instance_size;
|
||||||
|
|
||||||
|
next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
|
||||||
instance_size = align_object_size(next_nonstatic_type_offset / wordSize);
|
instance_size = align_object_size(next_nonstatic_type_offset / wordSize);
|
||||||
|
|
||||||
assert(instance_size == align_object_size(instanceOopDesc::header_size() + nonstatic_field_size), "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");
|
||||||
|
|
||||||
// Size of non-static oop map blocks (in words) allocated at end of klass
|
// Size of non-static oop map blocks (in words) allocated at end of klass
|
||||||
int nonstatic_oop_map_size = compute_oop_map_size(super_klass, nonstatic_oop_map_count, first_nonstatic_oop_offset);
|
int nonstatic_oop_map_size = compute_oop_map_size(super_klass, nonstatic_oop_map_count, first_nonstatic_oop_offset);
|
||||||
|
@ -3122,13 +3111,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if( PrintCompactFieldsSavings ) {
|
if( PrintCompactFieldsSavings ) {
|
||||||
if( nonstatic_field_size < orig_nonstatic_field_size ) {
|
if( nonstatic_field_size < orig_nonstatic_field_size ) {
|
||||||
tty->print("[Saved %d of %3d words in %s]\n",
|
tty->print("[Saved %d of %d bytes in %s]\n",
|
||||||
orig_nonstatic_field_size - nonstatic_field_size,
|
(orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize,
|
||||||
orig_nonstatic_field_size, this_klass->external_name());
|
orig_nonstatic_field_size*heapOopSize,
|
||||||
|
this_klass->external_name());
|
||||||
} else if( nonstatic_field_size > orig_nonstatic_field_size ) {
|
} else if( nonstatic_field_size > orig_nonstatic_field_size ) {
|
||||||
tty->print("[Wasted %d over %3d words in %s]\n",
|
tty->print("[Wasted %d over %d bytes in %s]\n",
|
||||||
nonstatic_field_size - orig_nonstatic_field_size,
|
(nonstatic_field_size - orig_nonstatic_field_size)*heapOopSize,
|
||||||
orig_nonstatic_field_size, this_klass->external_name());
|
orig_nonstatic_field_size*heapOopSize,
|
||||||
|
this_klass->external_name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1872,7 +1872,7 @@ oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) {
|
||||||
box->float_field_put(value_offset, value->f);
|
box->float_field_put(value_offset, value->f);
|
||||||
break;
|
break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
box->double_field_put(value_offset, value->d);
|
box->double_field_put(long_value_offset, value->d);
|
||||||
break;
|
break;
|
||||||
case T_BYTE:
|
case T_BYTE:
|
||||||
box->byte_field_put(value_offset, value->b);
|
box->byte_field_put(value_offset, value->b);
|
||||||
|
@ -1884,7 +1884,7 @@ oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) {
|
||||||
box->int_field_put(value_offset, value->i);
|
box->int_field_put(value_offset, value->i);
|
||||||
break;
|
break;
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
box->long_field_put(value_offset, value->j);
|
box->long_field_put(long_value_offset, value->j);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1915,7 +1915,7 @@ BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) {
|
||||||
value->f = box->float_field(value_offset);
|
value->f = box->float_field(value_offset);
|
||||||
break;
|
break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
value->d = box->double_field(value_offset);
|
value->d = box->double_field(long_value_offset);
|
||||||
break;
|
break;
|
||||||
case T_BYTE:
|
case T_BYTE:
|
||||||
value->b = box->byte_field(value_offset);
|
value->b = box->byte_field(value_offset);
|
||||||
|
@ -1927,7 +1927,7 @@ BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) {
|
||||||
value->i = box->int_field(value_offset);
|
value->i = box->int_field(value_offset);
|
||||||
break;
|
break;
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
value->j = box->long_field(value_offset);
|
value->j = box->long_field(long_value_offset);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return T_ILLEGAL;
|
return T_ILLEGAL;
|
||||||
|
@ -1949,7 +1949,7 @@ BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) {
|
||||||
box->float_field_put(value_offset, value->f);
|
box->float_field_put(value_offset, value->f);
|
||||||
break;
|
break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
box->double_field_put(value_offset, value->d);
|
box->double_field_put(long_value_offset, value->d);
|
||||||
break;
|
break;
|
||||||
case T_BYTE:
|
case T_BYTE:
|
||||||
box->byte_field_put(value_offset, value->b);
|
box->byte_field_put(value_offset, value->b);
|
||||||
|
@ -1961,7 +1961,7 @@ BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) {
|
||||||
box->int_field_put(value_offset, value->i);
|
box->int_field_put(value_offset, value->i);
|
||||||
break;
|
break;
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
box->long_field_put(value_offset, value->j);
|
box->long_field_put(long_value_offset, value->j);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return T_ILLEGAL;
|
return T_ILLEGAL;
|
||||||
|
@ -2163,6 +2163,7 @@ int java_lang_reflect_Field::modifiers_offset;
|
||||||
int java_lang_reflect_Field::signature_offset;
|
int java_lang_reflect_Field::signature_offset;
|
||||||
int java_lang_reflect_Field::annotations_offset;
|
int java_lang_reflect_Field::annotations_offset;
|
||||||
int java_lang_boxing_object::value_offset;
|
int java_lang_boxing_object::value_offset;
|
||||||
|
int java_lang_boxing_object::long_value_offset;
|
||||||
int java_lang_ref_Reference::referent_offset;
|
int java_lang_ref_Reference::referent_offset;
|
||||||
int java_lang_ref_Reference::queue_offset;
|
int java_lang_ref_Reference::queue_offset;
|
||||||
int java_lang_ref_Reference::next_offset;
|
int java_lang_ref_Reference::next_offset;
|
||||||
|
@ -2282,10 +2283,7 @@ oop java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(
|
||||||
// are not available to determine the offset_of_static_fields.
|
// are not available to determine the offset_of_static_fields.
|
||||||
void JavaClasses::compute_hard_coded_offsets() {
|
void JavaClasses::compute_hard_coded_offsets() {
|
||||||
const int x = heapOopSize;
|
const int x = heapOopSize;
|
||||||
// Objects don't get allocated in the gap in the header with compressed oops
|
const int header = instanceOopDesc::base_offset_in_bytes();
|
||||||
// for these special classes because hard coded offsets can't be conditional
|
|
||||||
// so base_offset_in_bytes() is wrong here, allocate after the header.
|
|
||||||
const int header = sizeof(instanceOopDesc);
|
|
||||||
|
|
||||||
// Do the String Class
|
// Do the String Class
|
||||||
java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header;
|
java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header;
|
||||||
|
@ -2308,7 +2306,8 @@ void JavaClasses::compute_hard_coded_offsets() {
|
||||||
java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
|
java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
|
||||||
|
|
||||||
// java_lang_boxing_object
|
// java_lang_boxing_object
|
||||||
java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset * x + header;
|
java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header;
|
||||||
|
java_lang_boxing_object::long_value_offset = align_size_up((java_lang_boxing_object::hc_value_offset + header), BytesPerLong);
|
||||||
|
|
||||||
// java_lang_ref_Reference:
|
// java_lang_ref_Reference:
|
||||||
java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header;
|
java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header;
|
||||||
|
@ -2322,7 +2321,7 @@ void JavaClasses::compute_hard_coded_offsets() {
|
||||||
java_lang_ref_Reference::number_of_fake_oop_fields = 1;
|
java_lang_ref_Reference::number_of_fake_oop_fields = 1;
|
||||||
|
|
||||||
// java_lang_ref_SoftReference Class
|
// java_lang_ref_SoftReference Class
|
||||||
java_lang_ref_SoftReference::timestamp_offset = java_lang_ref_SoftReference::hc_timestamp_offset * x + header;
|
java_lang_ref_SoftReference::timestamp_offset = align_size_up((java_lang_ref_SoftReference::hc_timestamp_offset * x + header), BytesPerLong);
|
||||||
// Don't multiply static fields because they are always in wordSize units
|
// Don't multiply static fields because they are always in wordSize units
|
||||||
java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x;
|
java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x;
|
||||||
|
|
||||||
|
@ -2469,6 +2468,9 @@ void JavaClasses::check_offsets() {
|
||||||
#define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
|
#define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
|
||||||
valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig)
|
valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig)
|
||||||
|
|
||||||
|
#define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
|
||||||
|
valid &= check_offset(klass_name, cpp_klass_name :: long_ ## field_name ## _offset, #field_name, field_sig)
|
||||||
|
|
||||||
#define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
|
#define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
|
||||||
valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig)
|
valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig)
|
||||||
|
|
||||||
|
@ -2501,11 +2503,11 @@ void JavaClasses::check_offsets() {
|
||||||
CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z");
|
CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z");
|
||||||
CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
|
CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
|
||||||
CHECK_OFFSET("java/lang/Float", java_lang_boxing_object, value, "F");
|
CHECK_OFFSET("java/lang/Float", java_lang_boxing_object, value, "F");
|
||||||
CHECK_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
|
CHECK_LONG_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
|
||||||
CHECK_OFFSET("java/lang/Byte", java_lang_boxing_object, value, "B");
|
CHECK_OFFSET("java/lang/Byte", java_lang_boxing_object, value, "B");
|
||||||
CHECK_OFFSET("java/lang/Short", java_lang_boxing_object, value, "S");
|
CHECK_OFFSET("java/lang/Short", java_lang_boxing_object, value, "S");
|
||||||
CHECK_OFFSET("java/lang/Integer", java_lang_boxing_object, value, "I");
|
CHECK_OFFSET("java/lang/Integer", java_lang_boxing_object, value, "I");
|
||||||
CHECK_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
|
CHECK_LONG_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
|
||||||
|
|
||||||
// java.lang.ClassLoader
|
// java.lang.ClassLoader
|
||||||
|
|
||||||
|
|
|
@ -653,6 +653,7 @@ class java_lang_boxing_object: AllStatic {
|
||||||
hc_value_offset = 0
|
hc_value_offset = 0
|
||||||
};
|
};
|
||||||
static int value_offset;
|
static int value_offset;
|
||||||
|
static int long_value_offset;
|
||||||
|
|
||||||
static oop initialize_and_allocate(BasicType type, TRAPS);
|
static oop initialize_and_allocate(BasicType type, TRAPS);
|
||||||
public:
|
public:
|
||||||
|
@ -665,7 +666,10 @@ class java_lang_boxing_object: AllStatic {
|
||||||
static bool is_instance(oop box) { return basic_type(box) != T_ILLEGAL; }
|
static bool is_instance(oop box) { return basic_type(box) != T_ILLEGAL; }
|
||||||
static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; }
|
static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; }
|
||||||
|
|
||||||
static int value_offset_in_bytes() { return value_offset; }
|
static int value_offset_in_bytes(BasicType type) {
|
||||||
|
return ( type == T_LONG || type == T_DOUBLE ) ? long_value_offset :
|
||||||
|
value_offset;
|
||||||
|
}
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
friend class JavaClasses;
|
friend class JavaClasses;
|
||||||
|
@ -747,7 +751,7 @@ class java_lang_ref_SoftReference: public java_lang_ref_Reference {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
// The timestamp is a long field and may need to be adjusted for alignment.
|
// The timestamp is a long field and may need to be adjusted for alignment.
|
||||||
hc_timestamp_offset = align_object_offset_(hc_discovered_offset + 1)
|
hc_timestamp_offset = hc_discovered_offset + 1
|
||||||
};
|
};
|
||||||
enum {
|
enum {
|
||||||
hc_static_clock_offset = 0
|
hc_static_clock_offset = 0
|
||||||
|
|
|
@ -54,6 +54,7 @@ isGCActiveMark.hpp parallelScavengeHeap.hpp
|
||||||
markSweep.inline.hpp psParallelCompact.hpp
|
markSweep.inline.hpp psParallelCompact.hpp
|
||||||
|
|
||||||
mutableNUMASpace.cpp mutableNUMASpace.hpp
|
mutableNUMASpace.cpp mutableNUMASpace.hpp
|
||||||
|
mutableNUMASpace.cpp oop.inline.hpp
|
||||||
mutableNUMASpace.cpp sharedHeap.hpp
|
mutableNUMASpace.cpp sharedHeap.hpp
|
||||||
mutableNUMASpace.cpp thread_<os_family>.inline.hpp
|
mutableNUMASpace.cpp thread_<os_family>.inline.hpp
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,10 @@ class arrayOopDesc : public oopDesc {
|
||||||
// Header size computation.
|
// Header size computation.
|
||||||
// The header is considered the oop part of this type plus the length.
|
// The header is considered the oop part of this type plus the length.
|
||||||
// Returns the aligned header_size_in_bytes. This is not equivalent to
|
// Returns the aligned header_size_in_bytes. This is not equivalent to
|
||||||
// sizeof(arrayOopDesc) which should not appear in the code, except here.
|
// sizeof(arrayOopDesc) which should not appear in the code.
|
||||||
static int header_size_in_bytes() {
|
static int header_size_in_bytes() {
|
||||||
size_t hs = UseCompressedOops ?
|
size_t hs = align_size_up(length_offset_in_bytes() + sizeof(int),
|
||||||
sizeof(arrayOopDesc) :
|
HeapWordSize);
|
||||||
align_size_up(sizeof(arrayOopDesc) + sizeof(int), HeapWordSize);
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// make sure it isn't called before UseCompressedOops is initialized.
|
// make sure it isn't called before UseCompressedOops is initialized.
|
||||||
static size_t arrayoopdesc_hs = 0;
|
static size_t arrayoopdesc_hs = 0;
|
||||||
|
|
|
@ -180,9 +180,8 @@ class instanceKlass: public Klass {
|
||||||
// End of the oop block.
|
// End of the oop block.
|
||||||
//
|
//
|
||||||
|
|
||||||
// number of words used by non-static fields in this klass (including
|
// Number of heapOopSize words used by non-static fields in this klass
|
||||||
// inherited fields but after header_size()). If fields are compressed into
|
// (including inherited fields but after header_size()).
|
||||||
// header, this can be zero so it's not the same as number of static fields.
|
|
||||||
int _nonstatic_field_size;
|
int _nonstatic_field_size;
|
||||||
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
|
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
|
||||||
int _static_oop_field_size;// number of static oop fields in this klass
|
int _static_oop_field_size;// number of static oop fields in this klass
|
||||||
|
|
|
@ -581,7 +581,7 @@ void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) {
|
||||||
OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
|
OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
|
||||||
OopMapBlock* end_map = map + ik->nonstatic_oop_map_size();
|
OopMapBlock* end_map = map + ik->nonstatic_oop_map_size();
|
||||||
while (map < end_map) {
|
while (map < end_map) {
|
||||||
st->print("%d-%d ", map->offset(), map->offset() + oopSize*(map->length() - 1));
|
st->print("%d-%d ", map->offset(), map->offset() + heapOopSize*(map->length() - 1));
|
||||||
map++;
|
map++;
|
||||||
}
|
}
|
||||||
st->cr();
|
st->cr();
|
||||||
|
|
|
@ -39,14 +39,7 @@ class instanceOopDesc : public oopDesc {
|
||||||
|
|
||||||
static bool contains_field_offset(int offset, int nonstatic_field_size) {
|
static bool contains_field_offset(int offset, int nonstatic_field_size) {
|
||||||
int base_in_bytes = base_offset_in_bytes();
|
int base_in_bytes = base_offset_in_bytes();
|
||||||
if (UseCompressedOops) {
|
|
||||||
return (offset >= base_in_bytes &&
|
return (offset >= base_in_bytes &&
|
||||||
// field can be embedded in header, or is after header.
|
(offset-base_in_bytes) < nonstatic_field_size * heapOopSize);
|
||||||
(offset < (int)sizeof(instanceOopDesc) ||
|
|
||||||
(offset-(int)sizeof(instanceOopDesc))/wordSize < nonstatic_field_size));
|
|
||||||
} else {
|
|
||||||
return (offset >= base_in_bytes &&
|
|
||||||
(offset-base_in_bytes)/wordSize < nonstatic_field_size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue