blob: d804c457f96b5fc46ef2b6983b0a4dc807f5e959 [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 Xiao-Feng Li, 2006/12/12
*/
#ifndef _FIX_REPOINTED_REFS_H_
#define _FIX_REPOINTED_REFS_H_
#include "gc_common.h"
#include "compressed_ref.h"
#include "../finalizer_weakref/finalizer_weakref.h"
extern void* los_boundary;
inline void slot_fix(REF* p_ref)
{
Partial_Reveal_Object* p_obj = read_slot(p_ref);
if(!p_obj) return;
#ifdef USE_UNIQUE_MOVE_COMPACT_GC
p_obj = obj_get_fw_in_table(p_obj);
assert(obj_belongs_to_gc_heap(p_obj));
write_slot(p_ref, p_obj);
return;
#endif
if(collect_is_compact_move()){
/* This condition is removed because we do los sliding compaction at every major compaction after add los minor sweep. */
//if(obj_is_moved(p_obj))
/*Fixme: los_boundery ruined the modularity of gc_common.h*/
if(p_obj < los_boundary){
p_obj = obj_get_fw_in_oi(p_obj);
}else{
p_obj = obj_get_fw_in_table(p_obj);
}
write_slot(p_ref, p_obj);
}else{ /* slide compact */
if(obj_is_fw_in_oi(p_obj)){
/* Condition obj_is_moved(p_obj) is for preventing mistaking previous mark bit of large obj as fw bit when fallback happens.
* Because until fallback happens, perhaps the large obj hasn't been marked. So its mark bit remains as the last time.
* This condition is removed because we do los sliding compaction at every major compaction after add los minor sweep.
* In major collection condition obj_is_fw_in_oi(p_obj) can be omitted,
* since those which can be scanned in MOS & NOS must have been set fw bit in oi. */
p_obj = obj_get_fw_in_oi(p_obj);
assert(obj_belongs_to_gc_heap(p_obj));
write_slot(p_ref, p_obj);
}
}
return;
}
inline void object_fix_ref_slots(Partial_Reveal_Object* p_obj)
{
if( !object_has_ref_field(p_obj) ) return;
/* scan array object */
if (object_is_array(p_obj)) {
Partial_Reveal_Array* array = (Partial_Reveal_Array*)p_obj;
assert(!obj_is_primitive_array(p_obj));
I_32 array_length = array->array_len;
REF* p_refs = (REF *)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array));
for (int i = 0; i < array_length; i++) {
slot_fix(p_refs + i);
}
return;
}
/* scan non-array object */
unsigned int num_refs = object_ref_field_num(p_obj);
int *ref_iterator = object_ref_iterator_init(p_obj);
for(unsigned int i=0; i<num_refs; i++){
REF* p_ref = object_ref_iterator_get(ref_iterator+i, p_obj);
slot_fix(p_ref);
}
#ifndef BUILD_IN_REFERENT
if(IGNORE_FINREF && is_reference_obj(p_obj)) {
REF* p_ref = obj_get_referent_field(p_obj);
slot_fix(p_ref);
}
#endif
return;
}
inline void block_fix_ref_after_copying(Block_Header* curr_block)
{
POINTER_SIZE_INT cur_obj = (POINTER_SIZE_INT)curr_block->base;
POINTER_SIZE_INT block_end = (POINTER_SIZE_INT)curr_block->free;
while(cur_obj < block_end){
object_fix_ref_slots((Partial_Reveal_Object*)cur_obj);
cur_obj = cur_obj + vm_object_size((Partial_Reveal_Object*)cur_obj);
}
return;
}
inline void block_fix_ref_after_marking(Block_Header* curr_block)
{
void* start_pos;
Partial_Reveal_Object* p_obj = block_get_first_marked_object(curr_block, &start_pos);
while( p_obj ){
assert( obj_is_marked_in_vt(p_obj));
obj_unmark_in_vt(p_obj);
object_fix_ref_slots(p_obj);
p_obj = block_get_next_marked_object(curr_block, &start_pos);
}
return;
}
inline void block_fix_ref_after_repointing(Block_Header* curr_block)
{
void* start_pos;
Partial_Reveal_Object* p_obj = block_get_first_marked_obj_after_prefetch(curr_block, &start_pos);
while( p_obj ){
assert( obj_is_marked_in_vt(p_obj));
object_fix_ref_slots(p_obj);
p_obj = block_get_next_marked_obj_after_prefetch(curr_block, &start_pos);
}
return;
}
#endif /* #ifndef _FIX_REPOINTED_REFS_H_ */