Skip to content

Commit 6934a6f

Browse files
committed
Some refactorings
1 parent 143be38 commit 6934a6f

9 files changed

Lines changed: 287 additions & 255 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ set(CMAKE_CXX_STANDARD 20)
2929
add_library(
3030
rt OBJECT
3131
src/rt/rt.cc
32+
src/rt/objects/region.cc
3233
src/rt/ui/mermaid.cc
3334
src/rt/core/builtin.cc
3435
)

src/rt/core.h

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
1-
#include "objects/dyn_object.h"
1+
#include "objects/prototype_object.h"
22
#include "rt.h"
33

44
#include <map>
55

66
namespace rt::core
77
{
8-
class PrototypeObject : public objects::DynObject
9-
{
10-
std::string name;
11-
12-
public:
13-
PrototypeObject(std::string name_, objects::DynObject* prototype = nullptr)
14-
: objects::DynObject(prototype), name(name_)
15-
{}
16-
17-
std::string get_name() override
18-
{
19-
std::stringstream stream;
20-
stream << "[" << name << "]";
21-
return stream.str();
22-
}
23-
};
8+
using PrototypeObject = objects::PrototypeObject;
249

2510
inline PrototypeObject* framePrototypeObject()
2611
{
@@ -39,7 +24,7 @@ namespace rt::core
3924
if (parent_frame)
4025
{
4126
auto old_value = this->set(objects::ParentField, parent_frame);
42-
add_reference(this, parent_frame);
27+
objects::add_reference(this, parent_frame);
4328
assert(!old_value);
4429
}
4530
}

src/rt/core/builtin.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace rt::core
2727
{
2828
auto value = stack->back();
2929
mermaid->add_always_hide(value);
30-
remove_reference(frame, value);
30+
rt::remove_reference(frame, value);
3131
stack->pop_back();
3232
}
3333

@@ -42,7 +42,7 @@ namespace rt::core
4242
auto value = stack->back();
4343
mermaid->remove_unreachable_hide(value);
4444
mermaid->remove_always_hide(value);
45-
remove_reference(frame, value);
45+
rt::remove_reference(frame, value);
4646
stack->pop_back();
4747
}
4848

@@ -66,7 +66,7 @@ namespace rt::core
6666

6767
auto region = pop(stack, "region for cown creation");
6868
auto cown = make_cown(region);
69-
move_reference(frame, cown, region);
69+
rt::move_reference(frame, cown, region);
7070

7171
return cown;
7272
});
@@ -89,7 +89,7 @@ namespace rt::core
8989

9090
auto value = pop(stack, "object to freeze");
9191
freeze(value);
92-
remove_reference(frame, value);
92+
rt::remove_reference(frame, value);
9393

9494
return std::nullopt;
9595
});
@@ -98,8 +98,8 @@ namespace rt::core
9898
assert(args == 1);
9999

100100
auto value = pop(stack, "region source");
101-
create_region(value);
102-
remove_reference(frame, value);
101+
rt::create_region(value);
102+
rt::remove_reference(frame, value);
103103

104104
return std::nullopt;
105105
});

src/rt/objects/dyn_object.h

Lines changed: 14 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)