debase-ruby_core_source 3.2.0 → 3.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +10 -0
  4. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/addr2line.h +20 -0
  5. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/builtin.h +117 -0
  6. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ccan/build_assert/build_assert.h +40 -0
  7. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ccan/check_type/check_type.h +63 -0
  8. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ccan/container_of/container_of.h +142 -0
  9. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ccan/list/list.h +789 -0
  10. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ccan/str/str.h +17 -0
  11. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/constant.h +53 -0
  12. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/darray.h +246 -0
  13. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/debug_counter.h +423 -0
  14. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/dln.h +31 -0
  15. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/encindex.h +70 -0
  16. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/eval_intern.h +341 -0
  17. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/hrtime.h +227 -0
  18. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/id.h +343 -0
  19. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/id_table.h +39 -0
  20. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/insns.inc +249 -0
  21. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/insns_info.inc +9133 -0
  22. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/array.h +144 -0
  23. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/basic_operators.h +63 -0
  24. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/bignum.h +244 -0
  25. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/bits.h +568 -0
  26. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/class.h +226 -0
  27. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/cmdlineopt.h +63 -0
  28. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/compar.h +29 -0
  29. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/compile.h +34 -0
  30. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/compilers.h +107 -0
  31. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/complex.h +29 -0
  32. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/cont.h +32 -0
  33. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/dir.h +16 -0
  34. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/enc.h +19 -0
  35. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/encoding.h +32 -0
  36. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/enum.h +18 -0
  37. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/enumerator.h +21 -0
  38. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/error.h +213 -0
  39. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/eval.h +32 -0
  40. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/file.h +38 -0
  41. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/fixnum.h +184 -0
  42. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/gc.h +361 -0
  43. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/hash.h +190 -0
  44. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/imemo.h +241 -0
  45. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/inits.h +50 -0
  46. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/io.h +137 -0
  47. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/load.h +18 -0
  48. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/loadpath.h +16 -0
  49. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/math.h +23 -0
  50. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/missing.h +18 -0
  51. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/numeric.h +273 -0
  52. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/object.h +59 -0
  53. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/parse.h +133 -0
  54. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/proc.h +30 -0
  55. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/process.h +124 -0
  56. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/ractor.h +6 -0
  57. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/random.h +16 -0
  58. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/range.h +40 -0
  59. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/rational.h +71 -0
  60. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/re.h +28 -0
  61. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/ruby_parser.h +69 -0
  62. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/sanitizers.h +186 -0
  63. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/serial.h +23 -0
  64. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/signal.h +25 -0
  65. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/static_assert.h +16 -0
  66. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/string.h +160 -0
  67. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/struct.h +127 -0
  68. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/symbol.h +42 -0
  69. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/thread.h +74 -0
  70. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/time.h +34 -0
  71. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/transcode.h +20 -0
  72. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/util.h +27 -0
  73. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/variable.h +71 -0
  74. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/vm.h +129 -0
  75. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal/warnings.h +16 -0
  76. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/internal.h +112 -0
  77. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/iseq.h +334 -0
  78. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/known_errors.inc +791 -0
  79. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/method.h +254 -0
  80. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/node.h +125 -0
  81. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/node_name.inc +210 -0
  82. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/optinsn.inc +128 -0
  83. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/optunifs.inc +43 -0
  84. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/parse.h +232 -0
  85. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/parser_bits.h +564 -0
  86. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/parser_node.h +133 -0
  87. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/parser_st.h +162 -0
  88. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/parser_value.h +106 -0
  89. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/probes_helper.h +42 -0
  90. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ractor_core.h +387 -0
  91. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/regenc.h +254 -0
  92. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/regint.h +996 -0
  93. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/regparse.h +370 -0
  94. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/revision.h +5 -0
  95. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/rjit.h +103 -0
  96. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/rjit_c.h +165 -0
  97. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ruby_assert.h +14 -0
  98. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/ruby_atomic.h +23 -0
  99. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/rubyparser.h +628 -0
  100. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/shape.h +232 -0
  101. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/siphash.h +48 -0
  102. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/symbol.h +119 -0
  103. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/thread_none.h +20 -0
  104. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/thread_pthread.h +126 -0
  105. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/thread_win32.h +58 -0
  106. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/timev.h +58 -0
  107. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/transcode_data.h +138 -0
  108. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/variable.h +30 -0
  109. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/version.h +65 -0
  110. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm.inc +5396 -0
  111. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_call_iseq_optimized.inc +244 -0
  112. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_callinfo.h +608 -0
  113. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_core.h +2089 -0
  114. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_debug.h +122 -0
  115. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_exec.h +199 -0
  116. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_insnhelper.h +271 -0
  117. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_opts.h +67 -0
  118. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vm_sync.h +137 -0
  119. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/vmtc.inc +243 -0
  120. data/lib/debase/ruby_core_source/ruby-3.3.0-preview2/yjit.h +70 -0
  121. data/lib/debase/ruby_core_source/version.rb +1 -1
  122. metadata +120 -3
