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
25 #include "cds/aotReferenceObjSupport.hpp"
26 #include "cds/heapShared.hpp"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "classfile/vmSymbols.hpp"
31 #include "logging/log.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "memory/universe.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/oopHandle.inline.hpp"
36 #include "runtime/fieldDescriptor.inline.hpp"
37 #include "runtime/javaCalls.hpp"
38 #include "utilities/hashTable.hpp"
39
40 // Handling of java.lang.ref.Reference objects in the AOT cache
41 // ============================================================
42 //
43 // When AOTArtifactFinder finds an oop which is a instance of java.lang.ref.Reference:
44 //
45 // - We check if the oop is eligible to be stored in the AOT cache. If not, the AOT cache
46 // creation fails -- see AOTReferenceObjSupport::check_if_ref_obj()
47 //
48 // - Otherwise, we store the oop into the AOT cache, but we unconditionally reset its
49 // "next" and "discovered" fields to null. Otherwise, if AOTArtifactFinder follows these
50 // fields, it may found unrelated objects that we don't intend to cache.
51 //
52 // Eligibility
53 // ===========
54 //
156 {
157 Symbol* cds_name = vmSymbols::jdk_internal_misc_CDS();
158 Klass* cds_klass = SystemDictionary::resolve_or_fail(cds_name, true /*throw error*/, CHECK);
159 TempNewSymbol method_name = SymbolTable::new_symbol("getKeepAliveObjects");
160 TempNewSymbol method_sig = SymbolTable::new_symbol("()[Ljava/lang/Object;");
161 JavaValue result(T_OBJECT);
162 JavaCalls::call_static(&result, cds_klass, method_name, method_sig, CHECK);
163
164 _keep_alive_objs_array = OopHandle(Universe::vm_global(), result.get_oop());
165 }
166
167 // Trigger a GC to prune eligible referents that were not kept alive
168 Universe::heap()->collect(GCCause::_java_lang_system_gc);
169 }
170 }
171
172 void AOTReferenceObjSupport::init_keep_alive_objs_table() {
173 assert_at_safepoint(); // _keep_alive_objs_table uses raw oops
174 oop a = _keep_alive_objs_array.resolve();
175 if (a != nullptr) {
176 precond(a->is_objArray());
177 precond(AOTReferenceObjSupport::is_enabled());
178 objArrayOop array = objArrayOop(a);
179
180 _keep_alive_objs_table = new (mtClass)KeepAliveObjectsTable();
181 for (int i = 0; i < array->length(); i++) {
182 oop obj = array->obj_at(i);
183 _keep_alive_objs_table->put(obj, true); // The array may have duplicated entries but that's OK.
184 }
185 }
186 }
187
188 // Returns true IFF obj is an instance of java.lang.ref.Reference. If so, perform extra eligibility checks.
189 bool AOTReferenceObjSupport::check_if_ref_obj(oop obj) {
190 assert_at_safepoint(); // _keep_alive_objs_table uses raw oops
191
192 if (obj->klass()->is_subclass_of(vmClasses::Reference_klass())) {
193 // The following check works only if the java.lang.ref.Reference$ReferenceHandler thread
194 // is not running.
195 //
196 // This code is called on every object found by AOTArtifactFinder. When dumping the
197 // preimage archive, AOTArtifactFinder should not find any Reference objects.
198 precond(!CDSConfig::is_dumping_preimage_static_archive());
|
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
25 #include "cds/aotReferenceObjSupport.hpp"
26 #include "cds/heapShared.hpp"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "classfile/vmSymbols.hpp"
31 #include "logging/log.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "memory/universe.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/oopCast.inline.hpp"
36 #include "oops/oopHandle.inline.hpp"
37 #include "runtime/fieldDescriptor.inline.hpp"
38 #include "runtime/javaCalls.hpp"
39 #include "utilities/hashTable.hpp"
40
41 // Handling of java.lang.ref.Reference objects in the AOT cache
42 // ============================================================
43 //
44 // When AOTArtifactFinder finds an oop which is a instance of java.lang.ref.Reference:
45 //
46 // - We check if the oop is eligible to be stored in the AOT cache. If not, the AOT cache
47 // creation fails -- see AOTReferenceObjSupport::check_if_ref_obj()
48 //
49 // - Otherwise, we store the oop into the AOT cache, but we unconditionally reset its
50 // "next" and "discovered" fields to null. Otherwise, if AOTArtifactFinder follows these
51 // fields, it may found unrelated objects that we don't intend to cache.
52 //
53 // Eligibility
54 // ===========
55 //
157 {
158 Symbol* cds_name = vmSymbols::jdk_internal_misc_CDS();
159 Klass* cds_klass = SystemDictionary::resolve_or_fail(cds_name, true /*throw error*/, CHECK);
160 TempNewSymbol method_name = SymbolTable::new_symbol("getKeepAliveObjects");
161 TempNewSymbol method_sig = SymbolTable::new_symbol("()[Ljava/lang/Object;");
162 JavaValue result(T_OBJECT);
163 JavaCalls::call_static(&result, cds_klass, method_name, method_sig, CHECK);
164
165 _keep_alive_objs_array = OopHandle(Universe::vm_global(), result.get_oop());
166 }
167
168 // Trigger a GC to prune eligible referents that were not kept alive
169 Universe::heap()->collect(GCCause::_java_lang_system_gc);
170 }
171 }
172
173 void AOTReferenceObjSupport::init_keep_alive_objs_table() {
174 assert_at_safepoint(); // _keep_alive_objs_table uses raw oops
175 oop a = _keep_alive_objs_array.resolve();
176 if (a != nullptr) {
177 precond(a->is_refArray());
178 precond(AOTReferenceObjSupport::is_enabled());
179 refArrayOop array = oop_cast<refArrayOop>(a);
180
181 _keep_alive_objs_table = new (mtClass)KeepAliveObjectsTable();
182 for (int i = 0; i < array->length(); i++) {
183 oop obj = array->obj_at(i);
184 _keep_alive_objs_table->put(obj, true); // The array may have duplicated entries but that's OK.
185 }
186 }
187 }
188
189 // Returns true IFF obj is an instance of java.lang.ref.Reference. If so, perform extra eligibility checks.
190 bool AOTReferenceObjSupport::check_if_ref_obj(oop obj) {
191 assert_at_safepoint(); // _keep_alive_objs_table uses raw oops
192
193 if (obj->klass()->is_subclass_of(vmClasses::Reference_klass())) {
194 // The following check works only if the java.lang.ref.Reference$ReferenceHandler thread
195 // is not running.
196 //
197 // This code is called on every object found by AOTArtifactFinder. When dumping the
198 // preimage archive, AOTArtifactFinder should not find any Reference objects.
199 precond(!CDSConfig::is_dumping_preimage_static_archive());
|