Skip to content

Commit d7ad546

Browse files
Stuart MarksDavid HolmesBrent Christian
committed
8276422: Add command-line option to disable finalization
Co-authored-by: David Holmes <[email protected]> Co-authored-by: Brent Christian <[email protected]> Reviewed-by: dholmes, kbarrett, bchristi
1 parent ec7cb6d commit d7ad546

File tree

13 files changed

+265
-17
lines changed

13 files changed

+265
-17
lines changed

make/data/hotspot-symbols/symbols-unix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ JVM_IsArrayClass
147147
JVM_IsCDSDumpingEnabled
148148
JVM_IsConstructorIx
149149
JVM_IsDumpingClassList
150+
JVM_IsFinalizationEnabled
150151
JVM_IsHiddenClass
151152
JVM_IsInterface
152153
JVM_IsPrimitiveClass

src/hotspot/share/classfile/classFileParser.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2835,7 +2835,8 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
28352835
annotation_default_length,
28362836
CHECK_NULL);
28372837

2838-
if (name == vmSymbols::finalize_method_name() &&
2838+
if (InstanceKlass::is_finalization_enabled() &&
2839+
name == vmSymbols::finalize_method_name() &&
28392840
signature == vmSymbols::void_method_signature()) {
28402841
if (m->is_empty_method()) {
28412842
_has_empty_finalizer = true;
@@ -4171,7 +4172,8 @@ void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
41714172
bool f = false;
41724173
const Method* const m = ik->lookup_method(vmSymbols::finalize_method_name(),
41734174
vmSymbols::void_method_signature());
4174-
if (m != NULL && !m->is_empty_method()) {
4175+
if (InstanceKlass::is_finalization_enabled() &&
4176+
(m != NULL) && !m->is_empty_method()) {
41754177
f = true;
41764178
}
41774179

src/hotspot/share/include/jvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,9 @@ JVM_SupportsCX8(void);
759759
JNIEXPORT void JNICALL
760760
JVM_ReportFinalizationComplete(JNIEnv *env, jobject finalizee);
761761

762+
JNIEXPORT jboolean JNICALL
763+
JVM_IsFinalizationEnabled(JNIEnv *env);
764+
762765
/*************************************************************************
763766
PART 2: Support for the Verifier and Class File Format Checker
764767
************************************************************************/

src/hotspot/share/oops/instanceKlass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141

142142
#endif // ndef DTRACE_ENABLED
143143

144+
bool InstanceKlass::_finalization_enabled = true;
144145

145146
static inline bool is_class_loader(const Symbol* class_name,
146147
const ClassFileParser& parser) {

src/hotspot/share/oops/instanceKlass.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,17 @@ class InstanceKlass: public Klass {
329329

330330
static bool _disable_method_binary_search;
331331

332+
// Controls finalizer registration
333+
static bool _finalization_enabled;
334+
332335
public:
336+
337+
// Queries finalization state
338+
static bool is_finalization_enabled() { return _finalization_enabled; }
339+
340+
// Sets finalization state
341+
static void set_finalization_enabled(bool val) { _finalization_enabled = val; }
342+
333343
// The three BUILTIN class loader types
334344
bool is_shared_boot_class() const {
335345
return (_misc_flags & _misc_is_shared_boot_class) != 0;

src/hotspot/share/prims/jvm.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,10 @@ JVM_ENTRY(void, JVM_ReportFinalizationComplete(JNIEnv * env, jobject finalizee))
690690
MANAGEMENT_ONLY(FinalizerService::on_complete(JNIHandles::resolve_non_null(finalizee), THREAD);)
691691
JVM_END
692692

693+
JVM_ENTRY(jboolean, JVM_IsFinalizationEnabled(JNIEnv * env))
694+
return InstanceKlass::is_finalization_enabled();
695+
JVM_END
696+
693697
// java.io.File ///////////////////////////////////////////////////////////////
694698

695699
JVM_LEAF(char*, JVM_NativePath(char* path))

src/hotspot/share/runtime/arguments.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "logging/logStream.hpp"
4141
#include "logging/logTag.hpp"
4242
#include "memory/allocation.inline.hpp"
43+
#include "oops/instanceKlass.hpp"
4344
#include "oops/oop.inline.hpp"
4445
#include "prims/jvmtiExport.hpp"
4546
#include "runtime/arguments.hpp"
@@ -2887,6 +2888,17 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
28872888
if (FLAG_SET_CMDLINE(ErrorFileToStdout, true) != JVMFlag::SUCCESS) {
28882889
return JNI_EINVAL;
28892890
}
2891+
} else if (match_option(option, "--finalization=", &tail)) {
2892+
if (strcmp(tail, "enabled") == 0) {
2893+
InstanceKlass::set_finalization_enabled(true);
2894+
} else if (strcmp(tail, "disabled") == 0) {
2895+
InstanceKlass::set_finalization_enabled(false);
2896+
} else {
2897+
jio_fprintf(defaultStream::error_stream(),
2898+
"Invalid finalization value '%s', must be 'disabled' or 'enabled'.\n",
2899+
tail);
2900+
return JNI_EINVAL;
2901+
}
28902902
} else if (match_option(option, "-XX:+ExtendedDTraceProbes")) {
28912903
#if defined(DTRACE_ENABLED)
28922904
if (FLAG_SET_CMDLINE(ExtendedDTraceProbes, true) != JVMFlag::SUCCESS) {

src/java.base/share/classes/java/lang/ref/Finalizer.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,17 @@ static ReferenceQueue<Object> getQueue() {
6161
return queue;
6262
}
6363

64+
static final boolean ENABLED = isFinalizationEnabled();
65+
66+
private static native boolean isFinalizationEnabled();
67+
6468
/* Invoked by VM */
6569
static void register(Object finalizee) {
66-
new Finalizer(finalizee);
70+
if (ENABLED) {
71+
new Finalizer(finalizee);
72+
} else {
73+
throw new InternalError("unexpected call to Finalizer::register when finalization is disabled");
74+
}
6775
}
6876

6977
private void runFinalizer(JavaLangAccess jla) {
@@ -130,7 +138,7 @@ public Void run() {
130138

131139
/* Called by Runtime.runFinalization() */
132140
static void runFinalization() {
133-
if (VM.initLevel() == 0) {
141+
if (VM.initLevel() == 0 || ! ENABLED) {
134142
return;
135143
}
136144

@@ -182,14 +190,16 @@ public void run() {
182190
}
183191

184192
static {
185-
ThreadGroup tg = Thread.currentThread().getThreadGroup();
186-
for (ThreadGroup tgn = tg;
187-
tgn != null;
188-
tg = tgn, tgn = tg.getParent());
189-
Thread finalizer = new FinalizerThread(tg);
190-
finalizer.setPriority(Thread.MAX_PRIORITY - 2);
191-
finalizer.setDaemon(true);
192-
finalizer.start();
193+
if (ENABLED) {
194+
ThreadGroup tg = Thread.currentThread().getThreadGroup();
195+
for (ThreadGroup tgn = tg;
196+
tgn != null;
197+
tg = tgn, tgn = tg.getParent());
198+
Thread finalizer = new FinalizerThread(tg);
199+
finalizer.setPriority(Thread.MAX_PRIORITY - 2);
200+
finalizer.setDaemon(true);
201+
finalizer.start();
202+
}
193203
}
194204

195205
}

src/java.base/share/classes/sun/launcher/resources/launcher.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,10 @@ java.launcher.X.usage=\n\
194194
\ override or augment a module with classes and resources\n\
195195
\ in JAR files or directories.\n\
196196
\ --source <version>\n\
197-
\ set the version of the source in source-file mode.\n\n\
197+
\ set the version of the source in source-file mode.\n\
198+
\ --finalization=<value>\n\
199+
\ controls finalization\n\
200+
\ <value> is one of "enabled" or "disabled"\n\n\
198201
These extra options are subject to change without notice.\n
199202

200203
# Translators please note do not translate the options themselves

src/java.base/share/native/libjava/Finalizer.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,7 @@ Java_java_lang_ref_Finalizer_reportComplete(JNIEnv* env, jclass cls, jobject fin
3232
JVM_ReportFinalizationComplete(env, finalizee);
3333
}
3434

35-
35+
JNIEXPORT jboolean JNICALL
36+
Java_java_lang_ref_Finalizer_isFinalizationEnabled(JNIEnv* env, jclass cls) {
37+
return JVM_IsFinalizationEnabled(env);
38+
}

0 commit comments

Comments
 (0)