diff -r 36d1d483d5d6 -r da91efe96a93 src/share/vm/code/relocInfo.cpp --- a/src/share/vm/code/relocInfo.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/code/relocInfo.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -439,6 +439,11 @@ oop_Relocation* r = (oop_Relocation*)reloc(); return oop_Relocation::spec(r->oop_index(), r->offset() + offset); } + case relocInfo::metadata_type: + { + metadata_Relocation* r = (metadata_Relocation*)reloc(); + return metadata_Relocation::spec(r->metadata_index(), r->offset() + offset); + } default: ShouldNotReachHere(); } @@ -578,33 +583,33 @@ unpack_2_ints(_oop_index, _offset); } +void metadata_Relocation::pack_data_to(CodeSection* dest) { + short* p = (short*) dest->locs_end(); + p = pack_2_ints_to(p, _metadata_index, _offset); + dest->set_locs_end((relocInfo*) p); +} + + +void metadata_Relocation::unpack_data() { + unpack_2_ints(_metadata_index, _offset); +} + void virtual_call_Relocation::pack_data_to(CodeSection* dest) { short* p = (short*) dest->locs_end(); address point = dest->locs_point(); - // Try to make a pointer NULL first. - if (_oop_limit >= point && - _oop_limit <= point + NativeCall::instruction_size) { - _oop_limit = NULL; - } - // If the _oop_limit is NULL, it "defaults" to the end of the call. - // See ic_call_Relocation::oop_limit() below. - - normalize_address(_first_oop, dest); - normalize_address(_oop_limit, dest); - jint x0 = scaled_offset_null_special(_first_oop, point); - jint x1 = scaled_offset_null_special(_oop_limit, point); - p = pack_2_ints_to(p, x0, x1); + normalize_address(_cached_value, dest); + jint x0 = scaled_offset_null_special(_cached_value, point); + p = pack_1_int_to(p, x0); dest->set_locs_end((relocInfo*) p); } void virtual_call_Relocation::unpack_data() { - jint x0, x1; unpack_2_ints(x0, x1); + jint x0 = unpack_1_int(); address point = addr(); - _first_oop = x0==0? NULL: address_from_scaled_offset(x0, point); - _oop_limit = x1==0? NULL: address_from_scaled_offset(x1, point); + _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point); } @@ -799,100 +804,48 @@ } } - -RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop, - oop* &oop_addr, bool *is_optimized) { - assert(ic_call != NULL, "ic_call address must be set"); - assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input"); - if (nm == NULL) { - CodeBlob* code; - if (ic_call != NULL) { - code = CodeCache::find_blob(ic_call); - } else if (first_oop != NULL) { - code = CodeCache::find_blob(first_oop); - } - nm = code->as_nmethod_or_null(); - assert(nm != NULL, "address to parse must be in nmethod"); - } - assert(ic_call == NULL || nm->contains(ic_call), "must be in nmethod"); - assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod"); - - address oop_limit = NULL; - - if (ic_call != NULL) { - // search for the ic_call at the given address - RelocIterator iter(nm, ic_call, ic_call+1); - bool ret = iter.next(); - assert(ret == true, "relocInfo must exist at this address"); - assert(iter.addr() == ic_call, "must find ic_call"); - if (iter.type() == relocInfo::virtual_call_type) { - virtual_call_Relocation* r = iter.virtual_call_reloc(); - first_oop = r->first_oop(); - oop_limit = r->oop_limit(); - *is_optimized = false; +// meta data versions +Metadata** metadata_Relocation::metadata_addr() { + int n = _metadata_index; + if (n == 0) { + // metadata is stored in the code stream + return (Metadata**) pd_address_in_code(); } else { - assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call"); - *is_optimized = true; - oop_addr = NULL; - first_oop = NULL; - return iter; + // metadata is stored in table at nmethod::metadatas_begin + return code()->metadata_addr_at(n); } } - // search for the first_oop, to get its oop_addr - RelocIterator all_oops(nm, first_oop); - RelocIterator iter = all_oops; - iter.set_limit(first_oop+1); - bool found_oop = false; - while (iter.next()) { - if (iter.type() == relocInfo::oop_type) { - assert(iter.addr() == first_oop, "must find first_oop"); - oop_addr = iter.oop_reloc()->oop_addr(); - found_oop = true; - break; - } - } - assert(found_oop, "must find first_oop"); - bool did_reset = false; - while (ic_call == NULL) { - // search forward for the ic_call matching the given first_oop - while (iter.next()) { - if (iter.type() == relocInfo::virtual_call_type) { - virtual_call_Relocation* r = iter.virtual_call_reloc(); - if (r->first_oop() == first_oop) { - ic_call = r->addr(); - oop_limit = r->oop_limit(); - break; - } - } - } - guarantee(!did_reset, "cannot find ic_call"); - iter = RelocIterator(nm); // search the whole nmethod - did_reset = true; +Metadata* metadata_Relocation::metadata_value() { + Metadata* v = *metadata_addr(); + // clean inline caches store a special pseudo-null + if (v == (Metadata*)Universe::non_oop_word()) v = NULL; + return v; } - assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, ""); - all_oops.set_limit(oop_limit); - return all_oops; + +void metadata_Relocation::fix_metadata_relocation() { + if (!metadata_is_immediate()) { + // get the metadata from the pool, and re-insert it into the instruction: + pd_fix_value(value()); + } } -address virtual_call_Relocation::first_oop() { - assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call"); - return _first_oop; +void metadata_Relocation::verify_metadata_relocation() { + if (!metadata_is_immediate()) { + // get the metadata from the pool, and re-insert it into the instruction: + verify_value(value()); + } } - -address virtual_call_Relocation::oop_limit() { - if (_oop_limit == NULL) - return addr() + NativeCall::instruction_size; - else - return _oop_limit; +address virtual_call_Relocation::cached_value() { + assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call"); + return _cached_value; } - void virtual_call_Relocation::clear_inline_cache() { // No stubs for ICs // Clean IC @@ -1139,6 +1092,25 @@ } break; } + case relocInfo::metadata_type: + { + metadata_Relocation* r = metadata_reloc(); + Metadata** metadata_addr = NULL; + Metadata* raw_metadata = NULL; + Metadata* metadata_value = NULL; + if (code() != NULL || r->metadata_is_immediate()) { + metadata_addr = r->metadata_addr(); + raw_metadata = *metadata_addr; + metadata_value = r->metadata_value(); + } + tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]", + metadata_addr, (address)raw_metadata, r->offset()); + if (metadata_value != NULL) { + tty->print("metadata_value=" INTPTR_FORMAT ": ", (address)metadata_value); + metadata_value->print_value_on(tty); + } + break; + } case relocInfo::external_word_type: case relocInfo::internal_word_type: case relocInfo::section_word_type: @@ -1157,8 +1129,8 @@ case relocInfo::virtual_call_type: { virtual_call_Relocation* r = (virtual_call_Relocation*) reloc(); - tty->print(" | [destination=" INTPTR_FORMAT " first_oop=" INTPTR_FORMAT " oop_limit=" INTPTR_FORMAT "]", - r->destination(), r->first_oop(), r->oop_limit()); + tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT "]", + r->destination(), r->cached_value()); break; } case relocInfo::static_stub_type: