defender methods analysis, classloading and java.lang.StackOverflowError

Sergey Kuksenko sergey.kuksenko at oracle.com
Wed Mar 14 08:17:05 PDT 2012


On 03/14/2012 07:08 PM, Sergey Kuksenko wrote:
> Hi All,
>
> It is not a big secret that HotSpot do classloading of 
> superclasses/superinterfaces recursively.
> That means - for any fixed stack size there is classes/interfaces 
> chain which causes java.lang.StackOverflowError
> For example, on Linux x86-32, chain of 512 interfaces needs at least 
> 2.5Megabytes stack size using jdk7u2 (default stack size == 320k).
> Maybe it is not a good idea to do classloading with recursion, but it 
> is a topic for another mail list.
>
> Let's back to defenders.
> I was playing with interface chains. All interfaces (except the first) 
> are empty. There are no defender methods here.
> As result I've got on Linux x86-32:
> - jdk7u2 requires ~4.8K per interface
> - jdk8 requires ~5K per interface
> - lambda build requires ~13K per interface.
>
> Lambda's HotSpot requires 2.5 larger stack size settings than jdk8. 
> This is really significant change. Jdk7 & 8 with default stack size 
> (Linux32) may load chain of ~60 classes/interfaces, but lambda may 
> load chain only of ~20 classes/interfaces. The source of that is 
> declaration "GenericAnalyzer ga;" in the 
> "ClassFileParser::parseClassFile" method and it doesn't matter that 
> the declaration is inside never executed scope/block.
> We may say "thank you" to gcc. I didn't check, but expecting the 
> similar problem for other C++ compilers and platforms.
>
> I've attached patch which solves that problem. Simple extracting 
> couple lines of code into separate method bring back lambda to jdk8 
> stack size requirements.
>

It looks like I lost the attachment, trying to repeat.


------------------------------
diff -r 108d1e7220ee src/share/vm/classfile/classFileParser.cpp
--- a/src/share/vm/classfile/classFileParser.cpp    Thu Feb 02 01:53:12 
2012 -0500
+++ b/src/share/vm/classfile/classFileParser.cpp    Tue Mar 13 19:24:51 
2012 +0400
@@ -3396,13 +3396,9 @@
  #endif

      if (has_default_methods && !access_flags.is_interface()) {
-      ResourceMark rm(THREAD);
-
-      GenericAnalyzer ga;
-      ga.run(
-        class_name, this_klass, super_klass, &all_mirandas,
-        methods, methods_annotations, methods_parameter_annotations,
-        methods_default_annotations, CHECK_(nullHandle));
+      analyze_defaults(class_name, this_klass, super_klass, &all_mirandas,
+                methods, methods_annotations, 
methods_parameter_annotations,
+                methods_default_annotations, CHECK_(nullHandle));
      }

      // Miranda methods
@@ -3523,6 +3519,22 @@
    return this_klass;
  }

+void ClassFileParser::analyze_defaults(
+      Symbol* class_name, instanceKlassHandle klass,
+      instanceKlassHandle super, GrowableArray<methodOop>* mirandas,
+      objArrayHandle methods, objArrayHandle annotations,
+      objArrayHandle annot_params, objArrayHandle annot_defaults, TRAPS){
+
+    ResourceMark rm(THREAD);
+
+    GenericAnalyzer ga;
+    ga.run(
+      class_name, klass, super, mirandas,
+      methods, annotations, annot_params,
+      annot_defaults, THREAD);
+
+}
+

  unsigned int
  ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
diff -r 108d1e7220ee src/share/vm/classfile/classFileParser.hpp
--- a/src/share/vm/classfile/classFileParser.hpp    Thu Feb 02 01:53:12 
2012 -0500
+++ b/src/share/vm/classfile/classFileParser.hpp    Tue Mar 13 19:24:51 
2012 +0400
@@ -139,6 +139,12 @@
    void parse_classfile_signature_attribute(constantPoolHandle cp, 
instanceKlassHandle k, TRAPS);
    void parse_classfile_bootstrap_methods_attribute(constantPoolHandle 
cp, instanceKlassHandle k, u4 attribute_length, TRAPS);

+  void analyze_defaults(
+      Symbol* class_name, instanceKlassHandle klass,
+      instanceKlassHandle super, GrowableArray<methodOop>* mirandas,
+      objArrayHandle methods, objArrayHandle annotations,
+      objArrayHandle annot_params, objArrayHandle annot_defaults, TRAPS);
+
    // Annotations handling
    typeArrayHandle assemble_annotations(u1* runtime_visible_annotations,
                                         int 
runtime_visible_annotations_length,

-- 
Best regards,
Sergey Kuksenko



More information about the lambda-dev mailing list