Skip to content

Instantly share code, notes, and snippets.

@rednaxelafx
Created January 10, 2017 05:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rednaxelafx/1735eb6c21f8567b1d47eb0baf21424f to your computer and use it in GitHub Desktop.
Save rednaxelafx/1735eb6c21f8567b1d47eb0baf21424f to your computer and use it in GitHub Desktop.
A partial patch to make CRuby 2.3.3 compile with OPT_STACK_CACHING on. Note that this doesn't fully work yet.

This patch fixes issues with building CRuby 2.3.3 with OPT_STACK_CACHING turned on.

Note that it doesn't fully work yet. This patch does allow the core VM to build, producing the miniruby binary. But as soon as it runs any substantial Ruby code, e.g. building the cgi library, it ends up crashing. The implementation in compile.c around iseq_set_sequence_stackcaching() / REPLACE_ELEM and friends is probably where the remaining bug is. It'd be nice to know what caused nobu-san to comment out REPLACE_ELEM in the first place.

$ make install
...
linking miniruby
generating encdb.h
/private/tmp/ruby-2.3.3/lib/cgi/util.rb:199: [BUG] Stack consistency error (sp: 39, bp: 35)
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin13]

-- Crash Report log information --------------------------------------------
   See Crash Report log file under the one of following:                    
     * ~/Library/Logs/CrashReporter                                         
     * /Library/Logs/CrashReporter                                          
     * ~/Library/Logs/DiagnosticReports                                     
     * /Library/Logs/DiagnosticReports                                      
   for more details.                                                        
Don't forget to include the above Crash Report log file in bug reports.     

-- Control frame information -----------------------------------------------
c:0007 p:0265 s:0039 e:000034 CLASS  /private/tmp/ruby-2.3.3/lib/cgi/util.rb:199
c:0006 p:0023 s:0033 e:000032 TOP    /private/tmp/ruby-2.3.3/lib/cgi/util.rb:3 [FINISH]
c:0005 p:---- s:0031 e:000030 CFUNC  :require
c:0004 p:0008 s:0027 e:000026 TOP    /private/tmp/ruby-2.3.3/lib/erb.rb:15 [FINISH]
c:0003 p:---- s:0025 e:000024 CFUNC  :require
c:0002 p:0008 s:0021 E:002468 EVAL   ./tool/generic_erb.rb:2 [FINISH]
c:0001 p:0000 s:0002 E:001f40 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
./tool/generic_erb.rb:2:in `<main>'
./tool/generic_erb.rb:2:in `require'
/private/tmp/ruby-2.3.3/lib/erb.rb:15:in `<top (required)>'
/private/tmp/ruby-2.3.3/lib/erb.rb:15:in `require'
/private/tmp/ruby-2.3.3/lib/cgi/util.rb:3:in `<top (required)>'
/private/tmp/ruby-2.3.3/lib/cgi/util.rb:199:in `<module:Util>'

-- C level backtrace information -------------------------------------------
0   miniruby                            0x0000000104391b44 rb_vm_bugreport + 388
1   miniruby                            0x00000001041ed715 rb_bug + 485
2   miniruby                            0x000000010434e2fa vm_exec_core + 125082
3   miniruby                            0x0000000104381899 vm_exec + 137
4   miniruby                            0x00000001041fa99e rb_load_internal0 + 286
5   miniruby                            0x00000001041fb11a rb_require_internal + 1434
6   miniruby                            0x00000001041faa28 rb_f_require + 24
7   miniruby                            0x000000010438f999 vm_call_cfunc + 329
8   miniruby                            0x000000010438ed68 vm_call_method_each_type + 104
9   miniruby                            0x000000010438eca9 vm_call_method + 265
10  miniruby                            0x000000010434d19d vm_exec_core + 120637
11  miniruby                            0x0000000104381899 vm_exec + 137
12  miniruby                            0x00000001041fa99e rb_load_internal0 + 286
13  miniruby                            0x00000001041fb11a rb_require_internal + 1434
14  miniruby                            0x00000001041faa28 rb_f_require + 24
15  miniruby                            0x000000010438f999 vm_call_cfunc + 329
16  miniruby                            0x000000010438ed68 vm_call_method_each_type + 104
17  miniruby                            0x000000010438eca9 vm_call_method + 265
18  miniruby                            0x000000010434d19d vm_exec_core + 120637
19  miniruby                            0x0000000104381899 vm_exec + 137
20  miniruby                            0x00000001041f6ce4 ruby_exec_internal + 148
21  miniruby                            0x00000001041f6c0e ruby_run_node + 78
22  miniruby                            0x00000001041ae09f main + 79

