8185925: StackFrameInfo::walker field can be replaced with bitmap to save footprint
authorbchristi
Thu, 09 Nov 2017 11:13:50 -0800
changeset 47818 2f6ab27efb60
parent 47817 5d15fd7e9bb1
child 47819 ee36a8e36561
8185925: StackFrameInfo::walker field can be replaced with bitmap to save footprint 8153682: StackFrameInfo.declaringClass could be removed Reviewed-by: coleenp, mchung
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/javaClasses.hpp
src/hotspot/share/classfile/vmSymbols.hpp
src/hotspot/share/prims/stackwalk.cpp
src/java.base/share/classes/java/lang/StackFrameInfo.java
src/java.base/share/classes/java/lang/StackWalker.java
src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java
--- a/src/hotspot/share/classfile/javaClasses.cpp	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Nov 09 11:13:50 2017 -0800
@@ -2258,8 +2258,9 @@
 
 void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) {
   ResourceMark rm(THREAD);
-  Handle k (THREAD, stackFrame->obj_field(_declaringClass_offset));
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k()));
+  Handle mname(THREAD, stackFrame->obj_field(java_lang_StackFrameInfo::_memberName_offset));
+  Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
+  InstanceKlass* holder = InstanceKlass::cast(clazz);
   Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
 
   short version = stackFrame->short_field(_version_offset);
@@ -2270,7 +2271,6 @@
 
 void java_lang_StackFrameInfo::compute_offsets() {
   Klass* k = SystemDictionary::StackFrameInfo_klass();
-  compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(),  vmSymbols::class_signature());
   compute_offset(_memberName_offset,     k, vmSymbols::memberName_name(),  vmSymbols::object_signature());
   compute_offset(_bci_offset,            k, vmSymbols::bci_name(),         vmSymbols::short_signature());
   STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
@@ -3679,7 +3679,6 @@
 int java_lang_StackTraceElement::classLoaderName_offset;
 int java_lang_StackTraceElement::declaringClass_offset;
 int java_lang_StackTraceElement::declaringClassObject_offset;
-int java_lang_StackFrameInfo::_declaringClass_offset;
 int java_lang_StackFrameInfo::_memberName_offset;
 int java_lang_StackFrameInfo::_bci_offset;
 int java_lang_StackFrameInfo::_version_offset;
@@ -3732,11 +3731,6 @@
   element->obj_field_put(declaringClassObject_offset, value);
 }
 
-// Support for java_lang_StackFrameInfo
-void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) {
-  element->obj_field_put(_declaringClass_offset, value);
-}
-
 void java_lang_StackFrameInfo::set_version(oop element, short value) {
   element->short_field_put(_version_offset, value);
 }
--- a/src/hotspot/share/classfile/javaClasses.hpp	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Thu Nov 09 11:13:50 2017 -0800
@@ -1370,7 +1370,6 @@
 
 class java_lang_StackFrameInfo: AllStatic {
 private:
-  static int _declaringClass_offset;
   static int _memberName_offset;
   static int _bci_offset;
   static int _version_offset;
@@ -1379,7 +1378,6 @@
 
 public:
   // Setters
-  static void set_declaringClass(oop info, oop value);
   static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci, TRAPS);
   static void set_bci(oop info, int value);
 
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Thu Nov 09 11:13:50 2017 -0800
@@ -429,7 +429,6 @@
   template(append_name,                               "append")                                   \
   template(klass_name,                                "klass")                                    \
   template(array_klass_name,                          "array_klass")                              \
-  template(declaringClass_name,                       "declaringClass")                           \
   template(memberName_name,                           "memberName")                               \
   template(mid_name,                                  "mid")                                      \
   template(cpref_name,                                "cpref")                                    \
--- a/src/hotspot/share/prims/stackwalk.cpp	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/hotspot/share/prims/stackwalk.cpp	Thu Nov 09 11:13:50 2017 -0800
@@ -272,9 +272,8 @@
   return array_h;
 }
 
-// Fill StackFrameInfo with declaringClass and bci and initialize memberName
+// Fill StackFrameInfo with bci and initialize memberName
 void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) {
-  java_lang_StackFrameInfo::set_declaringClass(stackFrame(), method->method_holder()->java_mirror());
   java_lang_StackFrameInfo::set_method_and_bci(stackFrame, method, bci(), THREAD);
 }
 
