Skip to content

Commit e7547a6

Browse files
committed
tweak code cache API
1 parent 90f85b8 commit e7547a6

File tree

4 files changed

+124
-91
lines changed

4 files changed

+124
-91
lines changed

ChangeLog

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
2012-10-04 Aleksey Demakov <[email protected]>
2+
3+
* jit/jit-cache.h, jit/jit-cache.c (_jit_cache_start_function):
4+
remove the restart_count argument.
5+
* jit/jit-cache.h, jit/jit-cache.c (_jit_cache_extend): add
6+
function to allocate more cache space.
7+
* jit/jit-cache.c (_jit_cache_alloc_data): let be called outside
8+
function generation context.
9+
110
2012-07-29 Aleksey Demakov <[email protected]>
211

312
* jit/jit-cache.h, jit/jit-cache.c (_jit_cache_start_function)

jit/jit-cache.c

Lines changed: 60 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ struct jit_cache
118118
/*
119119
* Allocate a cache page and add it to the cache.
120120
*/
121-
static void AllocCachePage(jit_cache_t cache, int factor)
121+
static void
122+
AllocCachePage(jit_cache_t cache, int factor)
122123
{
123124
long num;
124125
unsigned char *ptr;
@@ -230,8 +231,8 @@ CacheCompare(jit_cache_t cache, unsigned char *key, jit_cache_method_t node)
230231
/*
231232
* Rotate a sub-tree around a specific node.
232233
*/
233-
static jit_cache_method_t CacheRotate(jit_cache_t cache, unsigned char *key,
234-
jit_cache_method_t around)
234+
static jit_cache_method_t
235+
CacheRotate(jit_cache_t cache, unsigned char *key, jit_cache_method_t around)
235236
{
236237
jit_cache_method_t child, grandChild;
237238
int setOnLeft;
@@ -293,7 +294,8 @@ static jit_cache_method_t CacheRotate(jit_cache_t cache, unsigned char *key,
293294
* Add a method region block to the red-black lookup tree
294295
* that is associated with a method cache.
295296
*/
296-
static void AddToLookupTree(jit_cache_t cache, jit_cache_method_t method)
297+
static void
298+
AddToLookupTree(jit_cache_t cache, jit_cache_method_t method)
297299
{
298300
unsigned char *key = method->func->code_start;
299301
jit_cache_method_t temp;
@@ -354,27 +356,6 @@ static void AddToLookupTree(jit_cache_t cache, jit_cache_method_t method)
354356
SetBlack(cache->head.right);
355357
}
356358

357-
static unsigned char *
358-
cache_alloc_data(jit_cache_t cache, unsigned long size, unsigned long align)
359-
{
360-
unsigned char *ptr;
361-
362-
/* Allocate memory from the top of the free region, so that it
363-
does not overlap with the method code being written at the
364-
bottom of the free region */
365-
ptr = cache->free_end - size;
366-
ptr = (unsigned char *) (((jit_nuint) ptr) & ~((jit_nuint) align - 1));
367-
if(ptr < cache->free_start)
368-
{
369-
/* When we aligned the block, it caused an overflow */
370-
return 0;
371-
}
372-
373-
/* Allocate the block and return it */
374-
cache->free_end = ptr;
375-
return ptr;
376-
}
377-
378359
jit_cache_t
379360
_jit_cache_create(long limit, long cache_page_size, int max_page_factor)
380361
{
@@ -468,45 +449,51 @@ _jit_cache_destroy(jit_cache_t cache)
468449
jit_free(cache);
469450
}
470451

471-
int
472-
_jit_cache_start_function(jit_cache_t cache, jit_function_t func, int restart_count)
452+
void
453+
_jit_cache_extend(jit_cache_t cache, int count)
473454
{
474-
/* Bail out if there is a started function already */
455+
/* Compute the page size factor */
456+
int factor = 1 << count;
457+
458+
/* Bail out if there is a started function */
475459
if(cache->method)
476460
{
477-
return JIT_CACHE_ERROR;
461+
return;
478462
}
479463

480-
/* Do we need to allocate a new cache page? */
481-
if(restart_count > 0)
464+
/* If we had a newly allocated page then it has to be freed
465+
to let allocate another new page of appropriate size. */
466+
struct jit_cache_page *p = &cache->pages[cache->numPages - 1];
467+
if((cache->free_start == ((unsigned char *)p->page))
468+
&& (cache->free_end == (cache->free_start + cache->pageSize * p->factor)))
482469
{
483-
/* Compute the page size factor */
484-
int factor = 1 << (restart_count - 1);
470+
jit_free_exec(p->page, cache->pageSize * p->factor);
485471

486-
/* If we had a newly allocated page then it has to be freed
487-
to let allocate another new page of appropriate size. */
488-
struct jit_cache_page *p = &cache->pages[cache->numPages - 1];
489-
if((cache->free_start == ((unsigned char *)p->page))
490-
&& (cache->free_end == (cache->free_start + cache->pageSize * p->factor)))
472+
--(cache->numPages);
473+
if(cache->pagesLeft >= 0)
491474
{
492-
jit_free_exec(p->page, cache->pageSize * p->factor);
493-
494-
--(cache->numPages);
495-
if(cache->pagesLeft >= 0)
496-
{
497-
cache->pagesLeft += p->factor;
498-
}
499-
cache->free_start = 0;
500-
cache->free_end = 0;
475+
cache->pagesLeft += p->factor;
476+
}
477+
cache->free_start = 0;
478+
cache->free_end = 0;
501479

502-
if(factor <= p->factor)
503-
{
504-
factor = p->factor << 1;
505-
}
480+
if(factor <= p->factor)
481+
{
482+
factor = p->factor << 1;
506483
}
484+
}
507485

508-
/* Allocate a new page now */
509-
AllocCachePage(cache, factor);
486+
/* Allocate a new page now */
487+
AllocCachePage(cache, factor);
488+
}
489+
490+
int
491+
_jit_cache_start_function(jit_cache_t cache, jit_function_t func)
492+
{
493+
/* Bail out if there is a started function already */
494+
if(cache->method)
495+
{
496+
return JIT_CACHE_ERROR;
510497
}
511498

512499
/* Bail out if the cache is already full */
@@ -519,15 +506,18 @@ _jit_cache_start_function(jit_cache_t cache, jit_function_t func, int restart_co
519506
cache->prev_start = cache->free_start;
520507
cache->prev_end = cache->free_end;
521508

522-
/* Allocate memory for the method information block */
523-
cache->method = (jit_cache_method_t) cache_alloc_data(cache,
524-
sizeof(struct jit_cache_method),
525-
JIT_BEST_ALIGNMENT);
509+
/* Allocate memory for the function information block */
510+
cache->method = (jit_cache_method_t)
511+
_jit_cache_alloc_data(cache,
512+
sizeof(struct jit_cache_method),
513+
JIT_BEST_ALIGNMENT);
526514
if(!cache->method)
527515
{
528516
/* There is insufficient space in this page */
529517
return JIT_CACHE_RESTART;
530518
}
519+
520+
/* Initialize the function information */
531521
cache->method->func = func;
532522
cache->method->func->code_start = cache->free_start;
533523
cache->method->func->code_end = cache->free_start;
@@ -591,7 +581,8 @@ _jit_cache_set_code_break(jit_cache_t cache, void *ptr)
591581
{
592582
return;
593583
}
594-
if ((unsigned char *) ptr > cache->free_end) {
584+
if ((unsigned char *) ptr > cache->free_end)
585+
{
595586
return;
596587
}
597588

@@ -615,14 +606,22 @@ _jit_cache_get_code_limit(jit_cache_t cache)
615606
void *
616607
_jit_cache_alloc_data(jit_cache_t cache, unsigned long size, unsigned long align)
617608
{
618-
/* Bail out if there is no started function */
619-
if(!cache->method)
609+
unsigned char *ptr;
610+
611+
/* Get memory from the top of the free region, so that it does not
612+
overlap with the function code possibly being written at the bottom
613+
of the free region */
614+
ptr = cache->free_end - size;
615+
ptr = (unsigned char *) (((jit_nuint) ptr) & ~(align - 1));
616+
if(ptr < cache->free_start)
620617
{
618+
/* When we aligned the block, it caused an overflow */
621619
return 0;
622620
}
623621

624622
/* Allocate the block and return it */
625-
return cache_alloc_data(cache, size, align);
623+
cache->free_end = ptr;
624+
return ptr;
626625
}
627626

628627
void *

jit/jit-cache.h

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* jit-cache.h - Translated method cache implementation.
2+
* jit-cache.h - Translated function cache implementation.
33
*
44
* Copyright (C) 2002, 2004, 2008 Southern Storm Software, Pty Ltd.
55
*
@@ -36,7 +36,7 @@ extern "C" {
3636
#define JIT_CACHE_ERROR 3 /* Other error */
3737

3838
/*
39-
* Create a method cache. Returns NULL if out of memory.
39+
* Create a code cache. Returns NULL if out of memory.
4040
* If "limit" is non-zero, then it specifies the maximum
4141
* size of the cache in bytes. If "cache_page_size" is
4242
* non-zero, then it indicates the dafault/minimum cache
@@ -49,46 +49,76 @@ jit_cache_t _jit_cache_create(long limit,
4949
int max_page_factor);
5050

5151
/*
52-
* Destroy a method cache.
52+
* Destroy a code cache.
5353
*/
5454
void _jit_cache_destroy(jit_cache_t cache);
5555

5656
/*
57-
* Start output of a function. The "restart_count" value should be
58-
* equal to zero unless the method is being recompiled because it did
59-
* not fit last time into the memory. In the later case the value
60-
* should gradually increase until either the methods fits or the
61-
* maximum restart_count value is exceeded.
57+
* Request to allocate more code cache space.
58+
*
59+
* The "count" value should normally be zero except if just after the last
60+
* call a function is being recompiled again because it is still too big
61+
* to fit into the available cache space. In this case the "count" value
62+
* should gradually increase.
63+
*/
64+
void _jit_cache_extend(jit_cache_t cache, int count);
65+
66+
/*
67+
* Start output of a function.
6268
*/
63-
int _jit_cache_start_function(jit_cache_t cache,
64-
jit_function_t func,
65-
int restart_count);
69+
int _jit_cache_start_function(jit_cache_t cache, jit_function_t func);
6670

6771
/*
68-
* End output of a function. Returns zero if a restart is needed.
72+
* End output of a function.
6973
*/
7074
int _jit_cache_end_function(jit_cache_t cache, int result);
7175

7276
/*
73-
* Get the boundary between used and free code space.
77+
* Get the start address of memory available for function code generation.
78+
*
79+
* This function is only called betweed _jit_cache_start_function() and
80+
* corresponding _jit_cache_end_function() calls.
81+
*
82+
* Initially it should return the start address of the allocated memory.
83+
* Then the address may be moved forward with _jit_cache_set_code_break()
84+
* calls.
7485
*/
7586
void *_jit_cache_get_code_break(jit_cache_t cache);
7687

7788
/*
78-
* Set the boundary between used and free code space.
89+
* Set the address of memory yet available for function code generation.
90+
*
91+
* This function is only called betweed _jit_cache_start_function() and
92+
* corresponding _jit_cache_end_function() calls.
93+
*
94+
* The given address must be greater than or equal to its last value as
95+
* returned by the _jit_cache_get_code_break() call and also less than or
96+
* equal to the memory the address returned by _jit_cache_get_code_limit()
97+
* call.
98+
*
99+
* This function is to be used in two cases. First, on the end of code
100+
* generation just before the _jit_cache_end_function() call. Second,
101+
* before allocating data with _jit_cache_alloc_data() calls. This lets
102+
* the cache know how much space was actually used and how much is still
103+
* free.
79104
*/
80105
void _jit_cache_set_code_break(jit_cache_t cache, void *ptr);
81106

82107
/*
83-
* Get the end address of the free code space.
108+
* Get the end address of memory available for function code generation.
109+
*
110+
* This function is only called betweed _jit_cache_start_function() and
111+
* corresponding _jit_cache_end_function() calls.
112+
*
113+
* The available memory may change if during code generation there were
114+
* _jit_cache_alloc_data() calls. So after such calls available memory
115+
* should be rechecked.
84116
*/
85117
void *_jit_cache_get_code_limit(jit_cache_t cache);
86118

87119
/*
88-
* Allocate "size" bytes of storage in the function cache's
89-
* auxiliary data area. Returns NULL if insufficient space
90-
* to satisfy the request. It may be possible to satisfy
91-
* the request after a restart.
120+
* Allocate "size" bytes of memory in the data area. Returns NULL if
121+
* there is insufficient space to satisfy the request.
92122
*/
93123
void *_jit_cache_alloc_data(jit_cache_t cache,
94124
unsigned long size,
@@ -98,8 +128,7 @@ void *_jit_cache_alloc_data(jit_cache_t cache,
98128
* Allocate "size" bytes of storage when we aren't currently
99129
* translating a method.
100130
*/
101-
void *_jit_cache_alloc_no_method
102-
(jit_cache_t cache, unsigned long size, unsigned long align);
131+
void *_jit_cache_alloc_no_method(jit_cache_t cache, unsigned long size, unsigned long align);
103132

104133
/*
105134
* Find the method that is associated with a particular

jit/jit-compile.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -463,15 +463,12 @@ cache_alloc(_jit_compile_t *state)
463463
int result;
464464

465465
/* First try with the current cache page */
466-
result = _jit_cache_start_function(state->gen.cache,
467-
state->func,
468-
state->page_factor++);
466+
result = _jit_cache_start_function(state->gen.cache, state->func);
469467
if(result == JIT_CACHE_RESTART)
470468
{
471469
/* No space left on the current cache page. Allocate a new one. */
472-
result = _jit_cache_start_function(state->gen.cache,
473-
state->func,
474-
state->page_factor++);
470+
_jit_cache_extend(state->gen.cache, state->page_factor++);
471+
result = _jit_cache_start_function(state->gen.cache, state->func);
475472
}
476473
if(result != JIT_CACHE_OK)
477474
{
@@ -571,9 +568,8 @@ cache_realloc(_jit_compile_t *state)
571568

572569
/* Allocate a new cache page with the size that grows
573570
by factor of 2 on each reallocation */
574-
result = _jit_cache_start_function(state->gen.cache,
575-
state->func,
576-
state->page_factor++);
571+
_jit_cache_extend(state->gen.cache, state->page_factor++);
572+
result = _jit_cache_start_function(state->gen.cache, state->func);
577573
if(result != JIT_CACHE_OK)
578574
{
579575
/* Failed to allocate enough cache space */

0 commit comments

Comments
 (0)