|
@@ -587,6 +587,10 @@ DEFINE_PRIM(_DYN, alloc_enum_dyn, _TYPE _I32 _ARR _I32);
|
|
|
DEFINE_PRIM(_ARR, enum_parameters, _DYN);
|
|
|
DEFINE_PRIM(_BOOL, type_set_global, _TYPE _DYN);
|
|
|
|
|
|
+typedef void hl_mlookup_map;
|
|
|
+extern hl_mlookup_map *hl_mlookup_alloc();
|
|
|
+extern int *hl_mlookup_find( hl_mlookup_map *m, void *key );
|
|
|
+extern void hl_mlookup_set_impl( hl_mlookup_map *m, void *key, int value );
|
|
|
|
|
|
typedef struct {
|
|
|
char *buf;
|
|
@@ -595,10 +599,7 @@ typedef struct {
|
|
|
int *offsets;
|
|
|
int offsets_pos;
|
|
|
int offsets_size;
|
|
|
- void **lookup;
|
|
|
- int *lookup_index;
|
|
|
- int lookup_pos;
|
|
|
- int lookup_size;
|
|
|
+ hl_mlookup_map *lookup;
|
|
|
int *remap_target;
|
|
|
int remap_pos;
|
|
|
int remap_size;
|
|
@@ -641,50 +642,20 @@ static void compact_write_offset( mem_context *ctx, int position ) {
|
|
|
compact_write_ptr(ctx,(void*)(int_val)position);
|
|
|
}
|
|
|
|
|
|
-static int compact_lookup_index( mem_context *ctx, void *addr ) {
|
|
|
- int min = 0;
|
|
|
- int max = ctx->lookup_pos;
|
|
|
- while( min < max ) {
|
|
|
- int mid = (min + max) >> 1;
|
|
|
- void *a = ctx->lookup[mid];
|
|
|
- if( a < addr ) min = mid + 1; else if( a > addr ) max = mid; else return mid;
|
|
|
- }
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
#define BYTE_MARK 0x40000000
|
|
|
|
|
|
static int compact_lookup_ref( mem_context *ctx, void *addr, bool is_bytes ) {
|
|
|
- int min = 0;
|
|
|
- int max = ctx->lookup_pos;
|
|
|
- while( min < max ) {
|
|
|
- int mid = (min + max) >> 1;
|
|
|
- void *a = ctx->lookup[mid];
|
|
|
- if( a < addr ) min = mid + 1; else if( a > addr ) max = mid; else return ctx->remap_target[ctx->lookup_index[mid]&~BYTE_MARK];
|
|
|
- }
|
|
|
- if( ctx->lookup_pos == ctx->lookup_size ) {
|
|
|
- int nsize = ctx->lookup_size == 0 ? 128 : (ctx->lookup_size * 3) / 2;
|
|
|
- void **nlookup = (void**)malloc(nsize * sizeof(void*));
|
|
|
- int *nindex = (int*)malloc(nsize * sizeof(int));
|
|
|
- memcpy(nlookup,ctx->lookup,ctx->lookup_pos * sizeof(void*));
|
|
|
- memcpy(nindex,ctx->lookup_index,ctx->lookup_pos * sizeof(int));
|
|
|
- free(ctx->lookup);
|
|
|
- free(ctx->lookup_index);
|
|
|
- ctx->lookup = nlookup;
|
|
|
- ctx->lookup_index = nindex;
|
|
|
- ctx->lookup_size = nsize;
|
|
|
- }
|
|
|
- int pos = (min + max) >> 1;
|
|
|
- memmove(ctx->lookup + pos + 1, ctx->lookup + pos, (ctx->lookup_pos - pos) * sizeof(void*));
|
|
|
- memmove(ctx->lookup_index + pos + 1, ctx->lookup_index + pos, (ctx->lookup_pos - pos) * sizeof(int));
|
|
|
- int id = ctx->lookup_pos++;
|
|
|
- ctx->lookup[pos] = addr;
|
|
|
- ctx->lookup_index[pos] = id | (is_bytes ? BYTE_MARK : 0);
|
|
|
+ int *v = hl_mlookup_find(ctx->lookup, addr);
|
|
|
+ if( v )
|
|
|
+ return ctx->remap_target[(*v)&~BYTE_MARK];
|
|
|
+ int id = ctx->remap_pos;
|
|
|
+ hl_mlookup_set_impl(ctx->lookup, addr, id | (is_bytes ? BYTE_MARK : 0));
|
|
|
compact_grow(todos,todos_pos,todos_size,1,void*);
|
|
|
ctx->todos[ctx->todos_pos++] = addr;
|
|
|
compact_grow(remap_target,remap_pos,remap_size,1,int);
|
|
|
int target = -id-1;
|
|
|
- ctx->remap_target[ctx->remap_pos++] = target;
|
|
|
+ ctx->remap_target[id] = target;
|
|
|
+ ctx->remap_pos++;
|
|
|
return target;
|
|
|
}
|
|
|
|
|
@@ -908,6 +879,7 @@ HL_PRIM vdynamic *hl_mem_compact( vdynamic *d, varray *exclude, int flags, int *
|
|
|
int i;
|
|
|
int object_count = 0;
|
|
|
memset(ctx,0,sizeof(mem_context));
|
|
|
+ ctx->lookup = hl_mlookup_alloc();
|
|
|
ctx->flags = flags;
|
|
|
compact_lookup_ref(ctx,d,false);
|
|
|
if( exclude ) {
|
|
@@ -919,8 +891,7 @@ HL_PRIM vdynamic *hl_mem_compact( vdynamic *d, varray *exclude, int flags, int *
|
|
|
}
|
|
|
while( ctx->todos_pos > 0 ) {
|
|
|
void *addr = ctx->todos[--ctx->todos_pos];
|
|
|
- int pos = compact_lookup_index(ctx, addr);
|
|
|
- int index = ctx->lookup_index[pos];
|
|
|
+ int index = *hl_mlookup_find(ctx->lookup, addr);
|
|
|
compact_pad(ctx, &hlt_dyn);
|
|
|
ctx->remap_target[index&~BYTE_MARK] = ctx->buf_pos;
|
|
|
if( index & BYTE_MARK ) {
|
|
@@ -955,8 +926,6 @@ HL_PRIM vdynamic *hl_mem_compact( vdynamic *d, varray *exclude, int flags, int *
|
|
|
}
|
|
|
free(ctx->buf);
|
|
|
free(ctx->offsets);
|
|
|
- free(ctx->lookup);
|
|
|
- free(ctx->lookup_index);
|
|
|
free(ctx->remap_target);
|
|
|
free(ctx->todos);
|
|
|
# ifdef HL_WIN
|