/
mono-ptr-array.h
74 lines (58 loc) · 2.25 KB
/
mono-ptr-array.h
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
/*
* mono-ptr-array.h: GC aware equivalente of g_ptr_array
*
* Author:
* Rodrigo Kumpera <rkumpera@novell.com>
*
* (C) 2010 Novell, Inc
*/
#ifndef __MONO_PTR_ARRAY_H__
#define __MONO_PTR_ARRAY_H__
#include <glib.h>
#include "mono/metadata/gc-internal.h"
/* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
* It works by allocating an initial small array on stack and only going to gc tracked memory if needed.
* The array elements are assumed to be object references.
*/
typedef struct {
void **data;
int size;
int capacity;
} MonoPtrArray;
#define MONO_PTR_ARRAY_MAX_ON_STACK (16)
#define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
(ARRAY).size = 0; \
(ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
(ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, mono_gc_make_root_descr_all_refs (INITIAL_SIZE)) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
} while (0)
#define mono_ptr_array_destroy(ARRAY) do {\
if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
mono_gc_free_fixed ((ARRAY).data); \
} while (0)
#define mono_ptr_array_append(ARRAY, VALUE) do { \
if ((ARRAY).size >= (ARRAY).capacity) {\
void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, mono_gc_make_root_descr_all_refs ((ARRAY).capacity * 2)); \
mono_gc_memmove_aligned (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
mono_gc_free_fixed ((ARRAY).data); \
(ARRAY).data = __tmp; \
(ARRAY).capacity *= 2;\
}\
((ARRAY).data [(ARRAY).size++] = VALUE); \
} while (0)
#define mono_ptr_array_sort(ARRAY, COMPARE_FUNC) do { \
qsort ((ARRAY).data, (ARRAY).size, sizeof (gpointer), (COMPARE_FUNC)); \
} while (0)
#define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \
((ARRAY).data [(IDX)] = VALUE); \
} while (0)
#define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)])
#define mono_ptr_array_size(ARRAY) ((ARRAY).size)
#define mono_ptr_array_reset(ARRAY) do { \
(ARRAY).size = 0; \
} while (0)
#define mono_ptr_array_clear(ARRAY) do { \
(ARRAY).size = 0; \
mono_gc_bzero_aligned ((ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
} while (0)
#endif