@@ -27,6 +27,11 @@ namespace rt::objects
2727 const std::string PrototypeField{" __proto__" };
2828 const std::string ParentField{" __parent__" };
2929
30+ Region* get_region (DynObject* obj);
31+
32+ Region* get_local_region ();
33+ void set_local_region (Region* region);
34+
3035 // Representation of objects
3136 class DynObject
3237 {
@@ -39,8 +44,8 @@ namespace rt::objects
3944 friend void dealloc (DynObject* obj);
4045 template <typename Pre, typename Post>
4146 friend void visit (Edge, Pre, Post);
42-
43- thread_local static RegionPointer local_region ;
47+ friend Region* get_region (DynObject* obj);
48+ friend void add_to_region (Region* r, DynObject* target) ;
4449
4550 // TODO: Not concurrency safe
4651 inline static size_t count{0 };
@@ -53,68 +58,7 @@ namespace rt::objects
5358
5459 std::map<std::string, DynObject*> fields{};
5560
56- static Region* get_region (DynObject* obj)
57- {
58- if ((obj == nullptr ) || obj->is_immutable ())
59- return nullptr ;
60- return obj->region .get_ptr ();
61- }
62-
63- bool is_local_object ()
64- {
65- return region.get_ptr () == get_local_region ();
66- }
67-
68- static void remove_region_reference (Region* src, Region* target)
69- {
70- if (src == target)
71- {
72- std::cout << " Same region, no need to do anything" << std::endl;
73- return ;
74- }
75-
76- // Handle immutable case
77- if (target == nullptr )
78- return ;
79-
80- if (src == get_local_region ())
81- {
82- Region::dec_lrc (target);
83- return ;
84- }
85-
86- if (src)
87- {
88- assert (target->parent == src);
89- target->parent = nullptr ;
90- }
91- return ;
92- }
93-
94- static void add_region_reference (Region* src_region, DynObject* target)
95- {
96- if (target->is_immutable ())
97- return ;
98-
99- auto target_region = get_region (target);
100- if (src_region == target_region)
101- return ;
102-
103- if (src_region == get_local_region ())
104- {
105- Region::inc_lrc (target_region);
106- return ;
107- }
108-
109- if (target_region == get_local_region ())
110- {
111- target->add_to_region (src_region);
112- return ;
113- }
114-
115- Region::set_parent (target_region, src_region);
116- }
117-
61+ public:
11862 size_t change_rc (signed delta)
11963 {
12064 std::cout << " Change RC: " << get_name () << " " << rc << " + " << delta
@@ -134,50 +78,6 @@ namespace rt::objects
13478 delta;
13579 }
13680
137- void add_to_region (Region* r)
138- {
139- size_t internal_references{0 };
140- size_t rc_of_added_objects{0 };
141- visit (this , [&](Edge e) {
142- auto obj = e.target ;
143- if (obj == nullptr || obj->is_immutable ())
144- return false ;
145-
146- if (obj->is_local_object ())
147- {
148- std::cout << " Adding object to region: " << obj->get_name ()
149- << " rc = " << obj->rc << std::endl;
150- rc_of_added_objects += obj->rc ;
151- internal_references++;
152- obj->region = {r};
153- get_local_region ()->objects .erase (obj);
154- r->objects .insert (obj);
155- return true ;
156- }
157-
158- auto obj_region = get_region (obj);
159- if (obj_region == r)
160- {
161- std::cout << " Adding internal reference to object: "
162- << obj->get_name () << std::endl;
163- internal_references++;
164- return false ;
165- }
166-
167- Region::set_parent (obj_region, r);
168- Region::dec_lrc (obj_region);
169- return false ;
170- });
171- r->local_reference_count += rc_of_added_objects - internal_references;
172-
173- std::cout << " Added " << rc_of_added_objects - internal_references
174- << " to LRC of region" << std::endl;
175- std::cout << " Region LRC: " << r->local_reference_count << std::endl;
176- std::cout << " Internal references found: " << internal_references
177- << std::endl;
178- }
179-
180- public:
18181 // prototype is borrowed, the caller does not need to provide an RC.
18282 DynObject (DynObject* prototype_ = nullptr , bool first_frame = false )
18383 : prototype(prototype_)
@@ -194,7 +94,7 @@ namespace rt::objects
19494 if (prototype != nullptr )
19595 {
19696 // prototype->change_rc(1);
197- add_reference (this , prototype);
97+ objects:: add_reference (this , prototype);
19898 }
19999 std::cout << " Allocate: " << this << std::endl;
200100 }
@@ -224,6 +124,11 @@ namespace rt::objects
224124 std::cout << " Deallocate: " << get_name () << std::endl;
225125 }
226126
127+ size_t get_rc ()
128+ {
129+ return rc;
130+ }
131+
227132 // / @brief The string representation of this value to
228133 // / TODO remove virtual once we have primitive functions.
229134 virtual std::string get_name ()
@@ -333,127 +238,17 @@ namespace rt::objects
333238 return prototype;
334239 }
335240
336- static void add_reference (DynObject* src, DynObject* target)
337- {
338- if (target == nullptr )
339- return ;
340-
341- target->change_rc (1 );
342-
343- auto src_region = get_region (src);
344- add_region_reference (src_region, target);
345- }
346-
347- static void
348- remove_reference (DynObject* src_initial, DynObject* old_dst_initial)
349- {
350- visit (
351- {src_initial, " " , old_dst_initial},
352- [&](Edge e) {
353- if (e.target == nullptr )
354- return false ;
355-
356- std::cout << " Remove reference from: " << e.src ->get_name () << " to "
357- << e.target ->get_name () << std::endl;
358- bool result = e.target ->change_rc (-1 ) == 0 ;
359-
360- remove_region_reference (get_region (e.src ), get_region (e.target ));
361- return result;
362- },
363- [&](DynObject* obj) { delete obj; });
364-
365- Region::collect ();
366- }
367-
368- static void
369- move_reference (DynObject* src, DynObject* dst, DynObject* target)
370- {
371- if (target == nullptr || target->is_immutable ())
372- return ;
373-
374- auto src_region = get_region (src);
375- auto dst_region = get_region (dst);
376-
377- if (src_region == dst_region)
378- return ;
379-
380- auto target_region = get_region (target);
381-
382- add_region_reference (dst_region, target);
383- // Note that target_region and get_region(target) are not necessarily the
384- // same.
385- remove_region_reference (src_region, target_region);
386- }
387-
388- void create_region ()
389- {
390- Region* r = new Region ();
391- add_to_region (r);
392- // Add root reference as external.
393- r->local_reference_count ++;
394- }
395-
396241 static size_t get_count ()
397242 {
398243 return count;
399244 }
400245
401- static Region* get_local_region ()
402- {
403- return local_region;
404- }
405-
406246 static std::set<DynObject*> get_objects ()
407247 {
408248 return all_objects;
409249 }
410250 };
411251
412- inline void destruct (DynObject* obj)
413- {
414- // Called from the region destructor.
415- // Remove all references to other objects.
416- // If in the same region, then just remove the RC, but don't try to collect
417- // as the whole region is being torndown including any potential cycles.
418- auto same_region = [](DynObject* src, DynObject* target) {
419- return DynObject::get_region (src) == DynObject::get_region (target);
420- };
421- for (auto & [key, field] : obj->fields )
422- {
423- if (field == nullptr )
424- continue ;
425- if (same_region (obj, field))
426- {
427- // Same region just remove the rc, but don't try to collect.
428- field->change_rc (-1 );
429- continue ;
430- }
431-
432- auto old_value = obj->set (key, nullptr );
433- remove_reference (obj, old_value);
434- }
435-
436- if (same_region (obj, obj->prototype ))
437- {
438- obj->prototype ->change_rc (-1 );
439- }
440- else
441- {
442- auto old_value = obj->set_prototype (nullptr );
443- remove_reference (obj, old_value);
444- }
445- }
446-
447- inline void dealloc (DynObject* obj)
448- {
449- // Called from the region destructor.
450- // So remove from region if in one.
451- // This ensures we don't try to remove it from the set that is being
452- // iterated.
453- obj->region = nullptr ;
454- delete obj;
455- }
456-
457252 template <typename Pre, typename Post>
458253 inline void visit (Edge e, Pre pre , Post post )
459254 {
0 commit comments