Skip to content

Commit

Permalink
Handle breaking out of a block, enhance rbx.jit.dump_code
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Phoenix committed May 16, 2009
1 parent 6338aa5 commit 0de71f8
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 11 deletions.
7 changes: 5 additions & 2 deletions kernel/delta/rubinius.rb
Expand Up @@ -119,8 +119,11 @@ def self.received_signal(sig)
end

def self.jit(meth)
mm = meth.compiled_method.make_machine_method
if mm
cm = meth.compiled_method

return unless cm.respond_to? :make_machine_method

if mm = cm.make_machine_method
unless mm.activate
if $DEBUG
puts
Expand Down
5 changes: 3 additions & 2 deletions vm/configuration.hpp
Expand Up @@ -14,7 +14,7 @@ namespace rubinius {
// JIT/Interpreter
config::Bool jit_enabled;
config::Bool dynamic_interpreter_enabled;
config::Bool jit_dump_code;
config::Integer jit_dump_code;

// Debug
config::Bool print_config;
Expand All @@ -23,14 +23,15 @@ namespace rubinius {
static const int default_gc_bytes = 1048576 * 3;
static const int default_gc_large_object = 2700;
static const int default_gc_lifetime = 6;
static const int default_jit_dump_code = 0;

Configuration()
: gc_bytes(this, "rbx.gc.bytes", default_gc_bytes)
, gc_large_object(this, "rbx.gc.large_object", default_gc_large_object)
, gc_lifetime(this, "rbx.gc.lifetime", default_gc_lifetime)
, jit_enabled(this, "rbx.jit.enabled")
, dynamic_interpreter_enabled(this, "rbx.interpreter.dynamic")
, jit_dump_code(this, "rbx.jit.dump_code")
, jit_dump_code(this, "rbx.jit.dump_code", default_jit_dump_code)
, print_config(this, "config.print")
{}
};
Expand Down
13 changes: 12 additions & 1 deletion vm/llvm/jit.cpp
Expand Up @@ -452,12 +452,18 @@ namespace rubinius {
*/

if(state->shared.config.jit_dump_code) {
if(state->shared.config.jit_dump_code & cSimple) {
std::cout << "[[[ LLVM Simple IR ]]]\n";
std::cout << *func << "\n";
}

LLVMState::get(state)->passes()->run(*func);

if(state->shared.config.jit_dump_code & cOptimized) {
std::cout << "[[[ LLVM Optimized IR ]]]\n";
std::cout << *func << "\n";
}

function_ = func;
}

Expand All @@ -466,6 +472,11 @@ namespace rubinius {
if(!function_) return NULL;
mci_ = new llvm::MachineCodeInfo();
LLVMState::get(state)->engine()->runJITOnFunction(function_, mci_);

if(state->shared.config.jit_dump_code & cMachineCode) {
std::cout << "[[[ JIT Machine Code ]]]\n";
assembler_x86::AssemblerX86::show_buffer(mci_->address(), mci_->size(), false, NULL);
}
}

return mci_->address();
Expand Down
6 changes: 6 additions & 0 deletions vm/llvm/jit.hpp
Expand Up @@ -21,6 +21,12 @@

namespace rubinius {

enum JitDebug {
cSimple = 1,
cOptimized = 2,
cMachineCode = 4
};

class LLVMState {
llvm::Module* module_;
llvm::ExistingModuleProvider* mp_;
Expand Down
7 changes: 7 additions & 0 deletions vm/llvm/jit_util.cpp
Expand Up @@ -533,6 +533,13 @@ extern "C" {
return false;
}

bool rbx_break_to_here(STATE, CallFrame* call_frame) {
ThreadState* th = state->thread_state();
if(th->raise_reason() != cBreak) return false;
if(th->destination_scope() == call_frame->scope) return true;
return false;
}

Object* rbx_clear_raise_value(STATE) {
Object* val = state->thread_state()->raise_value();
state->thread_state()->clear_exception(true);
Expand Down
52 changes: 47 additions & 5 deletions vm/llvm/jit_visit.hpp
Expand Up @@ -145,20 +145,64 @@ namespace rubinius {
}

void check_for_return(Value* val) {

BasicBlock* cont = BasicBlock::Create("continue", function_);
BasicBlock* push_val = BasicBlock::Create("push_val", function_);

Value* null = Constant::getNullValue(ObjType);

Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, val, null, "null_check", block_);
BasicBlock* is_break = BasicBlock::Create("is_break", function_);
BranchInst::Create(is_break, push_val, cmp, block_);

/////
std::vector<const Type*> types;
types.push_back(VMTy);
types.push_back(CallFrameTy);

FunctionType* ft = FunctionType::get(Type::Int1Ty, types, false);
Function* func = cast<Function>(
module_->getOrInsertFunction("rbx_break_to_here", ft));

Value* call_args[] = {
vm_,
call_frame_
};

Value* isit = CallInst::Create(func, call_args, call_args+2, "bth", is_break);

BasicBlock* push_break_val = BasicBlock::Create("push_break_val", function_);
BasicBlock* next = 0;

// If there are handlers...
if(exception_handlers_.size() > 0) {
ExceptionHandler* handler = exception_handlers_.back();
BranchInst::Create(handler->code(), cont, cmp, block_);
next = handler->code();
} else {
BranchInst::Create(bail_out_, cont, cmp, block_);
next = bail_out_;
}

BranchInst::Create(push_break_val, next, isit, is_break);

////
std::vector<const Type*> types2;
types2.push_back(VMTy);

FunctionType* ft2 = FunctionType::get(ObjType, types2, false);
Function* func2 = cast<Function>(
module_->getOrInsertFunction("rbx_clear_raise_value", ft2));

Value* call_args2[] = { vm_ };

Value* crv = CallInst::Create(func2, call_args2, call_args2+1, "crv", push_break_val);
stack_push(crv, push_break_val);

BranchInst::Create(cont, push_break_val);

/////
stack_push(val, push_val);
BranchInst::Create(cont, push_val);

/////
block_ = cont;
}

Expand Down Expand Up @@ -925,7 +969,6 @@ namespace rubinius {
Value* ret = block_send(cache->name, args, block_, allow_private_);
stack_remove(args + 2);
check_for_return(ret);
stack_push(ret);
allow_private_ = false;
}

Expand Down Expand Up @@ -977,7 +1020,6 @@ namespace rubinius {
Value* ret = super_send(cache->name, args);
stack_remove(args + 1);
check_for_return(ret);
stack_push(ret);
}

void visit_send_super_stack_with_splat(opcode which, opcode args) {
Expand Down
7 changes: 6 additions & 1 deletion vm/util/configuration.hpp
Expand Up @@ -66,7 +66,12 @@ namespace config {
{}

virtual void set(const char* str) {
value = strtol(str, NULL, 0);
// true means either likely they set it with no value
if(strcmp("true", str) == 0) {
value = 1;
} else {
value = strtol(str, NULL, 0);
}
}

virtual void print_value() {
Expand Down

0 comments on commit 0de71f8

Please sign in to comment.