Permalink
Browse files

Cleanup stack usage and fix interpreter

Remove Task->stack, added Task methods for manipulating the stack that
use active.

VMMethod contains a resume now, so that the bytecode can again be
interpreted. Currently, this is the default while LLVM continues to be
debugged.
  • Loading branch information...
1 parent 7446de4 commit 310a461d31ec36fd25977f7b2c2808db6e24ea55 Evan Phoenix committed Aug 7, 2008
View
@@ -0,0 +1,7 @@
+define rbt
+p machine_print_callstack(0)
+end
+
+define rp
+p __show__(state, $arg0)
+end
View
@@ -5,8 +5,10 @@ task :vm => 'vm/vm'
############################################################
# Files, Flags, & Constants
+LLVM_STYLE = "Release"
+
ENV.delete 'CDPATH' # confuses llvm_config
-LLVM_CONFIG = "vm/external_libs/llvm/Release/bin/llvm-config"
+LLVM_CONFIG = "vm/external_libs/llvm/#{LLVM_STYLE}/bin/llvm-config"
tests = FileList["vm/test/test_*.hpp"]
# vm/test/test_instructions.hpp may not have been generated yet
@@ -69,19 +71,23 @@ field_extract_headers = %w[
]
BC = "vm/instructions.bc"
-LLVM_A = "vm/external_libs/llvm/Release/lib/libLLVMSystem.a"
+LLVM_A = "vm/external_libs/llvm/#{LLVM_STYLE}/lib/libLLVMSystem.a"
EXTERNALS = %W[ #{LLVM_A}
vm/external_libs/libtommath/libtommath.a
vm/external_libs/onig/.libs/libonig.a
vm/external_libs/libffi/.libs/libffi.a
vm/external_libs/libltdl/.libs/libltdl.a
vm/external_libs/libev/.libs/libev.a ]
OPTIONS = {
- LLVM_A => "--enable-targets=host-only --enable-optimized"
+ LLVM_A => "--enable-targets=host-only"
}
+if LLVM_STYLE == "Release"
+ OPTIONS[LLVM_A] << " --enable-optimized"
+end
+
INCLUDES = (EX_INC + %w[vm/test/cxxtest vm .]).map { |f| "-I#{f}" }
-FLAGS = %w(-Wall -ggdb -gdwarf-2)
+FLAGS = %w(-Wall -Werror -ggdb -gdwarf-2)
CC = ENV['CC'] || "gcc"
@@ -215,6 +221,14 @@ file 'vm/test/runner' => EXTERNALS + objs + %w[vm/test/runner.o] do |t|
link t
end
+# A simple JIT tester driver
+
+file 'vm/drivers/compile.o' => 'vm/drivers/compile.cpp'
+
+file 'vm/compile' => EXTERNALS + objs + %w[vm/drivers/compile.o] do |t|
+ link t
+end
+
rubypp_task 'vm/instructions.o', 'vm/llvm/instructions.cpp' do |path|
compile 'vm/instructions.o', path
end
@@ -45,6 +45,7 @@ namespace rubinius {
ctx->vmm = vmm;
ctx->ip = 0;
ctx->sp = -1;
+ ctx->js.stack = ctx->stack->field + ctx->sp;
return ctx;
}
@@ -10,6 +10,7 @@
#include "builtin/staticscope.hpp"
#include "builtin/symbol.hpp"
#include "builtin/tuple.hpp"
+#include "builtin/string.hpp"
namespace rubinius {
CompiledMethod* CompiledMethod::create(STATE) {
@@ -27,6 +28,7 @@ namespace rubinius {
SET(cm, stack_size, Object::i2n(1));
SET(cm, required_args, Object::i2n(0));
SET(cm, total_args, cm->required_args);
+ SET(cm, name, String::create(state, "__halt__")->to_sym(state));
SET(cm, iseq, InstructionSequence::create(state, 1));
cm->iseq->opcodes->put(state, 0, Object::i2n(InstructionSequence::insn_halt));
@@ -59,12 +61,17 @@ namespace rubinius {
}
}
VMMethod* vmm;
- if(ondemand) {
- vmm = new VMLLVMMethodUncompiled(state, this);
+ /* Controls whether we use LLVM out of the gate or not. */
+ if(state->config.compile_up_front) {
+ if(ondemand) {
+ vmm = new VMLLVMMethodUncompiled(state, this);
+ } else {
+ VMLLVMMethod* llvm = new VMLLVMMethod(state, this);
+ llvm->compile(state);
+ vmm = llvm;
+ }
} else {
- VMLLVMMethod* llvm = new VMLLVMMethod(state, this);
- llvm->compile();
- vmm = llvm;
+ vmm = new VMMethod(state, this);
}
executable = vmm;
return vmm;
View
@@ -3,6 +3,8 @@
#include "builtin/object.hpp"
#include "type_info.hpp"
+#include "vmmethod.hpp"
+#include "jit_state.h"
namespace rubinius {
class BlockContext;
@@ -29,6 +31,7 @@ namespace rubinius {
Tuple* stack; // slot
+ struct jit_state js;
int ip;
int sp;
size_t args;
@@ -41,6 +44,30 @@ namespace rubinius {
static MethodContext* create(STATE);
void reference(STATE);
+ /* Stack manipulation functions */
+
+ void clear_stack(size_t amount) {
+ sp -= amount;
+ js.stack -= amount;
+ }
+
+ OBJECT pop() {
+ return *js.stack--;
+ }
+
+ void push(OBJECT value) {
+ *++js.stack = value;
+ }
+
+ OBJECT stack_back(size_t position) {
+ OBJECT* pos = js.stack - position;
+ return *pos;
+ }
+
+ void set_top(OBJECT val) {
+ *js.stack = val;
+ }
+
class Info : public TypeInfo {
public:
BASIC_TYPEINFO(TypeInfo)
View
@@ -43,7 +43,6 @@ namespace rubinius {
Task* Task::create(STATE) {
Task* task = (Task*)state->new_struct(G(task), sizeof(Task));
task->ip = 0;
- task->sp = -1;
task->state = state;
task->probe = state->probe;
task->msg = new Message(state);
@@ -52,7 +51,6 @@ namespace rubinius {
SET(task, self, G(main));
SET(task, literals, Qnil);
SET(task, exception, Qnil);
- SET(task, stack, Qnil);
SET(task, home, Qnil);
CompiledMethod* cm = CompiledMethod::generate_tramp(state);
@@ -76,29 +74,27 @@ namespace rubinius {
ctx->vmm = (VMMethod*)meth->executable;
ctx->ip = 0;
ctx->sp = meth->number_of_locals() - 1;
+ ctx->js.stack = ctx->stack->field + ctx->sp;
return ctx;
}
void Task::restore_context(MethodContext* ctx) {
SET(this, literals, ctx->cm->literals);
- SET(this, stack, ctx->stack);
SET(this, active, ctx);
SET(this, home, ctx->home);
SET(this, self, home->self);
ip = ctx->ip;
ip_ptr = ctx->vmm->opcodes + ip;
- sp = ctx->sp;
}
void Task::make_active(MethodContext* ctx) {
/* Save the current Task registers into active. */
if(!active->nil_p()) {
active->ip = ip;
- active->sp = sp;
}
SET(ctx, sender, active);
@@ -153,7 +149,7 @@ namespace rubinius {
/* Now that we've processed everything from the stack, we need to clean it up */
stack_cleanup:
- sp -= msg.stack;
+ active->clear_stack(msg.stack);
}
/* Only called if send_message can't locate anything to run, which pretty
@@ -197,12 +193,12 @@ namespace rubinius {
MethodContext *target = active->sender;
restore_context(target);
- stack->put(state, ++sp, value);
+ active->push(value);
}
/* Called after a primitive has executed and wants to return a value. */
void Task::primitive_return(OBJECT value, Message& msg) {
- sp -= msg.stack;
+ active->clear_stack(msg.stack);
push(value);
}
@@ -487,12 +483,28 @@ namespace rubinius {
return mod;
}
+ /* Used in testing. Sets the stack of the current context to +stack+ */
+ void Task::set_stack(Tuple* stack) {
+ SET(active, stack, stack);
+ /* the - 1 is because the stack starts below the bottom, so push
+ * always increments and sets. */
+ active->js.stack = stack->field - 1;
+ }
+
+ Tuple* Task::current_stack() {
+ return active->stack;
+ }
+
void Task::push(OBJECT val) {
- stack->put(state, ++sp, val);
+ active->push(val);
}
OBJECT Task::pop() {
- return stack->at(sp--);
+ return active->pop();
+ }
+
+ int Task::calculate_sp() {
+ return active->js.stack - active->stack->field;
}
void Task::activate_method(Message&) { }
@@ -510,18 +522,6 @@ namespace rubinius {
}
}
- void Task::print_stack() {
- for(size_t i = 0; i < stack->field_count; i++) {
- if(i == (size_t)sp) {
- std::cout << "=> ";
- } else {
- std::cout << " ";
- }
-
- stack->field[i]->show(state);
- }
- }
-
void Task::execute() {
if(active->nil_p()) return;
View
@@ -33,7 +33,6 @@ namespace rubinius {
/* 'registers' */
native_int ip;
- int sp;
OBJECT self; // slot
Tuple* literals; // slot
@@ -46,11 +45,10 @@ namespace rubinius {
opcode blockargs;
/* Internal data */
- Tuple* stack; // slot
STATE;
Message* msg;
- jit_state js;
TaskProbe *probe;
+ struct jit_state js;
/* Optimization */
opcode *ip_ptr;
@@ -102,6 +100,9 @@ namespace rubinius {
void execute_stream(opcode* stream);
void push(OBJECT val);
OBJECT pop();
+ int calculate_sp();
+ void set_stack(Tuple* stack);
+ Tuple* current_stack();
void print_stack();
void tragic_failure(Message& msg);
View
@@ -5,6 +5,7 @@
#include "builtin/fixnum.hpp"
#include "builtin/symbol.hpp"
#include "builtin/task.hpp"
+#include "builtin/contexts.hpp"
#include "objectmemory.hpp"
#include "vm.hpp"
@@ -19,7 +20,7 @@ namespace rubinius {
GO(thread).set(state->new_class("Thread", Thread::fields));
G(thread)->set_object_type(Thread::type);
-
+
G(thread)->set_const(state, "ScheduledThreads", tup);
}
@@ -44,9 +45,9 @@ namespace rubinius {
}
void Thread::set_top(STATE, OBJECT val) {
- task->stack->put(state, task->sp, val);
+ task->active->set_top(val);
}
-
+
void Thread::sleep_for(STATE, Channel* chan) {
channel = chan;
set_ivar(state, state->symbol("@sleep"), Qtrue);
View
@@ -33,7 +33,7 @@ namespace rubinius {
}
bool CompiledFile::execute(STATE) {
- TypedRoot<Task*> task(state, Task::create(state));
+ TypedRoot<Task*> task(state, state->new_task());
TypedRoot<CompiledMethod*> cm(state, as<CompiledMethod>(body(state)));
Message msg(state);
Oops, something went wrong.

0 comments on commit 310a461

Please sign in to comment.