ruby-changes:69271
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:24:25 +0900 (JST)
Subject: [ruby-changes:69271] 0385ca2e97 (master): Try to break the code page refactoring into smaller steps
https://git.ruby-lang.org/ruby.git/commit/?id=0385ca2e97 From 0385ca2e97ba29653251dba96ab8cf0f21765bb4 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Tue, 21 Sep 2021 10:59:55 -0400 Subject: Try to break the code page refactoring into smaller steps --- yjit_asm.c | 24 ++++++++++++++++-------- yjit_asm.h | 8 ++++++++ yjit_iface.c | 42 ++++++++++++++++++++++++++++++++++++++++++ yjit_iface.h | 5 +++++ 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/yjit_asm.c b/yjit_asm.c index 4a296e314c..001856395f 100644 --- a/yjit_asm.c +++ b/yjit_asm.c @@ -219,20 +219,12 @@ uint8_t* alloc_exec_mem(uint32_t mem_size) https://github.com/ruby/ruby/blob/trunk/yjit_asm.c#L219 #endif } -// Size of code pages to allocate -#define CODE_PAGE_SIZE 16 * 1024 - -// How many code pages to allocate at once -#define PAGES_PER_ALLOC 512 - // Head of the list of free code pages code_page_t *freelist = NULL; // Allocate a single code page from a pool of free pages code_page_t* alloc_code_page() { - fprintf(stderr, "allocating code page\n"); - // If the free list is empty if (!freelist) { // Allocate many pages at once @@ -242,6 +234,7 @@ code_page_t* alloc_code_page() https://github.com/ruby/ruby/blob/trunk/yjit_asm.c#L234 for (int i = PAGES_PER_ALLOC - 1; i >= 0; --i) { code_page_t* code_page = malloc(sizeof(code_page_t)); code_page->mem_block = code_chunk + i * CODE_PAGE_SIZE; + assert ((intptr_t)code_page->mem_block % CODE_PAGE_SIZE == 0); code_page->page_size = CODE_PAGE_SIZE; code_page->_next = freelist; freelist = code_page; @@ -264,6 +257,7 @@ void free_code_page(code_page_t* code_page) https://github.com/ruby/ruby/blob/trunk/yjit_asm.c#L257 // Initialize a code block object void cb_init(codeblock_t* cb, uint8_t* mem_block, uint32_t mem_size) { + assert (mem_block); cb->mem_block = mem_block; cb->mem_size = mem_size; cb->write_pos = 0; @@ -290,6 +284,14 @@ void cb_set_pos(codeblock_t* cb, uint32_t pos) https://github.com/ruby/ruby/blob/trunk/yjit_asm.c#L284 cb->write_pos = pos; } +// Set the current write position from a pointer +void cb_set_write_ptr(codeblock_t* cb, uint8_t* code_ptr) +{ + intptr_t pos = code_ptr - cb->mem_block; + assert (pos < cb->mem_size); + cb->write_pos = (uint32_t)pos; +} + // Get a direct pointer into the executable memory block uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index) { @@ -297,6 +299,12 @@ uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index) https://github.com/ruby/ruby/blob/trunk/yjit_asm.c#L299 return &cb->mem_block[index]; } +// Get a direct pointer to the current write position +uint8_t* cb_get_write_ptr(codeblock_t* cb) +{ + return cb_get_ptr(cb, cb->write_pos); +} + // Write a byte at the current position void cb_write_byte(codeblock_t* cb, uint8_t byte) { diff --git a/yjit_asm.h b/yjit_asm.h index de6ccb1cdc..58f9a849ad 100644 --- a/yjit_asm.h +++ b/yjit_asm.h @@ -5,6 +5,12 @@ https://github.com/ruby/ruby/blob/trunk/yjit_asm.h#L5 #include <stddef.h> #include <stdbool.h> +// Size of code pages to allocate +#define CODE_PAGE_SIZE 16 * 1024 + +// How many code pages to allocate at once +#define PAGES_PER_ALLOC 512 + // Maximum number of labels to link #define MAX_LABELS 32 @@ -263,7 +269,9 @@ void free_code_page(code_page_t* code_page); https://github.com/ruby/ruby/blob/trunk/yjit_asm.h#L269 void cb_init(codeblock_t* cb, uint8_t* mem_block, uint32_t mem_size); void cb_align_pos(codeblock_t* cb, uint32_t multiple); void cb_set_pos(codeblock_t* cb, uint32_t pos); +void cb_set_write_ptr(codeblock_t* cb, uint8_t* code_ptr); uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index); +uint8_t* cb_get_write_ptr(codeblock_t* cb); void cb_write_byte(codeblock_t* cb, uint8_t byte); void cb_write_bytes(codeblock_t* cb, uint32_t num_bytes, ...); void cb_write_int(codeblock_t* cb, uint64_t val, uint32_t num_bits); diff --git a/yjit_iface.c b/yjit_iface.c index 18f35f576d..8268440465 100644 --- a/yjit_iface.c +++ b/yjit_iface.c @@ -971,6 +971,10 @@ VALUE rb_yjit_code_page_alloc(void) https://github.com/ruby/ruby/blob/trunk/yjit_iface.c#L971 { code_page_t* code_page = alloc_code_page(); VALUE cp_obj = TypedData_Wrap_Struct(0, &yjit_code_page_type, code_page); + + // Write a pointer to the wrapper object at the beginning of the code page + *((VALUE*)code_page->mem_block) = cp_obj; + return cp_obj; } @@ -982,6 +986,44 @@ code_page_t *rb_yjit_code_page_unwrap(VALUE cp_obj) https://github.com/ruby/ruby/blob/trunk/yjit_iface.c#L986 return code_page; } +// Get the code page wrapper object for a code pointer +VALUE rb_yjit_code_page_from_ptr(uint8_t* code_ptr) +{ + VALUE* page_start = (VALUE*)((intptr_t)code_ptr & ~(CODE_PAGE_SIZE - 1)); + VALUE wrapper = *page_start; + return wrapper; +} + +// Get the inline code block corresponding to a code pointer +void rb_yjit_get_cb(codeblock_t* cb, uint8_t* code_ptr) +{ + VALUE page_wrapper = rb_yjit_code_page_from_ptr(code_ptr); + code_page_t *code_page = rb_yjit_code_page_unwrap(page_wrapper); + + // A pointer to the page wrapper object is written at the start of the code page + uint8_t* mem_block = code_page->mem_block + sizeof(VALUE); + uint32_t mem_size = (code_page->page_size/2) - sizeof(VALUE); + RUBY_ASSERT(mem_block); + + // Map the code block to this memory region + cb_init(cb, mem_block, mem_size); +} + +// Get the outlined code block corresponding to a code pointer +void rb_yjit_get_ocb(codeblock_t* cb, uint8_t* code_ptr) +{ + VALUE page_wrapper = rb_yjit_code_page_from_ptr(code_ptr); + code_page_t *code_page = rb_yjit_code_page_unwrap(page_wrapper); + + // A pointer to the page wrapper object is written at the start of the code page + uint8_t* mem_block = code_page->mem_block + (code_page->page_size/2); + uint32_t mem_size = code_page->page_size/2; + RUBY_ASSERT(mem_block); + + // Map the code block to this memory region + cb_init(cb, mem_block, mem_size); +} + bool rb_yjit_enabled_p(void) { diff --git a/yjit_iface.h b/yjit_iface.h index c42b29e977..452d27fea8 100644 --- a/yjit_iface.h +++ b/yjit_iface.h @@ -126,4 +126,9 @@ const VALUE *rb_yjit_count_side_exit_op(const VALUE *exit_pc); https://github.com/ruby/ruby/blob/trunk/yjit_iface.h#L126 void yjit_unlink_method_lookup_dependency(block_t *block); void yjit_block_assumptions_free(block_t *block); +VALUE rb_yjit_code_page_alloc(void); +code_page_t *rb_yjit_code_page_unwrap(VALUE cp_obj); +void rb_yjit_get_cb(codeblock_t* cb, uint8_t* code_ptr); +void rb_yjit_get_ocb(codeblock_t* cb, uint8_t* code_ptr); + #endif // #ifndef YJIT_IFACE_H -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/