1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-17 07:52:43 +01:00

Checkpoint

This commit is contained in:
Eelco Dolstra 2019-04-22 23:25:47 +02:00
parent 4237414f4d
commit 7c716b4c49
27 changed files with 596 additions and 440 deletions

View file

@ -104,94 +104,6 @@ struct PtrList : Object
static Size wordsFor(Size size) { return 1 + size; }
};
template<class T>
struct Ptr
{
Ptr * prev = nullptr, * next = nullptr;
T * value = nullptr;
Ptr() { }
Ptr(Ptr * next, T * value) : next(next), value(value)
{
assert(value);
assert(next == next->prev->next);
prev = next->prev;
next->prev = this;
prev->next = this;
}
Ptr(const Ptr & p)
{
if (p.value) {
auto & p2 = const_cast<Ptr &>(p);
value = p2.value;
next = &p2;
prev = p2.prev;
prev->next = this;
p2.prev = this;
}
}
Ptr(Ptr && p)
{
*this = std::move(p);
}
Ptr & operator =(Ptr && p)
{
reset();
if (p.value) {
value = p.value;
next = p.next;
prev = p.prev;
p.value = nullptr;
prev->next = this;
next->prev = this;
}
return *this;
}
Ptr & operator =(const Ptr & p)
{
throw Error("NOT IMPLEMENTED = PTR &");
}
~Ptr()
{
reset();
}
void reset()
{
if (value) {
assert(next);
assert(prev);
assert(next->prev == this);
next->prev = prev;
assert(prev->next == this);
prev->next = next;
value = nullptr;
}
}
T * operator ->()
{
return value;
}
operator T * ()
{
return value;
}
operator T & ()
{
assert(value);
return *value;
}
};
struct Free : Object
{
Free * next;
@ -204,6 +116,12 @@ struct Free : Object
void setSize(Size size) { assert(size >= 1); setMisc(size); }
};
template<class T>
struct Ptr;
template<class T>
struct Root;
struct GC
{
@ -212,6 +130,15 @@ private:
Ptr<Object> * frontSentinel;
Ptr<Object> * backSentinel;
Root<Object> * frontRootSentinel;
Root<Object> * backRootSentinel;
template<class T>
friend class Ptr;
template<class T>
friend class Root;
struct Arena
{
Size size; // in words
@ -317,18 +244,17 @@ public:
auto raw = arena.alloc(size);
if (raw) {
auto obj = new (raw) T(args...);
//printError("ALLOC %x", obj);
return Ptr<T>((Ptr<T> *) frontSentinel->next, obj);
return obj;
}
}
if (i == 0) {
printError("allocation of %d bytes failed, GCing...", size * WORD_SIZE);
debug("allocation of %d bytes failed, GCing...", size * WORD_SIZE);
gc();
} else {
Size arenaSize = std::max(arenaList.nextSize, size);
arenaList.nextSize = arenaSize * 2; // FIXME: overflow
printError("allocating arena of %d bytes", arenaSize * WORD_SIZE);
arenaList.nextSize = arenaSize * 1.5; // FIXME: overflow
debug("allocating arena of %d bytes", arenaSize * WORD_SIZE);
arenaList.arenas.emplace_back(arenaSize);
}
}
@ -339,8 +265,159 @@ public:
void gc();
bool isObject(void * p);
void assertObject(void * p);
};
extern GC gc;
template<class T>
struct Ptr
{
private:
friend class GC;
Ptr * prev = nullptr, * next = nullptr;
T * value = nullptr;
void link()
{
prev = (Ptr *) gc.frontSentinel;
next = prev->next;
next->prev = this;
prev->next = this;
}
public:
Ptr() {
link();
}
Ptr(T * value) : value(value)
{
link();
}
Ptr(const Ptr & p)
{
auto & p2 = const_cast<Ptr &>(p);
value = p2.value;
next = &p2;
prev = p2.prev;
prev->next = this;
p2.prev = this;
}
Ptr(Ptr && p)
{
link();
value = p.value;
p.value = nullptr;
}
Ptr & operator =(const Ptr & p)
{
value = p.value;
return *this;
}
Ptr & operator =(Ptr && p)
{
value = p.value;
p.value = nullptr;
return *this;
}
Ptr & operator =(T * v)
{
value = v;
return *this;
}
~Ptr()
{
assert(next);
assert(prev);
assert(next->prev == this);
next->prev = prev;
assert(prev->next == this);
prev->next = next;
}
T * operator ->()
{
return value;
}
T * operator ->() const // FIXME
{
return value;
}
operator T * ()
{
return value;
}
operator T & ()
{
assert(value);
return *value;
}
operator bool() const
{
return value != nullptr;
}
};
template<class T>
struct Root
{
Root * prev = nullptr, * next = nullptr;
T value;
template<typename... Args>
Root(const Args & ... args)
: value{args... }
{
prev = (Root *) gc.frontRootSentinel;
next = prev->next;
next->prev = this;
prev->next = this;
}
Root(const Root & p) = delete;
Root(Root && p) = delete;
Root & operator =(const T & v) { value = v; return *this; }
~Root()
{
assert(next);
assert(prev);
assert(next->prev == this);
next->prev = prev;
assert(prev->next == this);
prev->next = next;
}
T * operator ->()
{
return &value;
}
operator T * ()
{
return &value;
}
operator T & ()
{
return value;
}
};
}