Skip to content

Commit

Permalink
[gc_heap] First cut of StackRoots object.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Chu committed Nov 13, 2020
1 parent 824b0ef commit 07ea4ce
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 5 deletions.
20 changes: 20 additions & 0 deletions mycpp/gc_heap.h
Expand Up @@ -223,6 +223,26 @@ class Heap {
// - For some applications, this can be thread_local rather than global.
extern Heap gHeap;

class StackRoots {
public:
StackRoots(std::initializer_list<void*> roots) {
n_ = roots.size();
for (auto root : roots) { // can't use roots[i]
gHeap.PushRoot(root);
}
}

~StackRoots() {
// TODO: optimize this
for (int i = 0; i < n_; ++i) {
gHeap.PopRoot();
}
}

private:
int n_;
};

template <typename T>
class Local {
// We can garbage collect at any Alloc() invocation, so we need a level of
Expand Down
65 changes: 65 additions & 0 deletions mycpp/gc_heap_test.cc
Expand Up @@ -514,6 +514,69 @@ TEST local_test() {
PASS();
}

class Base {
public:
Base(int a) : a_(a) {
}
int a_;
};

class Derived : public Base {
public:
Derived(int a, int b) : Base(a), b_(b) {
}
int b_;
};

int base_func(Base* base) {
return base->a_;
}

int base_func_local(Local<Base> base) {
return base->a_;
}

TEST variance_test() {
Base i1(5);
log("i1.a_ = %d", i1.a_);

Derived i2(3, 4);
log("i2 = %d %d", i2.a_, i2.b_);

ASSERT_EQ(5, base_func(&i1));
ASSERT_EQ(3, base_func(&i2));

Local<Base> h1 = &i1;
// Does NOT work
// Local<Base> h2 = i2;
Local<Derived> h2 = &i2;

ASSERT_EQ(5, base_func_local(h1));
// Variance doesn't work! Bad! So we don't want to use Local<T>.
// ASSERT_EQ(3, base_func_local(h2));

PASS();
}

TEST stack_roots_test() {
Str* s;
List<int>* L;

gHeap.Init(kInitialSize); // reset the whole thing

ASSERT_EQ(0, gHeap.roots_top_);

gc_heap::StackRoots _roots({&s, &L});

s = NewStr("foo");
// L = nullptr;
L = Alloc<List<int>>();

ASSERT_EQ_FMT(2, gHeap.roots_top_, "%d");

PASS();
}

void ShowSlab(Obj* obj) {
assert(obj->heap_tag_ == Tag::Scanned);
auto slab = reinterpret_cast<Slab<void*>*>(obj);
Expand Down Expand Up @@ -569,6 +632,8 @@ int main(int argc, char** argv) {
RUN_TEST(slab_trace_test);
RUN_TEST(global_trace_test);
RUN_TEST(local_test);
RUN_TEST(variance_test);
RUN_TEST(stack_roots_test);
RUN_TEST(field_mask_test);

GREATEST_MAIN_END(); /* display results */
Expand Down
9 changes: 5 additions & 4 deletions mycpp/my_runtime.cc
Expand Up @@ -40,8 +40,8 @@ Str* Str::replace(Str* old, Str* new_str) {
return this; // Reuse the string if there were no replacements
}

int length = len(this) - (replace_count * len(old)) +
(replace_count * len(new_str));
int length =
len(this) - (replace_count * len(old)) + (replace_count * len(new_str));

char* result = static_cast<char*>(malloc(length + 1)); // +1 for NUL

Expand All @@ -65,8 +65,9 @@ Str* Str::replace(Str* old, Str* new_str) {

p_this = next + len(old);
}
memcpy(p_result, p_this, data_ + len(this) - p_this); // Copy the rest of 'this'
result[length] = '\0'; // NUL terminate
memcpy(p_result, p_this,
data_ + len(this) - p_this); // Copy the rest of 'this'
result[length] = '\0'; // NUL terminate

// NOTE: This copies the buffer 'result'
return NewStr(result);
Expand Down
2 changes: 1 addition & 1 deletion mycpp/my_runtime_test.cc
Expand Up @@ -2,8 +2,8 @@
#include <stdarg.h> // va_list, etc.
#include <stdio.h> // vprintf

#include "greatest.h"
#include "gc_heap.h"
#include "greatest.h"
#include "my_runtime.h"

using gc_heap::gHeap;
Expand Down

0 comments on commit 07ea4ce

Please sign in to comment.