8007320: NPG: move method annotations

Allocate method annotations and attach to ConstMethod if present

Reviewed-by: dcubed, jiangli, sspitsyn, iklam
This commit is contained in:
Coleen Phillimore 2013-02-11 14:06:22 -05:00
parent ee53020f94
commit faea95b8d3
19 changed files with 862 additions and 838 deletions

View file

@ -36,51 +36,26 @@ const u2 ConstMethod::UNSET_IDNUM = 0xFFFF;
ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
int method_parameters_length,
u2 generic_signature_index,
InlineTableSizes* sizes,
MethodType method_type,
TRAPS) {
int size = ConstMethod::size(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
exception_table_length,
checked_exceptions_length,
method_parameters_length,
generic_signature_index);
int size = ConstMethod::size(byte_code_size, sizes);
return new (loader_data, size, true, THREAD) ConstMethod(
byte_code_size, compressed_line_number_size, localvariable_table_length,
exception_table_length, checked_exceptions_length,
method_parameters_length, generic_signature_index,
method_type, size);
byte_code_size, sizes, method_type, size);
}
ConstMethod::ConstMethod(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
int method_parameters_length,
u2 generic_signature_index,
InlineTableSizes* sizes,
MethodType method_type,
int size) {
No_Safepoint_Verifier no_safepoint;
set_interpreter_kind(Interpreter::invalid);
init_fingerprint();
set_constants(NULL);
set_stackmap_data(NULL);
set_code_size(byte_code_size);
set_constMethod_size(size);
set_inlined_tables_length(generic_signature_index,
checked_exceptions_length,
compressed_line_number_size,
localvariable_table_length,
exception_table_length,
method_parameters_length);
set_inlined_tables_length(sizes);
set_method_type(method_type);
assert(this->size() == size, "wrong size for object");
}
@ -88,47 +63,70 @@ ConstMethod::ConstMethod(int byte_code_size,
// Deallocate metadata fields associated with ConstMethod*
void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {
set_interpreter_kind(Interpreter::invalid);
if (stackmap_data() != NULL) {
MetadataFactory::free_array<u1>(loader_data, stackmap_data());
}
set_stackmap_data(NULL);
// deallocate annotation arrays
if (has_method_annotations())
MetadataFactory::free_array<u1>(loader_data, method_annotations());
if (has_parameter_annotations())
MetadataFactory::free_array<u1>(loader_data, parameter_annotations());
if (has_type_annotations())
MetadataFactory::free_array<u1>(loader_data, type_annotations());
if (has_default_annotations())
MetadataFactory::free_array<u1>(loader_data, default_annotations());
}
// How big must this constMethodObject be?
int ConstMethod::size(int code_size,
int compressed_line_number_size,
int local_variable_table_length,
int exception_table_length,
int checked_exceptions_length,
int method_parameters_length,
u2 generic_signature_index) {
InlineTableSizes* sizes) {
int extra_bytes = code_size;
if (compressed_line_number_size > 0) {
extra_bytes += compressed_line_number_size;
if (sizes->compressed_linenumber_size() > 0) {
extra_bytes += sizes->compressed_linenumber_size();
}
if (checked_exceptions_length > 0) {
if (sizes->checked_exceptions_length() > 0) {
extra_bytes += sizeof(u2);
extra_bytes += checked_exceptions_length * sizeof(CheckedExceptionElement);
extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement);
}
if (local_variable_table_length > 0) {
if (sizes->localvariable_table_length() > 0) {
extra_bytes += sizeof(u2);
extra_bytes +=
local_variable_table_length * sizeof(LocalVariableTableElement);
sizes->localvariable_table_length() * sizeof(LocalVariableTableElement);
}
if (exception_table_length > 0) {
if (sizes->exception_table_length() > 0) {
extra_bytes += sizeof(u2);
extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement);
}
if (generic_signature_index != 0) {
if (sizes->generic_signature_index() != 0) {
extra_bytes += sizeof(u2);
}
if (method_parameters_length > 0) {
if (sizes->method_parameters_length() > 0) {
extra_bytes += sizeof(u2);
extra_bytes += method_parameters_length * sizeof(MethodParametersElement);
extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
}
// Align sizes up to a word.
extra_bytes = align_size_up(extra_bytes, BytesPerWord);
// One pointer per annotation array
if (sizes->method_annotations_length() > 0) {
extra_bytes += sizeof(AnnotationArray*);
}
if (sizes->parameter_annotations_length() > 0) {
extra_bytes += sizeof(AnnotationArray*);
}
if (sizes->type_annotations_length() > 0) {
extra_bytes += sizeof(AnnotationArray*);
}
if (sizes->default_annotations_length() > 0) {
extra_bytes += sizeof(AnnotationArray*);
}
int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
assert(extra_words == extra_bytes/BytesPerWord, "should already be aligned");
return align_object_size(header_size() + extra_words);
}
@ -145,12 +143,28 @@ u_char* ConstMethod::compressed_linenumber_table() const {
return code_end();
}
// Last short in ConstMethod* before annotations
u2* ConstMethod::last_u2_element() const {
int offset = 0;
if (has_method_annotations()) offset++;
if (has_parameter_annotations()) offset++;
if (has_type_annotations()) offset++;
if (has_default_annotations()) offset++;
return (u2*)((AnnotationArray**)constMethod_end() - offset) - 1;
}
u2* ConstMethod::generic_signature_index_addr() const {
// Located at the end of the constMethod.
assert(has_generic_signature(), "called only if generic signature exists");
return last_u2_element();
}
u2* ConstMethod::method_parameters_length_addr() const {
assert(has_method_parameters(), "called only if table is present");
return has_generic_signature() ? (last_u2_element() - 1) :
last_u2_element();
}
u2* ConstMethod::checked_exceptions_length_addr() const {
// Located immediately before the generic signature index.
assert(has_checked_exceptions(), "called only if table is present");
@ -164,12 +178,6 @@ u2* ConstMethod::checked_exceptions_length_addr() const {
}
}
u2* ConstMethod::method_parameters_length_addr() const {
assert(has_method_parameters(), "called only if table is present");
return has_generic_signature() ? (last_u2_element() - 1) :
last_u2_element();
}
u2* ConstMethod::exception_table_length_addr() const {
assert(has_exception_handler(), "called only if table is present");
if (has_checked_exceptions()) {
@ -181,9 +189,9 @@ u2* ConstMethod::exception_table_length_addr() const {
return (u2*)method_parameters_start() - 1;
} else {
// Else, the exception table is at the end of the constMethod.
return has_generic_signature() ? (last_u2_element() - 1) :
last_u2_element();
}
return has_generic_signature() ? (last_u2_element() - 1) :
last_u2_element();
}
}
}
@ -204,32 +212,38 @@ u2* ConstMethod::localvariable_table_length_addr() const {
// Else, the exception table is at the end of the constMethod.
return has_generic_signature() ? (last_u2_element() - 1) :
last_u2_element();
}
}
}
}
}
// Update the flags to indicate the presence of these optional fields.
void ConstMethod::set_inlined_tables_length(u2 generic_signature_index,
int checked_exceptions_len,
int compressed_line_number_size,
int localvariable_table_len,
int exception_table_len,
int method_parameters_len) {
assert(_flags == 0, "Error");
if (compressed_line_number_size > 0)
void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
_flags = 0;
if (sizes->compressed_linenumber_size() > 0)
_flags |= _has_linenumber_table;
if (generic_signature_index != 0)
if (sizes->generic_signature_index() != 0)
_flags |= _has_generic_signature;
if (method_parameters_len > 0)
if (sizes->method_parameters_length() > 0)
_flags |= _has_method_parameters;
if (checked_exceptions_len > 0)
if (sizes->checked_exceptions_length() > 0)
_flags |= _has_checked_exceptions;
if (exception_table_len > 0)
if (sizes->exception_table_length() > 0)
_flags |= _has_exception_table;
if (localvariable_table_len > 0)
if (sizes->localvariable_table_length() > 0)
_flags |= _has_localvariable_table;
// annotations, they are all pointer sized embedded objects so don't have
// a length embedded also.
if (sizes->method_annotations_length() > 0)
_flags |= _has_method_annotations;
if (sizes->parameter_annotations_length() > 0)
_flags |= _has_parameter_annotations;
if (sizes->type_annotations_length() > 0)
_flags |= _has_type_annotations;
if (sizes->default_annotations_length() > 0)
_flags |= _has_default_annotations;
// This code is extremely brittle and should possibly be revised.
// The *_length_addr functions walk backwards through the
// constMethod data, using each of the length indexes ahead of them,
@ -242,17 +256,17 @@ void ConstMethod::set_inlined_tables_length(u2 generic_signature_index,
// Also, the servicability agent needs to be informed anytime
// anything is added here. It might be advisable to have some sort
// of indication of this inline.
if (generic_signature_index != 0)
*(generic_signature_index_addr()) = generic_signature_index;
if (sizes->generic_signature_index() != 0)
*(generic_signature_index_addr()) = sizes->generic_signature_index();
// New data should probably go here.
if (method_parameters_len > 0)
*(method_parameters_length_addr()) = method_parameters_len;
if (checked_exceptions_len > 0)
*(checked_exceptions_length_addr()) = checked_exceptions_len;
if (exception_table_len > 0)
*(exception_table_length_addr()) = exception_table_len;
if (localvariable_table_len > 0)
*(localvariable_table_length_addr()) = localvariable_table_len;
if (sizes->method_parameters_length() > 0)
*(method_parameters_length_addr()) = sizes->method_parameters_length();
if (sizes->checked_exceptions_length() > 0)
*(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
if (sizes->exception_table_length() > 0)
*(exception_table_length_addr()) = sizes->exception_table_length();
if (sizes->localvariable_table_length() > 0)
*(localvariable_table_length_addr()) = sizes->localvariable_table_length();
}
int ConstMethod::method_parameters_length() const {
@ -307,6 +321,34 @@ ExceptionTableElement* ConstMethod::exception_table_start() const {
return (ExceptionTableElement*)addr;
}
AnnotationArray** ConstMethod::method_annotations_addr() const {
assert(has_method_annotations(), "should only be called if method annotations are present");
return (AnnotationArray**)constMethod_end() - 1;
}
AnnotationArray** ConstMethod::parameter_annotations_addr() const {
assert(has_parameter_annotations(), "should only be called if method parameter annotations are present");
int offset = 1;
if (has_method_annotations()) offset++;
return (AnnotationArray**)constMethod_end() - offset;
}
AnnotationArray** ConstMethod::type_annotations_addr() const {
assert(has_type_annotations(), "should only be called if method type annotations are present");
int offset = 1;
if (has_method_annotations()) offset++;
if (has_parameter_annotations()) offset++;
return (AnnotationArray**)constMethod_end() - offset;
}
AnnotationArray** ConstMethod::default_annotations_addr() const {
assert(has_default_annotations(), "should only be called if method default annotations are present");
int offset = 1;
if (has_method_annotations()) offset++;
if (has_parameter_annotations()) offset++;
if (has_type_annotations()) offset++;
return (AnnotationArray**)constMethod_end() - offset;
}
// Printing
@ -339,8 +381,25 @@ void ConstMethod::collect_statistics(KlassSizeStats *sz) const {
sz->_bytecode_bytes += (n2 = code_size());
sz->_stackmap_bytes += (n3 = sz->count_array(stackmap_data()));
sz->_method_all_bytes += n1 + n3; // note: n2 is part of n3
sz->_ro_bytes += n1 + n3;
// Count method annotations
int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
if (has_method_annotations()) {
sz->_methods_annotations_bytes += (a1 = sz->count_array(method_annotations()));
}
if (has_parameter_annotations()) {
sz->_methods_parameter_annotations_bytes += (a2 = sz->count_array(parameter_annotations()));
}
if (has_type_annotations()) {
sz->_methods_type_annotations_bytes += (a3 = sz->count_array(type_annotations()));
}
if (has_default_annotations()) {
sz->_methods_default_annotations_bytes += (a4 = sz->count_array(default_annotations()));
}
int size_annotations = a1 + a2 + a3 + a4;
sz->_method_all_bytes += n1 + n3 + size_annotations; // note: n2 is part of n3
sz->_ro_bytes += n1 + n3 + size_annotations;
}
#endif // INCLUDE_SERVICES
@ -352,10 +411,9 @@ void ConstMethod::verify_on(outputStream* st) {
// Verification can occur during oop construction before the method or
// other fields have been initialized.
guarantee(is_metadata(), err_msg("Should be metadata " PTR_FORMAT, this));
guarantee(method()->is_method(), "should be method");
address m_end = (address)((oop*) this + size());
address m_end = (address)((intptr_t) this + size());
address compressed_table_start = code_end();
guarantee(compressed_table_start <= m_end, "invalid method layout");
address compressed_table_end = compressed_table_start;