2023-05-11 13:59:37 +00:00
|
|
|
/*
|
2024-08-07 14:16:01 +00:00
|
|
|
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
2023-05-11 13:59:37 +00:00
|
|
|
* 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_GC_Z_ZGENERATION_HPP
|
|
|
|
#define SHARE_GC_Z_ZGENERATION_HPP
|
|
|
|
|
|
|
|
#include "gc/z/zForwardingTable.hpp"
|
|
|
|
#include "gc/z/zGenerationId.hpp"
|
|
|
|
#include "gc/z/zMark.hpp"
|
|
|
|
#include "gc/z/zReferenceProcessor.hpp"
|
|
|
|
#include "gc/z/zRelocate.hpp"
|
|
|
|
#include "gc/z/zRelocationSet.hpp"
|
|
|
|
#include "gc/z/zRemembered.hpp"
|
|
|
|
#include "gc/z/zStat.hpp"
|
|
|
|
#include "gc/z/zTracer.hpp"
|
|
|
|
#include "gc/z/zUnload.hpp"
|
|
|
|
#include "gc/z/zWeakRootsProcessor.hpp"
|
|
|
|
#include "gc/z/zWorkers.hpp"
|
|
|
|
#include "memory/allocation.hpp"
|
|
|
|
|
|
|
|
class ThreadClosure;
|
|
|
|
class ZForwardingTable;
|
|
|
|
class ZGenerationOld;
|
|
|
|
class ZGenerationYoung;
|
|
|
|
class ZPage;
|
|
|
|
class ZPageAllocator;
|
|
|
|
class ZPageTable;
|
|
|
|
class ZRelocationSetSelector;
|
|
|
|
|
|
|
|
class ZGeneration {
|
|
|
|
friend class ZForwardingTest;
|
|
|
|
friend class ZLiveMapTest;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static ZGenerationYoung* _young;
|
|
|
|
static ZGenerationOld* _old;
|
|
|
|
|
|
|
|
enum class Phase {
|
|
|
|
Mark,
|
|
|
|
MarkComplete,
|
|
|
|
Relocate
|
|
|
|
};
|
|
|
|
|
|
|
|
const ZGenerationId _id;
|
|
|
|
ZPageAllocator* const _page_allocator;
|
|
|
|
ZPageTable* const _page_table;
|
|
|
|
ZForwardingTable _forwarding_table;
|
|
|
|
ZWorkers _workers;
|
|
|
|
ZMark _mark;
|
|
|
|
ZRelocate _relocate;
|
|
|
|
ZRelocationSet _relocation_set;
|
|
|
|
|
|
|
|
volatile size_t _freed;
|
|
|
|
volatile size_t _promoted;
|
|
|
|
volatile size_t _compacted;
|
|
|
|
|
|
|
|
Phase _phase;
|
|
|
|
uint32_t _seqnum;
|
|
|
|
|
|
|
|
ZStatHeap _stat_heap;
|
|
|
|
ZStatCycle _stat_cycle;
|
|
|
|
ZStatWorkers _stat_workers;
|
|
|
|
ZStatMark _stat_mark;
|
|
|
|
ZStatRelocation _stat_relocation;
|
|
|
|
|
|
|
|
ConcurrentGCTimer* _gc_timer;
|
|
|
|
|
|
|
|
void free_empty_pages(ZRelocationSetSelector* selector, int bulk);
|
|
|
|
void flip_age_pages(const ZRelocationSetSelector* selector);
|
|
|
|
void flip_age_pages(const ZArray<ZPage*>* pages);
|
|
|
|
|
|
|
|
void mark_free();
|
|
|
|
|
2025-04-04 11:53:11 +00:00
|
|
|
void select_relocation_set(bool promote_all);
|
2023-05-11 13:59:37 +00:00
|
|
|
void reset_relocation_set();
|
|
|
|
|
|
|
|
ZGeneration(ZGenerationId id, ZPageTable* page_table, ZPageAllocator* page_allocator);
|
|
|
|
|
|
|
|
void log_phase_switch(Phase from, Phase to);
|
|
|
|
|
|
|
|
public:
|
|
|
|
// GC phases
|
|
|
|
void set_phase(Phase new_phase);
|
|
|
|
bool is_phase_relocate() const;
|
|
|
|
bool is_phase_mark() const;
|
|
|
|
bool is_phase_mark_complete() const;
|
|
|
|
const char* phase_to_string() const;
|
|
|
|
|
|
|
|
uint32_t seqnum() const;
|
|
|
|
|
|
|
|
ZGenerationId id() const;
|
|
|
|
ZGenerationIdOptional id_optional() const;
|
|
|
|
bool is_young() const;
|
|
|
|
bool is_old() const;
|
|
|
|
|
|
|
|
static ZGenerationYoung* young();
|
|
|
|
static ZGenerationOld* old();
|
|
|
|
static ZGeneration* generation(ZGenerationId id);
|
|
|
|
|
|
|
|
// Statistics
|
|
|
|
void reset_statistics();
|
|
|
|
virtual bool should_record_stats() = 0;
|
2024-08-07 14:16:01 +00:00
|
|
|
size_t freed() const;
|
2023-05-11 13:59:37 +00:00
|
|
|
void increase_freed(size_t size);
|
|
|
|
size_t promoted() const;
|
|
|
|
void increase_promoted(size_t size);
|
|
|
|
size_t compacted() const;
|
|
|
|
void increase_compacted(size_t size);
|
|
|
|
|
|
|
|
ConcurrentGCTimer* gc_timer() const;
|
|
|
|
void set_gc_timer(ConcurrentGCTimer* gc_timer);
|
|
|
|
void clear_gc_timer();
|
|
|
|
|
|
|
|
ZStatHeap* stat_heap();
|
|
|
|
ZStatCycle* stat_cycle();
|
|
|
|
ZStatWorkers* stat_workers();
|
|
|
|
ZStatMark* stat_mark();
|
|
|
|
ZStatRelocation* stat_relocation();
|
|
|
|
|
|
|
|
void at_collection_start(ConcurrentGCTimer* gc_timer);
|
|
|
|
void at_collection_end();
|
|
|
|
|
|
|
|
// Workers
|
|
|
|
ZWorkers* workers();
|
|
|
|
uint active_workers() const;
|
|
|
|
void set_active_workers(uint nworkers);
|
|
|
|
|
|
|
|
// Worker resizing
|
|
|
|
bool should_worker_resize();
|
|
|
|
|
|
|
|
ZPageTable* page_table() const;
|
|
|
|
const ZForwardingTable* forwarding_table() const;
|
|
|
|
ZForwarding* forwarding(zaddress_unsafe addr) const;
|
|
|
|
|
|
|
|
ZRelocationSetParallelIterator relocation_set_parallel_iterator();
|
|
|
|
|
|
|
|
// Marking
|
|
|
|
template <bool resurrect, bool gc_thread, bool follow, bool finalizable>
|
|
|
|
void mark_object(zaddress addr);
|
|
|
|
template <bool resurrect, bool gc_thread, bool follow, bool finalizable>
|
|
|
|
void mark_object_if_active(zaddress addr);
|
2025-02-24 12:03:42 +00:00
|
|
|
void mark_flush(Thread* thread);
|
2023-05-11 13:59:37 +00:00
|
|
|
|
|
|
|
// Relocation
|
|
|
|
void synchronize_relocation();
|
|
|
|
void desynchronize_relocation();
|
2024-01-12 09:32:50 +00:00
|
|
|
bool is_relocate_queue_active() const;
|
2023-05-11 13:59:37 +00:00
|
|
|
zaddress relocate_or_remap_object(zaddress_unsafe addr);
|
|
|
|
zaddress remap_object(zaddress_unsafe addr);
|
|
|
|
|
|
|
|
// Threads
|
|
|
|
void threads_do(ThreadClosure* tc) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class ZYoungType {
|
|
|
|
minor,
|
|
|
|
major_full_preclean,
|
|
|
|
major_full_roots,
|
|
|
|
major_partial_roots,
|
|
|
|
none
|
|
|
|
};
|
|
|
|
|
|
|
|
class ZYoungTypeSetter {
|
|
|
|
public:
|
|
|
|
ZYoungTypeSetter(ZYoungType type);
|
|
|
|
~ZYoungTypeSetter();
|
|
|
|
};
|
|
|
|
|
|
|
|
class ZGenerationYoung : public ZGeneration {
|
|
|
|
friend class VM_ZMarkEndYoung;
|
|
|
|
friend class VM_ZMarkStartYoung;
|
|
|
|
friend class VM_ZMarkStartYoungAndOld;
|
|
|
|
friend class VM_ZRelocateStartYoung;
|
2025-06-04 14:56:20 +00:00
|
|
|
friend class ZRemapYoungRootsTask;
|
2023-05-11 13:59:37 +00:00
|
|
|
friend class ZYoungTypeSetter;
|
|
|
|
|
|
|
|
private:
|
|
|
|
ZYoungType _active_type;
|
|
|
|
uint _tenuring_threshold;
|
|
|
|
ZRemembered _remembered;
|
|
|
|
ZYoungTracer _jfr_tracer;
|
|
|
|
|
|
|
|
void flip_mark_start();
|
|
|
|
void flip_relocate_start();
|
|
|
|
|
|
|
|
void mark_start();
|
|
|
|
void mark_roots();
|
|
|
|
void mark_follow();
|
|
|
|
bool mark_end();
|
|
|
|
void relocate_start();
|
|
|
|
void relocate();
|
|
|
|
|
|
|
|
void pause_mark_start();
|
|
|
|
void concurrent_mark();
|
|
|
|
bool pause_mark_end();
|
|
|
|
void concurrent_mark_continue();
|
|
|
|
void concurrent_mark_free();
|
|
|
|
void concurrent_reset_relocation_set();
|
|
|
|
void concurrent_select_relocation_set();
|
|
|
|
void pause_relocate_start();
|
|
|
|
void concurrent_relocate();
|
|
|
|
|
2025-06-04 14:56:20 +00:00
|
|
|
ZRemembered* remembered();
|
|
|
|
|
2023-05-11 13:59:37 +00:00
|
|
|
public:
|
|
|
|
ZGenerationYoung(ZPageTable* page_table,
|
|
|
|
const ZForwardingTable* old_forwarding_table,
|
|
|
|
ZPageAllocator* page_allocator);
|
|
|
|
|
|
|
|
ZYoungType type() const;
|
|
|
|
|
|
|
|
void collect(ZYoungType type, ConcurrentGCTimer* timer);
|
|
|
|
|
|
|
|
// Statistics
|
|
|
|
bool should_record_stats();
|
|
|
|
|
|
|
|
// Support for promoting object to the old generation
|
|
|
|
void flip_promote(ZPage* from_page, ZPage* to_page);
|
|
|
|
void in_place_relocate_promote(ZPage* from_page, ZPage* to_page);
|
|
|
|
|
|
|
|
void register_flip_promoted(const ZArray<ZPage*>& pages);
|
|
|
|
void register_in_place_relocate_promoted(ZPage* page);
|
|
|
|
|
|
|
|
uint tenuring_threshold();
|
|
|
|
void select_tenuring_threshold(ZRelocationSetSelectorStats stats, bool promote_all);
|
|
|
|
uint compute_tenuring_threshold(ZRelocationSetSelectorStats stats);
|
|
|
|
|
|
|
|
// Add remembered set entries
|
|
|
|
void remember(volatile zpointer* p);
|
|
|
|
void remember_fields(zaddress addr);
|
|
|
|
|
|
|
|
// Scan a remembered set entry
|
|
|
|
void scan_remembered_field(volatile zpointer* p);
|
|
|
|
|
|
|
|
// Register old pages with remembered set
|
|
|
|
void register_with_remset(ZPage* page);
|
|
|
|
|
2025-06-04 14:56:20 +00:00
|
|
|
// Remap the oops of the current remembered set
|
|
|
|
void remap_current_remset(ZRemsetTableIterator* iter);
|
|
|
|
|
2023-05-11 13:59:37 +00:00
|
|
|
// Serviceability
|
|
|
|
ZGenerationTracer* jfr_tracer();
|
|
|
|
|
|
|
|
// Verification
|
|
|
|
bool is_remembered(volatile zpointer* p) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ZGenerationOld : public ZGeneration {
|
|
|
|
friend class VM_ZMarkEndOld;
|
|
|
|
friend class VM_ZMarkStartYoungAndOld;
|
|
|
|
friend class VM_ZRelocateStartOld;
|
|
|
|
|
|
|
|
private:
|
|
|
|
ZReferenceProcessor _reference_processor;
|
|
|
|
ZWeakRootsProcessor _weak_roots_processor;
|
|
|
|
ZUnload _unload;
|
|
|
|
uint _total_collections_at_start;
|
|
|
|
uint32_t _young_seqnum_at_reloc_start;
|
|
|
|
ZOldTracer _jfr_tracer;
|
|
|
|
|
|
|
|
void flip_mark_start();
|
|
|
|
void flip_relocate_start();
|
|
|
|
|
|
|
|
void mark_start();
|
|
|
|
void mark_roots();
|
|
|
|
void mark_follow();
|
|
|
|
bool mark_end();
|
|
|
|
void process_non_strong_references();
|
|
|
|
void relocate_start();
|
|
|
|
void relocate();
|
|
|
|
void remap_young_roots();
|
|
|
|
|
|
|
|
void concurrent_mark();
|
|
|
|
bool pause_mark_end();
|
|
|
|
void concurrent_mark_continue();
|
|
|
|
void concurrent_mark_free();
|
|
|
|
void concurrent_process_non_strong_references();
|
|
|
|
void concurrent_reset_relocation_set();
|
|
|
|
void pause_verify();
|
|
|
|
void concurrent_select_relocation_set();
|
|
|
|
void pause_relocate_start();
|
|
|
|
void concurrent_relocate();
|
|
|
|
void concurrent_remap_young_roots();
|
|
|
|
|
|
|
|
public:
|
|
|
|
ZGenerationOld(ZPageTable* page_table, ZPageAllocator* page_allocator);
|
|
|
|
|
|
|
|
void collect(ConcurrentGCTimer* timer);
|
|
|
|
|
|
|
|
// Statistics
|
|
|
|
bool should_record_stats();
|
|
|
|
|
|
|
|
// Reference processing
|
|
|
|
ReferenceDiscoverer* reference_discoverer();
|
|
|
|
void set_soft_reference_policy(bool clear);
|
2024-08-23 07:09:40 +00:00
|
|
|
bool uses_clear_all_soft_reference_policy() const;
|
2023-05-11 13:59:37 +00:00
|
|
|
|
|
|
|
uint total_collections_at_start() const;
|
|
|
|
|
|
|
|
bool active_remset_is_current() const;
|
|
|
|
|
|
|
|
ZRelocateQueue* relocate_queue();
|
|
|
|
|
|
|
|
// Serviceability
|
|
|
|
ZGenerationTracer* jfr_tracer();
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // SHARE_GC_Z_ZGENERATION_HPP
|