rustc: Use polymorphic logging
This commit is contained in:
parent
40ae704ff2
commit
adce35acd4
@ -26,11 +26,6 @@ import lib::llvm::llvm::TypeRef;
|
||||
|
||||
type upcalls =
|
||||
{grow_task: ValueRef,
|
||||
log_int: ValueRef,
|
||||
log_float: ValueRef,
|
||||
log_double: ValueRef,
|
||||
log_str: ValueRef,
|
||||
log_istr: ValueRef,
|
||||
trace_word: ValueRef,
|
||||
trace_str: ValueRef,
|
||||
new_port: ValueRef,
|
||||
@ -67,7 +62,8 @@ type upcalls =
|
||||
ivec_spill: ValueRef,
|
||||
ivec_resize_shared: ValueRef,
|
||||
ivec_spill_shared: ValueRef,
|
||||
cmp_type: ValueRef};
|
||||
cmp_type: ValueRef,
|
||||
log_type: ValueRef};
|
||||
|
||||
fn declare_upcalls(tn: type_names, tydesc_type: TypeRef,
|
||||
taskptr_type: TypeRef, llmod: ModuleRef) -> @upcalls {
|
||||
@ -89,11 +85,6 @@ fn declare_upcalls(tn: type_names, tydesc_type: TypeRef,
|
||||
|
||||
let empty_vec: [TypeRef] = ~[];
|
||||
ret @{grow_task: dv("grow_task", ~[T_size_t()]),
|
||||
log_int: dv("log_int", ~[T_i32(), T_i32()]),
|
||||
log_float: dv("log_float", ~[T_i32(), T_f32()]),
|
||||
log_double: dv("log_double", ~[T_i32(), T_ptr(T_f64())]),
|
||||
log_str: dv("log_str", ~[T_i32(), T_ptr(T_str())]),
|
||||
log_istr: dv("log_istr", ~[T_i32(), T_ptr(T_ivec(T_i8()))]),
|
||||
trace_word: dv("trace_word", ~[T_int()]),
|
||||
trace_str: dv("trace_str", ~[T_ptr(T_i8())]),
|
||||
new_port: d("new_port", ~[T_size_t()], T_opaque_port_ptr()),
|
||||
@ -159,6 +150,10 @@ fn declare_upcalls(tn: type_names, tydesc_type: TypeRef,
|
||||
dr("cmp_type", ~[T_ptr(T_i1()), taskptr_type,
|
||||
T_ptr(tydesc_type), T_ptr(T_ptr(tydesc_type)),
|
||||
T_ptr(T_i8()), T_ptr(T_i8()), T_i8()],
|
||||
T_void()),
|
||||
log_type:
|
||||
dr("log_type", ~[taskptr_type, T_ptr(tydesc_type),
|
||||
T_ptr(T_i8()), T_i32()],
|
||||
T_void())};
|
||||
}
|
||||
//
|
||||
|
@ -5190,48 +5190,18 @@ fn trans_log(lvl: int, cx: &@block_ctxt, e: &@ast::expr) -> result {
|
||||
let sub = trans_expr(log_cx, e);
|
||||
let e_ty = ty::expr_ty(bcx_tcx(cx), e);
|
||||
let log_bcx = sub.bcx;
|
||||
if ty::type_is_fp(bcx_tcx(cx), e_ty) {
|
||||
let tr: TypeRef;
|
||||
let is32bit: bool = false;
|
||||
alt ty::struct(bcx_tcx(cx), e_ty) {
|
||||
ty::ty_machine(ast::ty_f32.) { tr = T_f32(); is32bit = true; }
|
||||
ty::ty_machine(ast::ty_f64.) { tr = T_f64(); }
|
||||
_ { tr = T_float(); }
|
||||
}
|
||||
if is32bit {
|
||||
log_bcx.build.Call(bcx_ccx(log_bcx).upcalls.log_float,
|
||||
~[log_bcx.fcx.lltaskptr, C_int(lvl), sub.val]);
|
||||
} else {
|
||||
// FIXME: Eliminate this level of indirection.
|
||||
|
||||
let tmp = alloca(log_bcx, tr);
|
||||
sub.bcx.build.Store(sub.val, tmp);
|
||||
log_bcx.build.Call(bcx_ccx(log_bcx).upcalls.log_double,
|
||||
~[log_bcx.fcx.lltaskptr, C_int(lvl), tmp]);
|
||||
}
|
||||
} else if (ty::type_is_integral(bcx_tcx(cx), e_ty) ||
|
||||
ty::type_is_bool(bcx_tcx(cx), e_ty)) {
|
||||
// FIXME: Handle signedness properly.
|
||||
let ti = none[@tydesc_info];
|
||||
let r = get_tydesc(log_bcx, e_ty, false, ti);
|
||||
log_bcx = r.bcx;
|
||||
|
||||
let llintval =
|
||||
int_cast(log_bcx, T_int(), val_ty(sub.val), sub.val, false);
|
||||
log_bcx.build.Call(bcx_ccx(log_bcx).upcalls.log_int,
|
||||
~[log_bcx.fcx.lltaskptr, C_int(lvl), llintval]);
|
||||
} else {
|
||||
alt ty::struct(bcx_tcx(cx), e_ty) {
|
||||
ty::ty_str. {
|
||||
log_bcx.build.Call(bcx_ccx(log_bcx).upcalls.log_str,
|
||||
~[log_bcx.fcx.lltaskptr, C_int(lvl), sub.val]);
|
||||
}
|
||||
_ {
|
||||
// FIXME: Support these types.
|
||||
// Call the polymorphic log function.
|
||||
let llvalptr = spill_if_immediate(log_bcx, sub.val, e_ty);
|
||||
let llval_i8 = log_bcx.build.PointerCast(llvalptr, T_ptr(T_i8()));
|
||||
|
||||
log_bcx.build.Call(bcx_ccx(log_bcx).upcalls.log_type,
|
||||
~[log_bcx.fcx.lltaskptr, r.val, llval_i8, C_int(lvl)]);
|
||||
|
||||
bcx_ccx(cx).sess.span_fatal(e.span,
|
||||
"log called on unsupported type " +
|
||||
ty_to_str(bcx_tcx(cx), e_ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
log_bcx = trans_block_cleanups(log_bcx, log_cx);
|
||||
log_bcx.build.Br(after_cx.llbb);
|
||||
ret rslt(after_cx, C_nil());
|
||||
|
@ -343,36 +343,6 @@ fn trans_log(cx: &@block_ctxt, sp: &span, level: int, expr: &@ast::expr) ->
|
||||
ret lllevelptr;
|
||||
}
|
||||
|
||||
tag upcall_style { us_imm; us_imm_i32_zext; us_alias; us_alias_istr; }
|
||||
fn get_upcall(ccx: &@crate_ctxt, sp: &span, t: ty::t) ->
|
||||
{val: ValueRef, st: upcall_style} {
|
||||
alt ty::struct(ccx_tcx(ccx), t) {
|
||||
ty::ty_machine(ast::ty_f32.) {
|
||||
ret {val: ccx.upcalls.log_float, st: us_imm};
|
||||
}
|
||||
ty::ty_machine(ast::ty_f64.) | ty::ty_float. {
|
||||
// TODO: We have to spill due to legacy calling conventions that
|
||||
// should probably be modernized.
|
||||
ret {val: ccx.upcalls.log_double, st: us_alias};
|
||||
}
|
||||
ty::ty_bool. | ty::ty_machine(ast::ty_i8.) |
|
||||
ty::ty_machine(ast::ty_i16.) | ty::ty_machine(ast::ty_u8.) |
|
||||
ty::ty_machine(ast::ty_u16.) {
|
||||
ret {val: ccx.upcalls.log_int, st: us_imm_i32_zext};
|
||||
}
|
||||
ty::ty_int. | ty::ty_machine(ast::ty_i32.) |
|
||||
ty::ty_machine(ast::ty_u32.) {
|
||||
ret {val: ccx.upcalls.log_int, st: us_imm};
|
||||
}
|
||||
ty::ty_istr. { ret {val: ccx.upcalls.log_istr, st: us_alias_istr}; }
|
||||
_ {
|
||||
ccx.sess.span_unimpl(sp,
|
||||
"logging for values of type " +
|
||||
ppaux::ty_to_str(ccx_tcx(ccx), t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let bcx = cx;
|
||||
|
||||
let lllevelptr = trans_log_level(bcx_lcx(bcx));
|
||||
@ -386,34 +356,20 @@ fn trans_log(cx: &@block_ctxt, sp: &span, level: int, expr: &@ast::expr) ->
|
||||
bcx.build.CondBr(should_log, log_bcx.llbb, next_bcx.llbb);
|
||||
|
||||
let expr_t = ty::expr_ty(bcx_tcx(log_bcx), expr);
|
||||
let r = get_upcall(bcx_ccx(bcx), sp, expr_t);
|
||||
let llupcall = r.val;
|
||||
let style = r.st;
|
||||
|
||||
let arg_dest;
|
||||
alt style {
|
||||
us_imm. | us_imm_i32_zext. {
|
||||
arg_dest = dest_imm(bcx_tcx(log_bcx), expr_t);
|
||||
}
|
||||
us_alias. | us_alias_istr. {
|
||||
arg_dest = dest_alias(bcx_tcx(log_bcx), expr_t);
|
||||
}
|
||||
}
|
||||
let arg_dest = dest_alias(bcx_tcx(log_bcx), expr_t);
|
||||
log_bcx = trans_expr(log_bcx, arg_dest, expr);
|
||||
|
||||
let llarg = dest_llval(arg_dest);
|
||||
alt style {
|
||||
us_imm. | us_alias. {/* no-op */ }
|
||||
us_imm_i32_zext. { llarg = log_bcx.build.ZExt(llarg, tc::T_i32()); }
|
||||
us_alias_istr. {
|
||||
llarg =
|
||||
log_bcx.build.PointerCast(llarg,
|
||||
tc::T_ptr(tc::T_ivec(tc::T_i8())));
|
||||
}
|
||||
}
|
||||
let llarg_i8 = bcx.build.PointerCast(llarg, T_ptr(T_i8()));
|
||||
|
||||
log_bcx.build.Call(llupcall,
|
||||
~[bcx_fcx(bcx).lltaskptr, tc::C_int(level), llarg]);
|
||||
let ti = none;
|
||||
let r2 = trans::get_tydesc(bcx, expr_t, false, ti);
|
||||
bcx = r2.bcx;
|
||||
let lltydesc = r2.val;
|
||||
|
||||
log_bcx.build.Call(bcx_ccx(log_bcx).upcalls.log_type,
|
||||
~[bcx_fcx(bcx).lltaskptr, lltydesc, llarg_i8,
|
||||
tc::C_int(level)]);
|
||||
|
||||
log_bcx =
|
||||
trans::trans_block_cleanups(log_bcx, tc::find_scope_cx(log_bcx));
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
@ -76,20 +77,6 @@ align_to(T size, size_t alignment) {
|
||||
return x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T
|
||||
bump_dp(uint8_t *&dp) {
|
||||
T x = *((T *)dp);
|
||||
dp += sizeof(T);
|
||||
return x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T
|
||||
get_dp(uint8_t *dp) {
|
||||
return *((T *)dp);
|
||||
}
|
||||
|
||||
// Utility classes
|
||||
|
||||
struct size_align {
|
||||
@ -220,6 +207,52 @@ get_dp(ptr_pair &ptr) {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Pointer wrappers for data traversals
|
||||
|
||||
class ptr {
|
||||
private:
|
||||
uint8_t *p;
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
struct data { typedef T t; };
|
||||
|
||||
ptr(uint8_t *in_p)
|
||||
: p(in_p) {}
|
||||
|
||||
ptr(uintptr_t in_p)
|
||||
: p((uint8_t *)in_p) {}
|
||||
|
||||
inline ptr operator+(const size_t amount) const {
|
||||
return make(p + amount);
|
||||
}
|
||||
inline ptr &operator+=(const size_t amount) { p += amount; return *this; }
|
||||
|
||||
template<typename T>
|
||||
inline operator T *() { return (T *)p; }
|
||||
|
||||
inline operator uintptr_t() { return (uintptr_t)p; }
|
||||
|
||||
static inline ptr make(uint8_t *in_p) {
|
||||
ptr self(in_p);
|
||||
return self;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static inline T
|
||||
bump_dp(ptr &dp) {
|
||||
T x = *((T *)dp);
|
||||
dp += sizeof(T);
|
||||
return x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T
|
||||
get_dp(ptr dp) {
|
||||
return *((T *)dp);
|
||||
}
|
||||
|
||||
|
||||
// Contexts
|
||||
|
||||
@ -852,8 +885,8 @@ class data : public ctxt< data<T,U> > {
|
||||
protected:
|
||||
void walk_variant(bool align, tag_info &tinfo, uint32_t variant);
|
||||
|
||||
static std::pair<uint8_t *,uint8_t *> get_evec_data_range(uint8_t *dp);
|
||||
static std::pair<uint8_t *,uint8_t *> get_ivec_data_range(uint8_t *dp);
|
||||
static std::pair<uint8_t *,uint8_t *> get_evec_data_range(ptr dp);
|
||||
static std::pair<uint8_t *,uint8_t *> get_ivec_data_range(ptr dp);
|
||||
static std::pair<ptr_pair,ptr_pair> get_evec_data_range(ptr_pair &dp);
|
||||
static std::pair<ptr_pair,ptr_pair> get_ivec_data_range(ptr_pair &dp);
|
||||
|
||||
@ -924,14 +957,14 @@ data<T,U>::walk_variant(bool align, tag_info &tinfo, uint32_t variant_id) {
|
||||
|
||||
template<typename T,typename U>
|
||||
std::pair<uint8_t *,uint8_t *>
|
||||
data<T,U>::get_evec_data_range(uint8_t *dp) {
|
||||
data<T,U>::get_evec_data_range(ptr dp) {
|
||||
rust_vec *vp = bump_dp<rust_vec *>(dp);
|
||||
return std::make_pair(vp->data, vp->data + vp->fill);
|
||||
}
|
||||
|
||||
template<typename T,typename U>
|
||||
std::pair<uint8_t *,uint8_t *>
|
||||
data<T,U>::get_ivec_data_range(uint8_t *dp) {
|
||||
data<T,U>::get_ivec_data_range(ptr dp) {
|
||||
size_t fill = bump_dp<size_t>(dp);
|
||||
bump_dp<size_t>(dp); // Skip over alloc.
|
||||
uint8_t *payload_dp = dp;
|
||||
@ -1009,6 +1042,8 @@ data<T,U>::walk_tag(bool align, tag_info &tinfo) {
|
||||
tag_variant = 0;
|
||||
|
||||
static_cast<T *>(this)->walk_tag(align, tinfo, tag_variant);
|
||||
|
||||
dp = end_dp;
|
||||
}
|
||||
|
||||
|
||||
@ -1187,13 +1222,20 @@ cmp::walk_variant(bool align, tag_info &tinfo, uint32_t variant_id,
|
||||
|
||||
// Polymorphic logging, for convenience
|
||||
|
||||
class log : public data<log,uint8_t *> {
|
||||
friend class data<log,uint8_t *>;
|
||||
class log : public data<log,ptr> {
|
||||
friend class data<log,ptr>;
|
||||
|
||||
private:
|
||||
std::ostream &out;
|
||||
bool in_string;
|
||||
|
||||
log(log &other,
|
||||
const uint8_t *in_sp,
|
||||
const type_param *in_params,
|
||||
const rust_shape_tables *in_tables)
|
||||
: data<log,ptr>(other.task, in_sp, in_params, in_tables, other.dp),
|
||||
out(other.out) {}
|
||||
|
||||
void walk_evec(bool align, bool is_pod, uint16_t sp_size) {
|
||||
walk_vec(align, is_pod, get_evec_data_range(dp));
|
||||
}
|
||||
@ -1202,8 +1244,14 @@ private:
|
||||
walk_vec(align, is_pod, get_ivec_data_range(dp));
|
||||
}
|
||||
|
||||
void walk_vec(bool align, bool is_pod,
|
||||
const std::pair<uint8_t *,uint8_t *> &data);
|
||||
void walk_tag(bool align, tag_info &tinfo, uint32_t tag_variant) {
|
||||
out << "tag" << tag_variant;
|
||||
// TODO: Print insides.
|
||||
}
|
||||
|
||||
void walk_subcontext(bool align, log &sub) { sub.walk(align); }
|
||||
|
||||
void walk_vec(bool align, bool is_pod, const std::pair<ptr,ptr> &data);
|
||||
|
||||
template<typename T>
|
||||
void walk_number() { out << get_dp<T>(dp); }
|
||||
@ -1215,13 +1263,12 @@ public:
|
||||
const rust_shape_tables *in_tables,
|
||||
uint8_t *in_data,
|
||||
std::ostream &in_out)
|
||||
: data<log,uint8_t *>(in_task, in_sp, in_params, in_tables, in_data),
|
||||
: data<log,ptr>(in_task, in_sp, in_params, in_tables, in_data),
|
||||
out(in_out) {}
|
||||
};
|
||||
|
||||
void
|
||||
log::walk_vec(bool align, bool is_pod,
|
||||
const std::pair<uint8_t *,uint8_t *> &data) {
|
||||
log::walk_vec(bool align, bool is_pod, const std::pair<ptr,ptr> &data) {
|
||||
// TODO: Check to see whether this is a string (contains u8). If so,
|
||||
// write the vector ""-style; otherwise [ ... , ... ] style.
|
||||
}
|
||||
@ -1245,3 +1292,21 @@ upcall_cmp_type(int8_t *result, rust_task *task, type_desc *tydesc,
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
upcall_log_type(rust_task *task, type_desc *tydesc, uint8_t *data,
|
||||
uint32_t level) {
|
||||
if (task->sched->log_lvl < level)
|
||||
return; // TODO: Don't evaluate at all?
|
||||
|
||||
shape::arena arena;
|
||||
shape::type_param *params = shape::type_param::make(tydesc, arena);
|
||||
|
||||
std::stringstream ss;
|
||||
shape::log log(task, tydesc->shape, params, tydesc->shape_tables, data,
|
||||
ss);
|
||||
|
||||
log.walk(true);
|
||||
|
||||
task->sched->log(task, level, "%s", ss.str().c_str());
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ upcall_log_float
|
||||
upcall_log_int
|
||||
upcall_log_istr
|
||||
upcall_log_str
|
||||
upcall_log_type
|
||||
upcall_malloc
|
||||
upcall_mark
|
||||
upcall_new_chan
|
||||
|
Loading…
Reference in New Issue
Block a user