blob: fc68d398ae00dd24155585ab5bf72733ca751600 [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/10/05
*/
#include "interior_pointer.h"
#include <vector>
void gc_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned);
typedef struct slot_offset_entry_struct{
void** slot;
unsigned int offset;
Partial_Reveal_Object *base;
} slot_offset_entry;
static std::vector<slot_offset_entry> interior_pointer_set;
static const int initial_vector_size = 100;
static unsigned int interior_pointer_num_count = 0;
void add_root_set_entry_interior_pointer(void **slot, int offset, Boolean is_pinned)
{
//check size;
if( interior_pointer_set.size() == interior_pointer_num_count )
{
int size ;
if(interior_pointer_num_count == 0){
size = initial_vector_size ;
}else{
size = (unsigned int)interior_pointer_set.size()*2;
}
interior_pointer_set.resize(size);
}
Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*) ((U_8*)*slot - offset);
assert(p_obj->vt_raw);
slot_offset_entry* push_back_entry = (slot_offset_entry*)&interior_pointer_set[interior_pointer_num_count++];
push_back_entry->offset = offset;
push_back_entry->slot = slot;
push_back_entry->base = p_obj;
}
void gc_copy_interior_pointer_table_to_rootset()
{
unsigned int i;
for( i = 0; i<interior_pointer_num_count; i++)
{
slot_offset_entry* entry_traverser = (slot_offset_entry*)&interior_pointer_set[i];
gc_add_root_set_entry((Managed_Object_Handle*)(&(entry_traverser->base)), FALSE);
}
}
void update_rootset_interior_pointer()
{
unsigned int i;
for( i = 0; i<interior_pointer_num_count; i++)
{
slot_offset_entry* entry_traverser = (slot_offset_entry*)&interior_pointer_set[i];
void** root_slot = entry_traverser->slot;
Partial_Reveal_Object* root_base = (Partial_Reveal_Object*)entry_traverser->base;
unsigned int root_offset = entry_traverser->offset;
void *new_slot_contents = (void *)((U_8*)root_base + root_offset);
*root_slot = new_slot_contents;
}
//can not reset the table here, for the rootset may be updated multi times
}
void gc_reset_interior_pointer_table()
{
interior_pointer_num_count = 0;
//this function is for the case of out of memory which need to call update_rootset_interior_pointer multi-times
}