Permalink
Browse files

Refactor Scope and drop shared_ptr

  • Loading branch information...
1 parent e928491 commit c7ac75cd3858d859c681b79c57f8d43f02b164b0 @tadeuzagallo committed May 5, 2016
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
View
@@ -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(); }
};
}
View
@@ -3,6 +3,6 @@
namespace ceos {
std::set<uint64_t> GC::roots;
- std::set<ScopePtr> GC::scopes;
+ std::set<Scope *> GC::scopes;
}
View
@@ -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;
};
View
@@ -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
View
@@ -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;
};
}
View
@@ -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();
}
View
@@ -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.