From 064628471b83616b4463baa78618d1b7a66d0c7c Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Wed, 17 Apr 2024 17:35:17 +0000 Subject: [PATCH] 8317376: Minor improvements to the 'this' escape analyzer Reviewed-by: vromero --- make/CompileModuleTools.gmk | 2 +- make/modules/java.net.http/Java.gmk | 26 - make/modules/java.sql.rowset/Java.gmk | 2 - make/modules/jdk.charsets/Java.gmk | 2 - make/modules/jdk.compiler/Gendata.gmk | 2 +- make/modules/jdk.crypto.ec/Java.gmk | 26 - make/modules/jdk.javadoc/Gendata.gmk | 2 +- make/modules/jdk.jcmd/Java.gmk | 2 - make/modules/jdk.jconsole/Java.gmk | 2 - make/modules/jdk.jdeps/Gensrc.gmk | 2 - make/modules/jdk.jdeps/Launcher.gmk | 2 - make/modules/jdk.jdi/Java.gmk | 2 - make/modules/jdk.jpackage/Java.gmk | 2 - make/modules/jdk.localedata/Java.gmk | 2 - make/modules/jdk.sctp/Java.gmk | 2 - .../com/sun/tools/javac/comp/Flow.java | 2 +- .../tools/javac/comp/ThisEscapeAnalyzer.java | 882 ++++++++++++------ .../com/sun/tools/javac/tree/TreeInfo.java | 35 + .../tools/javac/warnings/ThisEscape.java | 120 ++- .../tools/javac/warnings/ThisEscape.out | 14 +- 20 files changed, 756 insertions(+), 375 deletions(-) delete mode 100644 make/modules/java.net.http/Java.gmk delete mode 100644 make/modules/jdk.crypto.ec/Java.gmk diff --git a/make/CompileModuleTools.gmk b/make/CompileModuleTools.gmk index bb3948f377e..0a3039b34d2 100644 --- a/make/CompileModuleTools.gmk +++ b/make/CompileModuleTools.gmk @@ -53,7 +53,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JIGSAW_TOOLS, \ build/tools/jigsaw, \ COPY := .properties .html, \ BIN := $(TOOLS_CLASSES_DIR), \ - DISABLED_WARNINGS := fallthrough this-escape, \ + DISABLED_WARNINGS := fallthrough, \ JAVAC_FLAGS := \ --add-modules jdk.jdeps \ --add-exports java.base/jdk.internal.module=ALL-UNNAMED \ diff --git a/make/modules/java.net.http/Java.gmk b/make/modules/java.net.http/Java.gmk deleted file mode 100644 index 269a1195b6a..00000000000 --- a/make/modules/java.net.http/Java.gmk +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2023, 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 -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -DISABLED_WARNINGS_java += this-escape diff --git a/make/modules/java.sql.rowset/Java.gmk b/make/modules/java.sql.rowset/Java.gmk index 6548dd46cae..2dc60515a1b 100644 --- a/make/modules/java.sql.rowset/Java.gmk +++ b/make/modules/java.sql.rowset/Java.gmk @@ -23,8 +23,6 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' CLEAN_FILES += $(wildcard \ diff --git a/make/modules/jdk.charsets/Java.gmk b/make/modules/jdk.charsets/Java.gmk index fad05cc29f1..3adf141e8e1 100644 --- a/make/modules/jdk.charsets/Java.gmk +++ b/make/modules/jdk.charsets/Java.gmk @@ -23,6 +23,4 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - COPY += .dat diff --git a/make/modules/jdk.compiler/Gendata.gmk b/make/modules/jdk.compiler/Gendata.gmk index 32fa70462b2..78847074c88 100644 --- a/make/modules/jdk.compiler/Gendata.gmk +++ b/make/modules/jdk.compiler/Gendata.gmk @@ -66,7 +66,7 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \ SRC := $(TOPDIR)/make/langtools/src/classes, \ INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javac, \ - DISABLED_WARNINGS := options this-escape, \ + DISABLED_WARNINGS := options, \ JAVAC_FLAGS := \ $(COMPILECREATESYMBOLS_ADD_EXPORTS), \ )) diff --git a/make/modules/jdk.crypto.ec/Java.gmk b/make/modules/jdk.crypto.ec/Java.gmk deleted file mode 100644 index 269a1195b6a..00000000000 --- a/make/modules/jdk.crypto.ec/Java.gmk +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2023, 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 -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -DISABLED_WARNINGS_java += this-escape diff --git a/make/modules/jdk.javadoc/Gendata.gmk b/make/modules/jdk.javadoc/Gendata.gmk index 412559c5fe1..95719c7b452 100644 --- a/make/modules/jdk.javadoc/Gendata.gmk +++ b/make/modules/jdk.javadoc/Gendata.gmk @@ -56,7 +56,7 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \ $(TOPDIR)/src/jdk.jdeps/share/classes, \ INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc, \ - DISABLED_WARNINGS := options this-escape, \ + DISABLED_WARNINGS := options, \ JAVAC_FLAGS := \ $(INTERIM_LANGTOOLS_ARGS) \ $(COMPILECREATESYMBOLS_ADD_EXPORTS), \ diff --git a/make/modules/jdk.jcmd/Java.gmk b/make/modules/jdk.jcmd/Java.gmk index 08209e93538..2cae8b0fdd5 100644 --- a/make/modules/jdk.jcmd/Java.gmk +++ b/make/modules/jdk.jcmd/Java.gmk @@ -23,6 +23,4 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - COPY += _options diff --git a/make/modules/jdk.jconsole/Java.gmk b/make/modules/jdk.jconsole/Java.gmk index 9166d6a7c11..b60b84cdc3c 100644 --- a/make/modules/jdk.jconsole/Java.gmk +++ b/make/modules/jdk.jconsole/Java.gmk @@ -23,8 +23,6 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - COPY += .gif .png CLEAN_FILES += $(wildcard \ diff --git a/make/modules/jdk.jdeps/Gensrc.gmk b/make/modules/jdk.jdeps/Gensrc.gmk index 640143b1b56..a81297348f3 100644 --- a/make/modules/jdk.jdeps/Gensrc.gmk +++ b/make/modules/jdk.jdeps/Gensrc.gmk @@ -26,8 +26,6 @@ include GensrcCommon.gmk include GensrcProperties.gmk -DISABLED_WARNINGS_java += this-escape - $(eval $(call SetupVersionProperties, JAVAP_VERSION, \ com/sun/tools/javap/resources/version.properties)) diff --git a/make/modules/jdk.jdeps/Launcher.gmk b/make/modules/jdk.jdeps/Launcher.gmk index 628b0cd5589..ceab7931245 100644 --- a/make/modules/jdk.jdeps/Launcher.gmk +++ b/make/modules/jdk.jdeps/Launcher.gmk @@ -25,8 +25,6 @@ include LauncherCommon.gmk -DISABLED_WARNINGS_java += this-escape - ################################################################################ ## Build javap ################################################################################ diff --git a/make/modules/jdk.jdi/Java.gmk b/make/modules/jdk.jdi/Java.gmk index 76d05b06df4..2e7cf805bc0 100644 --- a/make/modules/jdk.jdi/Java.gmk +++ b/make/modules/jdk.jdi/Java.gmk @@ -23,8 +23,6 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - EXCLUDES += \ com/sun/tools/example/debug/bdi \ com/sun/tools/example/debug/event \ diff --git a/make/modules/jdk.jpackage/Java.gmk b/make/modules/jdk.jpackage/Java.gmk index 60fe53475c9..acb8529f9ef 100644 --- a/make/modules/jdk.jpackage/Java.gmk +++ b/make/modules/jdk.jpackage/Java.gmk @@ -23,8 +23,6 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - COPY += .gif .png .txt .spec .script .prerm .preinst \ .postrm .postinst .list .sh .desktop .copyright .control .plist .template \ .icns .scpt .wxs .wxl .wxi .ico .bmp .tiff .service diff --git a/make/modules/jdk.localedata/Java.gmk b/make/modules/jdk.localedata/Java.gmk index d794dde2124..cb12bc560b2 100644 --- a/make/modules/jdk.localedata/Java.gmk +++ b/make/modules/jdk.localedata/Java.gmk @@ -23,8 +23,6 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - COPY += _dict _th # Exclude BreakIterator classes that are just used in compile process to generate # data files and shouldn't go in the product diff --git a/make/modules/jdk.sctp/Java.gmk b/make/modules/jdk.sctp/Java.gmk index 9fc531689ee..b1fbdcda9f4 100644 --- a/make/modules/jdk.sctp/Java.gmk +++ b/make/modules/jdk.sctp/Java.gmk @@ -23,8 +23,6 @@ # questions. # -DISABLED_WARNINGS_java += this-escape - # No SCTP implementation on Mac OS X or AIX. These classes should be excluded. SCTP_IMPL_CLASSES = \ $(TOPDIR)/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/AssociationChange.java \ diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index e36280ca018..c103ee342af 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -231,7 +231,7 @@ public class Flow { new AssignAnalyzer().analyzeTree(env, make); new FlowAnalyzer().analyzeTree(env, make); new CaptureAnalyzer().analyzeTree(env, make); - new ThisEscapeAnalyzer(names, syms, types, log, lint).analyzeTree(env); + new ThisEscapeAnalyzer(names, syms, types, rs, log, lint).analyzeTree(env); } public void analyzeLambda(Env env, JCLambda that, TreeMaker make, boolean speculative) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index f6ce19fac06..c063058d11c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -29,6 +29,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedHashMap; +import java.util.EnumSet; import java.util.HashSet; import java.util.Map.Entry; import java.util.Map; @@ -39,6 +40,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -72,9 +75,16 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*; * Looks for possible 'this' escapes and generates corresponding warnings. * *

