blob: 86565ce49130e6ce223f66031b97143afd19d905 [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/30
*/
#ifndef _FINREF_H_
#define _FINREF_H_
//#define BUILD_IN_REFERENT
#include "finalizer_weakref_metadata.h"
#include "../thread/collector.h"
extern Boolean IGNORE_FINREF;
/* Phanref status: for future use
* #define PHANTOM_REF_ENQUEUE_STATUS_MASK 0x3
* #define PHANTOM_REF_ENQUEUED_MASK 0x1
* #define PHANTOM_REF_PENDING_MASK 0x2
*
* inline Partial_Reveal_Object *get_reference_pointer(Partial_Reveal_Object *p_obj)
* {
* return (Partial_Reveal_Object *)((unsigned int)(p_obj)&(~PHANTOM_REF_ENQUEUE_STATUS_MASK));
* }
* inline void update_reference_pointer(Partial_Reveal_Object **p_ref, Partial_Reveal_Object *p_target_obj)
* {
* unsigned int temp = (unsigned int)*p_ref;
*
* temp &= PHANTOM_REF_ENQUEUE_STATUS_MASK;
* temp |= (unsigned int)p_target_obj;
* *p_ref = (Partial_Reveal_Object *)temp;
* }
*/
inline REF *obj_get_referent_field(Partial_Reveal_Object *p_obj)
{
assert(p_obj);
return (REF*)((U_8*)p_obj+get_gc_referent_offset());
}
extern Boolean DURING_RESURRECTION;
typedef void (* Scan_Slot_Func)(Collector *collector, REF *p_ref);
inline void scan_weak_reference(Collector *collector, Partial_Reveal_Object *p_obj, Scan_Slot_Func scan_slot)
{
WeakReferenceType type = special_reference_type(p_obj);
if(type == NOT_REFERENCE)
return;
REF *p_referent_field = obj_get_referent_field(p_obj);
REF p_referent = *p_referent_field;
if (!p_referent) return;
if(DURING_RESURRECTION){
write_slot(p_referent_field, NULL);
return;
}
switch(type){
case SOFT_REFERENCE :
if(collect_is_minor())
scan_slot(collector, p_referent_field);
else
collector_add_softref(collector, p_obj);
break;
case WEAK_REFERENCE :
collector_add_weakref(collector, p_obj);
break;
case PHANTOM_REFERENCE :
collector_add_phanref(collector, p_obj);
break;
default :
assert(0);
break;
}
}
inline void scan_weak_reference_direct(Collector *collector, Partial_Reveal_Object *p_obj, Scan_Slot_Func scan_slot)
{
WeakReferenceType type = special_reference_type(p_obj);
if(type == NOT_REFERENCE)
return;
REF *p_referent_field = obj_get_referent_field(p_obj);
REF p_referent = *p_referent_field;
if (!p_referent) return;
scan_slot(collector, p_referent_field);
}
inline Boolean is_reference_obj(Partial_Reveal_Object *p_obj)
{
WeakReferenceType type = special_reference_type(p_obj);
if(type == NOT_REFERENCE)
return FALSE;
else
return TRUE;
}
extern void gc_update_weakref_ignore_finref(GC *gc);
extern void collector_identify_finref(Collector *collector);
extern void fallback_finref_cleanup(GC *gc);
extern void gc_put_finref_to_vm(GC *gc);
extern void put_all_fin_on_exit(GC *gc);
extern void gc_update_finref_repointed_refs(GC *gc, Boolean double_fix);
extern void gc_activate_finref_threads(GC *gc);
void gc_copy_finaliable_obj_to_rootset(GC *gc);
#endif // _FINREF_H_