Skip to content

Commit

Permalink
Support JIT-ed method profiling
Browse files Browse the repository at this point in the history
  • Loading branch information
ryoqun committed Mar 6, 2013
1 parent 28f0e93 commit 4d6e554
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 47 deletions.
3 changes: 2 additions & 1 deletion rakelib/blueprint.rb
Expand Up @@ -49,7 +49,7 @@
gcc.cflags << "-D#{flag}"
end

gcc.ldflags << "-lstdc++" << "-lm"
gcc.ldflags << "-lstdc++" << "-lm" << "-lbfd"

Rubinius::BUILD_CONFIG[:lib_dirs].each do |path|
gcc.ldflags << "-L#{path}" if File.exists? path
Expand Down Expand Up @@ -212,6 +212,7 @@

ldflags = `#{conf} --ldflags`.strip.split(/\s+/)
objects = `#{conf} --libfiles`.strip.split(/\s+/)
objects << "/usr/lib/libbfd.a"

if Rubinius::BUILD_CONFIG[:windows]
ldflags = ldflags.sub(%r[-L/([a-zA-Z])/], '-L\1:/')
Expand Down
14 changes: 9 additions & 5 deletions vm/builtin/compiledcode.cpp
Expand Up @@ -87,20 +87,24 @@ namespace rubinius {
return as<Fixnum>(lines_->at(1))->to_native();
}

