--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 11 14:50:30 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jul 12 00:39:53 2012 -0700
@@ -318,6 +318,13 @@
bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
+inline Symbol* check_symbol_at(constantPoolHandle cp, int index) {
+ if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8())
+ return cp->symbol_at(index);
+ else
+ return NULL;
+}
+
constantPoolHandle ClassFileParser::parse_constant_pool(Handle class_loader, TRAPS) {
ClassFileStream* cfs = stream();
constantPoolHandle nullHandle;
@@ -902,6 +909,7 @@
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
typeArrayHandle* field_annotations,
+ ClassFileParser::FieldAnnotationCollector* parsed_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
assert(attributes_count > 0, "length should be greater than 0");
@@ -1142,12 +1150,14 @@
bool is_synthetic = false;
u2 generic_signature_index = 0;
bool is_static = access_flags.is_static();
+ FieldAnnotationCollector parsed_annotations;
u2 attributes_count = cfs->get_u2_fast();
if (attributes_count > 0) {
parse_field_attributes(cp, attributes_count, is_static, signature_index,
&constantvalue_index, &is_synthetic,
&generic_signature_index, &field_annotations,
+ &parsed_annotations,
CHECK_(nullHandle));
if (field_annotations.not_null()) {
if (fields_annotations->is_null()) {
@@ -1173,6 +1183,8 @@
signature_index,
constantvalue_index,
0);
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(field);
BasicType type = cp->basic_type_for_signature_at(signature_index);
@@ -1638,12 +1650,158 @@
name->as_C_string(), _class_name->as_C_string(), sig->as_C_string());
}
+// Skip an annotation. Return >=limit if there is any problem.
+int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) {
+ // annotation := atype:u2 do(nmem:u2) {member:u2 value}
+ // value := switch (tag:u1) { ... }
+ index += 2; // skip atype
+ if ((index += 2) >= limit) return limit; // read nmem
+ int nmem = Bytes::get_Java_u2(buffer+index-2);
+ while (--nmem >= 0 && index < limit) {
+ index += 2; // skip member
+ index = skip_annotation_value(buffer, limit, index);
+ }
+ return index;
+}
+
+// Skip an annotation value. Return >=limit if there is any problem.
+int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
+ // value := switch (tag:u1) {
+ // case B, C, I, S, Z, D, F, J, c: con:u2;
+ // case e: e_class:u2 e_name:u2;
+ // case s: s_con:u2;
+ // case [: do(nval:u2) {value};
+ // case @: annotation;
+ // case s: s_con:u2;
+ // }
+ if ((index += 1) >= limit) return limit; // read tag
+ u1 tag = buffer[index-1];
+ switch (tag) {
+ case 'B': case 'C': case 'I': case 'S': case 'Z':
+ case 'D': case 'F': case 'J': case 'c': case 's':
+ index += 2; // skip con or s_con
+ break;
+ case 'e':
+ index += 4; // skip e_class, e_name
+ break;
+ case '[':
+ {
+ if ((index += 2) >= limit) return limit; // read nval
+ int nval = Bytes::get_Java_u2(buffer+index-2);
+ while (--nval >= 0 && index < limit) {
+ index = skip_annotation_value(buffer, limit, index);
+ }
+ }
+ break;
+ case '@':
+ index = skip_annotation(buffer, limit, index);
+ break;
+ default:
+ assert(false, "annotation tag");
+ return limit; // bad tag byte
+ }
+ return index;
+}
+
+// Sift through annotations, looking for those significant to the VM:
+void ClassFileParser::parse_annotations(u1* buffer, int limit,
+ constantPoolHandle cp,
+ ClassFileParser::AnnotationCollector* coll,
+ TRAPS) {
+ // annotations := do(nann:u2) {annotation}
+ int index = 0;
+ if ((index += 2) >= limit) return; // read nann
+ int nann = Bytes::get_Java_u2(buffer+index-2);
+ enum { // initial annotation layout
+ atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;'
+ count_off = 2, // u2 such as 1 (one value)
+ member_off = 4, // utf8 such as 'value'
+ tag_off = 6, // u1 such as 'c' (type) or 'e' (enum)
+ e_tag_val = 'e',
+ e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
+ e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
+ e_size = 11, // end of 'e' annotation
+ c_tag_val = 'c',
+ c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;'
+ c_size = 9, // end of 'c' annotation
+ min_size = 6 // smallest possible size (zero members)
+ };
+ while ((--nann) >= 0 && (index-2 + min_size <= limit)) {
+ int index0 = index;
+ index = skip_annotation(buffer, limit, index);
+ u1* abase = buffer + index0;
+ int atype = Bytes::get_Java_u2(abase + atype_off);
+ int count = Bytes::get_Java_u2(abase + count_off);
+ Symbol* aname = check_symbol_at(cp, atype);
+ if (aname == NULL) break; // invalid annotation name
+ Symbol* member = NULL;
+ if (count >= 1) {
+ int member_index = Bytes::get_Java_u2(abase + member_off);
+ member = check_symbol_at(cp, member_index);
+ if (member == NULL) break; // invalid member name
+ }
+
+ // Here is where parsing particular annotations will take place.
+ AnnotationCollector::ID id = coll->annotation_index(aname);
+ if (id == AnnotationCollector::_unknown) continue;
+ coll->set_annotation(id);
+ // If there are no values, just set the bit and move on:
+ if (count == 0) continue;
+
+ // For the record, here is how annotation payloads can be collected.
+ // Suppose we want to capture @Retention.value. Here is how:
+ //if (id == AnnotationCollector::_class_Retention) {
+ // Symbol* payload = NULL;
+ // if (count == 1
+ // && e_size == (index0 - index) // match size
+ // && e_tag_val == *(abase + tag_off)
+ // && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off))
+ // == vmSymbols::RetentionPolicy_signature())
+ // && member == vmSymbols::value_name()) {
+ // payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off));
+ // }
+ // check_property(payload != NULL,
+ // "Invalid @Retention annotation at offset %u in class file %s",
+ // index0, CHECK);
+ // if (payload != NULL) {
+ // payload->increment_refcount();
+ // coll->_class_RetentionPolicy = payload;
+ // }
+ //}
+ }
+}
+
+ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) {
+ vmSymbols::SID sid = vmSymbols::find_sid(name);
+ switch (sid) {
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
+ if (_location != _in_method) break; // only allow for methods
+ return _method_ForceInline;
+ default: break;
+ }
+ return AnnotationCollector::_unknown;
+}
+
+void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
+ fatal("no field annotations yet");
+}
+
+void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
+ if (has_annotation(_method_ForceInline))
+ m->set_force_inline(true);
+}
+
+void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) {
+ fatal("no class annotations yet");
+}
+
+
#define MAX_ARGS_SIZE 255
#define MAX_CODE_SIZE 65535
#define INITIAL_MAX_LVT_NUMBER 256
// Note: the parse_method below is big and clunky because all parsing of the code and exceptions
-// attribute is inlined. This is curbersome to avoid since we inline most of the parts in the
+// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
// methodOop to save footprint, so we only know the size of the resulting methodOop when the
// entire method attribute is parsed.
//
@@ -1733,6 +1891,7 @@
// stackmap attribute - JDK1.5
typeArrayHandle stackmap_data;
u2 generic_signature_index = 0;
+ MethodAnnotationCollector parsed_annotations;
u1* runtime_visible_annotations = NULL;
int runtime_visible_annotations_length = 0;
u1* runtime_invisible_annotations = NULL;
@@ -1959,6 +2118,7 @@
runtime_visible_annotations_length = method_attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
+ parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
} else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = method_attribute_length;
@@ -2136,6 +2296,8 @@
clear_hashtable(lvt_Hash);
}
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(m);
*method_annotations = assemble_annotations(runtime_visible_annotations,
runtime_visible_annotations_length,
runtime_invisible_annotations,
@@ -2314,7 +2476,7 @@
}
-void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS) {
ClassFileStream* cfs = stream();
cfs->guarantee_more(2, CHECK); // sourcefile_index
u2 sourcefile_index = cfs->get_u2_fast();
@@ -2323,13 +2485,12 @@
cp->tag_at(sourcefile_index).is_utf8(),
"Invalid SourceFile attribute at constant pool index %u in class file %s",
sourcefile_index, CHECK);
- k->set_source_file_name(cp->symbol_at(sourcefile_index));
+ set_class_sourcefile(cp->symbol_at(sourcefile_index));
}
void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
- instanceKlassHandle k,
int length, TRAPS) {
ClassFileStream* cfs = stream();
u1* sde_buffer = cfs->get_u1_buffer();
@@ -2340,9 +2501,9 @@
// Optimistically assume that only 1 byte UTF format is used
// (common case)
TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK);
- k->set_source_debug_extension(sde_symbol);
// Note that set_source_debug_extension() increments the reference count
// for its copy of the Symbol*, so use a TempNewSymbol here.
+ set_class_sde_symbol(sde_symbol);
}
// Got utf8 string, set stream position forward
cfs->skip_u1(length, CHECK);
@@ -2358,7 +2519,7 @@
u2 enclosing_method_class_index,
u2 enclosing_method_method_index,
constantPoolHandle cp,
- instanceKlassHandle k, TRAPS) {
+ TRAPS) {
ClassFileStream* cfs = stream();
u1* current_mark = cfs->current();
u2 length = 0;
@@ -2449,7 +2610,7 @@
assert(index == size, "wrong size");
// Update instanceKlass with inner class info.
- k->set_inner_classes(inner_classes());
+ set_class_inner_classes(inner_classes);
// Restore buffer's current position.
cfs->set_current(current_mark);
@@ -2457,11 +2618,11 @@
return length;
}
-void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
- k->set_is_synthetic();
+void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS) {
+ set_class_synthetic_flag(true);
}
-void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS) {
ClassFileStream* cfs = stream();
u2 signature_index = cfs->get_u2(CHECK);
check_property(
@@ -2469,10 +2630,10 @@
cp->tag_at(signature_index).is_utf8(),
"Invalid constant pool index %u in Signature attribute in class file %s",
signature_index, CHECK);
- k->set_generic_signature(cp->symbol_at(signature_index));
+ set_class_generic_signature(cp->symbol_at(signature_index));
}
-void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k,
+void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp,
u4 attribute_byte_length, TRAPS) {
ClassFileStream* cfs = stream();
u1* current_start = cfs->current();
@@ -2544,10 +2705,12 @@
}
-void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp,
+ ClassFileParser::ClassAnnotationCollector* parsed_annotations,
+ TRAPS) {
ClassFileStream* cfs = stream();
// Set inner classes attribute to default sentinel
- k->set_inner_classes(Universe::the_empty_short_array());
+ set_class_inner_classes(typeArrayHandle(THREAD, Universe::the_empty_short_array()));
cfs->guarantee_more(2, CHECK); // attributes_count
u2 attributes_count = cfs->get_u2_fast();
bool parsed_sourcefile_attribute = false;
@@ -2583,10 +2746,10 @@
} else {
parsed_sourcefile_attribute = true;
}
- parse_classfile_sourcefile_attribute(cp, k, CHECK);
+ parse_classfile_sourcefile_attribute(cp, CHECK);
} else if (tag == vmSymbols::tag_source_debug_extension()) {
// Check for SourceDebugExtension tag
- parse_classfile_source_debug_extension_attribute(cp, k, (int)attribute_length, CHECK);
+ parse_classfile_source_debug_extension_attribute(cp, (int)attribute_length, CHECK);
} else if (tag == vmSymbols::tag_inner_classes()) {
// Check for InnerClasses tag
if (parsed_innerclasses_attribute) {
@@ -2605,7 +2768,7 @@
"Invalid Synthetic classfile attribute length %u in class file %s",
attribute_length, CHECK);
}
- parse_classfile_synthetic_attribute(cp, k, CHECK);
+ parse_classfile_synthetic_attribute(cp, CHECK);
} else if (tag == vmSymbols::tag_deprecated()) {
// Check for Deprecatd tag - 4276120
if (attribute_length != 0) {
@@ -2620,11 +2783,16 @@
"Wrong Signature attribute length %u in class file %s",
attribute_length, CHECK);
}
- parse_classfile_signature_attribute(cp, k, CHECK);
+ parse_classfile_signature_attribute(cp, CHECK);
} else if (tag == vmSymbols::tag_runtime_visible_annotations()) {
runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
+ parse_annotations(runtime_visible_annotations,
+ runtime_visible_annotations_length,
+ cp,
+ parsed_annotations,
+ CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK);
} else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = attribute_length;
@@ -2658,7 +2826,7 @@
if (parsed_bootstrap_methods_attribute)
classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
parsed_bootstrap_methods_attribute = true;
- parse_classfile_bootstrap_methods_attribute(cp, k, attribute_length, CHECK);
+ parse_classfile_bootstrap_methods_attribute(cp, attribute_length, CHECK);
} else {
// Unknown attribute
cfs->skip_u1(attribute_length, CHECK);
@@ -2673,7 +2841,7 @@
runtime_invisible_annotations,
runtime_invisible_annotations_length,
CHECK);
- k->set_class_annotations(annotations());
+ set_class_annotations(annotations);
if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
u2 num_of_classes = parse_classfile_inner_classes_attribute(
@@ -2681,7 +2849,7 @@
parsed_innerclasses_attribute,
enclosing_method_class_index,
enclosing_method_method_index,
- cp, k, CHECK);
+ cp, CHECK);
if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
guarantee_property(
inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
@@ -2695,6 +2863,21 @@
}
}
+void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) {
+ if (_synthetic_flag)
+ k->set_is_synthetic();
+ if (_sourcefile != NULL) {
+ _sourcefile->increment_refcount();
+ k->set_source_file_name(_sourcefile);
+ }
+ if (_generic_signature != NULL) {
+ _generic_signature->increment_refcount();
+ k->set_generic_signature(_generic_signature);
+ }
+ k->set_source_debug_extension(_sde_symbol); // increment_refcount inside
+ k->set_inner_classes(_inner_classes());
+ k->set_class_annotations(_annotations());
+}
typeArrayHandle ClassFileParser::assemble_annotations(u1* runtime_visible_annotations,
int runtime_visible_annotations_length,
@@ -2745,8 +2928,7 @@
jt->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::PARSE_CLASS);
- _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
- _max_bootstrap_specifier_index = -1;
+ init_parsed_class_attributes();
if (JvmtiExport::should_post_class_file_load_hook()) {
// Get the cached class file bytes (if any) from the class that
@@ -2979,6 +3161,13 @@
objArrayHandle methods_parameter_annotations(THREAD, methods_parameter_annotations_oop);
objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
+ // Additional attributes
+ ClassAnnotationCollector parsed_annotations;
+ parse_classfile_attributes(cp, &parsed_annotations, CHECK_(nullHandle));
+
+ // Make sure this is the end of class file stream
+ guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
+
// We check super class after class file is parsed and format is checked
if (super_class_index > 0 && super_klass.is_null()) {
Symbol* sk = cp->klass_name_at(super_class_index);
@@ -3467,11 +3656,10 @@
this_klass->set_has_miranda_methods(); // then set a flag
}
- // Additional attributes
- parse_classfile_attributes(cp, this_klass, CHECK_(nullHandle));
-
- // Make sure this is the end of class file stream
- guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
+ // Fill in field values obtained by parse_classfile_attributes
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(this_klass);
+ apply_parsed_class_attributes(this_klass);
// VerifyOops believes that once this has been set, the object is completely loaded.
// Compute transitive closure of interfaces this class implements
@@ -3486,6 +3674,7 @@
// Do final class setup
fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);
+ // Fill in has_finalizer, has_vanilla_constructor, and layout_helper
set_precomputed_flags(this_klass);
// reinitialize modifiers, using the InnerClasses attribute
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 11 14:50:30 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Thu Jul 12 00:39:53 2012 -0700
@@ -31,8 +31,8 @@
#include "oops/typeArrayOop.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/accessFlags.hpp"
+#include "classfile/symbolTable.hpp"
-class TempNewSymbol;
class FieldAllocationCount;
@@ -50,11 +50,77 @@
KlassHandle _host_klass;
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
+ // precomputed flags
bool _has_finalizer;
bool _has_empty_finalizer;
bool _has_vanilla_constructor;
+ int _max_bootstrap_specifier_index; // detects BSS values
- int _max_bootstrap_specifier_index;
+ // class attributes parsed before the instance klass is created:
+ bool _synthetic_flag;
+ Symbol* _sourcefile;
+ Symbol* _generic_signature;
+ TempNewSymbol _sde_symbol;
+ typeArrayHandle _inner_classes;
+ typeArrayHandle _annotations;
+
+ void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
+ void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
+ void set_class_generic_signature(Symbol* x) { _generic_signature = x; }
+ void set_class_sde_symbol(Symbol* x) { _sde_symbol = x; }
+ void set_class_inner_classes(typeArrayHandle x) { _inner_classes = x; }
+ void set_class_annotations(typeArrayHandle x) { _annotations = x; }
+ void init_parsed_class_attributes() {
+ _synthetic_flag = false;
+ _sourcefile = NULL;
+ _generic_signature = NULL;
+ // initialize the other flags too:
+ _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
+ _max_bootstrap_specifier_index = -1;
+ }
+ void apply_parsed_class_attributes(instanceKlassHandle k); // update k
+
+ class AnnotationCollector {
+ public:
+ enum Location { _in_field, _in_method, _in_class };
+ enum ID {
+ _unknown = 0,
+ _method_ForceInline,
+ _annotation_LIMIT
+ };
+ const Location _location;
+ int _annotations_present;
+ AnnotationCollector(Location location)
+ : _location(location), _annotations_present(0)
+ {
+ assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
+ }
+ // If this annotation name has an ID, report it (or _none).
+ ID annotation_index(Symbol* name);
+ // Set the annotation name:
+ void set_annotation(ID id) {
+ assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
+ _annotations_present |= nth_bit((int)id);
+ }
+ // Report if the annotation is present.
+ bool has_any_annotations() { return _annotations_present != 0; }
+ bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; }
+ };
+ class FieldAnnotationCollector: public AnnotationCollector {
+ public:
+ FieldAnnotationCollector() : AnnotationCollector(_in_field) { }
+ void apply_to(FieldInfo* f);
+ };
+ class MethodAnnotationCollector: public AnnotationCollector {
+ public:
+ MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
+ void apply_to(methodHandle m);
+ };
+ class ClassAnnotationCollector: public AnnotationCollector {
+ public:
+ ClassAnnotationCollector() : AnnotationCollector(_in_class) { }
+ void apply_to(instanceKlassHandle k);
+ };
enum { fixed_buffer_size = 128 };
u_char linenumbertable_buffer[fixed_buffer_size];
@@ -87,7 +153,9 @@
u2* constantvalue_index_addr,
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
- typeArrayHandle* field_annotations, TRAPS);
+ typeArrayHandle* field_annotations,
+ FieldAnnotationCollector* parsed_annotations,
+ TRAPS);
typeArrayHandle parse_fields(Symbol* class_name,
constantPoolHandle cp, bool is_interface,
FieldAllocationCount *fac,
@@ -128,25 +196,32 @@
typeArrayOop parse_stackmap_table(u4 code_attribute_length, TRAPS);
// Classfile attribute parsing
- void parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
- instanceKlassHandle k, int length, TRAPS);
+ void parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS);
+ void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp, int length, TRAPS);
u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
bool parsed_enclosingmethod_attribute,
u2 enclosing_method_class_index,
u2 enclosing_method_method_index,
constantPoolHandle cp,
- instanceKlassHandle k, TRAPS);
- void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k, u4 attribute_length, TRAPS);
+ TRAPS);
+ void parse_classfile_attributes(constantPoolHandle cp,
+ ClassAnnotationCollector* parsed_annotations,
+ TRAPS);
+ void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS);
+ void parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS);
+ void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, u4 attribute_length, TRAPS);
// Annotations handling
typeArrayHandle assemble_annotations(u1* runtime_visible_annotations,
int runtime_visible_annotations_length,
u1* runtime_invisible_annotations,
int runtime_invisible_annotations_length, TRAPS);
+ int skip_annotation(u1* buffer, int limit, int index);
+ int skip_annotation_value(u1* buffer, int limit, int index);
+ void parse_annotations(u1* buffer, int limit, constantPoolHandle cp,
+ /* Results (currently, only one result is supported): */
+ AnnotationCollector* result,
+ TRAPS);
// Final setup
unsigned int compute_oop_map_count(instanceKlassHandle super,