Skip to content

Commit

Permalink
Implement hacky lookup cache using a sidetable
Browse files Browse the repository at this point in the history
  • Loading branch information
tadeuzagallo committed May 12, 2016
1 parent e470aab commit c4e9a3e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 17 deletions.
14 changes: 13 additions & 1 deletion compiler/generator.cc
Expand Up @@ -6,6 +6,9 @@
#include <iomanip> #include <iomanip>


namespace ceos { namespace ceos {
static unsigned lookupID = 1;
static bool capturesScope = true;

std::stringstream &Generator::generate() { std::stringstream &Generator::generate() {
generateProgram(m_ast); generateProgram(m_ast);
emitOpcode(Opcode::exit); emitOpcode(Opcode::exit);
Expand Down Expand Up @@ -103,6 +106,11 @@ namespace ceos {
} else { } else {
emitOpcode(Opcode::lookup); emitOpcode(Opcode::lookup);
write(id->uid); write(id->uid);
if (capturesScope) {
write(0);
} else {
write(lookupID++);
}
} }
} }


Expand Down Expand Up @@ -155,6 +163,7 @@ namespace ceos {
} }
}; };


capturesScope = fn->body->capturesScope;
generateNode(fn->body); generateNode(fn->body);


emitOpcode(Opcode::ret); emitOpcode(Opcode::ret);
Expand Down Expand Up @@ -205,6 +214,7 @@ namespace ceos {


write(Section::Header); write(Section::Header);
write(Section::Text); write(Section::Text);
write(lookupID);
m_output << text; m_output << text;
} }


Expand Down Expand Up @@ -326,6 +336,7 @@ section_functions: {
} }