- * A 'this' escape is when a constructor invokes a method that could be overridden in a - * subclass, in which case the method will execute before the subclass constructor has - * finished initializing the instance. + * A 'this' escape occurs in the following scenario: + *

+ * This represents a problem because the method {@code B.m()} will execute before the constructor + * {@code B()} has performed any of its own initialization. * *

* This class attempts to identify possible 'this' escapes while also striking a balance @@ -83,34 +93,41 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*; * If it passes to code outside of the current module, we declare a possible leak. * *

- * As we analyze constructors and the methods they invoke, we track the various things in scope - * that could possibly reference the 'this' instance we are following. Such references are - * represented by {@link Ref} instances, of which there are these varieties: + * As we analyze constructors and the methods they invoke, we track the various object references that + * might reference the 'this' instance we are watching (i.e., the one under construction). Such object + * references are represented by the {@link Ref} class hierarchy, which models the various ways in which, + * at any point during the execution of a constructor or some other method or constructor that it invokes, + * there can live references to the object under construction lying around. In a nutshell, the analyzer + * keeps track of these references and watches what happens to them as the code executes so it can catch + * them in the act of trying to "escape". + * + *

+ * The {@link Ref} sub-types are: *

* *

- * For each type of reference, we distinguish between direct and indirect references. - * A direct reference means the reference directly refers to the 'this' instance we are tracking. - * An indirect reference means the reference refers to the 'this' instance we are tracking through - * at least one level of indirection. + * Currently we don't attempt to explicitly track references stored in fields (for future study). * *

- * Currently we do not attempt to explicitly track references stored in fields (for future study). + * For each object reference represented by a {@link Ref}, we track up to three distinct ways in which + * it might refer to the new 'this' instance: the reference can be direct, indirect, or via an associated + * enclosing instance (see {@link Indirection}). * *

* A few notes on this implementation: *