[macruby-changes] [3117] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Dec 14 17:42:49 PST 2009
Revision: 3117
http://trac.macosforge.org/projects/ruby/changeset/3117
Author: lsansonetti at apple.com
Date: 2009-12-14 17:42:46 -0800 (Mon, 14 Dec 2009)
Log Message:
-----------
emit dwarf metadata at compilation time and use it to establish backtracing later at runtime
Modified Paths:
--------------
MacRuby/trunk/bridgesupport.cpp
MacRuby/trunk/compiler.cpp
MacRuby/trunk/compiler.h
MacRuby/trunk/llvm.h
MacRuby/trunk/vm.cpp
Modified: MacRuby/trunk/bridgesupport.cpp
===================================================================
--- MacRuby/trunk/bridgesupport.cpp 2009-12-15 01:33:42 UTC (rev 3116)
+++ MacRuby/trunk/bridgesupport.cpp 2009-12-15 01:42:46 UTC (rev 3117)
@@ -13,6 +13,7 @@
#include <llvm/Instructions.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Intrinsics.h>
+#include <llvm/Analysis/DebugInfo.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/PassManager.h>
#include <llvm/Target/TargetData.h>
Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp 2009-12-15 01:33:42 UTC (rev 3116)
+++ MacRuby/trunk/compiler.cpp 2009-12-15 01:42:46 UTC (rev 3117)
@@ -8,6 +8,10 @@
#define ROXOR_COMPILER_DEBUG 0
+#if !defined(DW_LANG_Ruby)
+# define DW_LANG_Ruby 0x15 // TODO: Python is 0x14, request a real number
+#endif
+
#include "llvm.h"
#include "ruby/ruby.h"
#include "ruby/encoding.h"
@@ -17,6 +21,7 @@
#include "vm.h"
#include "compiler.h"
#include "objc.h"
+#include "version.h"
extern "C" const char *ruby_node_name(int node);
@@ -26,6 +31,9 @@
RoxorCompiler::RoxorCompiler(void)
{
+ assert(RoxorCompiler::module != NULL);
+ debug_info = new DIFactory(*RoxorCompiler::module);
+
fname = "";
inside_eval = false;
@@ -58,7 +66,6 @@
return_from_block = -1;
return_from_block_ids = 0;
ensure_pn = NULL;
- current_scope = NULL;
dispatcherFunc = NULL;
fastPlusFunc = NULL;
@@ -737,10 +744,11 @@
(module->getOrInsertFunction("rb_vm_dispatch", ft));
}
- assert(current_scope != NULL);
- current_scope->dispatch_lines.push_back(current_line);
-
- return compile_protected_call(dispatcherFunc, params);
+ Instruction *insn = compile_protected_call(dispatcherFunc, params);
+ if (fname != NULL) {
+ debug_info->InsertStopPoint(debug_compile_unit, current_line, 0, bb);
+ }
+ return insn;
}
Value *
@@ -3096,10 +3104,6 @@
Function *f = Function::Create(ft, GlobalValue::ExternalLinkage,
function_name, module);
- RoxorScope *old_current_scope = current_scope;
- current_scope = new RoxorScope(fname);
- scopes[f] = current_scope;
-
BasicBlock *old_rescue_invoke_bb = rescue_invoke_bb;
BasicBlock *old_rescue_rethrow_bb = rescue_rethrow_bb;
BasicBlock *old_entry_bb = entry_bb;
@@ -3110,6 +3114,13 @@
rescue_rethrow_bb = NULL;
bb = BasicBlock::Create(context, "MainBlock", f);
+ DISubprogram old_debug_subprogram = debug_subprogram;
+ debug_subprogram = debug_info->CreateSubprogram(
+ debug_compile_unit, f->getName(), f->getName(),
+ f->getName(), debug_compile_unit, nd_line(node),
+ DIType(), f->hasInternalLinkage(), true);
+ debug_info->InsertSubprogramStart(debug_subprogram, bb);
+
std::map<ID, Value *> old_lvars = lvars;
lvars.clear();
Value *old_self = current_self;
@@ -3360,7 +3371,7 @@
current_self = old_self;
current_var_uses = old_current_var_uses;
running_block = old_running_block;
- current_scope = old_current_scope;
+ debug_subprogram = old_debug_subprogram;
return cast<Value>(f);
}
@@ -5300,6 +5311,19 @@
return NULL;
}
+void
+RoxorCompiler::set_fname(const char *_fname)
+{
+ if (fname != _fname) {
+ fname = _fname;
+
+ if (fname != NULL) {
+ debug_compile_unit = debug_info->CreateCompileUnit(DW_LANG_Ruby,
+ fname, "", RUBY_DESCRIPTION, false, false, "");
+ }
+ }
+}
+
Function *
RoxorCompiler::compile_main_function(NODE *node)
{
Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h 2009-12-15 01:33:42 UTC (rev 3116)
+++ MacRuby/trunk/compiler.h 2009-12-15 01:42:46 UTC (rev 3117)
@@ -27,14 +27,6 @@
#define DEFINED_SUPER 6
#define DEFINED_METHOD 7
-class RoxorScope {
- public:
- std::string path;
- std::vector<unsigned int> dispatch_lines;
-
- RoxorScope(const char *fname) : path(fname) {}
-};
-
class RoxorCompiler {
public:
static llvm::Module *module;
@@ -43,9 +35,7 @@
RoxorCompiler(void);
virtual ~RoxorCompiler(void) { }
- void set_fname(const char *_fname) {
- fname = _fname;
- }
+ void set_fname(const char *_fname);
Value *compile_node(NODE *node);
@@ -71,26 +61,11 @@
bool is_dynamic_class(void) { return dynamic_class; }
void set_dynamic_class(bool flag) { dynamic_class = flag; }
- RoxorScope *scope_for_function(Function *f) {
- std::map<Function *, RoxorScope *>::iterator i = scopes.find(f);
- return i == scopes.end() ? NULL : i->second;
- }
-
- bool delete_scope(Function *f) {
- std::map<Function *, RoxorScope *>::iterator i = scopes.find(f);
- if (i != scopes.end()) {
- scopes.erase(i);
- delete i->second;
- return true;
- }
- return false;
- }
-
- void clear_scopes(void) {
- scopes.clear();
- }
-
protected:
+ DIFactory *debug_info;
+ DICompileUnit debug_compile_unit;
+ DISubprogram debug_subprogram;
+
const char *fname;
bool inside_eval;
@@ -99,7 +74,6 @@
std::map<ID, Value *> ivar_slots_cache;
std::map<std::string, GlobalVariable *> static_strings;
std::map<CFHashCode, GlobalVariable *> static_ustrings;
- std::map<Function *, RoxorScope *> scopes;
#if ROXOR_COMPILER_DEBUG
int level;
@@ -142,7 +116,6 @@
int return_from_block;
int return_from_block_ids;
PHINode *ensure_pn;
- RoxorScope *current_scope;
bool class_declaration;
Function *dispatcherFunc;
Modified: MacRuby/trunk/llvm.h
===================================================================
--- MacRuby/trunk/llvm.h 2009-12-15 01:33:42 UTC (rev 3116)
+++ MacRuby/trunk/llvm.h 2009-12-15 01:42:46 UTC (rev 3117)
@@ -11,6 +11,7 @@
#include <llvm/Instructions.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Intrinsics.h>
+#include <llvm/Analysis/DebugInfo.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/PassManager.h>
#include <llvm/Target/TargetData.h>
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2009-12-15 01:33:42 UTC (rev 3116)
+++ MacRuby/trunk/vm.cpp 2009-12-15 01:42:46 UTC (rev 3117)
@@ -16,10 +16,13 @@
#include <llvm/Instructions.h>
#include <llvm/ModuleProvider.h>
#include <llvm/PassManager.h>
+#include <llvm/Analysis/DebugInfo.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Target/TargetData.h>
+#include <llvm/CodeGen/MachineFunction.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/JITMemoryManager.h>
+#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Target/TargetMachine.h>
@@ -61,35 +64,55 @@
VALUE rb_cTopLevel = 0;
-struct RoxorFunction {
- Function *f;
- RoxorScope *scope;
- unsigned char *start;
- unsigned char *end;
- void *imp;
- std::vector<unsigned char *> ehs;
+class RoxorFunction {
+ public:
+ // Information retrieved from JITManager.
+ Function *f;
+ unsigned char *start;
+ unsigned char *end;
+ std::vector<unsigned char *> ehs;
- RoxorFunction(Function *_f, RoxorScope *_scope, unsigned char *_start,
- unsigned char *_end) {
- f = _f;
- scope = _scope;
- start = _start;
- end = _end;
- imp = NULL; // lazy
- }
+ // Information retrieved from JITListener.
+ std::string file;
+ class Line {
+ public:
+ uintptr_t address;
+ unsigned line;
+ Line(uintptr_t _address, unsigned _line) {
+ address = _address;
+ line = _line;
+ }
+ };
+ std::vector<Line> lines;
+
+ // Information retrieved later (lazily).
+ void *imp;
+
+ RoxorFunction(Function *_f, unsigned char *_start,
+ unsigned char *_end) {
+ f = _f;
+ start = _start;
+ end = _end;
+ imp = NULL;
+ }
};
-class RoxorJITManager : public JITMemoryManager {
+class RoxorJITManager : public JITMemoryManager, public JITEventListener {
private:
JITMemoryManager *mm;
std::vector<struct RoxorFunction *> functions;
+ RoxorFunction *current_function(void) {
+ assert(!functions.empty());
+ return functions.back();
+ }
+
public:
RoxorJITManager() : JITMemoryManager() {
mm = CreateDefaultMemManager();
}
- struct RoxorFunction *find_function(uint8_t *addr) {
+ RoxorFunction *find_function(uint8_t *addr) {
if (functions.empty()) {
return NULL;
}
@@ -125,6 +148,8 @@
return NULL;
}
+ // JITMemoryManager callbacks.
+
void setMemoryWritable(void) {
mm->setMemoryWritable();
}
@@ -172,8 +197,7 @@
uint8_t *FunctionEnd) {
mm->endFunctionBody(F, FunctionStart, FunctionEnd);
Function *f = const_cast<Function *>(F);
- RoxorScope *s = RoxorCompiler::shared->scope_for_function(f);
- functions.push_back(new RoxorFunction(f, s, FunctionStart,
+ functions.push_back(new RoxorFunction(f, FunctionStart,
FunctionEnd));
}
@@ -198,14 +222,37 @@
void endExceptionTable(const Function *F, uint8_t *TableStart,
uint8_t *TableEnd, uint8_t* FrameRegister) {
- assert(!functions.empty());
- functions.back()->ehs.push_back(FrameRegister);
+ current_function()->ehs.push_back(FrameRegister);
mm->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
}
void setPoisonMemory(bool poison) {
mm->setPoisonMemory(poison);
}
+
+ // JITEventListener callbacks.
+
+ void NotifyFunctionEmitted(const Function &F,
+ void *Code, size_t Size,
+ const EmittedFunctionDetails &Details)
+ {
+ RoxorFunction *function = current_function();
+
+ std::string file;
+ for (std::vector<EmittedFunctionDetails::LineStart>::const_iterator iter = Details.LineStarts.begin(); iter != Details.LineStarts.end(); ++iter) {
+ DebugLocTuple dlt = Details.MF->getDebugLocTuple(iter->Loc);
+ if (file.size() == 0) {
+ DICompileUnit unit(dlt.CompileUnit);
+ unit.getFilename(file);
+ assert(file.size() != 0);
+ }
+
+ RoxorFunction::Line line(iter->Address, dlt.Line);
+ function->lines.push_back(line);
+ }
+
+ function->file = file;
+ }
};
extern "C" void *__cxa_allocate_exception(size_t);
@@ -248,6 +295,7 @@
abort();
}
ee->DisableLazyCompilation();
+ ee->RegisterJITEventListener(jmm);
fpm = new FunctionPassManager(emp);
fpm->add(new TargetData(*ee->getTargetData()));
@@ -482,7 +530,6 @@
}
// Remove the compiler scope.
- RoxorCompiler::shared->delete_scope(func);
delete f;
// Delete machine code.
@@ -526,49 +573,21 @@
}
rb_vm_method_node_t *node = iter->second;
-
- RoxorScope *scope = f == NULL ? NULL : f->scope;
if (ln != NULL) {
- if (scope != NULL) {
-#if __LP64__
- // So, we need to determine here which call to the dispatcher
- // we are exactly, so that we can retrieve the appropriate
- // line number from the annotation.
- // Unfortunately, the only way to achieve that seems to scan
- // the current function's machine code.
- // This code has only been tested on x86_64 but could be
- // easily ported to i386.
- const uint32_t sym = *(uint32_t *)((unsigned char *)addr - 8);
- const int sentinel = sym & 0xff;
-
- unsigned char *p = f->start;
- unsigned int i = 0;
- while ((p = (unsigned char *)memchr(p, sentinel,
- (unsigned char *)addr - p)) != NULL) {
- if (*(uint32_t *)p == sym) {
- i++;
+ *ln = 0;
+ if (f != NULL) {
+ for (std::vector<RoxorFunction::Line>::iterator iter =
+ f->lines.begin(); iter != f->lines.end(); ++iter) {
+ if ((*iter).address == (uintptr_t)addr) {
+ *ln = (*iter).line;
+ break;
}
- p++;
}
-
- if (i > 0 && i - 1 < scope->dispatch_lines.size()) {
- *ln = scope->dispatch_lines[i - 1];
- }
- else {
- *ln = 0;
- }
-#else
- // TODO 32-bit hack...
- *ln = 0;
-#endif
}
- else {
- *ln = 0;
- }
}
if (path != NULL) {
- if (scope != NULL) {
- strncpy(path, scope->path.c_str(), path_len);
+ if (f != NULL && f->file.size() > 0) {
+ strncpy(path, f->file.c_str(), path_len);
}
else {
strncpy(path, "core", path_len);
@@ -3765,6 +3784,8 @@
return rb_vm_run(fname, node, binding, inside_eval);
}
+extern VALUE rb_progname;
+
extern "C"
void
rb_vm_aot_compile(NODE *node)
@@ -3773,6 +3794,7 @@
assert(ruby_aot_init_func);
// Compile the program as IR.
+ RoxorCompiler::shared->set_fname(RSTRING_PTR(rb_progname));
Function *f = RoxorCompiler::shared->compile_main_function(node);
f->setName(RSTRING_PTR(ruby_aot_init_func));
GET_CORE()->optimize(f);
@@ -4622,6 +4644,7 @@
Init_PreVM(void)
{
llvm::DwarfExceptionHandling = true; // required!
+ llvm::JITEmitDebugInfo = true;
RoxorCompiler::module = new llvm::Module("Roxor", getGlobalContext());
RoxorCompiler::module->setTargetTriple(TARGET_TRIPLE);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091214/dec36a48/attachment-0001.html>
More information about the macruby-changes
mailing list