@@ -3207,9 +3207,83 @@ objspace_each_objects(rb_objspace_t *objspace, each_obj_callback *callback, void
3207
3207
objspace_each_exec (protected , & each_obj_data );
3208
3208
}
3209
3209
3210
+ #if USE_MMTK
3211
+ struct rb_mmtk_build_obj_array_data {
3212
+ VALUE * * array_ptr ;
3213
+ size_t len ;
3214
+ size_t capa ;
3215
+ };
3216
+
3217
+ void
3218
+ rb_mmtk_build_obj_array_i (MMTk_ObjectReference object , void * data )
3219
+ {
3220
+ struct rb_mmtk_build_obj_array_data * build_array_data = (struct rb_mmtk_build_obj_array_data * )data ;
3221
+ VALUE * array = * build_array_data -> array_ptr ;
3222
+ size_t len = build_array_data -> len ;
3223
+ size_t capa = build_array_data -> capa ;
3224
+ if (len == capa ) {
3225
+ size_t new_capa = capa * 2 ;
3226
+ VALUE * new_array = (VALUE * )realloc (array , sizeof (VALUE ) * new_capa );
3227
+ * build_array_data -> array_ptr = new_array ;
3228
+ build_array_data -> capa = new_capa ;
3229
+ array = new_array ;
3230
+ }
3231
+
3232
+ RUBY_ASSERT (build_array_data -> len < build_array_data -> capa );
3233
+
3234
+ array [len ] = (VALUE )object ;
3235
+ build_array_data -> len = len + 1 ;
3236
+ }
3237
+
3238
+ void
3239
+ rb_mmtk_each_objects_safe (each_obj_callback * callback , void * data )
3240
+ {
3241
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer ();
3242
+
3243
+ // Build an array of object references.
3244
+ const size_t initial_capacity = 512 ;
3245
+ VALUE * array = (VALUE * )malloc (sizeof (VALUE ) * initial_capacity );
3246
+ struct rb_mmtk_build_obj_array_data build_array_data = {
3247
+ .array_ptr = & array ,
3248
+ .len = 0 ,
3249
+ .capa = initial_capacity ,
3250
+ };
3251
+ mmtk_enumerate_objects (rb_mmtk_build_obj_array_i , & build_array_data );
3252
+
3253
+ // Root the array.
3254
+ rb_imemo_tmpbuf_set_ptr (tmpbuf , array );
3255
+ ((rb_imemo_tmpbuf_t * )tmpbuf )-> cnt = build_array_data .len ;
3256
+
3257
+ RUBY_DEBUG_LOG ("Begin enumerating %zu objects\n" , build_array_data .len );
3258
+
3259
+ // Now enumerate objects
3260
+ for (size_t i = 0 ; i < build_array_data .len ; i ++ ) {
3261
+ VALUE object = array [i ];
3262
+ size_t object_size = rb_mmtk_get_object_size (object );
3263
+ uintptr_t object_end = object + object_size ;
3264
+
3265
+ RUBY_DEBUG_LOG ("Enumerating object: %p\n" , (void * )object );
3266
+ callback ((void * )object , (void * )object_end , object_size , data );
3267
+ RB_GC_GUARD (object );
3268
+
3269
+ // Clear the element so that it no longer pins the object if it dies.
3270
+ array [i ] = 0 ;
3271
+ }
3272
+
3273
+ RUBY_DEBUG_LOG ("End enumerating %zu objects\n" , build_array_data .len );
3274
+
3275
+ RB_GC_GUARD (tmpbuf );
3276
+ }
3277
+ #endif
3278
+
3210
3279
void
3211
3280
rb_gc_impl_each_objects (void * objspace_ptr , each_obj_callback * callback , void * data )
3212
3281
{
3282
+ WHEN_USING_MMTK ({
3283
+ rb_mmtk_each_objects_safe (callback , data );
3284
+ return ;
3285
+ })
3286
+
3213
3287
objspace_each_objects (objspace_ptr , callback , data , TRUE);
3214
3288
}
3215
3289
0 commit comments