8000 Merge pull request #237 from Shopify/code_page_logic · github/ruby@62e5e4a · GitHub
[go: up one dir, main page]

Skip to content

Commit 62e5e4a

Browse files
authored
Merge pull request ruby#237 from Shopify/code_page_logic
Try to break the code page refactoring into smaller steps
2 parents e0d74ed + 5a90ed5 commit 62e5e4a

File tree

4 files changed

+71
-8
lines changed

4 files changed

+71
-8
lines changed

yjit_asm.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -219,20 +219,12 @@ uint8_t* alloc_exec_mem(uint32_t mem_size)
219219
#endif
220220
}
221221

222-
// Size of code pages to allocate
223-
#define CODE_PAGE_SIZE 16 * 1024
224-
225-
// How many code pages to allocate at once
226-
#define PAGES_PER_ALLOC 512
227-
228222
// Head of the list of free code pages
229223
code_page_t *freelist = NULL;
230224

231225
// Allocate a single code page from a pool of free pages
232226
code_page_t* alloc_code_page()
233227
{
234-
fprintf(stderr, "allocating code page\n");
235-
236228
// If the free list is empty
237229
if (!freelist) {
238230
// Allocate many pages at once
@@ -242,6 +234,7 @@ code_page_t* alloc_code_page()
242234
for (int i = PAGES_PER_ALLOC - 1; i >= 0; --i) {
243235
code_page_t* code_page = malloc(sizeof(code_page_t));
244236
code_page->mem_block = code_chunk + i * CODE_PAGE_SIZE;
237+
assert ((intptr_t)code_page->mem_block % CODE_PAGE_SIZE == 0);
245238
code_page->page_size = CODE_PAGE_SIZE;
246239
code_page->_next = freelist;
247240
freelist = code_page;
@@ -264,6 +257,7 @@ void free_code_page(code_page_t* code_page)
264257
// Initialize a code block object
265258
void cb_init(codeblock_t* cb, uint8_t* mem_block, uint32_t mem_size)
266259
{
260+
assert (mem_block);
267261
cb->mem_block = mem_block;
268262
cb->mem_size = mem_size;
269263
cb->write_pos = 0;
@@ -290,13 +284,27 @@ void cb_set_pos(codeblock_t* cb, uint32_t pos)
290284
cb->write_pos = pos;
291285
}
292286

287+
// Set the current write position from a pointer
288+
void cb_set_write_ptr(codeblock_t* cb, uint8_t* code_ptr)
289+
{
290+
intptr_t pos = code_ptr - cb->mem_block;
291+
assert (pos < cb->mem_size);
292+
cb->write_pos = (uint32_t)pos;
293+
}
294+
293295
// Get a direct pointer into the executable memory block
294296
uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index)
295297
{
296298
assert (index < cb->mem_size);
297299
return &cb->mem_block[index];
298300
}
299301

302+
// Get a direct pointer to the current write position
303+
uint8_t* cb_get_write_ptr(codeblock_t* cb)
304+
{
305+
return cb_get_ptr(cb, cb->write_pos);
306+
}
307+
300308
// Write a byte at the current position
301309
void cb_write_byte(codeblock_t* cb, uint8_t byte)
302310
{

yjit_asm.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
#include <stddef.h>
66
#include <stdbool.h>
77

8+
// Size of code pages to allocate
9+
#define CODE_PAGE_SIZE 16 * 1024
10+
11+
// How many code pages to allocate at once
12+
#define PAGES_PER_ALLOC 512
13+
814
// Maximum number of labels to link
915
#define MAX_LABELS 32
1016

@@ -267,7 +273,9 @@ void free_code_page(code_page_t* code_page);
267273
void cb_init(codeblock_t* cb, uint8_t* mem_block, uint32_t mem_size);
268274
void cb_align_pos(codeblock_t* cb, uint32_t multiple);
269275
void cb_set_pos(codeblock_t* cb, uint32_t pos);
276+
void cb_set_write_ptr(codeblock_t* cb, uint8_t* code_ptr);
270277
uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index);
278+
uint8_t* cb_get_write_ptr(codeblock_t* cb);
271279
void cb_write_byte(codeblock_t* cb, uint8_t byte);
272280
void cb_write_bytes(codeblock_t* cb, uint32_t num_bytes, ...);
273281
void cb_write_int(codeblock_t* cb, uint64_t val, uint32_t num_bits);

yjit_iface.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,10 @@ VALUE rb_yjit_code_page_alloc(void)
971971
{
972972
code_page_t* code_page = alloc_code_page();
973973
VALUE cp_obj = TypedData_Wrap_Struct(0, &yjit_code_page_type, code_page);
974+
975+
// Write a pointer to the wrapper object at the beginning of the code page
976+
*((VALUE*)code_page->mem_block) = cp_obj;
977+
974978
return cp_obj;
975979
}
976980

@@ -982,6 +986,44 @@ code_page_t *rb_yjit_code_page_unwrap(VALUE cp_obj)
982986
return code_page;
983987
}
984988

989+
// Get the code page wrapper object for a code pointer
990+
VALUE rb_yjit_code_page_from_ptr(uint8_t* code_ptr)
991+
{
992+
VALUE* page_start = (VALUE*)((intptr_t)code_ptr & ~(CODE_PAGE_SIZE - 1));
993+
VALUE wrapper = *page_start;
994+
return wrapper;
995+
}
996+
997+
// Get the inline code block corresponding to a code pointer
998+
void rb_yjit_get_cb(codeblock_t* cb, uint8_t* code_ptr)
999+
{
1000+
VALUE page_wrapper = rb_yjit_code_page_from_ptr(code_ptr);
1001+
code_page_t *code_page = rb_yjit_code_page_unwrap(page_wrapper);
1002+
1003+
// A pointer to the page wrapper object is written at the start of the code page
1004+
uint8_t* mem_block = code_page->mem_block + sizeof(VALUE);
1005+
uint32_t mem_size = (code_page->page_size/2) - sizeof(VALUE);
1006+
RUBY_ASSERT(mem_block);
1007+
1008+
// Map the code block to this memory region
1009+
cb_init(cb, mem_block, mem_size);
1010+
}
1011+
1012+
// Get the outlined code block corresponding to a code pointer
1013+
void rb_yjit_get_ocb(codeblock_t* cb, uint8_t* code_ptr)
1014+
{
1015+
VALUE page_wrapper = rb_yjit_code_page_from_ptr(code_ptr);
1016+
code_page_t *code_page = rb_yjit_code_page_unwrap(page_wrapper);
1017+
1018+
// A pointer to the page wrapper object is written at the start of the code page
1019+
uint8_t* mem_block = code_page->mem_block + (code_page->page_size/2);
1020+
uint32_t mem_size = code_page->page_size/2;
1021+
RUBY_ASSERT(mem_block);
1022+
1023+
// Map the code block to this memory region
1024+
cb_init(cb, mem_block, mem_size);
1025+
}
1026+
9851027
bool
9861028
rb_yjit_enabled_p(void)
9871029
{

yjit_iface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,9 @@ const VALUE *rb_yjit_count_side_exit_op(const VALUE *exit_pc);
126126
void yjit_unlink_method_lookup_dependency(block_t *block);
127127
void yjit_block_assumptions_free(block_t *block);
128128

129+
VALUE rb_yjit_code_page_alloc(void);
130+
code_page_t *rb_yjit_code_page_unwrap(VALUE cp_obj);
131+
void rb_yjit_get_cb(codeblock_t* cb, uint8_t* code_ptr);
132+
void rb_yjit_get_ocb(codeblock_t* cb, uint8_t* code_ptr);
133+
129134
#endif // #ifndef YJIT_IFACE_H

0 commit comments

Comments
 (0)
0