Skip to content

Commit 7020595

Browse files
author
Thomas Schatzl
committed
8284435: Add dedicated filler objects for known dead Java heap areas
Reviewed-by: iklam, iwalulya
1 parent 1f9f873 commit 7020595

File tree

8 files changed

+111
-2
lines changed

8 files changed

+111
-2
lines changed

src/hotspot/share/classfile/systemDictionaryShared.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,5 +1717,6 @@ void SystemDictionaryShared::update_archived_mirror_native_pointers() {
17171717
Klass* k = Universe::typeArrayKlassObj((BasicType)t);
17181718
ArchivedMirrorPatcher::update_array_klasses(k);
17191719
}
1720+
ArchivedMirrorPatcher::update_array_klasses(Universe::fillerArrayKlassObj());
17201721
}
17211722
#endif

src/hotspot/share/classfile/vmClassMacros.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@
183183
do_klass(vector_VectorMask_klass, jdk_internal_vm_vector_VectorMask ) \
184184
do_klass(vector_VectorShuffle_klass, jdk_internal_vm_vector_VectorShuffle ) \
185185
\
186+
/* GC support */ \
187+
do_klass(FillerObject_klass, jdk_internal_vm_FillerObject ) \
188+
\
186189
/*end*/
187190

188191
#endif // SHARE_CLASSFILE_VMCLASSMACROS_HPP

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
template(ETYPE_name, "ETYPE") \
9292
template(VLENGTH_name, "VLENGTH") \
9393
\
94+
template(jdk_internal_vm_FillerObject, "jdk/internal/vm/FillerObject") \
95+
\
9496
template(java_lang_Shutdown, "java/lang/Shutdown") \
9597
template(java_lang_ref_Reference, "java/lang/ref/Reference") \
9698
template(java_lang_ref_SoftReference, "java/lang/ref/SoftReference") \

src/hotspot/share/gc/shared/collectedHeap.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ CollectedHeap::fill_with_array(HeapWord* start, size_t words, bool zap)
447447
const size_t len = payload_size * HeapWordSize / sizeof(jint);
448448
assert((int)len >= 0, "size too large " SIZE_FORMAT " becomes %d", words, (int)len);
449449

450-
ObjArrayAllocator allocator(Universe::intArrayKlassObj(), words, (int)len, /* do_zero */ false);
450+
ObjArrayAllocator allocator(Universe::fillerArrayKlassObj(), words, (int)len, /* do_zero */ false);
451451
allocator.initialize(start);
452452
if (DumpSharedSpaces) {
453453
// This array is written into the CDS archive. Make sure it
@@ -467,7 +467,7 @@ CollectedHeap::fill_with_object_impl(HeapWord* start, size_t words, bool zap)
467467
fill_with_array(start, words, zap);
468468
} else if (words > 0) {
469469
assert(words == min_fill_size(), "unaligned size");
470-
ObjAllocator allocator(vmClasses::Object_klass(), words);
470+
ObjAllocator allocator(vmClasses::FillerObject_klass(), words);
471471
allocator.initialize(start);
472472
}
473473
}

src/hotspot/share/memory/universe.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
// Known objects
8585
Klass* Universe::_typeArrayKlassObjs[T_LONG+1] = { NULL /*, NULL...*/ };
8686
Klass* Universe::_objectArrayKlassObj = NULL;
87+
Klass* Universe::_fillerArrayKlassObj = NULL;
8788
OopHandle Universe::_mirrors[T_VOID+1];
8889

8990
OopHandle Universe::_main_thread_group;
@@ -200,13 +201,19 @@ void Universe::basic_type_classes_do(KlassClosure *closure) {
200201
for (int i = T_BOOLEAN; i < T_LONG+1; i++) {
201202
closure->do_klass(_typeArrayKlassObjs[i]);
202203
}
204+
// We don't do the following because it will confuse JVMTI.
205+
// _fillerArrayKlassObj is used only by GC, which doesn't need to see
206+
// this klass from basic_type_classes_do().
207+
//
208+
// closure->do_klass(_fillerArrayKlassObj);
203209
}
204210

205211
void LatestMethodCache::metaspace_pointers_do(MetaspaceClosure* it) {
206212
it->push(&_klass);
207213
}
208214

