summaryrefslogtreecommitdiff
path: root/yjit.c
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2022-10-25 09:07:10 -0700
committerGitHub <noreply@github.com>2022-10-25 09:07:10 -0700
commitb7644a231100b1e1b70af528f9629d2e39572087 (patch)
treeeab3b5c4cd93e286b8d6014f3249dafc02bd842d /yjit.c
parent1d2d25dcadda0764f303183ac091d0c87b432566 (diff)
downloadruby-b7644a231100b1e1b70af528f9629d2e39572087.tar.gz
YJIT: GC and recompile all code pages (#6406)
when it fails to allocate a new page. Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Diffstat (limited to 'yjit.c')
-rw-r--r--yjit.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/yjit.c b/yjit.c
index f6e64aad65..7e6fc9e3fb 100644
--- a/yjit.c
+++ b/yjit.c
@@ -27,6 +27,7 @@
#include "probes_helper.h"
#include "iseq.h"
#include "ruby/debug.h"
+#include "internal/cont.h"
// For mmapp(), sysconf()
#ifndef _WIN32
@@ -65,10 +66,7 @@ STATIC_ASSERT(pointer_tagging_scheme, USE_FLONUM);
bool
rb_yjit_mark_writable(void *mem_block, uint32_t mem_size)
{
- if (mprotect(mem_block, mem_size, PROT_READ | PROT_WRITE)) {
- return false;
- }
- return true;
+ return mprotect(mem_block, mem_size, PROT_READ | PROT_WRITE) == 0;
}
void
@@ -85,6 +83,20 @@ rb_yjit_mark_executable(void *mem_block, uint32_t mem_size)
}
}
+// Free the specified memory block.
+bool
+rb_yjit_mark_unused(void *mem_block, uint32_t mem_size)
+{
+ // On Linux, you need to use madvise MADV_DONTNEED to free memory.
+ // We might not need to call this on macOS, but it's not really documented.
+ // We generally prefer to do the same thing on both to ease testing too.
+ madvise(mem_block, mem_size, MADV_DONTNEED);
+
+ // On macOS, mprotect PROT_NONE seems to reduce RSS.
+ // We also call this on Linux to avoid executing unused pages.
+ return mprotect(mem_block, mem_size, PROT_NONE) == 0;
+}
+
// `start` is inclusive and `end` is exclusive.
void
rb_yjit_icache_invalidate(void *start, void *end)
@@ -387,6 +399,9 @@ rb_iseq_reset_jit_func(const rb_iseq_t *iseq)
{
RUBY_ASSERT_ALWAYS(IMEMO_TYPE_P(iseq, imemo_iseq));
iseq->body->jit_func = NULL;
+ // Enable re-compiling this ISEQ. Event when it's invalidated for TracePoint,
+ // we'd like to re-compile ISEQs that haven't been converted to trace_* insns.
+ iseq->body->total_calls = 0;
}
// Get the PC for a given index in an iseq