Permalink
Browse files

use 1-bit flag to reduce virtual calls to gc_mark() for objects that …

…do not have gc_object members
  • Loading branch information...
1 parent 3fb96b9 commit 667d462f7e00e033f07b7f21bc16bb6fc7dd4681 @kazuho committed Mar 23, 2012
Showing with 23 additions and 15 deletions.
  1. +7 −6 picogc.cpp
  2. +15 −8 picogc.h
  3. +1 −1 test.cpp
View
@@ -53,7 +53,7 @@ gc::~gc()
*old_objs_end_ = reinterpret_cast<intptr_t>(new_objs_);
// free all objs
for (gc_object* o = old_objs_; o != NULL; ) {
- gc_object* next = reinterpret_cast<gc_object*>(o->next_ & ~1);
+ gc_object* next = reinterpret_cast<gc_object*>(o->next_ & ~FLAG_MASK);
o->gc_destroy();
o = next;
}
@@ -93,7 +93,8 @@ void gc::_mark()
gc_object* o = pending_.back();
pending_.pop_back();
// request deferred marking of the properties
- o->gc_mark(this);
+ if ((o->next_ & FLAG_HAS_GC_MEMBERS) != 0)
+ o->gc_mark(this);
}
emitter_->mark_end(this);
@@ -107,16 +108,16 @@ void gc::_sweep()
intptr_t* ref = reinterpret_cast<intptr_t*>(&old_objs_);
for (gc_object* obj = old_objs_; obj != NULL; ) {
intptr_t next = obj->next_;
- if ((next & 1) != 0) {
+ if ((next & FLAG_MARKED) != 0) {
// alive, clear the mark and connect to the list
- next &= ~1;
- *ref = reinterpret_cast<intptr_t>(obj);
+ next &= ~FLAG_MARKED;
+ *ref = reinterpret_cast<intptr_t>(obj) | (*ref & FLAG_HAS_GC_MEMBERS);
ref = &obj->next_;
} else {
// dead, destroy
obj->gc_destroy();
}
- obj = reinterpret_cast<gc_object*>(next);
+ obj = reinterpret_cast<gc_object*>(next & ~FLAG_MASK);
}
*ref = (intptr_t) NULL;
old_objs_end_ = ref;
View
@@ -38,6 +38,12 @@ extern "C" {
namespace picogc {
+ enum {
+ FLAG_MARKED = 1,
+ FLAG_HAS_GC_MEMBERS = 2,
+ FLAG_MASK = 3
+ };
+
class gc;
class gc_root;
class gc_object;
@@ -112,7 +118,7 @@ namespace picogc {
~gc();
void* allocate(size_t sz);
void trigger_gc();
- void _register(gc_object* obj);
+ void _register(gc_object* obj, bool has_gc_members);
template <typename T> void mark(member<T>& _obj);
void _mark_object(gc_object* obj);
void _register(gc_root* root);
@@ -151,7 +157,7 @@ namespace picogc {
gc_object(const gc_object&); // = delete;
gc_object& operator=(const gc_object&); // = delete;
protected:
- gc_object();
+ gc_object(bool has_gc_members);
~gc_object() {}
virtual void gc_destroy() = 0;
virtual void gc_mark(picogc::gc* gc) {}
@@ -226,9 +232,10 @@ namespace picogc {
return p;
}
- inline void gc::_register(gc_object* obj)
+ inline void gc::_register(gc_object* obj, bool has_gc_members)
{
- obj->next_ = reinterpret_cast<intptr_t>(new_objs_);
+ obj->next_ = reinterpret_cast<intptr_t>(new_objs_)
+ | (has_gc_members ? FLAG_HAS_GC_MEMBERS : 0);
new_objs_ = obj;
// NOTE: not marked
}
@@ -238,10 +245,10 @@ namespace picogc {
if (obj == NULL)
return;
// return if already marked
- if ((obj->next_ & 1) != 0)
+ if ((obj->next_ & FLAG_MARKED) != 0)
return;
// mark
- obj->next_ |= 1;
+ obj->next_ |= FLAG_MARKED;
// push to the mark stack
pending_.push_back(obj);
}
@@ -252,9 +259,9 @@ namespace picogc {
_mark_object(obj);
}
- inline gc_object::gc_object()
+ inline gc_object::gc_object(bool has_gc_members)
{
- scope::top()->_register(this);
+ scope::top()->_register(this, has_gc_members);
}
inline void* gc_object::operator new(size_t sz)
View
@@ -8,7 +8,7 @@ struct Label : public picogc::gc_object {
typedef picogc::gc_object super;
string label_;
picogc::member<Label> linked_;
- Label(const string& label) : label_(label), linked_(NULL) {}
+ Label(const string& label) : super(true), label_(label), linked_(NULL) {}
virtual void gc_mark(picogc::gc* gc) {
super::gc_mark(gc);
gc->mark(linked_);

0 comments on commit 667d462

Please sign in to comment.