Skip to content

Commit 4a8407b

Browse files
committed
use block array for precess_array in liveness
1 parent e8ca62a commit 4a8407b

File tree

1 file changed

+45
-85
lines changed

1 file changed

+45
-85
lines changed

mono/metadata/unity-liveness.c

Lines changed: 45 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@
99
#include <mono/utils/mono-error.h>
1010

1111
typedef struct _LivenessState LivenessState;
12-
typedef struct _custom_growable_array {
13-
gpointer *pdata;
14-
guint len; // used
15-
guint size; // reserved
16-
} custom_growable_array;
1712

1813
#define k_block_size (8 * 1024)
1914
#define k_array_elements_per_block ((k_block_size - 2 * sizeof (guint) - sizeof (gpointer)) / sizeof (gpointer))
@@ -22,6 +17,7 @@ typedef struct _custom_array_block custom_array_block;
2217

2318
typedef struct _custom_array_block {
2419
gpointer *next_item;
20+
custom_array_block *prev_block;
2521
custom_array_block *next_block;
2622
gpointer p_data[k_array_elements_per_block];
2723
} custom_array_block;
@@ -50,7 +46,7 @@ struct _LivenessState {
5046

5147
MonoClass *filter;
5248

53-
custom_growable_array *process_array;
49+
custom_growable_block_array *process_array;
5450
guint initial_alloc_count;
5551

5652
void *callback_userdata;
@@ -64,6 +60,7 @@ custom_growable_block_array * block_array_create(LivenessState *state)
6460
{
6561
custom_growable_block_array *array = g_new0(custom_growable_block_array, 1);
6662
array->current_block = state->reallocateArray(NULL, k_block_size, state->callback_userdata);
63+
array->current_block->prev_block = NULL;
6764
array->current_block->next_block = NULL;
6865
array->current_block->next_item = array->current_block->p_data;
6966
array->first_block = array->current_block;
@@ -75,17 +72,39 @@ custom_growable_block_array * block_array_create(LivenessState *state)
7572
return array;
7673
}
7774

75+
gboolean block_array_is_empty(custom_growable_block_array *block_array)
76+
{
77+
return block_array->first_block->next_item == block_array->first_block->p_data;
78+
}
79+
7880
void block_array_push_back(custom_growable_block_array *block_array, gpointer value, LivenessState *state)
7981
{
8082
if (block_array->current_block->next_item == block_array->current_block->p_data + k_array_elements_per_block) {
81-
block_array->current_block->next_block = state->reallocateArray(NULL, k_block_size, state->callback_userdata);
82-
block_array->current_block = block_array->current_block->next_block;
83-
block_array->current_block->next_block = NULL;
84-
block_array->current_block->next_item = block_array->current_block->p_data;
83+
custom_array_block* new_block = block_array->current_block->next_block;
84+
if (block_array->current_block->next_block == NULL)
85+
{
86+
new_block = state->reallocateArray(NULL, k_block_size, state->callback_userdata);
87+
new_block->next_block = NULL;
88+
new_block->prev_block = block_array->current_block;
89+
new_block->next_item = new_block->p_data;
90+
block_array->current_block->next_block = new_block;
91+
}
92+
block_array->current_block = new_block;
8593
}
8694
*block_array->current_block->next_item++ = value;
8795
}
8896

97+
gpointer block_array_pop_back(custom_growable_block_array *block_array)
98+
{
99+
if (block_array->current_block->next_item == block_array->current_block->p_data) {
100+
if (block_array->current_block->prev_block == NULL)
101+
return NULL;
102+
block_array->current_block = block_array->current_block->prev_block;
103+
block_array->current_block->next_item = block_array->current_block->p_data + k_array_elements_per_block;
104+
}
105+
return *--block_array->current_block->next_item;
106+
}
107+
89108
void block_array_reset_iterator(custom_growable_block_array *array)
90109
{
91110
array->iterator->current_block = array->first_block;
@@ -106,6 +125,15 @@ gpointer block_array_next(custom_growable_block_array *block_array)
106125
return *iterator->current_position++;
107126
}
108127

128+
void block_array_clear(custom_growable_block_array *block_array)
129+
{
130+
custom_array_block *block = block_array->first_block;
131+
while (block != NULL) {
132+
block->next_item = block->p_data;
133+
block = block->next_block;
134+
}
135+
}
136+
109137
void block_array_destroy(custom_growable_block_array *block_array, LivenessState *state)
110138
{
111139
custom_array_block *block = block_array->first_block;
@@ -118,8 +146,6 @@ void block_array_destroy(custom_growable_block_array *block_array, LivenessState
118146
g_free(block_array);
119147
}
120148

121-
#define array_at_index(array, index) (array)->pdata[(index)]
122-
123149
#if defined(HAVE_SGEN_GC)
124150
void sgen_stop_world(int generation);
125151
void sgen_restart_world(int generation);
@@ -141,54 +167,6 @@ void GC_start_world_external()
141167
#error need to implement liveness GC API
142168
#endif
143169

144-
custom_growable_array * array_create_and_initialize(guint capacity)
145-
{
146-
custom_growable_array *array = g_ptr_array_sized_new(capacity);
147-
array->len = 0;
148-
return array;
149-
}
150-
151-
gboolean array_is_full(custom_growable_array *array)
152-
{
153-
return g_ptr_array_capacity(array) == array->len;
154-
}
155-
156-
void array_destroy(custom_growable_array *array)
157-
{
158-
g_ptr_array_free(array, TRUE);
159-
g_free(array);
160-
}
161-
162-
void array_push_back(custom_growable_array *array, gpointer value)
163-
{
164-
g_assert(!array_is_full(array));
165-
array->pdata[array->len] = value;
166-
array->len++;
167-
}
168-
169-
gpointer array_pop_back(custom_growable_array *array)
170-
{
171-
array->len--;
172-
return array->pdata[array->len];
173-
}
174-
175-
void array_clear(custom_growable_array *array)
176-
{
177-
array->len = 0;
178-
}
179-
180-
void array_reserve(LivenessState *state, custom_growable_array *array, guint size)
181-
{
182-
array->pdata = state->reallocateArray(array->pdata, size * sizeof(gpointer), state->callback_userdata);
183-
array->size = size;
184-
}
185-
186-
void array_grow(LivenessState *state, custom_growable_array *array)
187-
{
188-
array->pdata = state->reallocateArray(array->pdata, array->size * 2 * sizeof(gpointer), state->callback_userdata);
189-
array->size = array->size * 2;
190-
}
191-
192170
/* number of sub elements of an array to process before recursing
193171
* we take a depth first approach to use stack space rather than re-allocating
194172
* processing array which requires restarting world to ensure allocator lock is not held
@@ -228,12 +206,7 @@ void mono_filter_objects(LivenessState *state);
228206

229207
void mono_reset_state(LivenessState *state)
230208
{
231-
array_clear(state->process_array);
232-
}
233-
234-
void array_safe_grow(LivenessState *state, custom_growable_array *array)
235-
{
236-
array_grow(state, array);
209+
block_array_clear(state->process_array);
237210
}
238211

239212
static gboolean should_process_value(MonoObject *val, MonoClass *filter)
@@ -277,9 +250,7 @@ static gboolean mono_add_process_object(MonoObject *object, LivenessState *state
277250
}
278251
// Check if klass has further references - if not skip adding
279252
if (has_references) {
280-
if (array_is_full(state->process_array))
281-
array_safe_grow(state, state->process_array);
282-
array_push_back(state->process_array, object);
253+
block_array_push_back(state->process_array, object, state);
283254
return TRUE;
284255
}
285256
}
@@ -377,8 +348,8 @@ static void mono_traverse_objects(LivenessState *state)
377348
MonoObject *object = NULL;
378349

379350
state->traverse_depth++;
380-
while (state->process_array->len > 0) {
381-
object = array_pop_back(state->process_array);
351+
while (!block_array_is_empty(state->process_array)) {
352+
object = block_array_pop_back(state->process_array);
382353
mono_traverse_generic_object(object, state);
383354
}
384355
state->traverse_depth--;
@@ -524,16 +495,6 @@ void mono_unity_liveness_calculation_from_statics(LivenessState *liveness_state)
524495
mono_filter_objects(liveness_state);
525496
}
526497

527-
void mono_unity_liveness_add_object_callback(gpointer *objs, gint count, void *arr)
528-
{
529-
int i;
530-
custom_growable_array *objects = (custom_growable_array *)arr;
531-
for (i = 0; i < count; i++) {
532-
if (objects->size > objects->len)
533-
objects->pdata[objects->len++] = objs[i];
534-
}
535-
}
536-
537498
/**
538499
* mono_unity_liveness_calculation_from_root:
539500
*
@@ -544,7 +505,7 @@ void mono_unity_liveness_calculation_from_root(MonoObject *root, LivenessState *
544505
{
545506
mono_reset_state(liveness_state);
546507

547-
array_push_back(liveness_state->process_array, root);
508+
block_array_push_back(liveness_state->process_array, root, liveness_state);
548509

549510
mono_traverse_objects(liveness_state);
550511

@@ -563,7 +524,6 @@ LivenessState * mono_unity_liveness_allocate_struct(MonoClass *filter, guint max
563524
// if all_objects run out of space, run through list, add objects that match the filter, clear bit in vtable and then clear the array.
564525

565526
state = g_new0(LivenessState, 1);
566-
max_count = max_count < 1000 ? 1000 : max_count;
567527

568528
state->filter = filter;
569529
state->traverse_depth = 0;
@@ -573,7 +533,7 @@ LivenessState * mono_unity_liveness_allocate_struct(MonoClass *filter, guint max
573533
state->reallocateArray = reallocateArray;
574534

575535
state->all_objects = block_array_create(state);
576-
state->process_array = array_create(state, max_count);
536+
state->process_array = block_array_create(state);
577537

578538
return state;
579539
}
@@ -593,7 +553,7 @@ void mono_unity_liveness_free_struct(LivenessState *state)
593553
{
594554
//cleanup the liveness_state
595555
block_array_destroy(state->all_objects, state);
596-
array_destroy(state->process_array);
556+
block_array_destroy(state->process_array, state);
597557
g_free(state);
598558
}
599559

0 commit comments

Comments
 (0)