Permalink
Browse files

Implement hacky lookup cache using a sidetable

  • Loading branch information...
1 parent e470aab commit c4e9a3e0166ac4ac4da2dd562a380a9e720b2fe4 @tadeuzagallo committed May 12, 2016
Showing with 61 additions and 17 deletions.
  1. +13 −1 compiler/generator.cc
  2. +37 −9 compiler/interpreter.S
  3. +11 −7 compiler/vm.cc
View
@@ -6,6 +6,9 @@
#include <iomanip>
namespace ceos {
+ static unsigned lookupID = 1;
+ static bool capturesScope = true;
+
std::stringstream &Generator::generate() {
generateProgram(m_ast);
emitOpcode(Opcode::exit);
@@ -103,6 +106,11 @@ namespace ceos {
} else {
emitOpcode(Opcode::lookup);
write(id->uid);
+ if (capturesScope) {
+ write(0);
+ } else {
+ write(lookupID++);
+ }
}
}
@@ -155,6 +163,7 @@ namespace ceos {
}
};
+ capturesScope = fn->body->capturesScope;
generateNode(fn->body);
emitOpcode(Opcode::ret);
@@ -205,6 +214,7 @@ namespace ceos {
write(Section::Header);
write(Section::Text);
+ write(lookupID);
m_output << text;
}
@@ -326,6 +336,7 @@ section_functions: {
}
section_code:
+ bytecode.seekg(4, bytecode.cur);
while (true) {
char opcode = bytecode.get();
if (bytecode.eof() || bytecode.fail()) {
@@ -358,7 +369,8 @@ section_functions: {
}
case Opcode::lookup: {
READ_INT(bytecode, id);
- WRITE(5, "lookup $" << id << "(" << strings[id] << ")");
+ READ_INT(bytecode, cacheSlot);
+ WRITE(9, "lookup $" << id << "(" << strings[id] << ") [cacheSlot=" << cacheSlot << "]");
break;
}
case Opcode::create_closure: {
@@ -4,10 +4,13 @@
#define STRINGS r13
#define VM r14
#define BCBASE r15
+#define LOOKUP rbx
.macro read
.if $0 == 1
mov 0x1(%BYTECODE), $1
+.elseif $0 == 2
+ mov 0x5(%BYTECODE), $1
.else
mov $$$0, %rax
mov -0x3(%BYTECODE, %rax, 4), $1
@@ -57,11 +60,13 @@ _execute:
push %STRINGS
push %VM
push %BCBASE
+ push %LOOKUP
mov %rsp, %rbp
mov %rdi, %BYTECODE
mov %rsi, %STRINGS
mov %rdx, %VM
mov %rcx, %BCBASE
+ mov %r8, %LOOKUP
_loop:
xor %rax, %rax
@@ -88,6 +93,7 @@ _loop_op_addresses:
_op_exit:
mov %rbp, %rsp
+ pop %LOOKUP
pop %BCBASE
pop %VM
pop %STRINGS
@@ -101,20 +107,29 @@ _op_push:
skip 1
_op_lookup:
+_op_lookup_fast_path:
+ read 2, %edi
+ mov (%LOOKUP, %rdi, 8), %rsi // Cached address
+ test %rsi, %rsi
+ jz _op_lookup_slow_path
+ push %rsi
+ skip 2
+
+_op_lookup_slow_path:
read 1, %esi // string ID
- mov (%STRINGS, %rsi, 8), %rsi // actual char *
mov (%VM), %r9 // VM::m_scope *
+ mov (%STRINGS, %rsi, 8), %rsi // actual char *
-load:
+_op_lookup_load:
mov (%r9), %rax // Scope::table *
test %rax, %rax
- jz check_parent
+ jz _op_lookup_check_parent
mov 0x18(%r9), %edx // Scope::tableHash
mov %esi, %ecx // index
and %edx, %ecx // index &= hash
mov %ecx, %r8d // begin
-begin:
+_op_lookup_begin:
mov %ecx, %edi
shl $1, %edi
mov (%rax, %rdi, 0x8), %r11 // Entry::key
@@ -125,22 +140,35 @@ begin:
skip 1
slow_path:
+ cmp %rsi, %r11
+ jz _op_lookup_found
test %r11,%r11
- jz check_parent
+ jz _op_lookup_check_parent
inc %ecx
and %edx, %ecx
cmp %ecx, %r8d
- jnz begin
+ jnz _op_lookup_begin
-check_parent:
+_op_lookup_check_parent:
mov 0x8(%r9), %r9 // Scope::parent
test %r9, %r9
- jnz load
+ jnz _op_lookup_load
-not_found:
+_op_lookup_not_found:
mov %rsi, %rdi
ccall _symbolNotFound
+_op_lookup_found:
+ mov 0x8(%rax, %rdi, 0x8), %rax // Entry::value
+ read 2, %edx
+ test %edx, %edx
+ jz _op_lookup_done
+ mov %rax, (%LOOKUP, %rdx, 8) // cache value
+
+_op_lookup_done:
+ push %rax
+ skip 2
+
_op_call:
// pop the callee from the stack
pop %rcx
View
@@ -11,7 +11,8 @@ extern "C" void execute(
const uint8_t *bytecode,
String *stringTable,
VM *vm,
- const uint8_t *bcbase);
+ const uint8_t *bcbase,
+ void *lookupTable);
extern "C" void setScope(VM *vm, const char *name, Value value);
void setScope(VM *vm, const char *name, Value value) {
@@ -41,7 +42,7 @@ uint64_t createClosure(VM *vm, unsigned fnID, bool capturesScope) {
extern "C" unsigned prepareClosure(unsigned argc, Value *argv, VM *vm, Closure *closure);
unsigned prepareClosure(__unused unsigned argc, __unused Value *argv, VM *vm, Closure *closure) {
- if (closure->scope) {
+ if (closure->scope != NULL) {
vm->m_scope = vm->m_scope->create(closure->scope);
}
return closure->fn->offset;
@@ -55,7 +56,7 @@ void finishClosure(VM *vm, Closure *closure) {
}
extern "C" void symbolNotFound(char *);
-extern "C" void symbolNotFound(char *symbolName) {
+void symbolNotFound(char *symbolName) {
fprintf(stderr, "Symbol not found: %s\n", symbolName);
throw;
}
@@ -80,17 +81,20 @@ extern "C" void symbolNotFound(char *symbolName) {
case Section::Functions:
loadFunctions();
break;
- case Section::Text:
- ::ceos::execute(m_bytecode + pc, m_stringTable.data(), this, m_bytecode);
+ case Section::Text: {
+ auto lookupTableSize = read<unsigned>();
+ void *lookupTable = calloc(lookupTableSize * 8, 1);
+ ::ceos::execute(m_bytecode + pc, m_stringTable.data(), this, m_bytecode, lookupTable);
return;
+ }
default:
std::cerr << "Unknown section: `0x0" << std::hex << section << "`\n";
throw;
}
}
}
- void VM::loadStrings() {
+ inline void VM::loadStrings() {
while (true) {
auto header = read<unsigned>();
@@ -104,7 +108,7 @@ extern "C" void symbolNotFound(char *symbolName) {
}
}
- void VM::loadFunctions() {
+ inline void VM::loadFunctions() {
auto initialHeader = read<unsigned>();
assert(initialHeader == Section::FunctionHeader);

0 comments on commit c4e9a3e

Please sign in to comment.