--- a/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Nov 09 11:13:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,14 +32,12 @@
 import java.lang.invoke.MethodType;
 
 class StackFrameInfo implements StackFrame {
+    private final byte RETAIN_CLASS_REF = 0x01;
+
     private final static JavaLangInvokeAccess JLIA =
         SharedSecrets.getJavaLangInvokeAccess();
 
-    // Footprint improvement: MemberName::clazz can replace
-    // StackFrameInfo::declaringClass.
-
-    private final StackWalker walker;
-    private final Class<?> declaringClass;
+    private final byte flags;
     private final Object memberName;
     private final short bci;
     private volatile StackTraceElement ste;
@@ -49,8 +47,7 @@
      * to use
      */
     StackFrameInfo(StackWalker walker) {
-        this.walker = walker;
-        this.declaringClass = null;
+        this.flags = walker.retainClassRef ? RETAIN_CLASS_REF : 0;
         this.bci = -1;
         this.memberName = JLIA.newMemberName();
     }
@@ -58,20 +55,20 @@
     // package-private called by StackStreamFactory to skip
     // the capability check
     Class<?> declaringClass() {
-        return declaringClass;
+        return JLIA.getDeclaringClass(memberName);
     }
 
     // ----- implementation of StackFrame methods
 
     @Override
     public String getClassName() {
-        return declaringClass.getName();
+        return declaringClass().getName();
     }
 
     @Override
     public Class<?> getDeclaringClass() {
-        walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
-        return declaringClass;
+        ensureRetainClassRefEnabled();
+        return declaringClass();
     }
 
     @Override
@@ -81,7 +78,7 @@
 
     @Override
     public MethodType getMethodType() {
-        walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
+        ensureRetainClassRefEnabled();
         return JLIA.getMethodType(memberName);
     }
 
@@ -137,4 +134,10 @@
         }
         return s;
     }
+
+    private void ensureRetainClassRefEnabled() {
+        if ((flags & RETAIN_CLASS_REF) == 0) {
+            throw new UnsupportedOperationException("No access to RETAIN_CLASS_REFERENCE");
+        }
+    }
 }
--- a/src/java.base/share/classes/java/lang/StackWalker.java	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/java.base/share/classes/java/lang/StackWalker.java	Thu Nov 09 11:13:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -296,6 +296,7 @@
     private final Set<Option> options;
     private final ExtendedOption extendedOption;
     private final int estimateDepth;
+    final boolean retainClassRef; // cached for performance
 
     /**
      * Returns a {@code StackWalker} instance.
@@ -412,6 +413,7 @@
         this.options = options;
         this.estimateDepth = estimateDepth;
         this.extendedOption = extendedOption;
+        this.retainClassRef = hasOption(Option.RETAIN_CLASS_REFERENCE);
     }
 
     private static void checkPermission(Set<Option> options) {
@@ -590,7 +592,7 @@
      */
     @CallerSensitive
     public Class<?> getCallerClass() {
-        if (!options.contains(Option.RETAIN_CLASS_REFERENCE)) {
+        if (!retainClassRef) {
             throw new UnsupportedOperationException("This stack walker " +
                     "does not have RETAIN_CLASS_REFERENCE access");
         }
@@ -617,11 +619,4 @@
     boolean hasLocalsOperandsOption() {
         return extendedOption == ExtendedOption.LOCALS_AND_OPERANDS;
     }
-
-    void ensureAccessEnabled(Option access) {
-        if (!hasOption(access)) {
-            throw new UnsupportedOperationException("No access to " + access +
-                    ": " + options.toString());
-        }
-    }
 }
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Nov 09 11:13:50 2017 -0800
@@ -1784,6 +1784,11 @@
                 MemberName memberName = (MemberName)mname;
                 return memberName.getName();
             }
+            @Override
+            public Class<?> getDeclaringClass(Object mname) {
+                MemberName memberName = (MemberName)mname;
+                return memberName.getDeclaringClass();
+            }
 
             @Override
             public MethodType getMethodType(Object mname) {
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Nov 09 10:11:19 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Nov 09 11:13:50 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,34 +30,40 @@
 
 public interface JavaLangInvokeAccess {
     /**
-     * Create a new MemberName instance. Used by {@see StackFrameInfo}.
+     * Create a new MemberName instance. Used by {@code StackFrameInfo}.
      */
     Object newMemberName();
 
     /**
-     * Returns the name for the given MemberName. Used by {@see StackFrameInfo}.
+     * Returns the name for the given MemberName. Used by {@code StackFrameInfo}.
      */
     String getName(Object mname);
 
     /**
      * Returns the {@code MethodType} for the given MemberName.
-     * Used by {@see StackFrameInfo}.
+     * Used by {@code StackFrameInfo}.
      */
     MethodType getMethodType(Object mname);
 
     /**
      * Returns the descriptor for the given MemberName.
-     * Used by {@see StackFrameInfo}.
+     * Used by {@code StackFrameInfo}.
      */
     String getMethodDescriptor(Object mname);
 
     /**
-     * Returns {@code true} if the given MemberName is a native method. Used by
-     * {@see StackFrameInfo}.
+     * Returns {@code true} if the given MemberName is a native method.
+     * Used by {@code StackFrameInfo}.
      */
     boolean isNative(Object mname);
 
     /**
+     * Returns the declaring class for the given MemberName.
+     * Used by {@code StackFrameInfo}.
+     */
+    Class<?> getDeclaringClass(Object mname);
+
+    /**
      * Returns a {@code byte[]} representation of a class implementing
      * DirectMethodHandle of each pairwise combination of {@code MethodType} and
      * an {@code int} representing method type.  Used by