Skip to content

Commit

Permalink
Change rbx unmarshaling to support lazy loading.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Ford committed Apr 22, 2011
1 parent dcbb20d commit 87fc5d8
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 12 deletions.
27 changes: 24 additions & 3 deletions vm/builtin/lazy_executable.cpp
Expand Up @@ -4,14 +4,16 @@
#include "builtin/symbol.hpp"
#include "builtin/fixnum.hpp"

#include "builtin/thunk.hpp"

#include "compiled_file.hpp"
#include "dispatch.hpp"
#include "call_frame.hpp"
#include "arguments.hpp"

#include "object_utils.hpp"

#include <iostream>
#include <fstream>

namespace rubinius {
void LazyExecutable::init(STATE) {
GO(lmethod).set(state->new_class("LazyExecutable", G(executable), G(rubinius)));
Expand All @@ -20,6 +22,12 @@ namespace rubinius {
G(lmethod)->set_const(state, "Index", LookupTable::create(state));
}

void LazyExecutable::add_index(STATE, Symbol* path, LookupTable* index, size_t base) {
index->store(state, state->symbol("base"), Fixnum::from(base));
LookupTable* tbl = as<LookupTable>(G(lmethod)->get_const(state, state->symbol("Index")));
tbl->store(state, path, index);
}

LazyExecutable* LazyExecutable::create(STATE, Symbol* path, Symbol* name) {
LazyExecutable* le = state->new_object<LazyExecutable>(G(lmethod));
le->path(state, path);
Expand All @@ -37,6 +45,19 @@ namespace rubinius {
}

Executable* LazyExecutable::load(STATE) {
return Thunk::create(state, G(object), state->symbol("booya"));
LookupTable* index = as<LookupTable>(
G(lmethod)->get_const(state, state->symbol("Index")));
native_int base = as<Fixnum>(index->fetch(state, state->symbol("base")))->to_native();
native_int offset = as<Fixnum>(index->fetch(state, name_))->to_native();

std::ifstream stream(path_->c_str(state));
if(!stream) {
std::string msg = "Unable to load CompiledMethod from ";
msg += std::string(path_->c_str(state));
throw std::runtime_error(msg);
}
stream.seekg(base + offset, std::ios::beg);

return CompiledFile::load_method(state, stream, path_);
}
}
2 changes: 2 additions & 0 deletions vm/builtin/lazy_executable.hpp
Expand Up @@ -20,6 +20,8 @@ namespace rubinius {
attr_accessor(name, Symbol);

static void init(STATE);
static void LazyExecutable::add_index(STATE, Symbol* path,
LookupTable* index, size_t base);

// Ruby.primitive :lazy_executable_create
static LazyExecutable* create(STATE, Symbol* path, Symbol* name);
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/system.cpp
Expand Up @@ -144,7 +144,7 @@ namespace rubinius {
return Primitives::failure();
}

CompiledFile* cf = CompiledFile::load(stream);
CompiledFile* cf = CompiledFile::load(stream, state->symbol(path));
if(cf->magic != "!RBIX") {
return Primitives::failure();
}
Expand Down
15 changes: 12 additions & 3 deletions vm/compiled_file.cpp
Expand Up @@ -15,10 +15,12 @@
#include "builtin/staticscope.hpp"
#include "builtin/compiledmethod.hpp"
#include "builtin/class.hpp"
#include "builtin/lazy_executable.hpp"
#include "builtin/symbol.hpp"
#include "builtin/thread.hpp"

namespace rubinius {
CompiledFile* CompiledFile::load(std::istream& stream) {
CompiledFile* CompiledFile::load(std::istream& stream, Symbol* path) {
std::string magic, sum;
uint64_t ver;

Expand All @@ -27,11 +29,18 @@ namespace rubinius {
stream >> sum;
stream.get(); // eat the \n

return new CompiledFile(magic, ver, sum, &stream);
return new CompiledFile(magic, ver, sum, path, &stream);
}

CompiledMethod* CompiledFile::load_method(STATE, std::istream& stream, Symbol* path) {
UnMarshaller mar(state, path, stream);
return as<CompiledMethod>(mar.unmarshal());
}

Object* CompiledFile::body(STATE) {
UnMarshaller mar(state, *stream);
UnMarshaller mar(state, path, *stream);
LazyExecutable::add_index(state, path, (LookupTable*)mar.unmarshal(), stream->tellg());

return mar.unmarshal();
}

Expand Down
9 changes: 7 additions & 2 deletions vm/compiled_file.hpp
Expand Up @@ -7,28 +7,33 @@

namespace rubinius {

class CompiledMethod;
class Object;
class Symbol;
class VM;

class CompiledFile {
public:
std::string magic;
uint64_t version;
std::string sum;
Symbol* path;

private:
std::istream* stream;

public:
CompiledFile(std::string magic, uint64_t version, std::string sum,
std::istream* stream)
Symbol* path, std::istream* stream)
: magic(magic)
, version(version)
, sum(sum)
, path(path)
, stream(stream)
{}

static CompiledFile* load(std::istream& stream);
static CompiledFile* load(std::istream& stream, Symbol* path);
static CompiledMethod* load_method(STATE, std::istream& stream, Symbol* path);
Object* body(STATE);
bool execute(STATE);
};
Expand Down
2 changes: 1 addition & 1 deletion vm/environment.cpp
Expand Up @@ -470,7 +470,7 @@ namespace rubinius {
throw std::runtime_error(msg);
}

CompiledFile* cf = CompiledFile::load(stream);
CompiledFile* cf = CompiledFile::load(stream, state->symbol(file.c_str()));
if(cf->magic != "!RBIX") throw std::runtime_error("Invalid file");
if(signature_ > 0) {
if(cf->version != signature_) throw BadKernelFile(file);
Expand Down
28 changes: 28 additions & 0 deletions vm/marshal.cpp
Expand Up @@ -16,6 +16,8 @@
#include "builtin/fixnum.hpp"
#include "builtin/float.hpp"
#include "builtin/iseq.hpp"
#include "builtin/lazy_executable.hpp"
#include "builtin/lookuptable.hpp"
#include "builtin/string.hpp"
#include "builtin/symbol.hpp"
#include "builtin/tuple.hpp"
Expand Down Expand Up @@ -165,6 +167,28 @@ namespace rubinius {
return cm;
}

LazyExecutable* UnMarshaller::get_lazy_executable() {
Symbol* name = (Symbol*)unmarshal();
return LazyExecutable::create(state, path, name);
}

LookupTable* UnMarshaller::get_index() {
LookupTable* index = LookupTable::create(state);
Symbol* id;
Fixnum* offset;

size_t count;
stream >> count;

for(size_t i = 0; i < count; i++) {
id = (Symbol*)unmarshal();
offset = (Fixnum*)unmarshal();
index->store(state, id, offset);
}

return index;
}

Object* UnMarshaller::unmarshal() {
char code;

Expand All @@ -191,6 +215,10 @@ namespace rubinius {
return get_iseq();
case 'M':
return get_cmethod();
case 'L':
return get_index();
case 'l':
return get_lazy_executable();
default:
std::string str = "unknown marshal code: ";
str.append( 1, code );
Expand Down
12 changes: 10 additions & 2 deletions vm/marshal.hpp
Expand Up @@ -16,16 +16,22 @@ namespace rubinius {
class Array;
class Bignum;
class Float;
class LazyExecutable;
class LookupTable;
class Symbol;
class Tuple;

class UnMarshaller {
public:
STATE;
Symbol* path;
std::istream& stream;

UnMarshaller(STATE, std::istream& stream) :
state(state), stream(stream) { }
UnMarshaller(STATE, Symbol* path, std::istream& stream)
: state(state)
, path(path)
, stream(stream)
{ }

Object* unmarshal();

Expand All @@ -37,6 +43,8 @@ namespace rubinius {
Float* get_float();
InstructionSequence* get_iseq();
CompiledMethod* get_cmethod();
LazyExecutable* get_lazy_executable();
LookupTable* get_index();

public:
class Error {
Expand Down

0 comments on commit 87fc5d8

Please sign in to comment.