8185925: StackFrameInfo::walker field can be replaced with bitmap to save footprint
8153682: StackFrameInfo.declaringClass could be removed
Reviewed-by: coleenp, mchung
--- 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