123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /*
- * Part of Scheme 48 1.9. See file COPYING for notices and license.
- *
- * Authors: David Frese
- */
- /* Remembered Sets */
- #include <stdlib.h>
- #include "scheme48.h"
- #include "remset.h"
- #include "memory.h"
- #include "utils.h"
- #include "data.h"
- #include "generation_gc.h"
- #include "memory_map.h"
- #include "gc_config.h"
- #if (S48_USE_REMEMBERED_SETS)
-
- static int s48_remset_member(s48_address ip, RemSet* remset);
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- /* Construction of a Rem_ip */
- static Rem_ip* allocate_Rem_ip(){
- Rem_ip* rem_ip = (Rem_ip*)calloc(1,sizeof(Rem_ip));
- if (!rem_ip){
- s48_gc_error("allocate_Rem_ip: out of memory");
- }
- return rem_ip;
- }
- static void initialize_Rem_ip(Rem_ip* rem_ip){
- rem_ip->ip = 0;
- rem_ip->next_ip = 0;
- }
- static Rem_ip* make_Rem_ip(){
- Rem_ip* rem_ip = (Rem_ip*)allocate_Rem_ip();
- initialize_Rem_ip(rem_ip);
- return rem_ip;
- }
- #endif
- /* Construction of a Rem_set */
- static RemSet* allocate_RemSet(){
- RemSet* remset = (RemSet*)calloc(1, (sizeof(RemSet)));
- if (!remset){
- s48_gc_error("allocate_RemSet: out of memory");
- }
- return remset;
- }
- static void initialize_RemSet(RemSet* remset){
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- Rem_ip* el = (Rem_ip*)make_Rem_ip();
- remset->first_el = el;
- remset->last_el = el;
- #elif S48_REMEMBERED_SET_TYPE==S48_STATIC_REMEMBERED_SETS
- remset->free_index = 0;
- #elif S48_REMEMBERED_SET_TYPE==S48_EXTENSIBLE_REMEMBERED_SETS
- remset->free_index = 0;
- remset->next_remset = NULL;
- #endif
- }
- RemSet* s48_make_remset(){
- RemSet* remset = allocate_RemSet();
- initialize_RemSet(remset);
- return remset;
- }
- int s48_remset_size(RemSet* remset){
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- Rem_ip* next = remset->first_el;
- Rem_ip* empty = remset->last_el;
- int size = 0;
-
- while(next != empty){
- size++;
- next = next->next_ip;
- }
- return size;
- #elif S48_REMEMBERED_SET_TYPE==S48_STATIC_REMEMBERED_SETS
- return remset->free_index;
- #elif S48_REMEMBERED_SET_TYPE==S48_EXTENSIBLE_REMEMBERED_SETS
- int size=0;
- while(remset != NULL){
- size += remset->free_index;
- remset = remset->next_remset;
- }
- return size;
- #endif
- }
- /* Adds an IP to a RS and returns a boolean */
- int s48_remset_add(s48_address ip, RemSet* remset){
- #if S48_UNIQUE_REMEMBERED_SET==TRUE /* no duplicates */
- if (s48_remset_member(ip, remset))
- return TRUE;
- #endif
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- {
- Rem_ip* last = remset->last_el;
- Rem_ip* new_el = make_Rem_ip();
-
- last->ip = ip;
- last->next_ip = new_el;
- remset->last_el = new_el;
- return TRUE;
- }
- #elif S48_REMEMBERED_SET_TYPE==S48_STATIC_REMEMBERED_SETS
- if (remset->free_index == S48_REMEMBERED_SET_SIZE){
- return FALSE;
- }
- else{
- remset->elements[remset->free_index] = ip;
- remset->free_index++;
- return TRUE;
- }
- #elif S48_REMEMBERED_SET_TYPE==S48_EXTENSIBLE_REMEMBERED_SETS
- /* search or create a free remset */
- while (remset->free_index == S48_REMEMBERED_SET_SIZE){
- if (remset->next_remset == NULL)
- remset->next_remset= s48_make_remset();
- remset = remset->next_remset;
- }
-
- remset->elements[remset->free_index] = ip;
- remset->free_index++;
- return TRUE;
- #endif /* S48_REMEMBERED_SET_TYPE */
- }
- static int s48_remset_member(s48_address ip, RemSet* remset){
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- Rem_ip* next = remset->first_el;
- Rem_ip* empty = remset->last_el;
-
- /* if both pointers point to the same rem_ip -> not a member */
- while(next != empty){
- if ((s48_address)next->ip == ip){
- return TRUE;
- }
- next = next->next_ip;
- }
- return FALSE;
- #elif S48_REMEMBERED_SET_TYPE==S48_STATIC_REMEMBERED_SETS
- int i;
- for (i = 0; i < remset->free_index; i++){
- if (remset->elements[i] == ip)
- return TRUE;
- }
-
- return FALSE;
- #elif S48_REMEMBERED_SET_TYPE==S48_EXTENSIBLE_REMEMBERED_SETS
- int i;
- while (remset != NULL){
- for (i = 0; i < remset->free_index; i++){
- if (remset->elements[i] == ip)
- return TRUE;
- }
- remset = remset->next_remset;
- }
- return FALSE;
- #endif /* S48_REMEMBERED_SET_TYPE */
- }
- static inline void call_trace_locationsB(s48_address addr) {
- Area* area = (Area*)s48_memory_map_ref(addr);
- /* we only want to trace locations, that are not currently
- collected. This test should be sufficient */
- if (area->action == GC_ACTION_IGNORE)
- s48_internal_trace_locationsB(area, TRUE, addr, S48_ADDRESS_INC(addr), "call_trace_locationsB");
- }
- void s48_trace_remset(RemSet* remset){
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- Rem_ip* next = remset->first_el;
- Rem_ip* empty = remset->last_el;
- /* if both pointers point to the same rem_ip -> done*/
- while(next != empty){
- call_trace_locationsB(next->ip);
- next = next->next_ip;
- }
- #elif S48_REMEMBERED_SET_TYPE==S48_STATIC_REMEMBERED_SETS
- int i;
- for (i = 0; i < remset->free_index; i++)
- call_trace_locationsB(remset->elements[i]);
- #elif S48_REMEMBERED_SET_TYPE==S48_EXTENSIBLE_REMEMBERED_SETS
- int i;
- while (remset != NULL){
- for (i = 0; i < remset->free_index; i++)
- call_trace_locationsB(remset->elements[i]);
- remset = remset->next_remset;
- }
- #endif
- }
- void s48_free_remset(RemSet* remset){
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- Rem_ip* next_ip;
- Rem_ip* rem_ip = remset->first_el;
- while(rem_ip != NULL){
- next_ip = rem_ip->next_ip;
- free(rem_ip);
- rem_ip = next_ip;
- }
- free(remset);
- #elif S48_REMEMBERED_SET_TYPE==S48_STATIC_REMEMBERED_SETS
- free(remset);
- #elif S48_REMEMBERED_SET_TYPE==S48_EXTENSIBLE_REMEMBERED_SETS
- RemSet* next_remset;
- while(remset != NULL){
- next_remset = remset->next_remset;
- free(remset);
- remset = next_remset;
- }
- #endif
- }
- void s48_check_remset(RemSet* remset) {
- /* only implemented for dynamic remsets, for now */
- #if S48_REMEMBERED_SET_TYPE==S48_DYNAMIC_REMEMBERED_SETS
- Rem_ip* next = remset->first_el;
- Rem_ip* empty = remset->last_el;
-
- while(next != empty) {
- Area* a = (Area*)s48_memory_map_ref(next->ip);
- if ((a == NULL) || (next->ip >= a->frontier)) {
- s48_gc_error("remembered-set currupted! Location 0x%X outside the heap.",
- next->ip);
- }
- next = next->next_ip;
- }
- #endif
- }
- #endif
|