int CompiledCode::line(STATE, int ip) {
int CompiledCode::line(int ip) {
if(lines_->nil_p()) return -3;

native_int fin = lines_->num_fields() - 2;
for(native_int i = 0; i < fin; i += 2) {
Fixnum* start_ip = as<Fixnum>(lines_->at(state, i));
Fixnum* end_ip = as<Fixnum>(lines_->at(state, i+2));
Fixnum* start_ip = as<Fixnum>(lines_->at(i));
Fixnum* end_ip = as<Fixnum>(lines_->at(i+2));

if(start_ip->to_native() <= ip && end_ip->to_native() > ip) {
return as<Fixnum>(lines_->at(state, i+1))->to_native();
return as<Fixnum>(lines_->at(i+1))->to_native();
}
}

return as<Fixnum>(lines_->at(state, fin+1))->to_native();
return as<Fixnum>(lines_->at(fin+1))->to_native();
}

int CompiledCode::line(STATE, int ip) {
return line(ip);
}

MachineCode* CompiledCode::internalize(STATE, GCToken gct,
Expand Down
1 change: 1 addition & 0 deletions vm/builtin/compiledcode.hpp
Expand Up @@ -92,6 +92,7 @@ namespace rubinius {
int start_line(STATE);
int start_line();
int line(STATE, int ip);
int line(int ip);

void post_marshal(STATE);
size_t number_of_locals();
Expand Down
22 changes: 11 additions & 11 deletions vm/builtin/tuple.cpp
Expand Up @@ -124,9 +124,9 @@ namespace rubinius {
native_int osize = other->num_fields();
native_int size = this->num_fields();

native_int src_start = start->to_native();
native_int dst_start = dest->to_native();
native_int len = length->to_native();
int src_start = start->to_native();
int dst_start = dest->to_native();
int len = length->to_native();

// left end should be within range
if(src_start < 0 || src_start > osize) {
Expand Down Expand Up @@ -189,10 +189,10 @@ namespace rubinius {
}

Fixnum* Tuple::delete_inplace(STATE, Fixnum *start, Fixnum *length, Object *obj) {
native_int size = this->num_fields();
native_int len = length->to_native();
native_int lend = start->to_native();
native_int rend = lend + len;
int size = this->num_fields();
int len = length->to_native();
int lend = start->to_native();
int rend = lend + len;

if(size == 0 || len == 0) return Fixnum::from(0);
if(lend < 0 || lend >= size) {
Expand All @@ -203,10 +203,10 @@ namespace rubinius {
return force_as<Fixnum>(bounds_exceeded_error(state, "Tuple::delete_inplace", rend));
}

native_int i = lend;
int i = lend;
while(i < rend) {
if(this->at(i) == obj) {
native_int j = i;
if(this->at(state,i) == obj) {
int j = i;
++i;
while(i < rend) {
Object *val = this->field[i];
Expand Down Expand Up @@ -236,7 +236,7 @@ namespace rubinius {
*/
Tuple* Tuple::lshift_inplace(STATE, Fixnum* shift) {
native_int size = this->num_fields();
const native_int start = shift->to_native();
const int start = shift->to_native();

assert(start >= 0);

Expand Down
18 changes: 9 additions & 9 deletions vm/capi/array.cpp
Expand Up @@ -48,8 +48,8 @@ namespace rubinius {
Tuple* tuple = array->tuple();
RArray* rarray = handle->as_rarray(env);

native_int size = tuple->num_fields();
native_int num = 0;
size_t size = tuple->num_fields();
size_t num = 0;

if(rarray->ptr != rarray->dmwmb) {
// This is a very bad C extension. Assume len is valid.
Expand All @@ -66,7 +66,7 @@ namespace rubinius {
array->start(env->state(), Fixnum::from(0));
array->total(env->state(), Fixnum::from(rarray->len));

for(native_int i = 0; i < num; i++) {
for(size_t i = 0; i < num; i++) {
tuple->put(env->state(), i, env->get_object(rarray->ptr[i]));
}
}
Expand All @@ -91,9 +91,9 @@ namespace rubinius {
Tuple* tuple = array->tuple();
RArray* rarray = handle->as_rarray(env);

native_int size = tuple->num_fields();
native_int start = array->start()->to_native();
native_int num = 0;
ssize_t size = tuple->num_fields();
ssize_t start = array->start()->to_native();
ssize_t num = 0;

if(rarray->ptr != rarray->dmwmb) {
// This is a very bad C extension. Assume len is valid
Expand All @@ -113,7 +113,7 @@ namespace rubinius {
env->shared().capi_ds_lock().unlock();
}

for(native_int i = 0, j = start; i < num && j < size; i++, j++) {
for(ssize_t i = 0, j = start; i < num && j < size; i++, j++) {
rarray->ptr[i] = env->get_handle(tuple->at(j));
}
}
Expand All @@ -139,11 +139,11 @@ namespace rubinius {
// have changed since we asked for the lock.
if(type_ != cRArray) {
Array* array = c_as<Array>(object());
native_int size = array->tuple()->num_fields();
size_t size = array->tuple()->num_fields();

RArray* ary = new RArray;
VALUE* ptr = new VALUE[size];
for(native_int i = 0; i < size; i++) {
for(size_t i = 0; i < size; i++) {
ptr[i] = env->get_handle(array->get(env->state(), i));
}

Expand Down
4 changes: 4 additions & 0 deletions vm/llvm/inline.cpp
Expand Up @@ -8,6 +8,9 @@

#include "llvm/stack_args.hpp"

#include "llvm/Analysis/DIBuilder.h"
#include "llvm/Analysis/DebugInfo.h"

#include "builtin/alias.hpp"
#include "builtin/methodtable.hpp"
#include "builtin/nativefunction.hpp"
Expand Down Expand Up @@ -572,6 +575,7 @@ namespace rubinius {

jit::InlineMethodBuilder work(ops_.context(), info, rd);
work.valid_flag = ops_.valid_flag();
work.record_source_location(code);

Value* blk = 0;

Expand Down
34 changes: 30 additions & 4 deletions vm/llvm/jit_builder.cpp
Expand Up @@ -11,19 +11,24 @@

#include "instruments/tooling.hpp"
#include <llvm/Analysis/CaptureTracking.h>
#include <llvm/Support/Dwarf.h>
#include "llvm/Analysis/DIBuilder.h"
#include "llvm/Analysis/DebugInfo.h"


namespace rubinius {
namespace jit {

Builder::Builder(Context* ctx, JITMethodInfo& i)
: ctx_(ctx)
, machine_code_(i.machine_code)
, builder_(ctx->llvm_context())
, builder_(ctx->llvm_context(), llvm::ConstantFolder(), IRBuilderInserterWithDebug(this))
, use_full_scope_(false)
, import_args_(0)
, body_(0)
, info_(i)
, runtime_data_(0)
, debug_builder_(*ctx->module())
{
llvm::Module* mod = ctx->module();
cf_type = mod->getTypeByName("struct.rubinius::CallFrame");
Expand All @@ -34,6 +39,24 @@ namespace jit {
check_global_interrupts_pos = b().CreateIntToPtr(
llvm::ConstantInt::get(ctx_->IntPtrTy, (intptr_t)ctx_->llvm_state()->shared().check_global_interrupts_address()),
llvm::PointerType::getUnqual(ctx_->Int8Ty), "cast_to_intptr");
debug_builder_.createCompileUnit(llvm::dwarf::DW_LANG_Python, "sample.rb", "/tmp", "runbininus", true, "-XXiinnt", 12343);
}

void Builder::record_source_location(CompiledCode *code) {
DICompileUnit cu(debug_builder().getCU());
DIFile di_file = debug_builder().createFile(ctx_->llvm_state()->symbol_debug_str(code->file()), "");
DIType di_type = debug_builder().createTemporaryType();
DISubprogram subprogram = debug_builder().createFunction(cu, "abcdef", "abjdie", di_file, 123, di_type, false, false, 0, 0, false, info_.function());
debug_builder().finalize();
b().SetCurrentDebugLocation(llvm::DebugLoc::get(code->start_line(), 0, subprogram));
//printf("set current\n");
}

void Builder::record_source_line(opcode ip) {
//printf("%ld => %d\n", ip, info_.method()->line(ip));
int line = info_.method()->line(ip);
DISubprogram subprogram(b().getCurrentDebugLocation().getScope(ctx_->llvm_context()));
b().SetCurrentDebugLocation(llvm::DebugLoc::get(line, 0, subprogram));
}

Value* Builder::get_field(Value* val, int which) {
Expand Down Expand Up @@ -493,14 +516,17 @@ namespace jit {
class Walker {
JITVisit& v_;
BlockMap& map_;
Builder& builder_;

public:
Walker(JITVisit& v, BlockMap& map)
Walker(JITVisit& v, BlockMap& map, Builder& builder)
: v_(v)
, map_(map)
, builder_(builder)
{}

void call(OpcodeIterator& iter) {
builder_.record_source_line(iter.ip());
v_.dispatch(iter.ip());

if(v_.b().GetInsertBlock()->getTerminator() == NULL) {
Expand All @@ -513,7 +539,7 @@ namespace jit {
};

bool Builder::generate_body() {
JITVisit visitor(ctx_, info_, block_map_, b().GetInsertBlock());
JITVisit visitor(this, info_, block_map_, b().GetInsertBlock());

if(info_.inline_policy) {
visitor.set_policy(info_.inline_policy);
Expand All @@ -535,7 +561,7 @@ namespace jit {
// Pass 2, compile!
// Drive by following the control flow.
jit::ControlFlowWalker walker(info_.machine_code);
Walker cb(visitor, block_map_);
Walker cb(visitor, block_map_, *this);

try {
walker.run<Walker>(cb);
Expand Down
15 changes: 13 additions & 2 deletions vm/llvm/jit_builder.hpp
Expand Up @@ -2,6 +2,7 @@
#define RBX_LLVM_BUILDER_HPP

#include "unwind_info.hpp"
#include "machine_code.hpp"

#include "llvm/jit_context.hpp"
#include "llvm/basic_block.hpp"
Expand All @@ -12,13 +13,17 @@
#else
#include <llvm/Support/IRBuilder.h>
#endif
#include <llvm/Analysis/DIBuilder.h>

namespace rubinius {
class InlinePolicy;
class MachineCode;
class JITMethodInfo;

namespace jit {



class RuntimeData;

class Builder {
Expand Down Expand Up @@ -52,7 +57,7 @@ namespace jit {

llvm::Value* check_global_interrupts_pos;

llvm::IRBuilder<> builder_;
IRBuilder builder_;

llvm::Value* call_frame_flags;
bool use_full_scope_;
Expand All @@ -69,13 +74,19 @@ namespace jit {
protected:
llvm::Value* counter2_;
jit::RuntimeData* runtime_data_;
llvm::DIBuilder debug_builder_;

public:

llvm::IRBuilder<>& b() { return builder_; }
IRBuilder& b() { return builder_; }

llvm::DIBuilder& debug_builder() { return debug_builder_; }

Builder(Context* ctx, JITMethodInfo& info);

void record_source_location(CompiledCode *);
void record_source_line(opcode ip);

void pass_one(llvm::BasicBlock* body);

void nil_stack(int size, llvm::Value* nil);
Expand Down
4 changes: 3 additions & 1 deletion vm/llvm/jit_compiler.cpp
Expand Up @@ -64,7 +64,7 @@ namespace jit {
if(indy) ctx_->llvm_state()->gc_independent();
if(ctx_->llvm_state()->jit_dump_code() & cSimple) {
llvm::outs() << "[[[ LLVM Simple IR ]]]\n";
llvm::outs() << *function_ << "\n";
llvm::outs() << *ctx_->module() << "\n";
}

std::vector<BasicBlock*> to_remove;
Expand Down Expand Up @@ -185,6 +185,7 @@ namespace jit {

jit::BlockBuilder work(ctx_, info);
work.setup();
work.record_source_location(code);

compile_builder(info, work);
ctx_->set_root(NULL);
Expand Down Expand Up @@ -236,6 +237,7 @@ namespace jit {

jit::MethodBuilder work(ctx_, info);
work.setup();
work.record_source_location(code);

compile_builder(info, work);
ctx_->set_root(NULL);
Expand Down

0 comments on commit 4d6e554

Please sign in to comment.