File: areas.c

package info (click to toggle)
scheme48 1.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 14,980 kB
  • ctags: 14,127
  • sloc: lisp: 76,272; ansic: 71,514; sh: 3,026; makefile: 637
file content (163 lines) | stat: -rw-r--r-- 4,417 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees.
   See file COPYING. */

#include <stdlib.h>
#include "utils.h"
#include "areas.h"
#include "page_constants.h"
#include "memory_map.h"
#include "area_roots.h"
#include "page_alloc.h"
#include "gc_config.h"
#include "remset.h"

static Area* make_area(s48_address start, s48_address end,
		       s48_address frontier, 
		       unsigned char generation_index,
		       area_type_size_t area_type_size) {
  Area* area = (Area*)malloc(sizeof(Area));
  if (area == NULL) s48_gc_error("make_area: out of memory");
  area->start = start;
  area->end = end;
  area->frontier = frontier;
  area->trace = start;
  area->next = NULL;
  area->generation_index = generation_index;
  area->area_type_size = area_type_size;
#if S48_USE_GENERATION_INDEXING==TRUE
  area->minimum_index = 255;
  area->maximum_index = 0;
#endif
  s48_init_dirty_vector(area);
#if S48_USE_REMEMBERED_SETS==TRUE
  area->remset = s48_make_remset();
#endif
  return area;
}

inline static void free_area(Area* area) {
  s48_deinit_dirty_vector(area);
#if S48_USE_REMEMBERED_SETS==TRUE
  s48_free_remset(area->remset);
#endif
  free(area);
}

/* delete_area deletes AREA from the linked list starting with START,
   and returns the (eventually different) new start of the list. Does
   NOT free the memory allocated for the area structure (nor the area
   itself)! */

Area* s48_delete_area(Area* start, Area* area) {
  if (start == NULL)
    /* no areas in the list? -> Done */
    return start;
  else if (start == area) {
    /* list starts with AREA? -> next is new start */
    Area* next = area->next;
    area->next = NULL;
    return next;
  } else {
    /* search for the area before AREA */
    Area* prev = start;
    /* if AREA is not in the list, prev->next can be NULL. But of
       corse this should never happen !? */
    while (prev->next != NULL) {
      if (prev->next == area) {
	prev->next = area->next;
	break;
      }
      prev = prev->next;
    }
    area->next = NULL;
    return start;
  }
}

/* Allocate an area of between MINIMUM and MAXIMUM pages, inclusive. */
    
Area* s48_allocate_area(unsigned int minimum, unsigned int maximum,
			unsigned char generation_index, area_type_size_t area_type_size) {
  s48_address start;
  Area* area;
  unsigned int i;
  unsigned int size = s48_allocate_pages(minimum, maximum, &start);
#if (BIBOP_LOG)
  s48_bibop_log("s48_allocate_pages: size = %i",
	    size);
#endif
  area = make_area(start, ADD_PAGES(start, size), start,
			 generation_index, area_type_size);
  /* The area is put into all memory-map cells that are covered by
     it. */
  for (i = 0; i < size; i++)
    s48_memory_map_setB(ADD_PAGES(start, i), area);

  return area;
}

/* Free the pages covered by AREA, and free the struct itself too. */

void s48_free_area(Area* area) {
  unsigned int size = BYTES_TO_PAGES(area->end - area->start);
  s48_address start = area->start;
  unsigned int i;
  
  s48_free_pagesB(start, size);

  /* This is not really needed, I think. It's only a waste of time */
  for (i = 0; i < size; i++) {
    s48_memory_map_setB(ADD_PAGES(start, i), NULL);
  }

  free_area(area);
}

/* Call s48_free_area on all areas in the list starting with START */
void s48_free_areas(Area* start) {
  while (start != NULL) {
    Area* next = start->next;
    s48_free_area(start);
    start = next;
  }
}

/* Get the type size of this stob's area: small, large, weaks. Called
   from the BIBOP dumper */
area_type_size_t s48_area_type_size(s48_value stob) {
  Area* area;
  area = s48_memory_map_ref((s48_address)stob);

  if (area == NULL) {
    return AREA_TYPE_SIZE_ILLEGAL;
  }

  return area->area_type_size;
}


/* Allocate a block for the whole image */
void s48_allocate_image_area(long bytes, s48_address* start, s48_address* end) {
  
  s48_address memory;
  
  memory = (s48_address)malloc(bytes + BYTES_PER_PAGE);
  
  if (memory == NULL) s48_gc_error("s48_allocate_image_area: out of memory\n");
  
  *start = PAGE_START_ADDRESS(memory + BYTES_PER_PAGE - 1);
  *end = PAGE_START_ADDRESS(*start + bytes);
  
  return;
}

/* Wrap the static make_area */
Area* s48_make_area(s48_address start, s48_address end,
		    s48_address frontier, 
		    unsigned char generation_index,
		    area_type_size_t area_type_size) {
  Area* res;

  res = make_area(start, end, frontier, generation_index, area_type_size);
  return res;
}