@@ -0,0 +1,608 @@
1
+ #ifndef RUBY_VM_CALLINFO_H /*-*-C-*-vi:se ft=c:*/
2
+ #define RUBY_VM_CALLINFO_H
3
+ /**
4
+ * @author Ruby developers <ruby-core@ruby-lang.org>
5
+ * @copyright This file is a part of the programming language Ruby.
6
+ * Permission is hereby granted, to either redistribute and/or
7
+ * modify this file, provided that the conditions mentioned in the
8
+ * file COPYING are met. Consult the file for details.
9
+ */
10
+
11
+ #include "debug_counter.h"
12
+ #include "internal/class.h"
13
+ #include "shape.h"
14
+
15
+ enum vm_call_flag_bits {
16
+ VM_CALL_ARGS_SPLAT_bit, // m(*args)
17
+ VM_CALL_ARGS_BLOCKARG_bit, // m(&block)
18
+ VM_CALL_FCALL_bit, // m(args) # receiver is self
19
+ VM_CALL_VCALL_bit, // m # method call that looks like a local variable
20
+ VM_CALL_ARGS_SIMPLE_bit, // (ci->flag & (SPLAT|BLOCKARG)) && blockiseq == NULL && ci->kw_arg == NULL
21
+ VM_CALL_KWARG_bit, // has kwarg
22
+ VM_CALL_KW_SPLAT_bit, // m(**opts)
23
+ VM_CALL_TAILCALL_bit, // located at tail position
24
+ VM_CALL_SUPER_bit, // super
25
+ VM_CALL_ZSUPER_bit, // zsuper
26
+ VM_CALL_OPT_SEND_bit, // internal flag
27
+ VM_CALL_KW_SPLAT_MUT_bit, // kw splat hash can be modified (to avoid allocating a new one)
28
+ VM_CALL__END
29
+ };
30
+
31
+ #define VM_CALL_ARGS_SPLAT (0x01 << VM_CALL_ARGS_SPLAT_bit)
32
+ #define VM_CALL_ARGS_BLOCKARG (0x01 << VM_CALL_ARGS_BLOCKARG_bit)
33
+ #define VM_CALL_FCALL (0x01 << VM_CALL_FCALL_bit)
34
+ #define VM_CALL_VCALL (0x01 << VM_CALL_VCALL_bit)
35
+ #define VM_CALL_ARGS_SIMPLE (0x01 << VM_CALL_ARGS_SIMPLE_bit)
36
+ #define VM_CALL_KWARG (0x01 << VM_CALL_KWARG_bit)
37
+ #define VM_CALL_KW_SPLAT (0x01 << VM_CALL_KW_SPLAT_bit)
38
+ #define VM_CALL_TAILCALL (0x01 << VM_CALL_TAILCALL_bit)
39
+ #define VM_CALL_SUPER (0x01 << VM_CALL_SUPER_bit)
40
+ #define VM_CALL_ZSUPER (0x01 << VM_CALL_ZSUPER_bit)
41
+ #define VM_CALL_OPT_SEND (0x01 << VM_CALL_OPT_SEND_bit)
42
+ #define VM_CALL_KW_SPLAT_MUT (0x01 << VM_CALL_KW_SPLAT_MUT_bit)
43
+
44
+ struct rb_callinfo_kwarg {
45
+ int keyword_len;
46
+ VALUE keywords[];
47
+ };
48
+
49
+ static inline size_t
50
+ rb_callinfo_kwarg_bytes(int keyword_len)
51
+ {
52
+ return rb_size_mul_add_or_raise(
53
+ keyword_len,
54
+ sizeof(VALUE),
55
+ sizeof(struct rb_callinfo_kwarg),
56
+ rb_eRuntimeError);
57
+ }
58
+
59
+ // imemo_callinfo
60
+ struct rb_callinfo {
61
+ VALUE flags;
62
+ const struct rb_callinfo_kwarg *kwarg;
63
+ VALUE mid;
64
+ VALUE flag;
65
+ VALUE argc;
66
+ };
67
+
68
+ #if !defined(USE_EMBED_CI) || (USE_EMBED_CI+0)
69
+ #undef USE_EMBED_CI
70
+ #define USE_EMBED_CI 1
71
+ #else
72
+ #undef USE_EMBED_CI
73
+ #define USE_EMBED_CI 0
74
+ #endif
75
+
76
+ #if SIZEOF_VALUE == 8
77
+ #define CI_EMBED_TAG_bits 1
78
+ #define CI_EMBED_ARGC_bits 15
79
+ #define CI_EMBED_FLAG_bits 16
80
+ #define CI_EMBED_ID_bits 32
81
+ #elif SIZEOF_VALUE == 4
82
+ #define CI_EMBED_TAG_bits 1
83
+ #define CI_EMBED_ARGC_bits 3
84
+ #define CI_EMBED_FLAG_bits 13
85
+ #define CI_EMBED_ID_bits 15
86
+ #endif
87
+
88
+ #if (CI_EMBED_TAG_bits + CI_EMBED_ARGC_bits + CI_EMBED_FLAG_bits + CI_EMBED_ID_bits) != (SIZEOF_VALUE * 8)
89
+ #error
90
+ #endif
91
+
92
+ #define CI_EMBED_FLAG 0x01
93
+ #define CI_EMBED_ARGC_SHFT (CI_EMBED_TAG_bits)
94
+ #define CI_EMBED_ARGC_MASK ((((VALUE)1)<<CI_EMBED_ARGC_bits) - 1)
95
+ #define CI_EMBED_FLAG_SHFT (CI_EMBED_TAG_bits + CI_EMBED_ARGC_bits)
96
+ #define CI_EMBED_FLAG_MASK ((((VALUE)1)<<CI_EMBED_FLAG_bits) - 1)
97
+ #define CI_EMBED_ID_SHFT (CI_EMBED_TAG_bits + CI_EMBED_ARGC_bits + CI_EMBED_FLAG_bits)
98
+ #define CI_EMBED_ID_MASK ((((VALUE)1)<<CI_EMBED_ID_bits) - 1)
99
+
100
+ static inline bool
101
+ vm_ci_packed_p(const struct rb_callinfo *ci)
102
+ {
103
+ if (!USE_EMBED_CI) {
104
+ return 0;
105
+ }
106
+ if (LIKELY(((VALUE)ci) & 0x01)) {
107
+ return 1;
108
+ }
109
+ else {
110
+ VM_ASSERT(IMEMO_TYPE_P(ci, imemo_callinfo));
111
+ return 0;
112
+ }
113
+ }
114
+
115
+ static inline bool
116
+ vm_ci_p(const struct rb_callinfo *ci)
117
+ {
118
+ if (vm_ci_packed_p(ci) || IMEMO_TYPE_P(ci, imemo_callinfo)) {
119
+ return 1;
120
+ }
121
+ else {
122
+ return 0;
123
+ }
124
+ }
125
+
126
+ static inline ID
127
+ vm_ci_mid(const struct rb_callinfo *ci)
128
+ {
129
+ if (vm_ci_packed_p(ci)) {
130
+ return (((VALUE)ci) >> CI_EMBED_ID_SHFT) & CI_EMBED_ID_MASK;
131
+ }
132
+ else {
133
+ return (ID)ci->mid;
134
+ }
135
+ }
136
+
137
+ static inline unsigned int
138
+ vm_ci_flag(const struct rb_callinfo *ci)
139
+ {
140
+ if (vm_ci_packed_p(ci)) {
141
+ return (unsigned int)((((VALUE)ci) >> CI_EMBED_FLAG_SHFT) & CI_EMBED_FLAG_MASK);
142
+ }
143
+ else {
144
+ return (unsigned int)ci->flag;
145
+ }
146
+ }
147
+
148
+ static inline unsigned int
149
+ vm_ci_argc(const struct rb_callinfo *ci)
150
+ {
151
+ if (vm_ci_packed_p(ci)) {
152
+ return (unsigned int)((((VALUE)ci) >> CI_EMBED_ARGC_SHFT) & CI_EMBED_ARGC_MASK);
153
+ }
154
+ else {
155
+ return (unsigned int)ci->argc;
156
+ }
157
+ }
158
+
159
+ static inline const struct rb_callinfo_kwarg *
160
+ vm_ci_kwarg(const struct rb_callinfo *ci)
161
+ {
162
+ if (vm_ci_packed_p(ci)) {
163
+ return NULL;
164
+ }
165
+ else {
166
+ return ci->kwarg;
167
+ }
168
+ }
169
+
170
+ static inline void
171
+ vm_ci_dump(const struct rb_callinfo *ci)
172
+ {
173
+ if (vm_ci_packed_p(ci)) {
174
+ ruby_debug_printf("packed_ci ID:%s flag:%x argc:%u\n",
175
+ rb_id2name(vm_ci_mid(ci)), vm_ci_flag(ci), vm_ci_argc(ci));
176
+ }
177
+ else {
178
+ rp(ci);
179
+ }
180
+ }
181
+
182
+ #define vm_ci_new(mid, flag, argc, kwarg) vm_ci_new_(mid, flag, argc, kwarg, __FILE__, __LINE__)
183
+ #define vm_ci_new_runtime(mid, flag, argc, kwarg) vm_ci_new_runtime_(mid, flag, argc, kwarg, __FILE__, __LINE__)
184
+
185
+ /* This is passed to STATIC_ASSERT. Cannot be an inline function. */
186
+ #define VM_CI_EMBEDDABLE_P(mid, flag, argc, kwarg) \
187
+ (((mid ) & ~CI_EMBED_ID_MASK) ? false : \
188
+ ((flag) & ~CI_EMBED_FLAG_MASK) ? false : \
189
+ ((argc) & ~CI_EMBED_ARGC_MASK) ? false : \
190
+ (kwarg) ? false : true)
191
+
192
+ #define vm_ci_new_id(mid, flag, argc, must_zero) \
193
+ ((const struct rb_callinfo *) \
194
+ ((((VALUE)(mid )) << CI_EMBED_ID_SHFT) | \
195
+ (((VALUE)(flag)) << CI_EMBED_FLAG_SHFT) | \
196
+ (((VALUE)(argc)) << CI_EMBED_ARGC_SHFT) | \
197
+ RUBY_FIXNUM_FLAG))
198
+
199
+ static inline const struct rb_callinfo *
200
+ vm_ci_new_(ID mid, unsigned int flag, unsigned int argc, const struct rb_callinfo_kwarg *kwarg, const char *file, int line)
201
+ {
202
+ if (USE_EMBED_CI && VM_CI_EMBEDDABLE_P(mid, flag, argc, kwarg)) {
203
+ RB_DEBUG_COUNTER_INC(ci_packed);
204
+ return vm_ci_new_id(mid, flag, argc, kwarg);
205
+ }
206
+
207
+ const bool debug = 0;
208
+ if (debug) ruby_debug_printf("%s:%d ", file, line);
209
+
210
+ // TODO: dedup
211
+ const struct rb_callinfo *ci = (const struct rb_callinfo *)
212
+ rb_imemo_new(imemo_callinfo,
213
+ (VALUE)mid,
214
+ (VALUE)flag,
215
+ (VALUE)argc,
216
+ (VALUE)kwarg);
217
+ if (debug) rp(ci);
218
+ if (kwarg) {
219
+ RB_DEBUG_COUNTER_INC(ci_kw);
220
+ }
221
+ else {
222
+ RB_DEBUG_COUNTER_INC(ci_nokw);
223
+ }
224
+
225
+ VM_ASSERT(vm_ci_flag(ci) == flag);
226
+ VM_ASSERT(vm_ci_argc(ci) == argc);
227
+
228
+ return ci;
229
+ }
230
+
231
+
232
+ static inline const struct rb_callinfo *
233
+ vm_ci_new_runtime_(ID mid, unsigned int flag, unsigned int argc, const struct rb_callinfo_kwarg *kwarg, const char *file, int line)
234
+ {
235
+ RB_DEBUG_COUNTER_INC(ci_runtime);
236
+ return vm_ci_new_(mid, flag, argc, kwarg, file, line);
237
+ }
238
+
239
+ #define VM_CALLINFO_NOT_UNDER_GC IMEMO_FL_USER0
240
+
241
+ static inline bool
242
+ vm_ci_markable(const struct rb_callinfo *ci)
243
+ {
244
+ if (! ci) {
245
+ return false; /* or true? This is Qfalse... */
246
+ }
247
+ else if (vm_ci_packed_p(ci)) {
248
+ return true;
249
+ }
250
+ else {
251
+ VM_ASSERT(IMEMO_TYPE_P(ci, imemo_callinfo));
252
+ return ! FL_ANY_RAW((VALUE)ci, VM_CALLINFO_NOT_UNDER_GC);
253
+ }
254
+ }
255
+
256
+ #define VM_CI_ON_STACK(mid_, flags_, argc_, kwarg_) \
257
+ (struct rb_callinfo) { \
258
+ .flags = T_IMEMO | \
259
+ (imemo_callinfo << FL_USHIFT) | \
260
+ VM_CALLINFO_NOT_UNDER_GC, \
261
+ .mid = mid_, \
262
+ .flag = flags_, \
263
+ .argc = argc_, \
264
+ .kwarg = kwarg_, \
265
+ }
266
+
267
+ typedef VALUE (*vm_call_handler)(
268
+ struct rb_execution_context_struct *ec,
269
+ struct rb_control_frame_struct *cfp,
270
+ struct rb_calling_info *calling);
271
+
272
+ // imemo_callcache
273
+
274
+ struct rb_callcache {
275
+ const VALUE flags;
276
+
277
+ /* inline cache: key */
278
+ const VALUE klass; // should not mark it because klass can not be free'd
279
+ // because of this marking. When klass is collected,
280
+ // cc will be cleared (cc->klass = 0) at vm_ccs_free().
281
+
282
+ /* inline cache: values */
283
+ const struct rb_callable_method_entry_struct * const cme_;
284
+ const vm_call_handler call_;
285
+
286
+ union {
287
+ struct {
288
+ uintptr_t value; // Shape ID in upper bits, index in lower bits
289
+ } attr;
290
+ const enum method_missing_reason method_missing_reason; /* used by method_missing */
291
+ VALUE v;
292
+ const struct rb_builtin_function *bf;
293
+ } aux_;
294
+ };
295
+
296
+ #define VM_CALLCACHE_UNMARKABLE FL_FREEZE
297
+ #define VM_CALLCACHE_ON_STACK FL_EXIVAR
298
+
299
+ #define VM_CALLCACHE_IVAR IMEMO_FL_USER0
300
+ #define VM_CALLCACHE_BF IMEMO_FL_USER1
301
+ #define VM_CALLCACHE_SUPER IMEMO_FL_USER2
302
+ #define VM_CALLCACHE_REFINEMENT IMEMO_FL_USER3
303
+
304
+ enum vm_cc_type {
305
+ cc_type_normal, // chained from ccs
306
+ cc_type_super,
307
+ cc_type_refinement,
308
+ };
309
+
310
+ extern const struct rb_callcache *rb_vm_empty_cc(void);
311
+ extern const struct rb_callcache *rb_vm_empty_cc_for_super(void);
312
+
313
+ #define vm_cc_empty() rb_vm_empty_cc()
314
+
315
+ static inline void vm_cc_attr_index_set(const struct rb_callcache *cc, attr_index_t index, shape_id_t dest_shape_id);
316
+
317
+ static inline void
318
+ vm_cc_attr_index_initialize(const struct rb_callcache *cc, shape_id_t shape_id)
319
+ {
320
+ vm_cc_attr_index_set(cc, (attr_index_t)-1, shape_id);
321
+ }
322
+
323
+ static inline const struct rb_callcache *
324
+ vm_cc_new(VALUE klass,
325
+ const struct rb_callable_method_entry_struct *cme,
326
+ vm_call_handler call,
327
+ enum vm_cc_type type)
328
+ {
329
+ const struct rb_callcache *cc = (const struct rb_callcache *)rb_imemo_new(imemo_callcache, (VALUE)cme, (VALUE)call, 0, klass);
330
+
331
+ switch (type) {
332
+ case cc_type_normal:
333
+ break;
334
+ case cc_type_super:
335
+ *(VALUE *)&cc->flags |= VM_CALLCACHE_SUPER;
336
+ break;
337
+ case cc_type_refinement:
338
+ *(VALUE *)&cc->flags |= VM_CALLCACHE_REFINEMENT;
339
+ break;
340
+ }
341
+
342
+ vm_cc_attr_index_initialize(cc, INVALID_SHAPE_ID);
343
+ RB_DEBUG_COUNTER_INC(cc_new);
344
+ return cc;
345
+ }
346
+
347
+ static inline bool
348
+ vm_cc_super_p(const struct rb_callcache *cc)
349
+ {
350
+ return (cc->flags & VM_CALLCACHE_SUPER) != 0;
351
+ }
352
+
353
+ static inline bool
354
+ vm_cc_refinement_p(const struct rb_callcache *cc)
355
+ {
356
+ return (cc->flags & VM_CALLCACHE_REFINEMENT) != 0;
357
+ }
358
+
359
+ #define VM_CC_ON_STACK(clazz, call, aux, cme) \
360
+ (struct rb_callcache) { \
361
+ .flags = T_IMEMO | \
362
+ (imemo_callcache << FL_USHIFT) | \
363
+ VM_CALLCACHE_UNMARKABLE | \
364
+ VM_CALLCACHE_ON_STACK, \
365
+ .klass = clazz, \
366
+ .cme_ = cme, \
367
+ .call_ = call, \
368
+ .aux_ = aux, \
369
+ }
370
+
371
+ static inline bool
372
+ vm_cc_class_check(const struct rb_callcache *cc, VALUE klass)
373
+ {
374
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
375
+ VM_ASSERT(cc->klass == 0 ||
376
+ RB_TYPE_P(cc->klass, T_CLASS) || RB_TYPE_P(cc->klass, T_ICLASS));
377
+ return cc->klass == klass;
378
+ }
379
+
380
+ static inline int
381
+ vm_cc_markable(const struct rb_callcache *cc)
382
+ {
383
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
384
+ return FL_TEST_RAW((VALUE)cc, VM_CALLCACHE_UNMARKABLE) == 0;
385
+ }
386
+
387
+ static inline const struct rb_callable_method_entry_struct *
388
+ vm_cc_cme(const struct rb_callcache *cc)
389
+ {
390
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
391
+ VM_ASSERT(cc->call_ == NULL || // not initialized yet
392
+ !vm_cc_markable(cc) ||
393
+ cc->cme_ != NULL);
394
+
395
+ return cc->cme_;
396
+ }
397
+
398
+ static inline vm_call_handler
399
+ vm_cc_call(const struct rb_callcache *cc)
400
+ {
401
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
402
+ VM_ASSERT(cc->call_ != NULL);
403
+ return cc->call_;
404
+ }
405
+
406
+ static inline attr_index_t
407
+ vm_cc_attr_index(const struct rb_callcache *cc)
408
+ {
409
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
410
+ return (attr_index_t)((cc->aux_.attr.value & SHAPE_FLAG_MASK) - 1);
411
+ }
412
+
413
+ static inline shape_id_t
414
+ vm_cc_attr_index_dest_shape_id(const struct rb_callcache *cc)
415
+ {
416
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
417
+
418
+ return cc->aux_.attr.value >> SHAPE_FLAG_SHIFT;
419
+ }
420
+
421
+ static inline void
422
+ vm_cc_atomic_shape_and_index(const struct rb_callcache *cc, shape_id_t * shape_id, attr_index_t * index)
423
+ {
424
+ uintptr_t cache_value = cc->aux_.attr.value; // Atomically read 64 bits
425
+ *shape_id = (shape_id_t)(cache_value >> SHAPE_FLAG_SHIFT);
426
+ *index = (attr_index_t)(cache_value & SHAPE_FLAG_MASK) - 1;
427
+ return;
428
+ }
429
+
430
+ static inline void
431
+ vm_ic_atomic_shape_and_index(const struct iseq_inline_iv_cache_entry *ic, shape_id_t * shape_id, attr_index_t * index)
432
+ {
433
+ uintptr_t cache_value = ic->value; // Atomically read 64 bits
434
+ *shape_id = (shape_id_t)(cache_value >> SHAPE_FLAG_SHIFT);
435
+ *index = (attr_index_t)(cache_value & SHAPE_FLAG_MASK) - 1;
436
+ return;
437
+ }
438
+
439
+ static inline shape_id_t
440
+ vm_ic_attr_index_dest_shape_id(const struct iseq_inline_iv_cache_entry *ic)
441
+ {
442
+ return (shape_id_t)(ic->value >> SHAPE_FLAG_SHIFT);
443
+ }
444
+
445
+ static inline unsigned int
446
+ vm_cc_cmethod_missing_reason(const struct rb_callcache *cc)
447
+ {
448
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
449
+ return cc->aux_.method_missing_reason;
450
+ }
451
+
452
+ static inline bool
453
+ vm_cc_invalidated_p(const struct rb_callcache *cc)
454
+ {
455
+ if (cc->klass && !METHOD_ENTRY_INVALIDATED(vm_cc_cme(cc))) {
456
+ return false;
457
+ }
458
+ else {
459
+ return true;
460
+ }
461
+ }
462
+
463
+ // For RJIT. cc_cme is supposed to have inlined `vm_cc_cme(cc)`.
464
+ static inline bool
465
+ vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *cc_cme, VALUE klass)
466
+ {
467
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
468
+ if (cc->klass == klass && !METHOD_ENTRY_INVALIDATED(cc_cme)) {
469
+ return 1;
470
+ }
471
+ else {
472
+ return 0;
473
+ }
474
+ }
475
+
476
+ /* callcache: mutate */
477
+
478
+ static inline void
479
+ vm_cc_call_set(const struct rb_callcache *cc, vm_call_handler call)
480
+ {
481
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
482
+ VM_ASSERT(cc != vm_cc_empty());
483
+ *(vm_call_handler *)&cc->call_ = call;
484
+ }
485
+
486
+ static inline void
487
+ vm_cc_attr_index_set(const struct rb_callcache *cc, attr_index_t index, shape_id_t dest_shape_id)
488
+ {
489
+ uintptr_t *attr_value = (uintptr_t *)&cc->aux_.attr.value;
490
+ if (!vm_cc_markable(cc)) {
491
+ *attr_value = (uintptr_t)INVALID_SHAPE_ID << SHAPE_FLAG_SHIFT;
492
+ return;
493
+ }
494
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
495
+ VM_ASSERT(cc != vm_cc_empty());
496
+ *attr_value = (attr_index_t)(index + 1) | ((uintptr_t)(dest_shape_id) << SHAPE_FLAG_SHIFT);
497
+ *(VALUE *)&cc->flags |= VM_CALLCACHE_IVAR;
498
+ }
499
+
500
+ static inline bool
501
+ vm_cc_ivar_p(const struct rb_callcache *cc)
502
+ {
503
+ return (cc->flags & VM_CALLCACHE_IVAR) != 0;
504
+ }
505
+
506
+ static inline void
507
+ vm_ic_attr_index_set(const rb_iseq_t *iseq, const struct iseq_inline_iv_cache_entry *ic, attr_index_t index, shape_id_t dest_shape_id)
508
+ {
509
+ *(uintptr_t *)&ic->value = ((uintptr_t)dest_shape_id << SHAPE_FLAG_SHIFT) | (attr_index_t)(index + 1);
510
+ }
511
+
512
+ static inline void
513
+ vm_ic_attr_index_initialize(const struct iseq_inline_iv_cache_entry *ic, shape_id_t shape_id)
514
+ {
515
+ *(uintptr_t *)&ic->value = (uintptr_t)shape_id << SHAPE_FLAG_SHIFT;
516
+ }
517
+
518
+ static inline void
519
+ vm_cc_method_missing_reason_set(const struct rb_callcache *cc, enum method_missing_reason reason)
520
+ {
521
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
522
+ VM_ASSERT(cc != vm_cc_empty());
523
+ *(enum method_missing_reason *)&cc->aux_.method_missing_reason = reason;
524
+ }
525
+
526
+ static inline void
527
+ vm_cc_bf_set(const struct rb_callcache *cc, const struct rb_builtin_function *bf)
528
+ {
529
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
530
+ VM_ASSERT(cc != vm_cc_empty());
531
+ *(const struct rb_builtin_function **)&cc->aux_.bf = bf;
532
+ *(VALUE *)&cc->flags |= VM_CALLCACHE_BF;
533
+ }
534
+
535
+ static inline bool
536
+ vm_cc_bf_p(const struct rb_callcache *cc)
537
+ {
538
+ return (cc->flags & VM_CALLCACHE_BF) != 0;
539
+ }
540
+
541
+ static inline void
542
+ vm_cc_invalidate(const struct rb_callcache *cc)
543
+ {
544
+ VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
545
+ VM_ASSERT(cc != vm_cc_empty());
546
+ VM_ASSERT(cc->klass != 0); // should be enable
547
+
548
+ *(VALUE *)&cc->klass = 0;
549
+ RB_DEBUG_COUNTER_INC(cc_ent_invalidate);
550
+ }
551
+
552
+ /* calldata */
553
+
554
+ struct rb_call_data {
555
+ const struct rb_callinfo *ci;
556
+ const struct rb_callcache *cc;
557
+ };
558
+
559
+ struct rb_class_cc_entries {
560
+ #if VM_CHECK_MODE > 0
561
+ VALUE debug_sig;
562
+ #endif
563
+ int capa;
564
+ int len;
565
+ const struct rb_callable_method_entry_struct *cme;
566
+ struct rb_class_cc_entries_entry {
567
+ const struct rb_callinfo *ci;
568
+ const struct rb_callcache *cc;
569
+ } *entries;
570
+ };
571
+
572
+ #if VM_CHECK_MODE > 0
573
+
574
+ const rb_callable_method_entry_t *rb_vm_lookup_overloaded_cme(const rb_callable_method_entry_t *cme);
575
+ void rb_vm_dump_overloaded_cme_table(void);
576
+
577
+ static inline bool
578
+ vm_ccs_p(const struct rb_class_cc_entries *ccs)
579
+ {
580
+ return ccs->debug_sig == ~(VALUE)ccs;
581
+ }
582
+
583
+ static inline bool
584
+ vm_cc_check_cme(const struct rb_callcache *cc, const rb_callable_method_entry_t *cme)
585
+ {
586
+ if (vm_cc_cme(cc) == cme ||
587
+ (cme->def->iseq_overload && vm_cc_cme(cc) == rb_vm_lookup_overloaded_cme(cme))) {
588
+ return true;
589
+ }
590
+ else {
591
+ #if 1
592
+ // debug print
593
+
594
+ fprintf(stderr, "iseq_overload:%d\n", (int)cme->def->iseq_overload);
595
+ rp(cme);
596
+ rp(vm_cc_cme(cc));
597
+ rb_vm_lookup_overloaded_cme(cme);
598
+ #endif
599
+ return false;
600
+ }
601
+ }
602
+
603
+ #endif
604
+
605
+ // gc.c
606
+ void rb_vm_ccs_free(struct rb_class_cc_entries *ccs);
607
+
608
+ #endif /* RUBY_VM_CALLINFO_H */