209215
void Universe::metaspace_pointers_do(MetaspaceClosure* it) {
216+
it->push(&_fillerArrayKlassObj);
210217
for (int i = 0; i < T_LONG+1; i++) {
211218
it->push(&_typeArrayKlassObjs[i]);
212219
}
@@ -255,6 +262,7 @@ void Universe::serialize(SerializeClosure* f) {
255262
}
256263
#endif
257264

265+
f->do_ptr((void**)&_fillerArrayKlassObj);
258266
for (int i = 0; i < T_LONG+1; i++) {
259267
f->do_ptr((void**)&_typeArrayKlassObjs[i]);
260268
}
@@ -314,6 +322,10 @@ void Universe::genesis(TRAPS) {
314322
compute_base_vtable_size();
315323

316324
if (!UseSharedSpaces) {
325+
// Initialization of the fillerArrayKlass must come before regular
326+
// int-TypeArrayKlass so that the int-Array mirror points to the
327+
// int-TypeArrayKlass.
328+
_fillerArrayKlassObj = TypeArrayKlass::create_klass(T_INT, "Ljava/internal/vm/FillerArray;", CHECK);
317329
for (int i = T_BOOLEAN; i < T_LONG+1; i++) {
318330
_typeArrayKlassObjs[i] = TypeArrayKlass::create_klass((BasicType)i, CHECK);
319331
}
@@ -355,6 +367,8 @@ void Universe::genesis(TRAPS) {
355367
_the_array_interfaces_array->at_put(1, vmClasses::Serializable_klass());
356368
}
357369

370+
initialize_basic_type_klass(_fillerArrayKlassObj, CHECK);
371+
358372
initialize_basic_type_klass(boolArrayKlassObj(), CHECK);
359373
initialize_basic_type_klass(charArrayKlassObj(), CHECK);
360374
initialize_basic_type_klass(floatArrayKlassObj(), CHECK);
@@ -363,6 +377,9 @@ void Universe::genesis(TRAPS) {
363377
initialize_basic_type_klass(shortArrayKlassObj(), CHECK);
364378
initialize_basic_type_klass(intArrayKlassObj(), CHECK);
365379
initialize_basic_type_klass(longArrayKlassObj(), CHECK);
380+
381+
assert(_fillerArrayKlassObj != intArrayKlassObj(),
382+
"Internal filler array klass should be different to int array Klass");
366383
} // end of core bootstrapping
367384

368385
{

src/hotspot/share/memory/universe.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class Universe: AllStatic {
9595
// Known classes in the VM
9696
static Klass* _typeArrayKlassObjs[T_LONG+1];
9797
static Klass* _objectArrayKlassObj;
98+
// Special int-Array that represents filler objects that are used by GC to overwrite
99+
// dead objects. References to them are generally an error.
100+
static Klass* _fillerArrayKlassObj;
98101

99102
// Known objects in the VM
100103
static OopHandle _main_thread_group; // Reference to the main thread group object
@@ -208,6 +211,8 @@ class Universe: AllStatic {
208211

209212
static Klass* objectArrayKlassObj() { return _objectArrayKlassObj; }
210213

214+
static Klass* fillerArrayKlassObj() { return _fillerArrayKlassObj; }
215+
211216
static Klass* typeArrayKlassObj(BasicType t) {
212217
assert((uint)t >= T_BOOLEAN, "range check for type: %s", type2name(t));
213218
assert((uint)t < T_LONG+1, "range check for type: %s", type2name(t));
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.internal.vm;
26+
27+
/*
28+
* Support class used for filling small dead areas.
29+
*/
30+
class FillerObject {
31+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package gc;
25+
26+
/*
27+
* @test TestFillerObjectInstantiation
28+
* @summary Test that GC filler objects can not be instantiated by Java programs.
29+
* @library /test/lib
30+
* @run driver gc.TestFillerObjectInstantiation
31+
*/
32+
33+
public class TestFillerObjectInstantiation {
34+
35+
private static void testInstantiationFails(String classname) throws Exception {
36+
System.out.println("trying to instantiate " + classname);
37+
try {
38+
Object o = ClassLoader.getSystemClassLoader().loadClass(classname).newInstance();
39+
throw new Error("Have been able to instantiate " + classname);
40+
} catch (IllegalAccessException | ClassNotFoundException e) {
41+
System.out.println("Could not instantiate " + classname + " as expected");
42+
System.out.println("Message: " + e.toString());
43+
}
44+
}
45+
46+
public static void main(String[] args) throws Exception {
47+
testInstantiationFails("jdk.internal.vm.FillerObject");
48+
testInstantiationFails("jdk.internal.vm.FillerArray");
49+
}
50+
}

0 commit comments

Comments
 (0)