Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
From dc34706366802534e8f24b4efc312942c31cca72 Mon Sep 17 00:00:00 2001
From: "Urabe, Shyouhei" <shyouhei@ruby-lang.org>
Date: Wed, 5 Sep 2018 14:15:08 +0900
Subject: [PATCH] print N-gram of instructions that run
This is different from N-gram of generated iseq. Rather it prints
the sequence that was actually executed.
Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org>
---
tool/ruby_vm/views/_insn_entry.erb | 1 +
vm_core.h | 1 +
vm_insnhelper.c | 52 ++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+)
diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb
index e3e3ea42ea..3fcef729cd 100644
--- a/tool/ruby_vm/views/_insn_entry.erb
+++ b/tool/ruby_vm/views/_insn_entry.erb
@@ -49,6 +49,7 @@ INSN_ENTRY(<%= insn.name %>)
TOPN(<%= i %>) = <%= insn.cast_to_VALUE ret %>;
% end
% end
+ vm_print_ngram(GET_THREAD(), INSN_ATTR(bin));
END_INSN(<%= insn.name %>);
# undef INSN_ATTR
# undef NAME_OF_CURRENT_INSN
diff --git a/vm_core.h b/vm_core.h
index bb6409719b..3abc0e20c5 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -921,6 +921,7 @@ typedef struct rb_thread_struct {
/* misc */
VALUE name;
+ const char *names_of_last_insns[2];
} rb_thread_t;
typedef enum {
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index f82b0e075b..ff546198d3 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3900,3 +3900,55 @@ vm_trace(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE *p
}
}
}
+
+#ifdef MJIT_HEADER
+#define vm_print_ngram(t, b) /* vanish */
+#else
+static FILE *__log__ = NULL;
+static void __attribute__((constructor)) __openlog__(void);
+static void __attribute__((destructor)) __closelog__(void);
+static void __attribute__((constructor)) __Initlog__(void);
+
+void
+__Initlog__(void)
+{
+ pthread_atfork(__closelog__, __openlog__, __openlog__);
+}
+
+void
+__openlog__(void)
+{
+ __log__ = fopen("/tmp/ruby-ngram.txt", "ae");
+}
+
+void
+__closelog__(void)
+{
+ fclose(__log__);
+}
+
+void
+vm_print_ngram(rb_thread_t *t, enum ruby_vminsn_type bin)
+{
+ char buf[BUFSIZ] = {'\0'};
+ const char **src = t->names_of_last_insns;
+ int i, n = numberof(t->names_of_last_insns);
+
+ for (i = 0; i < n - 1; i++) {
+ src[i] = src[i + 1];
+ }
+ src[n - 1] = rb_insns_name(bin);
+
+ for (i = 0; i < n - 1; i++) {
+ if (LIKELY(src[i])) {
+ strlcat(buf, src[i], BUFSIZ);
+ strlcat(buf, " -> ", BUFSIZ);
+ }
+ }
+ strlcat(buf, src[n - 1], BUFSIZ);
+ strlcat(buf, "\n", BUFSIZ);
+ buf[BUFSIZ - 2] = '\n'; /* ensure newline */
+ buf[BUFSIZ - 1] = '\0'; /* ensure NUL */
+ fputs(buf, __log__);
+}
+#endif
--
2.18.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.