From a385142398eee102ff1a53d848230dc95c4ebd37 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Wed, 6 Apr 2022 14:26:58 +0000 Subject: [PATCH] 8177107: Reduce memory footprint of java.lang.reflect.Constructor/Method Reviewed-by: darcy, shade, coleenp --- src/hotspot/share/runtime/reflection.cpp | 13 ++++++++++--- .../classes/java/lang/reflect/Constructor.java | 5 +++-- .../share/classes/java/lang/reflect/Method.java | 5 +++-- .../generics/repository/GenericDeclRepository.java | 7 ++++++- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index a7e232124b17..56b3d86911df 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -728,8 +728,15 @@ static objArrayHandle get_parameter_types(const methodHandle& method, int parameter_count, oop* return_type, TRAPS) { - // Allocate array holding parameter types (java.lang.Class instances) - objArrayOop m = oopFactory::new_objArray(vmClasses::Class_klass(), parameter_count, CHECK_(objArrayHandle())); + objArrayOop m; + if (parameter_count == 0) { + // Avoid allocating an array for the empty case + // Still need to parse the signature for the return type below + m = Universe::the_empty_class_array(); + } else { + // Allocate array holding parameter types (java.lang.Class instances) + m = oopFactory::new_objArray(vmClasses::Class_klass(), parameter_count, CHECK_(objArrayHandle())); + } objArrayHandle mirrors(THREAD, m); int index = 0; // Collect parameter types diff --git a/src/java.base/share/classes/java/lang/reflect/Constructor.java b/src/java.base/share/classes/java/lang/reflect/Constructor.java index 17277c7eb355..4f384953e295 100644 --- a/src/java.base/share/classes/java/lang/reflect/Constructor.java +++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, 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 @@ -35,6 +35,7 @@ import sun.reflect.annotation.TypeAnnotation; import sun.reflect.annotation.TypeAnnotationParser; import sun.reflect.generics.repository.ConstructorRepository; +import sun.reflect.generics.repository.GenericDeclRepository; import sun.reflect.generics.factory.CoreReflectionFactory; import sun.reflect.generics.factory.GenericsFactory; import sun.reflect.generics.scope.ConstructorScope; @@ -244,7 +245,7 @@ public TypeVariable>[] getTypeParameters() { if (getSignature() != null) { return (TypeVariable>[])getGenericInfo().getTypeParameters(); } else - return (TypeVariable>[])new TypeVariable[0]; + return (TypeVariable>[])GenericDeclRepository.EMPTY_TYPE_VARS; } diff --git a/src/java.base/share/classes/java/lang/reflect/Method.java b/src/java.base/share/classes/java/lang/reflect/Method.java index 2aff745d5536..0a62be40240c 100644 --- a/src/java.base/share/classes/java/lang/reflect/Method.java +++ b/src/java.base/share/classes/java/lang/reflect/Method.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, 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 @@ -36,6 +36,7 @@ import jdk.internal.vm.annotation.Stable; import sun.reflect.annotation.ExceptionProxy; import sun.reflect.annotation.TypeNotPresentExceptionProxy; +import sun.reflect.generics.repository.GenericDeclRepository; import sun.reflect.generics.repository.MethodRepository; import sun.reflect.generics.factory.CoreReflectionFactory; import sun.reflect.generics.factory.GenericsFactory; @@ -254,7 +255,7 @@ public TypeVariable[] getTypeParameters() { if (getGenericSignature() != null) return (TypeVariable[])getGenericInfo().getTypeParameters(); else - return (TypeVariable[])new TypeVariable[0]; + return (TypeVariable[])GenericDeclRepository.EMPTY_TYPE_VARS; } /** diff --git a/src/java.base/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java b/src/java.base/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java index 5a34ab1749ad..841526320474 100644 --- a/src/java.base/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java +++ b/src/java.base/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -42,6 +42,8 @@ public abstract class GenericDeclRepository extends AbstractRepository { + public static final TypeVariable[] EMPTY_TYPE_VARS = new TypeVariable[0]; + /** The formal type parameters. Lazily initialized. */ private volatile TypeVariable[] typeParameters; @@ -77,6 +79,9 @@ private TypeVariable[] computeTypeParameters() { FormalTypeParameter[] ftps = getTree().getFormalTypeParameters(); // create array to store reified subtree(s) int length = ftps.length; + if (length == 0) { + return EMPTY_TYPE_VARS; + } TypeVariable[] typeParameters = new TypeVariable[length]; // reify all subtrees for (int i = 0; i < length; i++) {