提交 ca5b832c 编写于 作者: K kvn

6703888: Compressed Oops: use the 32-bits gap after klass in a object

Summary: Use the gap also for a narrow oop field and a boxing object value.
Reviewed-by: coleenp, never
上级 4469b1f4
...@@ -2556,7 +2556,6 @@ nmethod *SharedRuntime::generate_dtrace_nmethod( ...@@ -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( ...@@ -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) %{ ...@@ -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) %{ ...@@ -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( ...@@ -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( ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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() { ...@@ -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() { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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; ...@@ -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( ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 ...@@ -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 { ...@@ -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 { ...@@ -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) { ...@@ -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 { ...@@ -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 && (offset-base_in_bytes) < nonstatic_field_size * heapOopSize);
// field can be embedded in header, or is after header.
(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);
}
} }
}; };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册