mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
6964458: Reimplement class meta-data storage to use native memory
Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com> Co-authored-by: Mikael Gerdin <mikael.gerdin@oracle.com> Co-authored-by: Tom Rodriguez <tom.rodriguez@oracle.com> Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
This commit is contained in:
parent
36eee7c8c8
commit
5c58d27aac
853 changed files with 26124 additions and 82956 deletions
|
@ -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 @@ RelocationHolder RelocationHolder::plus(int offset) const {
|
|||
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 @@ void oop_Relocation::unpack_data() {
|
|||
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 @@ void oop_Relocation::verify_oop_relocation() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
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 @@ void RelocIterator::print_current() {
|
|||
}
|
||||
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 @@ void RelocIterator::print_current() {
|
|||
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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue