mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
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:
parent
ee53020f94
commit
faea95b8d3
19 changed files with 862 additions and 838 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue