@@ -1144,58 +1144,30 @@ int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t , void *);
1144
1144
/* We're lazily copying cache values from main thread because these cache values
1145
1145
could be different between ones on enqueue timing and ones on dequeue timing.
1146
1146
Return true if copy succeeds. */
1147
- static mjit_copy_job_result_t
1148
- copy_cache_from_main_thread (const rb_iseq_t * iseq )
1147
+ static bool
1148
+ copy_cache_from_main_thread (mjit_copy_job_t * job )
1149
1149
{
1150
- mjit_copy_job_t * job = & mjit_copy_job ; // just a shorthand
1151
-
1152
- CRITICAL_SECTION_START (3 , "in copy_cache_from_main_thread" );
1153
- job -> finish_p = true; // disable dispatching this job in mjit_copy_job_handler while it's being modified
1154
- CRITICAL_SECTION_FINISH (3 , "in copy_cache_from_main_thread" );
1155
-
1156
- const struct rb_iseq_constant_body * body = iseq -> body ;
1157
- job -> iseq = iseq ;
1158
- job -> cc_entries = NULL ;
1159
- if (body -> ci_size > 0 || body -> ci_kw_size > 0 )
1160
- job -> cc_entries = alloca (sizeof (struct rb_call_cache ) * (body -> ci_size + body -> ci_kw_size ));
1161
- job -> is_entries = NULL ;
1162
- if (body -> is_size > 0 )
1163
- job -> is_entries = alloca (sizeof (union iseq_inline_storage_entry ) * body -> is_size );
1164
-
1165
- if (job -> cc_entries == NULL && job -> is_entries == NULL ) {
1166
- return (mjit_copy_job_result_t ){ .success_p = true, .cc_entries = NULL , .is_entries = NULL };
1167
- }
1168
-
1169
1150
CRITICAL_SECTION_START (3 , "in copy_cache_from_main_thread" );
1170
1151
job -> finish_p = false; // allow dispatching this job in mjit_copy_job_handler
1171
1152
CRITICAL_SECTION_FINISH (3 , "in copy_cache_from_main_thread" );
1172
1153
1173
1154
if (UNLIKELY (mjit_opts .wait )) {
1174
1155
mjit_copy_job_handler ((void * )job );
1175
- } else {
1176
- if (!rb_workqueue_register (0 , mjit_copy_job_handler , (void * )job )) {
1177
- // Disable dispatching this job in mjit_copy_job_handler while memory allocated by alloca
1178
- // could be expired after finishing this function.
1179
- job -> finish_p = true;
1180
- return (mjit_copy_job_result_t ){ .success_p = false };
1181
- }
1182
-
1183
- CRITICAL_SECTION_START (3 , "in MJIT copy job wait" );
1184
- /* checking `stop_worker_p` too because `RUBY_VM_CHECK_INTS(ec)` may not
1185
- lush mjit_copy_job_handler when EC_EXEC_TAG() is not TAG_NONE, and then
1186
- `stop_worker()` could dead lock with this function. */
1187
- while (!job -> finish_p && !stop_worker_p ) {
1188
- rb_native_cond_wait (& mjit_worker_wakeup , & mjit_engine_mutex );
1189
- verbose (3 , "Getting wakeup from client" );
1190
- }
1191
- CRITICAL_SECTION_FINISH (3 , "in MJIT copy job wait" );
1156
+ return job -> finish_p ;
1192
1157
}
1193
1158
1194
- bool finish_p = job -> finish_p ;
1195
- // Disable dispatching this job in mjit_copy_job_handler while memory allocated by alloca
1196
- // could be expired after finishing this function.
1197
- job -> finish_p = true;
1198
- return (mjit_copy_job_result_t ){ .success_p = finish_p , .cc_entries = job -> cc_entries , .is_entries = job -> is_entries };
1159
+ if (!rb_workqueue_register (0 , mjit_copy_job_handler , (void * )job ))
1160
+ return false;
1161
+ CRITICAL_SECTION_START (3 , "in MJIT copy job wait" );
1162
+ /* checking `stop_worker_p` too because `RUBY_VM_CHECK_INTS(ec)` may not
1163
+ lush mjit_copy_job_handler when EC_EXEC_TAG() is not TAG_NONE, and then
1164
+ `stop_worker()` could dead lock with this function. */
1165
+ while (!job -> finish_p && !stop_worker_p ) {
1166
+ rb_native_cond_wait (& mjit_worker_wakeup , & mjit_engine_mutex );
1167
+ verbose (3 , "Getting wakeup from client" );
1168
+ }
1169
+ CRITICAL_SECTION_FINISH (3 , "in MJIT copy job wait" );
1170
+ return job -> finish_p ;
1199
1171
}
1200
1172
1201
1173
/* The function implementing a worker. It is executed in a separate
@@ -1204,6 +1176,8 @@ copy_cache_from_main_thread(const rb_iseq_t *iseq)
1204
1176
void
1205
1177
mjit_worker (void )
1206
1178
{
1179
+ mjit_copy_job_t * job = & mjit_copy_job ; /* just a shorthand */
1180
+
1207
1181
#ifndef _MSC_VER
1208
1182
if (pch_status == PCH_NOT_READY ) {
1209
1183
make_pch ();
@@ -1230,17 +1204,28 @@ mjit_worker(void)
1230
1204
verbose (3 , "Getting wakeup from client" );
1231
1205
}
1232
1206
unit = get_from_list (& unit_queue );
1207
+ if (unit ) job -> iseq = unit -> iseq ;
1208
+ job -> finish_p = true; // disable dispatching this job in mjit_copy_job_handler while it's being modified
1233
1209
CRITICAL_SECTION_FINISH (3 , "in worker dequeue" );
1234
1210
1235
1211
if (unit ) {
1236
- // Copy mutable values from main threads
1237
- mjit_copy_job_result_t result = copy_cache_from_main_thread (unit -> iseq );
1238
- if (result .success_p == false) {
1239
- continue ; // retry postponed_job failure, or stop worker
1212
+ const struct rb_iseq_constant_body * body = unit -> iseq -> body ;
1213
+ job -> cc_entries = NULL ;
1214
+ if (body -> ci_size > 0 || body -> ci_kw_size > 0 )
1215
+ job -> cc_entries = alloca (sizeof (struct rb_call_cache ) * (body -> ci_size + body -> ci_kw_size ));
1216
+ job -> is_entries = NULL ;
1217
+ if (body -> is_size > 0 )
1218
+ job -> is_entries = alloca (sizeof (union iseq_inline_storage_entry ) * body -> is_size );
1219
+
1220
+ /* Copy ISeq's inline caches values to avoid race condition. */
1221
+ if (job -> cc_entries != NULL || job -> is_entries != NULL ) {
1222
+ if (copy_cache_from_main_thread (job ) == false) {
1223
+ continue ; /* retry postponed_job failure, or stop worker */
1224
+ }
1240
1225
<
957B
div class="diff-text-inner"> }
1241
1226
1242
1227
// JIT compile
1243
- mjit_func_t func = convert_unit_to_func (unit , result . cc_entries , result . is_entries );
1228
+ mjit_func_t func = convert_unit_to_func (unit , job -> cc_entries , job -> is_entries );
1244
1229
1245
1230
CRITICAL_SECTION_START (3 , "in jit func replace" );
1246
1231
while (in_gc ) { /* Make sure we're not GC-ing when touching ISeq */
@@ -1263,6 +1248,10 @@ mjit_worker(void)
1263
1248
}
1264
1249
}
1265
1250
1251
+ // Disable dispatching this job in mjit_copy_job_handler while memory allocated by alloca
1252
+ // could be expired after finishing this function.
1253
+ job -> finish_p = true;
1254
+
1266
1255
// To keep mutex unlocked when it is destroyed by mjit_finish, don't wrap CRITICAL_SECTION here.
1267
1256
worker_stopped = true;
1268
1257
}
0 commit comments