Permalink
Browse files

Finished the locals allocation code

* The locals tuple is now allocated in the fast context stack.
* Refactored the context allocation code for methods and blocks.
* Fixed a channel bug
  • Loading branch information...
1 parent 14e2b20 commit b9448a02b3ccd159d7a74421b64cf109f5cfaa2b @evanphx evanphx committed Nov 30, 2007
View
@@ -566,5 +566,3 @@ namespace "doc" do
end
end
-task :build => 'doc:vm:html'
-
@@ -1,5 +1,5 @@
class Channel
- ivar_as_index :waiting => 0, :value => 1
+ ivar_as_index :waiting => 1, :value => 2
def waiting; @waiting ; end
def value ; @value ; end
@@ -200,12 +200,7 @@ def caller(start=1)
ret = []
ctx = MethodContext.current.sender
until ctx.nil?
- if ctx.method.name == :__script__ # This is where MRI stops
- ret << "#{ctx.file}:#{ctx.line}"
- break
- else
- ret << "#{ctx.file}:#{ctx.line}:in `#{ctx.method.name}'"
- end
+ ret << "#{ctx.file}:#{ctx.line}"
ctx = ctx.sender
end
ret[start..-1]
@@ -5,6 +5,10 @@
class Thread
ivar_as_index :__ivars__ => 0, :priority => 1, :task => 2, :joins => 3
+ def inspect
+ "#<#{self.class}:0x#{object_id.to_s(16)}>"
+ end
+
def setup(prime_lock)
@__ivars__ = {}
@alive = true
View
@@ -250,7 +250,8 @@ void baker_gc_mutate_context(STATE, baker_gc g, OBJECT iobj, int shifted, int to
struct fast_context *fc = FASTCTX(iobj);
OBJECT old_sender;
-
+
+ old_sender = fc->sender;
if(REFERENCE_P(fc->sender)) {
/* This is the top most stack context, handle it differently */
@@ -263,6 +264,7 @@ void baker_gc_mutate_context(STATE, baker_gc g, OBJECT iobj, int shifted, int to
}
fc_mutate(sender);
} else {
+ /*
if(shifted) {
old_sender = fc->sender;
xassert(om_on_stack(state->om, old_sender));
@@ -271,17 +273,27 @@ void baker_gc_mutate_context(STATE, baker_gc g, OBJECT iobj, int shifted, int to
} else {
xassert(om_on_stack(state->om, fc->sender));
}
+ */
}
}
+ if(top) {
+ assert(NIL_P(fc->sender) || fc->sender->obj_type == MContextType || fc->sender->obj_type == BContextType);
+ }
+
+
+
fc_mutate(method);
fc_mutate(block);
fc_mutate(literals);
fc_mutate(self);
if(!NIL_P(fc->locals) && fc->locals->gc_zone == 0) {
- int i, fields = NUM_FIELDS(fc->locals);
+ int i, fields;
OBJECT mut, tmp;
- fc->locals = object_memory_context_locals(iobj);
+
+ fc->locals = object_memory_context_locals(iobj);
+ fields = NUM_FIELDS(fc->locals);
+
for(i = 0; i < fields; i++) {
tmp = NTH_FIELD(fc->locals, i);
if(!REFERENCE_P(tmp)) continue;
View
@@ -161,11 +161,12 @@ void cpu_update_roots(STATE, cpu c, ptr_array roots, int start) {
if(state->ac_on_stack) {
/* if active_context is on the stack, it's the last object. */
- /* if context_top is nil, then we didn't need to compact, they're
+ /* if context_offset is 0, then we didn't need to compact, they're
still pointed at the right point. */
- if(state->om->context_top != Qnil) {
- c->active_context = state->om->context_top;
+ if(state->om->context_offset != 0) {
+ c->active_context = (OBJECT)((uintptr_t)(c->active_context) - state->om->context_offset);
+ state->om->context_offset = 0;
}
} else {
ar(c->active_context);
View
@@ -154,6 +154,7 @@ 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);
+OBJECT cpu_create_block_context(STATE, cpu c, OBJECT env, int sp);
void cpu_set_encloser_path(STATE, cpu c, OBJECT cls);
void cpu_push_encloser(STATE, cpu c);
@@ -195,7 +196,7 @@ void cpu_clear_cache_for_class(STATE, cpu c, OBJECT klass);
OBJECT cpu_task_dup(STATE, cpu c, OBJECT cur);
int cpu_task_select(STATE, cpu c, OBJECT self);
-OBJECT cpu_task_associate(STATE, OBJECT self, OBJECT be);
+OBJECT cpu_task_associate(STATE, cpu c, OBJECT self, OBJECT be);
void cpu_task_set_debugging(STATE, OBJECT self, OBJECT dc, OBJECT cc);
OBJECT cpu_channel_new(STATE);
OBJECT cpu_channel_send(STATE, cpu c, OBJECT self, OBJECT obj);
@@ -338,73 +338,107 @@ OBJECT cpu_compile_method(STATE, OBJECT cm) {
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, ins;
- int num_lcls, i;
+static inline OBJECT _allocate_context(STATE, cpu c, OBJECT meth, int locals) {
+ OBJECT ctx, ins;
struct fast_context *fc;
+ int i;
- sender = c->active_context;
-
- ins = cmethod_get_compiled(mo);
-
- if(NIL_P(ins)) {
- ins = cpu_compile_method(state, mo);
- }
-
- num_lcls = FIXNUM_TO_INT(cmethod_get_locals(mo));
-
- cpu_flush_sp(c);
-
- ctx = object_memory_new_context(state->om, num_lcls);
+ ctx = object_memory_new_context(state->om, locals);
if(ctx >= state->om->context_last) {
state->om->collect_now |= OMCollectYoung;
}
-
+
+ ins = cmethod_get_compiled(meth);
+
+ if(NIL_P(ins)) {
+ ins = cpu_compile_method(state, meth);
+ }
+
CLEAR_FLAGS(ctx);
- ctx->gc_zone = 0;
ctx->klass = Qnil;
ctx->field_count = FASTCTX_FIELDS;
-
+
fc = FASTCTX(ctx);
- fc->sender = sender;
- fc->ip = 0;
- fc->sp = c->sp;
- /* fp points to the location on the stack as the context
- was being created. */
- fc->fp = c->sp;
-
- fc->block = block;
- fc->method = mo;
+ fc->flags = 0;
+ fc->sender = c->active_context;
+
+ fc->method = meth;
fc->data = bytearray_byte_address(state, ins);
- fc->literals = cmethod_get_literals(mo);
- fc->self = recv;
- if(num_lcls > 0) {
- //fc->locals = tuple_new(state, num_lcls);
-
+ fc->literals = cmethod_get_literals(meth);
+
+ if(locals > 0) {
+ // fc->locals = tuple_new(state, locals);
fc->locals = object_memory_context_locals(ctx);
CLEAR_FLAGS(fc->locals);
fc->locals->gc_zone = 0;
fc->locals->klass = BASIC_CLASS(tuple);
- SET_NUM_FIELDS(fc->locals, num_lcls);
-
- for(i = 0; i < num_lcls; i++) {
+ SET_NUM_FIELDS(fc->locals, locals);
+
+ for(i = 0; i < locals; i++) {
SET_FIELD_DIRECT(fc->locals, i, Qnil);
}
} else {
fc->locals = Qnil;
}
// printf("Locals for %p at %p (%d, %d)\n", ctx, fc->locals, num_lcls, FASTCTX(ctx)->size);
+
+ return ctx;
+}
+
+static inline OBJECT cpu_create_context(STATE, cpu c, OBJECT recv,
+ OBJECT mo, OBJECT name, OBJECT mod,
+ unsigned long int args, OBJECT block) {
+ OBJECT ctx;
+ struct fast_context *fc;
+
+ ctx = _allocate_context(state, c, mo, FIXNUM_TO_INT(cmethod_get_locals(mo)));
+ fc = FASTCTX(ctx);
+ cpu_flush_sp(c);
+ fc->ip = 0;
+ fc->sp = c->sp;
+ /* fp points to the location on the stack as the context
+ was being created. */
+ fc->fp = c->sp;
+
+ fc->block = block;
+ fc->self = recv;
fc->argcount = args;
fc->name = name;
fc->method_module = mod;
fc->type = FASTCTX_NORMAL;
- fc->flags = 0;
- xassert(om_valid_sender_p(state->om, ctx, sender));
+ return ctx;
+}
+OBJECT cpu_create_block_context(STATE, cpu c, OBJECT env, int sp) {
+ OBJECT ctx;
+ struct fast_context *fc;
+
+ ctx = _allocate_context(state, c, blokenv_get_method(env),
+ FIXNUM_TO_INT(blokenv_get_local_count(env)));
+ fc = FASTCTX(ctx);
+
+ fc->ip = FIXNUM_TO_INT(blokenv_get_initial_ip(env));
+ fc->sp = sp;
+
+ fc->block = Qnil;
+ fc->self = Qnil;
+ fc->argcount = 0;
+
+ /* env lives here */
+ fc->name = env;
+
+ fc->method_module = Qnil;
+ fc->type = FASTCTX_BLOCK;
+
+ /* If post send is nil, that means we're not allowed to return directly to
+ the home context. */
+ if(NIL_P(blokenv_get_post_send(env))) {
+ fc->flags |= CTX_FLAG_NO_LONG_RETURN;
+ }
+
return ctx;
}
@@ -157,13 +157,15 @@ int cpu_task_select(STATE, cpu c, OBJECT nw) {
void cpu_task_push(STATE, OBJECT self, OBJECT val);
-OBJECT cpu_task_associate(STATE, OBJECT self, OBJECT be) {
+OBJECT cpu_task_associate(STATE, cpu c, OBJECT self, OBJECT be) {
OBJECT bc;
struct cpu_task *task;
task = (struct cpu_task*)BYTES_OF(self);
- bc = blokenv_create_context(state, be, Qnil, 1);
+ bc = cpu_create_block_context(state, c, be, 1);
+ FASTCTX(bc)->sender = Qnil;
+
if(task->stack_slave) {
task->stack_top = (OBJECT*)calloc(InitialStackSize, sizeof(OBJECT));
task->stack_size = InitialStackSize;
View
@@ -19,6 +19,7 @@ OBJECT methctx_dup(STATE, OBJECT self) {
old = FASTCTX(self);
cur = FASTCTX(ctx);
+ if(!NIL_P(old->sender)) methctx_reference(state, old->sender);
SET_STRUCT_FIELD(ctx, cur->sender, old->sender);
SET_STRUCT_FIELD(ctx, cur->block, old->block);
SET_STRUCT_FIELD(ctx, cur->method, old->method);
@@ -100,77 +101,6 @@ OBJECT blokenv_s_under_context2(STATE, OBJECT cmethod, OBJECT ctx, OBJECT ctx_bl
return obj;
}
-
-OBJECT blokenv_create_context(STATE, OBJECT self, OBJECT sender, int sp) {
- OBJECT ctx, ins;
- int cnt, i;
- struct fast_context *fc;
-
- cnt = FIXNUM_TO_INT(blokenv_get_local_count(self));
-
- ctx = object_memory_new_context(state->om, cnt);
- if(ctx >= state->om->context_last) {
- state->om->collect_now |= OMCollectYoung;
- }
-
- if(state->excessive_tracing) {
- printf("CTX: block running %d\n", (int)ctx);
- }
-
- CLEAR_FLAGS(ctx);
- ctx->gc_zone = 0;
- ctx->field_count = FASTCTX_FIELDS;
- ctx->klass = Qnil;
-
- fc = FASTCTX(ctx);
- fc->sender = sender;
- fc->ip = FIXNUM_TO_INT(blokenv_get_initial_ip(self));
- fc->sp = sp;
- /* env lives here */
- fc->name = self;
- fc->self = Qnil;
- fc->method = blokenv_get_method(self);
-
- ins = cmethod_get_compiled(fc->method);
-
- if(NIL_P(ins)) {
- ins = cpu_compile_method(state, fc->method);
- }
-
- fc->data = bytearray_byte_address(state, ins);
-
- fc->literals = cmethod_get_literals(fc->method);
- fc->block = Qnil;
- fc->method_module = Qnil;
-
- if(cnt > 0) {
- // fc->locals = tuple_new(state, cnt);
-
- fc->locals = object_memory_context_locals(ctx);
- CLEAR_FLAGS(fc->locals);
- fc->locals->gc_zone = 0;
- fc->locals->klass = BASIC_CLASS(tuple);
- SET_NUM_FIELDS(fc->locals, cnt);
-
- for(i = 0; i < cnt; i++) {
- SET_FIELD_DIRECT(fc->locals, i, Qnil);
- }
-
- } else {
- fc->locals = Qnil;
- }
- fc->flags = 0;
-
- /* If post send is nil, that means we're not allowed to return directly to
- the home context. */
- if(NIL_P(blokenv_get_post_send(self))) {
- fc->flags |= CTX_FLAG_NO_LONG_RETURN;
- }
-
- fc->type = FASTCTX_BLOCK;
- return ctx;
-}
-
void methctx_reference(STATE, OBJECT ctx) {
struct fast_context *fc;
/* Don't do it again. */
@@ -4,7 +4,6 @@
OBJECT blokctx_s_under_context(STATE, OBJECT ctx);
OBJECT blokenv_s_under_context(STATE, OBJECT ctx, OBJECT ctx_block, int start, OBJECT lst, OBJECT vlst, OBJECT locals);
OBJECT blokenv_s_under_context2(STATE, OBJECT cmethod, OBJECT ctx, OBJECT ctx_block);
-OBJECT blokenv_create_context(STATE, OBJECT self, OBJECT sender, int sp);
OBJECT methctx_dup(STATE, OBJECT self);
OBJECT methctx_dup_chain(STATE, OBJECT ctx, OBJECT *also);
Oops, something went wrong.

0 comments on commit b9448a0

Please sign in to comment.