Skip to content

Commit 899f9a6

Browse files
authored
Merge pull request #41 from mjp41/immutable_region
Create an explicit immutable and cown region.
2 parents 03b22b2 + 8b67a92 commit 899f9a6

5 files changed

Lines changed: 43 additions & 33 deletions

File tree

src/rt/core.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace rt::core
1515

1616
class FrameObject : public objects::DynObject
1717
{
18-
FrameObject() : objects::DynObject(framePrototypeObject(), true) {}
18+
FrameObject() : objects::DynObject(framePrototypeObject()) {}
1919

2020
public:
2121
FrameObject(objects::DynObject* parent_frame)
@@ -58,8 +58,7 @@ namespace rt::core
5858
class FuncObject : public objects::DynObject
5959
{
6060
public:
61-
FuncObject(objects::DynObject* prototype_, bool global = false)
62-
: objects::DynObject(prototype_, global)
61+
FuncObject(objects::DynObject* prototype_) : objects::DynObject(prototype_)
6362
{}
6463
};
6564

@@ -197,7 +196,7 @@ namespace rt::core
197196
{
198197
public:
199198
CownObject(objects::DynObject* region)
200-
: objects::DynObject(cownPrototypeObject())
199+
: objects::DynObject(cownPrototypeObject(), objects::cown_region)
201200
{
202201
// FIXME: Add once regions are reified
203202
// assert(
@@ -232,11 +231,6 @@ namespace rt::core
232231
// always be opaque.
233232
return true;
234233
}
235-
236-
bool is_cown() override
237-
{
238-
return true;
239-
}
240234
};
241235

242236
inline std::set<objects::DynObject*>* globals()

src/rt/objects/dyn_object.h

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,16 @@ namespace rt::objects
7979
}
8080

8181
// prototype is borrowed, the caller does not need to provide an RC.
82-
DynObject(DynObject* prototype_ = nullptr, bool first_frame = false)
82+
DynObject(
83+
DynObject* prototype_ = nullptr,
84+
Region* containing_region = get_local_region())
8385
: prototype(prototype_)
8486
{
85-
if (!first_frame)
86-
{
87-
count++;
88-
all_objects.insert(this);
89-
auto local_region = get_local_region();
90-
region = local_region;
91-
local_region->objects.insert(this);
92-
}
87+
assert(containing_region != nullptr);
88+
count++;
89+
all_objects.insert(this);
90+
region = containing_region;
91+
containing_region->objects.insert(this);
9392

9493
if (prototype != nullptr)
9594
{
@@ -149,33 +148,30 @@ namespace rt::objects
149148
return false;
150149
}
151150

152-
virtual bool is_cown()
151+
bool is_cown()
153152
{
154-
return false;
153+
return region.get_ptr() == objects::cown_region;
155154
}
156155

157156
void freeze()
158157
{
159158
// TODO SCC algorithm
160159
visit(this, [](Edge e) {
161160
auto obj = e.target;
162-
if (!obj || obj->is_immutable())
161+
if (!obj || obj->is_immutable() || obj->is_cown())
163162
return false;
164163

165164
auto r = get_region(obj);
166-
if (r != nullptr)
167-
{
168-
get_region(obj)->objects.erase(obj);
169-
}
170-
obj->region.set_tag(ImmutableTag);
165+
get_region(obj)->objects.erase(obj);
166+
obj->region.set_ptr(immutable_region);
171167

172-
return !obj->is_cown();
168+
return true;
173169
});
174170
}
175171

176172
bool is_immutable()
177173
{
178-
return region.get_tag() == ImmutableTag;
174+
return region.get_ptr() == immutable_region;
179175
}
180176

181177
[[nodiscard]] DynObject* get(std::string name)

src/rt/objects/region.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ namespace rt::objects
44
{
55
Region* get_region(DynObject* obj)
66
{
7-
if ((obj == nullptr) || obj->is_immutable())
8-
return nullptr;
7+
assert(obj != nullptr);
98
return obj->region.get_ptr();
109
}
1110

@@ -75,7 +74,11 @@ namespace rt::objects
7574
}
7675

7776
// Handle immutable case
78-
if (target == nullptr)
77+
if (target == immutable_region)
78+
return;
79+
80+
// Handle cown case
81+
if (target == cown_region)
7982
return;
8083

8184
if (src == get_local_region())
@@ -94,6 +97,7 @@ namespace rt::objects
9497

9598
void add_region_reference(Region* src_region, DynObject* target)
9699
{
100+
assert(target != nullptr);
97101
if (target->is_immutable())
98102
return;
99103

@@ -118,6 +122,7 @@ namespace rt::objects
118122

119123
void add_reference(DynObject* src, DynObject* target)
120124
{
125+
assert(src != nullptr);
121126
if (target == nullptr)
122127
return;
123128

@@ -149,7 +154,9 @@ namespace rt::objects
149154

150155
void move_reference(DynObject* src, DynObject* dst, DynObject* target)
151156
{
152-
if (target == nullptr || target->is_immutable())
157+
assert(src != nullptr);
158+
assert(dst != nullptr);
159+
if (target == nullptr || target->is_immutable() || target->is_cown())
153160
return;
154161

155162
auto src_region = get_region(src);
@@ -173,6 +180,8 @@ namespace rt::objects
173180
// If in the same region, then just remove the RC, but don't try to collect
174181
// as the whole region is being torndown including any potential cycles.
175182
auto same_region = [](DynObject* src, DynObject* target) {
183+
assert(src != nullptr);
184+
assert(target != nullptr);
176185
return get_region(src) == get_region(target);
177186
};
178187
for (auto& [key, field] : obj->fields)
@@ -190,8 +199,9 @@ namespace rt::objects
190199
remove_reference(obj, old_value);
191200
}
192201

193-
if (same_region(obj, obj->prototype))
202+
if ((obj->prototype != nullptr) && same_region(obj, obj->prototype))
194203
{
204+
// TODO When freeze is no longer immortal, this will need to be updated.
195205
obj->prototype->change_rc(-1);
196206
}
197207
else

src/rt/objects/region.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,9 @@ namespace rt::objects
179179
// encode special regions.
180180
using RegionPointer = utils::TaggedPointer<Region>;
181181

182+
inline Region immutable_region_impl;
183+
inline constexpr Region* immutable_region{&immutable_region_impl};
184+
185+
inline Region cown_region_impl;
186+
inline constexpr Region* cown_region{&cown_region_impl};
182187
} // namespace rt::objects

src/utils/tagged_pointer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ namespace utils
4545
ptr = (ptr & ~0x3) | tag;
4646
}
4747

48+
void set_ptr(T* new_ptr)
49+
{
50+
ptr = (ptr & 0x3) | reinterpret_cast<uintptr_t>(new_ptr);
51+
}
52+
4853
void add_tag(uintptr_t tag)
4954
{
5055
assert(tag < 4);

0 commit comments

Comments
 (0)