Permalink
Browse files

Refactor Scope and drop shared_ptr

  • Loading branch information...
tadeuzagallo committed May 5, 2016
1 parent e928491 commit c7ac75cd3858d859c681b79c57f8d43f02b164b0
Showing with 177 additions and 55 deletions.
  1. +4 −1 compiler/closure.h
  2. +1 −1 compiler/gc.cc
  3. +4 −5 compiler/gc.h
  4. +3 −3 compiler/generator.h
  5. +65 −0 compiler/old_scope.h
  6. +97 −40 compiler/scope.h
  7. +1 −2 compiler/vm.cc
  8. +2 −3 compiler/vm.h
@@ -9,7 +9,10 @@ namespace ceos {
struct Closure {
Function *fn;
std::shared_ptr<Scope<Value>> scope;
Scope *scope;
Closure(Scope *s) : scope(s->inc()) {}
~Closure() { scope->dec(); }
};
}
@@ -3,6 +3,6 @@
namespace ceos {
std::set<uint64_t> GC::roots;
std::set<ScopePtr> GC::scopes;
std::set<Scope *> GC::scopes;
}
@@ -10,7 +10,6 @@
namespace ceos {
typedef std::shared_ptr<Scope<Value>> ScopePtr;
typedef std::vector<std::pair<size_t, void *>> Heap;
class GC {
@@ -52,7 +51,7 @@ namespace ceos {
}
}
static void markScope(ScopePtr &scope, Heap &heap) {
static void markScope(Scope *scope, Heap &heap) {
if (scopes.find(scope) != scopes.end()) {
return;
}
@@ -63,8 +62,8 @@ namespace ceos {
markValue(value, heap);
});
if (scope->parent()) {
markScope(scope->parent(), heap);
if (scope->parent) {
markScope(scope->parent, heap);
}
}
@@ -97,7 +96,7 @@ namespace ceos {
private:
static std::set<uint64_t> roots;
static std::set<ScopePtr> scopes;
static std::set<Scope *> scopes;
};
}
@@ -4,7 +4,7 @@
#include "ast.h"
#include "opcodes.h"
#include "scope.h"
#include "old_scope.h"
#ifndef CEOS_GENERATOR_H
#define CEOS_GENERATOR_H
@@ -14,7 +14,7 @@ namespace ceos {
class Generator {
public:
Generator(std::shared_ptr<AST::Program> ast) : m_ast(ast) {
m_scope = std::make_shared<Scope<std::shared_ptr<AST>>>();
m_scope = std::make_shared<OldScope<std::shared_ptr<AST>>>();
}
std::stringstream &generate(void);
@@ -42,7 +42,7 @@ namespace ceos {
static void printOpcode(std::stringstream &, Opcode::Type);
std::shared_ptr<AST::Program> m_ast;
std::shared_ptr<Scope<std::shared_ptr<AST>>> m_scope;
std::shared_ptr<OldScope<std::shared_ptr<AST>>> m_scope;
std::stringstream m_output;
};
@@ -0,0 +1,65 @@
#include <functional>
#include <iostream>
#include <memory>
#include <unordered_map>
#ifndef CEOS_OLD_SCOPE_H
#define CEOS_OLD_SCOPE_H
namespace ceos {
template<typename T>
class OldScope : public std::enable_shared_from_this<OldScope<T>> {
typedef std::shared_ptr<OldScope<T>> OldScopePtr;
public:
OldScope() {}
inline OldScopePtr create() {
auto s = std::make_shared<OldScope<T>>();
s->m_parent = this->shared_from_this();
return s;
}
inline OldScopePtr create(OldScopePtr parent) {
auto s = std::make_shared<OldScope<T>>();
s->m_parent = parent;
s->m_previous = this->shared_from_this();
return s;
}
inline OldScopePtr restore() {
return m_previous ?: m_parent ?: this->shared_from_this();
}
inline T get(std::string var) {
auto it = m_table.find(var);
if (it != m_table.end()) return it->second;
else if (m_parent) return m_parent->get(var);
else return T();
}
inline void set(std::string key, T value) {
m_table[key] = value;
}
inline void visit(std::function<void(T)> visitor) {
OldScopePtr ptr = this->shared_from_this();
for (auto it : m_table) {
visitor(it.second);
}
}
inline OldScopePtr &parent() {
return m_parent;
}
private:
OldScopePtr m_parent;
OldScopePtr m_previous;
std::unordered_map<std::string, T> m_table;
};
}
#endif
@@ -1,63 +1,120 @@
#include "value.h"
#include <functional>
#include <iostream>
#include <memory>
#include <unordered_map>
#ifndef CEOS_SCOPE_H
#define CEOS_SCOPE_H
namespace ceos {
class ScopeTest;
template<typename T>
class Scope : public std::enable_shared_from_this<Scope<T>> {
typedef std::shared_ptr<Scope<T>> ScopePtr;
namespace {
static inline unsigned hash(const char *str) {
unsigned limit = 16;
unsigned long hash = 5381;
int c;
while ((c = *str++) && --limit) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
}
public:
Scope() {}
struct Scope {
inline ScopePtr create() {
auto s = std::make_shared<Scope<T>>();
s->m_parent = this->shared_from_this();
return s;
}
friend class ScopeTest;
inline ScopePtr create(ScopePtr parent) {
auto s = std::make_shared<Scope<T>>();
s->m_parent = parent;
s->m_previous = this->shared_from_this();
return s;
}
Scope() : Scope(32) {}
inline ScopePtr restore() {
return m_previous ?: m_parent ?: this->shared_from_this();
}
Scope(unsigned size) : cacheSize(size), cacheHash(size - 1) {
refCount = 1;
table = new Entry[cacheSize]();
parent = NULL;
previous = NULL;
}
~Scope() {
if (parent) parent->dec();
if (previous) previous->dec();
}
inline T get(std::string var) {
auto it = m_table.find(var);
if (it != m_table.end()) return it->second;
else if (m_parent) return m_parent->get(var);
else return T();
inline Scope *inc() {
refCount++;
return this;
}
inline void dec() {
if (!--refCount) {
delete this;
}
}
inline Scope *create(Scope *p) {
auto s = new Scope();
s->parent = p->inc();
s->previous = this->inc();
return s;
}
inline void set(std::string key, T value) {
m_table[key] = value;
inline Scope *create() {
auto s = new Scope();
s->parent = this->inc();
s->previous = NULL;
return s;
}
inline Scope *restore() {
auto ret = previous ?: parent ?: this;
if (ret != this) this->dec();
return ret;
}
Value get(char *key) {
unsigned index = hash(key) % cacheSize;
auto begin = index;
while (table[index].key != NULL) {
if (table[index].key == key || strcmp(table[index].key, key) == 0) {
return table[index].value;
}
if ((index = (index + 1) & cacheHash) == begin) break;
}
if (parent) return parent->get(key);
return Value();
}
inline void visit(std::function<void(T)> visitor) {
ScopePtr ptr = this->shared_from_this();
for (auto it : m_table) {
visitor(it.second);
void set(char *key, Value value) {
unsigned index = hash(key) % cacheSize;
auto begin = index;
do {
if (table[index].key == NULL || table[index].key == key) {
table[index].key = key;
table[index].value = value;
return;
}
}
} while((index = (index + 1) & cacheHash) != begin);
throw;
}
inline ScopePtr &parent() {
return m_parent;
inline void visit(std::function<void(Value)> visitor) {
for (unsigned i = 0; i < cacheSize; i++) {
if (table[i].key != NULL) {
visitor(table[i].value);
}
}
}
struct Entry {
char *key;
Value value;
};
Scope *parent;
private:
ScopePtr m_parent;
ScopePtr m_previous;
std::unordered_map<std::string, T> m_table;
private:
Entry *table;
Scope *previous;
unsigned refCount;
unsigned cacheSize;
unsigned cacheHash;
};
}
@@ -35,10 +35,9 @@ void restoreScope(VM *vm) {
extern "C" uint64_t createClosure(VM *vm, unsigned fnID);
uint64_t createClosure(VM *vm, unsigned fnID) {
auto closure = new Closure();
auto closure = new Closure(vm->m_scope);
vm->trackAllocation(closure, sizeof(Closure));
closure->fn = &vm->m_userFunctions[fnID];
closure->scope = vm->m_scope;
return Value(closure).encode();
}
@@ -26,8 +26,7 @@ namespace ceos {
m_bytecode = (uint8_t *)malloc(length);
memcpy(m_bytecode, bc.data(), length);
m_scope = std::make_shared<Scope<Value>>();
m_scope = new Scope(1024);
registerBuiltins(*this);
}
@@ -77,7 +76,7 @@ namespace ceos {
size_t heapLimit;
std::vector<std::pair<size_t, void *>> blocks;
std::shared_ptr<Scope<Value>> m_scope;
Scope *m_scope;
std::vector<char *> m_stringTable;
std::vector<Function> m_userFunctions;

0 comments on commit c7ac75c

Please sign in to comment.