Permalink
Browse files

Added compiled field to CompiledMethod.

The VM now stores a VM translated version of the CompiledMethods
bytecodes in the compiled field. This keeps the InstructionSequence
object in the bytecodes field prisitine. It also simplifies detecting
which methods need to be translated (this is done lazily, as methods)
are executed.
  • Loading branch information...
1 parent 18faa98 commit 08d09790e4a94227181eafbca2ab10961dec1de8 @evanphx evanphx committed Nov 17, 2007
View
4 Rakefile
@@ -106,6 +106,10 @@ task :compiler do
end
end
+task :stable_shell => :compiler do
+ sh "shotgun/rubinius --gdb"
+end
+
rule ".rbc" => %w[compiler .rb] do |t|
compile t.source, t.name
end
View
2 compiler/bytecode/system_hints.rb
@@ -11,7 +11,7 @@ module Bootstrap
"Float"=>{:@__ivars__=>0},
"Array"=>{:@total=>0, :@tuple=>1, :@start => 2, :@shared => 3},
"String"=>{:@bytes=>0, :@characters=>1, :@encoding=>2, :@data=>3, :@hash => 4, :@shared => 5},
- "CompiledMethod"=>{:@__ivars__=>0, :@primitive => 1, :@required=>2, :@serial=>3, :@bytecodes=>4, :@name=>5, :@file=>6, :@locals=>7, :@literals=>8, :@arguments=>9, :@scope=>10, :@exceptions=>11, :@lines=>12, :@path=>13, :@cache=>14, :@bonus => 15},
+ "CompiledMethod"=>{:@__ivars__=>0, :@primitive => 1, :@required=>2, :@serial=>3, :@bytecodes=>4, :@name=>5, :@file=>6, :@locals=>7, :@literals=>8, :@arguments=>9, :@scope=>10, :@exceptions=>11, :@lines=>12, :@path=>13, :@cache=>14, :@bonus => 15, :@compiled => 16},
"SymbolTable"=>{:@__ivars__=>0,:@symbols=>1, :@strings=>2},
"IO"=>{:@__ivars__ => 0, :@descriptor => 1, :@buffer => 2, :mode => 3 },
"Module"=>{:@__ivars__=>0, :@methods=>1, :@method_cache=>2, :@name=>3, :@constants=>4, :@parent=>5, :@superclass => 6},
View
1 shotgun/lib/.gitignore
@@ -0,0 +1 @@
+primitive_util.h
View
4 shotgun/lib/baker.c
@@ -204,7 +204,7 @@ static inline void _mutate_references(STATE, baker_gc g, OBJECT iobj) {
/* We cache the bytecode in a char*, so adjust it.
We mutate the data first so we cache the newest address. */
OBJECT ba;
- ba = cmethod_get_bytecodes(fc->method);
+ ba = cmethod_get_compiled(fc->method);
ba = baker_gc_maybe_mutate(state, g, ba);
fc->data = BYTEARRAY_ADDRESS(ba);
@@ -285,7 +285,7 @@ void baker_gc_mutate_context(STATE, baker_gc g, OBJECT iobj, int shifted, int to
/* We cache the bytecode in a char*, so adjust it.
We mutate the data first so we cache the newest address. */
OBJECT ba;
- ba = cmethod_get_bytecodes(fc->method);
+ ba = cmethod_get_compiled(fc->method);
ba = baker_gc_maybe_mutate(state, g, ba);
fc->data = BYTEARRAY_ADDRESS(ba);
View
24 shotgun/lib/bytearray.c
@@ -71,23 +71,12 @@ OBJECT iseq_new(STATE, int fields) {
return obj;
}
-
-#if defined(__BIG_ENDIAN__)
-static inline uint32_t read_int(uint8_t *str) {
- return (uint32_t)(str[0]
- | (str[1] << 8 )
- | (str[2] << 16)
- | (str[3] << 24));
-}
-#define ISET_FLAG(o)
-#else
-static inline uint32_t read_int(uint8_t *str) {
+static inline uint32_t read_int_from_be(uint8_t *str) {
return (uint32_t)((str[0] << 24)
| (str[1] << 16)
| (str[2] << 8 )
| str[3] );
}
-#endif
void iseq_flip(STATE, OBJECT self) {
uint8_t *buf;
@@ -98,14 +87,11 @@ void iseq_flip(STATE, OBJECT self) {
buf = (uint8_t*)bytearray_byte_address(state, self);
ibuf = (uint32_t*)bytearray_byte_address(state, self);
/* A sanity check. The first thing is always an instruction,
- * and we've got less that 512 instructions, so if it's less
+ * and we've got less that 1024 instructions, so if it's less
* it's already been flipped. */
- if(*ibuf < 512) {
- self->IsLittleEndian = TRUE;
- return;
- }
+ if(*ibuf < 1024) return;
+
for(i = 0; i < f; i += 4, ibuf++) {
- *ibuf = read_int(buf + i);
+ *ibuf = read_int_from_be(buf + i);
}
- self->IsLittleEndian = TRUE;
}
View
1 shotgun/lib/cpu.c
@@ -554,3 +554,4 @@ void cpu_hard_cache(STATE, cpu c) {
cpu_cache_ip(c);
}
+
View
1 shotgun/lib/cpu.h
@@ -152,6 +152,7 @@ OBJECT cpu_const_set(STATE, cpu c, OBJECT sym, OBJECT val, OBJECT under);
void cpu_run(STATE, cpu c, int setup);
int cpu_dispatch(STATE, cpu c);
inline void cpu_compile_instructions(STATE, OBJECT ba);
+OBJECT cpu_compile_method(STATE, OBJECT cm);
void cpu_set_encloser_path(STATE, cpu c, OBJECT cls);
void cpu_push_encloser(STATE, cpu c);
View
49 shotgun/lib/cpu_instructions.c
@@ -317,45 +317,40 @@ static inline OBJECT cpu_locate_method(STATE, cpu c, OBJECT obj, OBJECT sym,
return mo;
}
-inline void cpu_compile_instructions(STATE, OBJECT ba) {
-#if DIRECT_THREADED
- if(!ba->IsFrozen) {
- if(ba->IsLittleEndian) {
-#if defined(__BIG_ENDIAN__)
- iseq_flip(state, ba);
-#endif
- } else {
-#if !defined(__BIG_ENDIAN__)
- iseq_flip(state, ba);
-#endif
- }
- calculate_into_gotos(state, ba, _dt_addresses);
- ba->IsFrozen = TRUE;
- }
-#else
- if(ba->IsLittleEndian) {
-#if defined(__BIG_ENDIAN__)
- iseq_flip(state, ba);
-#endif
- } else {
+OBJECT cpu_compile_method(STATE, OBJECT cm) {
+ OBJECT ba;
+ ba = bytearray_dup(state, cmethod_get_bytecodes(cm));
+
+ /* If this is not a big endian platform, we need to adjust
+ the iseq to have the right order */
#if !defined(__BIG_ENDIAN__)
- iseq_flip(state, ba);
+ iseq_flip(state, ba);
#endif
- }
+ /* If we're compiled with direct threading, then translate
+ the compiled version into addresses. */
+#if DIRECT_THREADED
+ calculate_into_gotos(state, ba, _dt_addresses);
#endif
+
+ cmethod_set_compiled(cm, ba);
+
+ return ba;
}
static inline OBJECT cpu_create_context(STATE, cpu c, OBJECT recv, OBJECT mo,
OBJECT name, OBJECT mod, unsigned long int args, OBJECT block) {
- OBJECT sender, ctx, ba;
+ OBJECT sender, ctx, ins;
int num_lcls;
struct fast_context *fc;
sender = c->active_context;
- ba = cmethod_get_bytecodes(mo);
- cpu_compile_instructions(state, ba);
+ ins = cmethod_get_compiled(mo);
+
+ if(NIL_P(ins)) {
+ ins = cpu_compile_method(state, mo);
+ }
num_lcls = FIXNUM_TO_INT(cmethod_get_locals(mo));
@@ -380,7 +375,7 @@ static inline OBJECT cpu_create_context(STATE, cpu c, OBJECT recv, OBJECT mo,
fc->block = block;
fc->method = mo;
- fc->data = bytearray_byte_address(state, ba);
+ fc->data = bytearray_byte_address(state, ins);
fc->literals = cmethod_get_literals(mo);
fc->self = recv;
if(num_lcls > 0) {
View
13 shotgun/lib/cpu_marshal.c
@@ -280,11 +280,7 @@ static OBJECT unmarshal_bytes(STATE, struct marshal_state *ms) {
static void marshal_iseq(STATE, OBJECT obj, bstring buf) {
int i;
append_c('I');
- if(obj->IsLittleEndian) {
- append_c('l');
- } else {
- append_c('b');
- }
+ append_c('b');
i = SIZE_OF_BODY(obj);
append_sz(i);
@@ -305,11 +301,8 @@ static OBJECT unmarshal_iseq(STATE, struct marshal_state *ms) {
memcpy(bytearray_byte_address(state, obj), ms->buf + 6, sz);
- #if defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN)
- if(endian != 'b') iseq_flip(state, obj);
- #else
- if(endian != 'l') iseq_flip(state, obj);
- #endif
+ /* We only support iseq's stored big endian currently. */
+ sassert(endian == 'b');
return obj;
}
View
5 shotgun/lib/machine.c
@@ -527,7 +527,7 @@ int machine_run_file(machine m, const char *path) {
if(m->s->excessive_tracing) {
printf("[ Loading file %s]\n", path);
}
-
+
meth = machine_load_file(m, path);
if(!RTEST(meth)) {
printf("Unable to load '%s'.\n", path);
@@ -892,8 +892,9 @@ OBJECT machine_load_archive(machine m, const char *path) {
goto out;
}
if(m->s->excessive_tracing) {
- printf("[ Loading file %s]\n", files);
+ printf("[ Loading archived file %s]\n", files);
}
+
/* We push this on the stack so it's properly seen by the GCs */
cpu_stack_push(m->s, m->c, cm, FALSE);
cpu_run_script(m->s, m->c, cm);
View
4 shotgun/lib/marksweep.c
@@ -304,7 +304,7 @@ static OBJECT mark_sweep_mark_object(STATE, mark_sweep_gc ms, OBJECT iobj) {
if(!NIL_P(fc->method)) {
/* We cache the bytecode in a char*, so adjust it. */
OBJECT ba;
- ba = cmethod_get_bytecodes(fc->method);
+ ba = cmethod_get_compiled(fc->method);
fc->data = BYTEARRAY_ADDRESS(ba);
}
} else if(ISA(iobj, BASIC_CLASS(task))) {
@@ -375,7 +375,7 @@ void mark_sweep_mark_context(STATE, mark_sweep_gc ms, OBJECT iobj) {
if(!NIL_P(fc->method)) {
/* We cache the bytecode in a char*, so adjust it. */
OBJECT ba;
- ba = cmethod_get_bytecodes(fc->method);
+ ba = cmethod_get_compiled(fc->method);
fc->data = BYTEARRAY_ADDRESS(ba);
}
#undef fc_mutate
View
11 shotgun/lib/methctx.c
@@ -43,7 +43,7 @@ OBJECT blokenv_s_under_context2(STATE, OBJECT cmethod, OBJECT ctx, OBJECT ctx_bl
OBJECT blokenv_create_context(STATE, OBJECT self, OBJECT sender, int sp) {
- OBJECT ctx, ba;
+ OBJECT ctx, ins;
int cnt;
struct fast_context *fc;
@@ -67,11 +67,14 @@ OBJECT blokenv_create_context(STATE, OBJECT self, OBJECT sender, int sp) {
fc->name = self;
fc->self = Qnil;
fc->method = blokenv_get_method(self);
+
+ ins = cmethod_get_compiled(fc->method);
- ba = cmethod_get_bytecodes(fc->method);
- cpu_compile_instructions(state, ba);
+ if(NIL_P(ins)) {
+ ins = cpu_compile_method(state, fc->method);
+ }
- fc->data = bytearray_byte_address(state, ba);
+ fc->data = bytearray_byte_address(state, ins);
fc->literals = cmethod_get_literals(fc->method);
fc->block = Qnil;

0 comments on commit 08d0979

Please sign in to comment.