blob: 5d293f20af0737bcc6ad4d10ee7a9bfc4fb0ef35 [file] [edit]
/*
* Copyright (c) 2025, 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.
*
* 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.
*
*/
#ifndef SHARE_CDS_AOTARTIFACTFINDER_HPP
#define SHARE_CDS_AOTARTIFACTFINDER_HPP
#include "memory/allStatic.hpp"
#include "utilities/exceptions.hpp"
class ArrayKlass;
class InstanceKlass;
class MetaspaceClosure;
class TypeArrayKlass;
// AOTArtifactFinder finds (the roots of) all artifacts that should be included in the AOT cache. These include:
// [1] C++ Klasses
// [2] Java heap objects
// It also decides what Klasses must be cached in aot-initialized state.
//
// ArchiveBuilder uses [1] as roots to scan for all MetaspaceObjs that need to be cached.
// ArchiveHeapWriter uses [2] to create an image of the archived heap.
//
// [1] is stored in _all_cached_classes in aotArtifactFinder.cpp.
// [2] is stored in HeapShared::archived_object_cache().
//
// Although many Klasses and heap objects are created in the assembly phase, we only store a subset of them into
// the AOT cache. For example:
// - Klasses that fail verification are excluded
// - Many Klasses are stored in non-initialized state, so any initialized static fields in their
// java mirrors must be cleared.
// - To conserve space, we exclude any hidden classes that are not referenced.
//
// The discovery of [1] and [2] is interdependent, and is done inside AOTArtifactFinder::find()
// - We first add a set of roots that must be included in the AOT cache
// - mirrors of primitive classes (e.g., int.class in Java source code).
// - primitive array classes
// - non hidden classes
// - registered lambda proxy classes
// - Whenever a class is added, we scan its constant pool. This will discover references
// to hidden classes. All such hidden classes are added.
// - As heap objects (**Note2) and classes are discovered, we find out what classes must
// be AOT-initialized:
// - If we discover at least one instance of class X, then class X is AOT-initialized (** Note1).
// - If AOTClassInitializer::can_archive_initialized_mirror(X) is true, then X is AOT-initialized.
// - For each AOT-initialized class, we scan all the static fields in its java mirror. This will in
// turn discover more Klasses and java heap objects.
// - The scanning continues until we reach a steady state.
//
// Note1: See TODO comments in HeapShared::archive_object() for exceptions to this rule.
//
// Note2: The scanning of Java objects is done in heapShared.cpp. Please see calls into the HeapShared class
// from AOTArtifactFinder.
class AOTArtifactFinder : AllStatic {
static void start_scanning_for_oops();
static void end_scanning_for_oops();
static void scan_oops_in_instance_class(InstanceKlass* ik);
static void scan_oops_in_array_class(ArrayKlass* ak);
static void add_cached_type_array_class(TypeArrayKlass* tak);
static void add_cached_instance_class(InstanceKlass* ik);
static void append_to_all_cached_classes(Klass* k);
public:
static void initialize();
static void find_artifacts();
static void add_cached_class(Klass* k);
static void add_aot_inited_class(InstanceKlass* ik);
static void all_cached_classes_do(MetaspaceClosure* it);
static void dispose();
};
#endif // SHARE_CDS_AOTARTIFACTFINDER_HPP