-- Other runtime information -----------------------------------------------

* Loaded script: ./tool/generic_erb.rb

* Loaded features:

    0 enumerator.so
    1 thread.rb
    2 rational.so
    3 complex.so

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

make: *** [encdb.h] Abort trap: 6
diff --git a/compile.c b/compile.c
index f767dc4..54373e7 100644
--- a/compile.c
+++ b/compile.c
@@ -853,7 +853,7 @@ INSERT_ELEM_PREV(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
}
}
-#if 0
+#if OPT_STACK_CACHING
/*
* elemX, elem1, elemY => elemX, elem2, elemY
*/
diff --git a/insns.def b/insns.def
index 2deb199..ef351ca 100644
--- a/insns.def
+++ b/insns.def
@@ -1224,7 +1224,7 @@ once
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)ic;
#define RUNNING_THREAD_ONCE_DONE ((rb_thread_t *)(0x1))
- retry:
+ INSN_LABEL(retry):
if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) {
val = is->once.value;
}
@@ -1243,7 +1243,7 @@ once
/* waiting for finish */
RUBY_VM_CHECK_INTS(th);
rb_thread_schedule();
- goto retry;
+ goto INSN_LABEL(retry);
}
}
diff --git a/template/opt_sc.inc.tmpl b/template/opt_sc.inc.tmpl
index 41492b2..5b06f99 100644
--- a/template/opt_sc.inc.tmpl
+++ b/template/opt_sc.inc.tmpl
@@ -22,11 +22,11 @@
#define SC_ERROR 0xffffffff
-static const VALUE sc_insn_info[][SC_STATE_SIZE] = {
+static const enum ruby_vminsn_type sc_insn_info[][SC_STATE_SIZE] = {
<%= sc_insn_info %>
};
-static const VALUE sc_insn_next[] = {
+static const int sc_insn_next[] = {
<%= sc_insn_next %>
};
diff --git a/tool/instruction.rb b/tool/instruction.rb
index 4f7d08c..49d23df 100755
--- a/tool/instruction.rb
+++ b/tool/instruction.rb
@@ -514,6 +514,7 @@ def make_stackcaching_insns
oname = insn.name
after = SPECIAL_INSN_FOR_SC_AFTER.find {|k, v| k =~ oname}
+ after = after && after.last
insns = []
FROM_SC.each{|from|
@@ -612,7 +613,7 @@ def calc_stack insn, ofrom, oafter, opops, orets
exit
end
- ret = ["#{insn.name}_SC_#{InstructionsLoader.complement_name(ofrom)}_#{complement_name(from)}",
+ ret = ["#{insn.name}_SC_#{InstructionsLoader.complement_name(ofrom)}_#{InstructionsLoader.complement_name(from)}",
pops, rets, pushs_before, pushs, from]
end
end
diff --git a/vm_core.h b/vm_core.h
index 67a9f00..9f91d73 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -1007,7 +1007,11 @@ VALUE rb_binding_alloc(VALUE klass);
/* for debug */
extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
extern void rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp, VALUE *_pc);
-extern void rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp);
+extern void rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp
+#if OPT_STACK_CACHING
+ , VALUE reg_a, VALUE reg_b
+#endif
+);
#define SDR() rb_vmdebug_stack_dump_raw(GET_THREAD(), GET_THREAD()->cfp)
#define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_THREAD(), (cfp))
diff --git a/vm_opts.h b/vm_opts.h
index 3fedf1d..b1d6977 100644
--- a/vm_opts.h
+++ b/vm_opts.h
@@ -45,7 +45,7 @@
#define OPT_OPERANDS_UNIFICATION 1
#define OPT_INSTRUCTIONS_UNIFICATION 0
#define OPT_UNIFY_ALL_COMBINATION 0
-#define OPT_STACK_CACHING 0
+#define OPT_STACK_CACHING 1
/* misc */
#define SUPPORT_JOKE 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment