blob: a87ca39b9c1b8cefb4027a074f0cd4c980d49acb (
plain)
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
|
Index: gauche-c-wrapper/src/closure_alloc.c
===================================================================
--- gauche-c-wrapper.orig/src/closure_alloc.c
+++ gauche-c-wrapper/src/closure_alloc.c
@@ -45,11 +45,15 @@ typedef struct FreeNodeRec {
static FreeNode *free_list_start = NULL;
+static int page_size;
+
static void expand_area()
{
void *area;
FreeNode *node;
- int page_size = getpagesize();
+
+ if (!page_size)
+ page_size = getpagesize();
area = mmap(NULL, page_size, PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
@@ -80,12 +84,16 @@ ffi_closure *closure_alloc()
}
node = free_list_start;
- ptr = node->start + (node->n - 1)*CLOSURE_SIZE;
- if (node->n == 1) {
+ if (node->n < 0) {
+ ptr = node->start;
free_list_start = node->next;
free(node);
} else {
--(node->n);
+ ptr = node->start + node->n*CLOSURE_SIZE;
+ if (node->n == 0) {
+ expand_area();
+ }
}
return ptr;
@@ -93,18 +101,25 @@ ffi_closure *closure_alloc()
void closure_free(ffi_closure *ptr)
{
- FreeNode *node = free_list_start;
+ FreeNode *node;
- while (node != NULL) {
- if ((node->start + node->n*CLOSURE_SIZE) == (void*) ptr) {
- ++(node->n);
- return;
- }
+ for (node = free_list_start; node; node = node->next) {
+ if (node->n < 0) {
+ if (node->start == (void *)ptr) {
+ free_list_start = node->next;
+ free (node);
+ return;
+ }
+ } else if (node->n < page_size / CLOSURE_SIZE
+ && (node->start + node->n*CLOSURE_SIZE) == (void *)ptr) {
+ ++(node->n);
+ return;
+ }
}
node = malloc(sizeof(FreeNode));
node->start = (void*) ptr;
- node->n = 1;
+ node->n = -1;
node->next = free_list_start;
free_list_start = node;
}
|