Skip to content

Commit a0c31a6

Browse files
committed
Create an explicit immutable region.
1 parent 5fb69bd commit a0c31a6

4 files changed

Lines changed: 21 additions & 6 deletions

File tree

src/rt/objects/dyn_object.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,19 +163,21 @@ namespace rt::objects
163163
return false;
164164

165165
auto r = get_region(obj);
166+
// If we are freezing something primitive it doesn't have a region
167+
// So need to check for nullptr region here.
166168
if (r != nullptr)
167169
{
168170
get_region(obj)->objects.erase(obj);
169171
}
170-
obj->region.set_tag(ImmutableTag);
172+
obj->region.set_ptr(immutable_region);
171173

172174
return !obj->is_cown();
173175
});
174176
}
175177

176178
bool is_immutable()
177179
{
178-
return region.get_tag() == ImmutableTag;
180+
return region.get_ptr() == immutable_region;
179181
}
180182

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

src/rt/objects/region.cc

Lines changed: 10 additions & 4 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,7 @@ namespace rt::objects
7574
}
7675

7776
// Handle immutable case
78-
if (target == nullptr)
77+
if (target == immutable_region)
7978
return;
8079

8180
if (src == get_local_region())
@@ -94,6 +93,7 @@ namespace rt::objects
9493

9594
void add_region_reference(Region* src_region, DynObject* target)
9695
{
96+
assert(target != nullptr);
9797
if (target->is_immutable())
9898
return;
9999

@@ -118,6 +118,7 @@ namespace rt::objects
118118

119119
void add_reference(DynObject* src, DynObject* target)
120120
{
121+
assert(src != nullptr);
121122
if (target == nullptr)
122123
return;
123124

@@ -149,6 +150,8 @@ namespace rt::objects
149150

150151
void move_reference(DynObject* src, DynObject* dst, DynObject* target)
151152
{
153+
assert(src != nullptr);
154+
assert(dst != nullptr);
152155
if (target == nullptr || target->is_immutable())
153156
return;
154157

@@ -173,6 +176,8 @@ namespace rt::objects
173176
// If in the same region, then just remove the RC, but don't try to collect
174177
// as the whole region is being torndown including any potential cycles.
175178
auto same_region = [](DynObject* src, DynObject* target) {
179+
assert(src != nullptr);
180+
assert(target != nullptr);
176181
return get_region(src) == get_region(target);
177182
};
178183
for (auto& [key, field] : obj->fields)
@@ -190,8 +195,9 @@ namespace rt::objects
190195
remove_reference(obj, old_value);
191196
}
192197

193-
if (same_region(obj, obj->prototype))
198+
if ((obj->prototype != nullptr) && same_region(obj, obj->prototype))
194199
{
200+
// TODO When freeze is no longer immortal, this will need to be updated.
195201
obj->prototype->change_rc(-1);
196202
}
197203
else

src/rt/objects/region.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,6 @@ 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};
182184
} // 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)