blob: 854a3013e36f508a4cda877bfaced0eaad2ccb4c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Li-Gang Wang, 2006/11/29
*/
#ifndef _FINREF_METADATA_H_
#define _FINREF_METADATA_H_
#include "../common/gc_common.h"
#include "../utils/vector_block.h"
#include "../utils/sync_pool.h"
#define FINREF_METADATA_SEGMENT_NUM 256
typedef struct Finref_Metadata{
void *segments[FINREF_METADATA_SEGMENT_NUM]; // malloced free pool segments' addresses array
unsigned int num_alloc_segs; // allocated segment number
SpinLock alloc_lock; // thread must hold this lock when allocating new segment
Pool *free_pool; // list of free buffers for the five pools below
Pool *obj_with_fin_pool; // list of objects that have finalizers
// these objects are added in when they are being allocated
Pool *finalizable_obj_pool; // temporary buffer for finalizable objects identified during one single GC
Pool *finalizable_obj_pool_copy;
Pool *softref_pool; // temporary buffer for soft references identified during one single GC
Pool *weakref_pool; // temporary buffer for weak references identified during one single GC
Pool *phanref_pool; // temporary buffer for phantom references identified during one single GC
Pool *repset_pool; // repointed reference slot sets
Pool *fallback_ref_pool; // temporary buffer for weakref needing to be put to vm when resurrection fallback happens
Vector_Block *finalizable_obj_set; // buffer for finalizable_obj_pool
Vector_Block *repset; // buffer for repset_pool
Boolean pending_finalizers; // there are objects waiting to be finalized
Boolean pending_weakrefs; // there are weak references waiting to be enqueued
unsigned int gc_referent_offset; // the referent field's offset in Reference Class; it is a constant during VM's liftime
}Finref_Metadata;
extern unsigned int get_gc_referent_offset(void);
extern void set_gc_referent_offset(unsigned int offset);
extern void gc_finref_metadata_initialize(GC *gc);
extern void gc_finref_metadata_destruct(GC *gc);
extern void gc_finref_metadata_verify(GC *gc, Boolean is_before_gc);
extern void gc_set_obj_with_fin(GC *gc);
extern void collector_reset_weakref_sets(Collector *collector);
extern void gc_set_weakref_sets(GC *gc);
extern void gc_reset_finref_metadata(GC *gc);
extern void mutator_add_finalizer(Mutator *mutator, Partial_Reveal_Object *ref);
extern Vector_Block *gc_add_finalizer(GC *gc, Vector_Block *vector_block_in_use, Partial_Reveal_Object *ref);
extern void gc_add_finalizable_obj(GC *gc, Partial_Reveal_Object *ref);
extern void collector_add_softref(Collector *collector, Partial_Reveal_Object *ref);
extern void collector_add_weakref(Collector *collector, Partial_Reveal_Object *ref);
extern void collector_add_phanref(Collector *collector, Partial_Reveal_Object *ref);
extern void finref_repset_add_entry(GC *gc, REF* ref);
extern Vector_Block *finref_add_fallback_ref(GC *gc, Vector_Block *vector_block_in_use, Partial_Reveal_Object *p_ref);
extern Boolean obj_with_fin_pool_is_empty(GC *gc);
extern Boolean finalizable_obj_pool_is_empty(GC *gc);
extern Boolean softref_pool_is_empty(GC *gc);
extern Boolean weakref_pool_is_empty(GC *gc);
extern Boolean phanref_pool_is_empty(GC *gc);
extern Boolean finref_repset_pool_is_empty(GC *gc);
extern void finref_metadata_clear_pool(Pool *pool);
extern Boolean finref_copy_pool(Pool* src_pool, Pool* dest_pool, GC* gc);
extern void gc_clear_weakref_pools(GC *gc);
extern void gc_clear_finref_repset_pool(GC* gc);
extern Vector_Block *finref_metadata_extend(void);
/* Every place requesting a free vector block in finref should call this function */
inline Vector_Block *finref_get_free_block(GC *gc)
{
Vector_Block *block = pool_get_entry(gc->finref_metadata->free_pool);
while(!block)
block = finref_metadata_extend();
assert(vector_block_is_empty(block));
return block;
}
/* called before loop of recording finalizable objects */
inline void gc_reset_finalizable_objects(GC *gc)
{
Finref_Metadata *metadata = gc->finref_metadata;
assert(!metadata->finalizable_obj_set);
metadata->finalizable_obj_set = finref_get_free_block(gc);
assert(metadata->finalizable_obj_set);
}
/* called after loop of recording finalizable objects */
inline void gc_put_finalizable_objects(GC *gc)
{
Finref_Metadata *metadata = gc->finref_metadata;
pool_put_entry(metadata->finalizable_obj_pool, metadata->finalizable_obj_set);
metadata->finalizable_obj_set = NULL;
}
/* called before loop of recording repointed reference */
inline void finref_reset_repset(GC *gc)
{
Finref_Metadata *metadata = gc->finref_metadata;
assert(!metadata->repset);
metadata->repset = finref_get_free_block(gc);
assert(metadata->repset);
}
/* called after loop of recording repointed reference */
inline void finref_put_repset(GC *gc)
{
Finref_Metadata *metadata = gc->finref_metadata;
pool_put_entry(metadata->repset_pool, metadata->repset);
metadata->repset = NULL;
}
#endif // _FINREF_METADATA_H_