diff --git a/src/rt/rust_abi.cpp b/src/rt/rust_abi.cpp index 98b80fb41bd..2a08a25a9fa 100644 --- a/src/rt/rust_abi.cpp +++ b/src/rt/rust_abi.cpp @@ -1,10 +1,35 @@ +// ABI-specific routines. + +#include #include #include #include "rust_abi.h" +#define END_OF_STACK_RA (void (*)())0xdeadbeef + weak_symbol abi_version("rust_abi_version"); uint32_t get_abi_version() { return (*abi_version == NULL) ? 0 : **abi_version; } +namespace stack_walk { + +std::vector +backtrace() { + std::vector frames; + + // Ideally we would use the current value of EIP here, but there's no + // portable way to get that and there are never any GC roots in our C++ + // frames anyhow. + frame f(__builtin_frame_address(0), (void (*)())NULL); + + while (f.ra != END_OF_STACK_RA) { + frames.push_back(f); + f.next(); + } + return frames; +} + +} // end namespace stack_walk + diff --git a/src/rt/rust_abi.h b/src/rt/rust_abi.h index 9c22ea3fe7e..884eed4b717 100644 --- a/src/rt/rust_abi.h +++ b/src/rt/rust_abi.h @@ -1,7 +1,10 @@ +// ABI-specific routines. + #ifndef RUST_ABI_H #define RUST_ABI_H #include +#include #ifdef __WIN32__ #include @@ -36,6 +39,25 @@ public: T *&operator*() { fill(); return data; } }; +namespace stack_walk { + +struct frame { + uint8_t *bp; // The frame pointer. + void (*ra)(); // The return address. + + frame(void *in_bp, void (*in_ra)()) : bp((uint8_t *)in_bp), ra(in_ra) {} + + inline void next() { + ra = *(void (**)())(bp + sizeof(void *)); + bp = *(uint8_t **)bp; + } +}; + +std::vector backtrace(); + +} // end namespace stack_walk + + uint32_t get_abi_version(); #endif diff --git a/src/rt/rust_gc.cpp b/src/rt/rust_gc.cpp index 6e698de59db..ae3c5a01031 100644 --- a/src/rt/rust_gc.cpp +++ b/src/rt/rust_gc.cpp @@ -18,24 +18,12 @@ #include #endif -#define END_OF_STACK_RA (void (*)())0xdeadbeef +using namespace stack_walk; namespace gc { weak_symbol safe_point_data("rust_gc_safe_points"); -struct frame { - uint8_t *bp; // The frame pointer. - void (*ra)(); // The return address. - - frame(void *in_bp, void (*in_ra)()) : bp((uint8_t *)in_bp), ra(in_ra) {} - - inline void next() { - ra = *(void (**)())(bp + sizeof(void *)); - bp = *(uint8_t **)bp; - } -}; - struct root_info { intptr_t frame_offset; uintptr_t dynamic; // 0 = static, 1 = dynamic @@ -98,9 +86,7 @@ private: public: gc(rust_task *in_task) : task(in_task) {} - void run(); - std::vector backtrace(); }; const safe_point * @@ -135,22 +121,6 @@ gc::sweep() { // TODO } -std::vector -gc::backtrace() { - std::vector frames; - - // Ideally we would use the current value of EIP here, but there's no - // portable way to get that and there are never any GC roots in our C++ - // frames anyhow. - frame f(__builtin_frame_address(0), (void (*)())NULL); - - while (f.ra != END_OF_STACK_RA) { - frames.push_back(f); - f.next(); - } - return frames; -} - void gc::run() { safe_point_map map;