[macruby-changes] [2562] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Sep 18 01:30:16 PDT 2009
Revision: 2562
http://trac.macosforge.org/projects/ruby/changeset/2562
Author: lsansonetti at apple.com
Date: 2009-09-18 01:30:15 -0700 (Fri, 18 Sep 2009)
Log Message:
-----------
added preliminary support for backtracing/symbolication
Modified Paths:
--------------
MacRuby/trunk/compiler.cpp
MacRuby/trunk/compiler.h
MacRuby/trunk/vm.cpp
MacRuby/trunk/vm.h
Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp 2009-09-18 08:29:05 UTC (rev 2561)
+++ MacRuby/trunk/compiler.cpp 2009-09-18 08:30:15 UTC (rev 2562)
@@ -20,9 +20,13 @@
extern "C" const char *ruby_node_name(int node);
+// Will be set later, in vm.cpp.
llvm::Module *RoxorCompiler::module = NULL;
RoxorCompiler *RoxorCompiler::shared = NULL;
+AnnotationID RoxorFunctionAnnotation::id =
+ AnnotationManager::getID("RoxorFunction");
+
RoxorCompiler::RoxorCompiler(void)
{
fname = NULL;
@@ -128,6 +132,8 @@
setCurrentClassFunc = NULL;
getCacheFunc = NULL;
+ func_annotation = NULL;
+
#if __LP64__
RubyObjTy = IntTy = Type::Int64Ty;
#else
@@ -730,6 +736,9 @@
(module->getOrInsertFunction("rb_vm_dispatch", ft));
}
+ assert(func_annotation != NULL);
+ func_annotation->dispatch_lines.push_back(current_line);
+
return compile_protected_call(dispatcherFunc, params);
}
@@ -2944,6 +2953,7 @@
}
printf("... %s\n", ruby_node_name(nd_type(node)));
#endif
+ current_line = nd_line(node);
switch (nd_type(node)) {
case NODE_SCOPE:
@@ -2985,6 +2995,9 @@
Function *f = Function::Create(ft, GlobalValue::PrivateLinkage,
"", module);
+ RoxorFunctionAnnotation *old_func_annotation = func_annotation;
+ func_annotation = new RoxorFunctionAnnotation(f, fname);
+
BasicBlock *old_rescue_bb = rescue_bb;
BasicBlock *old_entry_bb = entry_bb;
BasicBlock *old_bb = bb;
@@ -3205,6 +3218,7 @@
rescue_bb->eraseFromParent();
}
+ func_annotation = old_func_annotation;
bb = old_bb;
entry_bb = old_entry_bb;
lvars = old_lvars;
Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h 2009-09-18 08:29:05 UTC (rev 2561)
+++ MacRuby/trunk/compiler.h 2009-09-18 08:30:15 UTC (rev 2562)
@@ -27,6 +27,23 @@
#define DEFINED_SUPER 6
#define DEFINED_METHOD 7
+class RoxorFunctionAnnotation : public Annotation {
+ public:
+ static AnnotationID id;
+ std::string path;
+ std::vector<unsigned int> dispatch_lines;
+
+ RoxorFunctionAnnotation(Function *function, const char *_path)
+ : Annotation(RoxorFunctionAnnotation::id), path(_path) {
+ function->addAnnotation(this);
+ }
+
+ static RoxorFunctionAnnotation *from_function(Function *function) {
+ return (RoxorFunctionAnnotation *)
+ function->getAnnotation(RoxorFunctionAnnotation::id);
+ }
+};
+
class RoxorCompiler {
public:
static llvm::Module *module;
@@ -81,6 +98,7 @@
# define DEBUG_LEVEL_DEC()
#endif
+ unsigned int current_line;
BasicBlock *bb;
BasicBlock *entry_bb;
ID current_mid;
@@ -108,6 +126,7 @@
int return_from_block;
int return_from_block_ids;
PHINode *ensure_pn;
+ RoxorFunctionAnnotation *func_annotation;
Function *dispatcherFunc;
Function *fastPlusFunc;
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2009-09-18 08:29:05 UTC (rev 2561)
+++ MacRuby/trunk/vm.cpp 2009-09-18 08:30:15 UTC (rev 2562)
@@ -406,8 +406,8 @@
}
bool
-RoxorCore::symbolize_call_address(void *addr, void **startp, unsigned long *ln,
- char *name, size_t name_len)
+RoxorCore::symbolize_call_address(void *addr, void **startp, char *path,
+ size_t path_len, unsigned long *ln, char *name, size_t name_len)
{
void *start = NULL;
@@ -429,7 +429,7 @@
*startp = start;
}
- if (name != NULL || ln != NULL) {
+ if (name != NULL || path != NULL || ln != NULL) {
std::map<IMP, rb_vm_method_node_t *>::iterator iter =
ruby_imps.find((IMP)start);
if (iter == ruby_imps.end()) {
@@ -438,11 +438,56 @@
}
rb_vm_method_node_t *node = iter->second;
-#if 0 // TODO
+
+ RoxorFunctionAnnotation *annotation = f == NULL
+ ? NULL
+ : RoxorFunctionAnnotation::from_function(f->f);
if (ln != NULL) {
- *ln = nd_line(node->node);
+ if (annotation != 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++;
+ }
+ p++;
+ }
+
+ if (i > 0 && i - 1 < annotation->dispatch_lines.size()) {
+ *ln = annotation->dispatch_lines[i - 1];
+ }
+ else {
+ *ln = 0;
+ }
+#else
+ // TODO 32-bit hack...
+ *ln = 0;
+#endif
+ }
+ else {
+ *ln = 0;
+ }
}
-#endif
+ if (path != NULL) {
+ if (annotation != NULL) {
+ strncpy(path, annotation->path.c_str(), path_len);
+ }
+ else {
+ strncpy(path, "core", path_len);
+ }
+ }
if (name != NULL) {
strncpy(name, sel_getName(node->sel), name_len);
}
@@ -2329,7 +2374,7 @@
for (int i = callstack_n - 1; i >= 0; i--) {
void *start = NULL;
if (GET_CORE()->symbolize_call_address(callstack[i],
- &start, NULL, NULL, 0)) {
+ &start, NULL, 0, NULL, NULL, 0)) {
start = (void *)objc_imp((IMP)start);
if (start == (void *)self) {
skip = false;
@@ -4507,13 +4552,14 @@
VALUE ary = rb_ary_new();
for (int i = 0; i < callstack_n; i++) {
+ char path[PATH_MAX];
char name[100];
unsigned long ln = 0;
- if (GET_CORE()->symbolize_call_address(callstack[i], NULL, &ln, name,
- sizeof name)) {
- char entry[100];
- snprintf(entry, sizeof entry, "%ld:in `%s'", ln, name);
+ if (GET_CORE()->symbolize_call_address(callstack[i], NULL,
+ path, sizeof path, &ln, name, sizeof name)) {
+ char entry[PATH_MAX];
+ snprintf(entry, sizeof entry, "%s:%ld:in `%s'", path, ln, name);
rb_ary_push(ary, rb_str_new2(entry));
}
}
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2009-09-18 08:29:05 UTC (rev 2561)
+++ MacRuby/trunk/vm.h 2009-09-18 08:30:15 UTC (rev 2562)
@@ -670,7 +670,8 @@
}
bool symbolize_call_address(void *addr, void **startp,
- unsigned long *ln, char *name, size_t name_len);
+ char *path, size_t path_len, unsigned long *ln,
+ char *name, size_t name_len);
struct mcache *method_cache_get(SEL sel, bool super);
rb_vm_method_node_t *method_node_get(IMP imp);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090918/852c87a3/attachment.html>
More information about the macruby-changes
mailing list