22
33#include <stdbool.h>
44
5+ #include "ruby/assert.h"
6+
57#include "gc/gc.h"
68#include "gc/gc_impl.h"
79#include "gc/mmtk.h"
810
11+ struct objspace {
12+ st_table * id_to_obj_tbl ;
13+ st_table * obj_to_id_tbl ;
14+ unsigned long long next_object_id ;
15+ };
16+
917bool
1018rb_mmtk_is_mutator (void )
1119{
@@ -66,14 +74,24 @@ rb_gc_impl_objspace_alloc(void)
6674 MMTk_Builder * builder = mmtk_builder_default ();
6775 mmtk_init_binding (builder , NULL , & ruby_upcalls );
6876
69- return NULL ;
77+ return calloc ( 1 , sizeof ( struct objspace )) ;
7078}
7179
72- static st_table * obj_id_to_obj_table_alloc ( void );
80+ static void objspace_obj_id_init ( struct objspace * objspace );
7381
74- void rb_gc_impl_objspace_init (void * objspace_ptr ) { }
82+ void
83+ rb_gc_impl_objspace_init (void * objspace_ptr )
84+ {
85+ struct objspace * objspace = objspace_ptr ;
7586
76- void rb_gc_impl_objspace_free (void * objspace_ptr ) { }
87+ objspace_obj_id_init (objspace );
88+ }
89+
90+ void
91+ rb_gc_impl_objspace_free (void * objspace_ptr )
92+ {
93+ free (objspace_ptr );
94+ }
7795
7896void *
7997rb_gc_impl_ractor_cache_alloc (void * objspace_ptr )
@@ -345,8 +363,85 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr)
345363}
346364
347365// Object ID
348- VALUE rb_gc_impl_object_id (void * objspace_ptr , VALUE obj ) { }
349- VALUE rb_gc_impl_object_id_to_ref (void * objspace_ptr , VALUE object_id ) { }
366+ static int
367+ object_id_cmp (st_data_t x , st_data_t y )
368+ {
369+ if (RB_TYPE_P (x , T_BIGNUM )) {
370+ return !rb_big_eql (x , y );
371+ }
372+ else {
373+ return x != y ;
374+ }
375+ }
376+
377+ static st_index_t
378+ object_id_hash (st_data_t n )
379+ {
380+ return FIX2LONG (rb_hash ((VALUE )n ));
381+ }
382+
383+ #define OBJ_ID_INCREMENT (RUBY_IMMEDIATE_MASK + 1)
384+ #define OBJ_ID_INITIAL (OBJ_ID_INCREMENT)
385+
386+ static const struct st_hash_type object_id_hash_type = {
387+ object_id_cmp ,
388+ object_id_hash ,
389+ };
390+
391+ static void
392+ objspace_obj_id_init (struct objspace * objspace )
393+ {
394+ objspace -> id_to_obj_tbl = st_init_table (& object_id_hash_type );
395+ objspace -> obj_to_id_tbl = st_init_numtable ();
396+ objspace -> next_object_id = OBJ_ID_INITIAL ;
397+ }
398+
399+ VALUE
400+ rb_gc_impl_object_id (void * objspace_ptr , VALUE obj )
401+ {
402+ struct objspace * objspace = objspace_ptr ;
403+
404+ unsigned int lev = rb_gc_vm_lock ();
405+
406+ VALUE id ;
407+ if (st_lookup (objspace -> obj_to_id_tbl , (st_data_t )obj , & id )) {
408+ RUBY_ASSERT (FL_TEST (obj , FL_SEEN_OBJ_ID ));
409+ }
410+ else {
411+ RUBY_ASSERT (!FL_TEST (obj , FL_SEEN_OBJ_ID ));
412+
413+ id = ULL2NUM (objspace -> next_object_id );
414+ objspace -> next_object_id += OBJ_ID_INCREMENT ;
415+
416+ st_insert (objspace -> obj_to_id_tbl , (st_data_t )obj , (st_data_t )id );
417+ st_insert (objspace -> id_to_obj_tbl , (st_data_t )id , (st_data_t )obj );
418+ FL_SET (obj , FL_SEEN_OBJ_ID );
419+ }
420+
421+ rb_gc_vm_unlock (lev );
422+
423+ return id ;
424+ }
425+
426+ VALUE
427+ rb_gc_impl_object_id_to_ref (void * objspace_ptr , VALUE object_id )
428+ {
429+ struct objspace * objspace = objspace_ptr ;
430+
431+ VALUE obj ;
432+ if (st_lookup (objspace -> id_to_obj_tbl , object_id , & obj ) &&
433+ !rb_gc_impl_garbage_object_p (objspace , obj )) {
434+ return obj ;
435+ }
436+
437+ if (rb_funcall (object_id , rb_intern (">=" ), 1 , ULL2NUM (objspace -> next_object_id ))) {
438+ rb_raise (rb_eRangeError , "%+" PRIsVALUE " is not id value" , rb_funcall (object_id , rb_intern ("to_s" ), 1 , INT2FIX (10 )));
439+ }
440+ else {
441+ rb_raise (rb_eRangeError , "%+" PRIsVALUE " is recycled object" , rb_funcall (object_id , rb_intern ("to_s" ), 1 , INT2FIX (10 )));
442+ }
443+ }
444+
350445// Statistics
351446VALUE rb_gc_impl_set_measure_total_time (void * objspace_ptr , VALUE flag ) { }
352447VALUE rb_gc_impl_get_measure_total_time (void * objspace_ptr ) { }
@@ -358,6 +453,12 @@ size_t rb_gc_impl_stat_heap(void *objspace_ptr, VALUE heap_name, VALUE hash_or_s
358453// Miscellaneous
359454size_t rb_gc_impl_obj_flags (void * objspace_ptr , VALUE obj , ID * flags , size_t max ) { }
360455bool rb_gc_impl_pointer_to_heap_p (void * objspace_ptr , const void * ptr ) { }
361- bool rb_gc_impl_garbage_object_p (void * objspace_ptr , VALUE obj ) { }
456+
457+ bool
458+ rb_gc_impl_garbage_object_p (void * objspace_ptr , VALUE obj )
459+ {
460+ return false;
461+ }
462+
362463void rb_gc_impl_set_event_hook (void * objspace_ptr , const rb_event_flag_t event ) { }
363464void rb_gc_impl_copy_attributes (void * objspace_ptr , VALUE dest , VALUE obj ) { }
0 commit comments