section_code: section_code:
bytecode.seekg(4, bytecode.cur);
while (true) { while (true) {
char opcode = bytecode.get(); char opcode = bytecode.get();
if (bytecode.eof() || bytecode.fail()) { if (bytecode.eof() || bytecode.fail()) {
Expand Down Expand Up @@ -358,7 +369,8 @@ section_functions: {
} }
case Opcode::lookup: { case Opcode::lookup: {
READ_INT(bytecode, id); READ_INT(bytecode, id);
WRITE(5, "lookup $" << id << "(" << strings[id] << ")"); READ_INT(bytecode, cacheSlot);
WRITE(9, "lookup $" << id << "(" << strings[id] << ") [cacheSlot=" << cacheSlot << "]");
break; break;
} }
case Opcode::create_closure: { case Opcode::create_closure: {
Expand Down
46 changes: 37 additions & 9 deletions compiler/interpreter.S
Expand Up @@ -4,10 +4,13 @@
#define STRINGS r13 #define STRINGS r13
#define VM r14 #define VM r14
#define BCBASE r15 #define BCBASE r15
#define LOOKUP rbx


.macro read .macro read
.if $0 == 1 .if $0 == 1
mov 0x1(%BYTECODE), $1 mov 0x1(%BYTECODE), $1
.elseif $0 == 2
mov 0x5(%BYTECODE), $1
.else .else
mov $$$0, %rax mov $$$0, %rax
mov -0x3(%BYTECODE, %rax, 4), $1 mov -0x3(%BYTECODE, %rax, 4), $1
Expand Down Expand Up @@ -57,11 +60,13 @@ _execute:
push %STRINGS push %STRINGS
push %VM push %VM
push %BCBASE push %BCBASE
push %LOOKUP
mov %rsp, %rbp mov %rsp, %rbp
mov %rdi, %BYTECODE mov %rdi, %BYTECODE
mov %rsi, %STRINGS mov %rsi, %STRINGS
mov %rdx, %VM mov %rdx, %VM
mov %rcx, %BCBASE mov %rcx, %BCBASE
mov %r8, %LOOKUP


_loop: _loop:
xor %rax, %rax xor %rax, %rax
Expand All @@ -88,6 +93,7 @@ _loop_op_addresses:


_op_exit: _op_exit:
mov %rbp, %rsp mov %rbp, %rsp
pop %LOOKUP
pop %BCBASE pop %BCBASE
pop %VM pop %VM
pop %STRINGS pop %STRINGS
Expand All @@ -101,20 +107,29 @@ _op_push:
skip 1 skip 1


_op_lookup: _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 read 1, %esi // string ID
mov (%STRINGS, %rsi, 8), %rsi // actual char *
mov (%VM), %r9 // VM::m_scope * mov (%VM), %r9 // VM::m_scope *
mov (%STRINGS, %rsi, 8), %rsi // actual char *


load: _op_lookup_load:
mov (%r9), %rax // Scope::table * mov (%r9), %rax // Scope::table *
test %rax, %rax test %rax, %rax
jz check_parent jz _op_lookup_check_parent
mov 0x18(%r9), %edx // Scope::tableHash mov 0x18(%r9), %edx // Scope::tableHash
mov %esi, %ecx // index mov %esi, %ecx // index
and %edx, %ecx // index &= hash and %edx, %ecx // index &= hash
mov %ecx, %r8d // begin mov %ecx, %r8d // begin


begin: _op_lookup_begin:
mov %ecx, %edi mov %ecx, %edi
shl $1, %edi shl $1, %edi
mov (%rax, %rdi, 0x8), %r11 // Entry::key mov (%rax, %rdi, 0x8), %r11 // Entry::key
Expand All @@ -125,22 +140,35 @@ begin:
skip 1 skip 1


slow_path: slow_path:
cmp %rsi, %r11
jz _op_lookup_found
test %r11,%r11 test %r11,%r11
jz check_parent jz _op_lookup_check_parent
inc %ecx inc %ecx
and %edx, %ecx and %edx, %ecx
cmp %ecx, %r8d cmp %ecx, %r8d
jnz begin jnz _op_lookup_begin


check_parent: _op_lookup_check_parent:
mov 0x8(%r9), %r9 // Scope::parent mov 0x8(%r9), %r9 // Scope::parent
test %r9, %r9 test %r9, %r9
jnz load jnz _op_lookup_load


not_found: _op_lookup_not_found:
mov %rsi, %rdi mov %rsi, %rdi
ccall _symbolNotFound 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: _op_call:
// pop the callee from the stack // pop the callee from the stack
pop %rcx pop %rcx
Expand Down
18 changes: 11 additions & 7 deletions compiler/vm.cc
Expand Up @@ -11,7 +11,8 @@ extern "C" void execute(
const uint8_t *bytecode, const uint8_t *bytecode,
String *stringTable, String *stringTable,
VM *vm, VM *vm,
const uint8_t *bcbase); const uint8_t *bcbase,
void *lookupTable);


extern "C" void setScope(VM *vm, const char *name, Value value); extern "C" void setScope(VM *vm, const char *name, Value value);
void setScope(VM *vm, const char *name, Value value) { void setScope(VM *vm, const char *name, Value value) {
Expand Down Expand Up @@ -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); extern "C" unsigned prepareClosure(unsigned argc, Value *argv, VM *vm, Closure *closure);
unsigned prepareClosure(__unused unsigned argc, __unused 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); vm->m_scope = vm->m_scope->create(closure->scope);
} }
return closure->fn->offset; return closure->fn->offset;
Expand All @@ -55,7 +56,7 @@ void finishClosure(VM *vm, Closure *closure) {
} }


extern "C" void symbolNotFound(char *); extern "C" void symbolNotFound(char *);
extern "C" void symbolNotFound(char *symbolName) { void symbolNotFound(char *symbolName) {
fprintf(stderr, "Symbol not found: %s\n", symbolName); fprintf(stderr, "Symbol not found: %s\n", symbolName);
throw; throw;
} }
Expand All @@ -80,17 +81,20 @@ extern "C" void symbolNotFound(char *symbolName) {
case Section::Functions: case Section::Functions:
loadFunctions(); loadFunctions();
break; break;
case Section::Text: case Section::Text: {
::ceos::execute(m_bytecode + pc, m_stringTable.data(), this, m_bytecode); auto lookupTableSize = read<unsigned>();
void *lookupTable = calloc(lookupTableSize * 8, 1);
::ceos::execute(m_bytecode + pc, m_stringTable.data(), this, m_bytecode, lookupTable);
return; return;
}
default: default:
std::cerr << "Unknown section: `0x0" << std::hex << section << "`\n"; std::cerr << "Unknown section: `0x0" << std::hex << section << "`\n";
throw; throw;
} }
} }
} }


void VM::loadStrings() { inline void VM::loadStrings() {
while (true) { while (true) {
auto header = read<unsigned>(); auto header = read<unsigned>();


Expand All @@ -104,7 +108,7 @@ extern "C" void symbolNotFound(char *symbolName) {
} }
} }


void VM::loadFunctions() { inline void VM::loadFunctions() {
auto initialHeader = read<unsigned>(); auto initialHeader = read<unsigned>();
assert(initialHeader == Section::FunctionHeader); assert(initialHeader == Section::FunctionHeader);


Expand Down

0 comments on commit c4e9a3e

Please sign in to comment.