JDK-8005994 : Method annotations are allocated unnecessarily during class file parsing
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: hs25
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-01-10
  • Updated: 2014-06-26
  • Resolved: 2013-01-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 Other
8Fixed hs25Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
In ClassFileParser::parse_methods, the four arrays -- methods_annotations, methods_parameter_annotations, methods_default_annotations and methods_type_annotations are allocated, even if they would contain all NULL values.

It may be possible to apply a patch like this to avoid the unnecessary allocations. I tested with running  Eclipse on JDK8/x64 VM and the saving is about 4MB, or about 7% of total class meta data loaded by Eclipse.


hg diff src/share/vm/classfile/classFileParser.cpp
diff -r 36171820ba15 src/share/vm/classfile/classFileParser.cpp
--- a/src/share/vm/classfile/classFileParser.cpp	Mon Jan 07 13:10:37 2013 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Jan 10 06:21:54 2013 -0800
@@ -2452,27 +2452,35 @@
         *has_default_methods = true;
       }
       methods->at_put(index, method());
+    if (method_annotations != NULL) {
       if (*methods_annotations == NULL) {
         *methods_annotations =
              MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
       }
       (*methods_annotations)->at_put(index, method_annotations);
+    }
+    if (method_parameter_annotations != NULL) {
       if (*methods_parameter_annotations == NULL) {
         *methods_parameter_annotations =
             MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
       }
       (*methods_parameter_annotations)->at_put(index, method_parameter_annotations);
+    }
+    if (method_default_annotations != NULL) {
       if (*methods_default_annotations == NULL) {
         *methods_default_annotations =
             MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
       }
       (*methods_default_annotations)->at_put(index, method_default_annotations);
+    }
+    if (method_type_annotations != NULL) {
       if (*methods_type_annotations == NULL) {
         *methods_type_annotations =
              MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
       }
       (*methods_type_annotations)->at_put(index, method_type_annotations);
     }
+    }
 
     if (_need_verify && length > 1) {
       // Check duplicated methods


This bug seems to have been introduced in JDK8. In JDK7, checks similar to the patch above are performed (this is the latest jdk7u code as of the filing of this bug).

http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/0d5d62e38450/src/share/vm/classfile/classFileParser.cpp 

Thu Oct 11 14:46:20 2012 -0700
changeset 4034	cc602d511176

     2393       if (method_annotations.not_null()) {
     2394         if (methods_annotations.is_null()) {
     2395           objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
     2396           methods_annotations = objArrayHandle(THREAD, md);
     2397         }
     2398         methods_annotations->obj_at_put(index, method_annotations());
     2399       }
     2400       if (method_parameter_annotations.not_null()) {
     2401         if (methods_parameter_annotations.is_null()) {
     2402           objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
     2403           methods_parameter_annotations = objArrayHandle(THREAD, md);
     2404         }
     2405         methods_parameter_annotations->obj_at_put(index, method_parameter_annotations());
     2406       }
     2407       if (method_default_annotations.not_null()) {
     2408         if (methods_default_annotations.is_null()) {
     2409           objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
     2410           methods_default_annotations = objArrayHandle(THREAD, md);
     2411         }
     2412         methods_default_annotations->obj_at_put(index, method_default_annotations());
     2413       }

Comments
This was changed by the NPG work changeset: 3601:da91efe96a93 parent: 3598:36d1d483d5d6 user: coleenp date: Sat Sep 01 13:25:18 2012 -0400 summary: 6964458: Reimplement class meta-data storage to use native memory The field annotation changes seems to preserve the outer null check - if (field_annotations.not_null()) { - if (fields_annotations->is_null()) { - objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle)); - *fields_annotations = objArrayHandle(THREAD, md); + CHECK_NULL); + if (field_annotations != NULL) { + if (*fields_annotations == NULL) { + *fields_annotations = MetadataFactory::new_array<AnnotationArray*>( + loader_data, length, NULL, + CHECK_NULL); whereas the method annotation changes lost it.
10-01-2013