Introduce a SHAPE_UNBOXED_VEC shape in order to seperate out vector logic.

This commit is contained in:
Michael Sullivan 2012-06-11 16:51:21 -07:00
parent ebdf0c20cd
commit e67b5b25a6
6 changed files with 102 additions and 7 deletions

View file

@ -45,6 +45,10 @@ class annihilator : public shape::data<annihilator,shape::ptr> {
task->kernel->free(vec);
}
void walk_unboxed_vec2(bool is_pod) {
walk_vec2(is_pod, get_unboxed_vec_data_range(dp));
}
void walk_fixedvec2(uint16_t n_elts, size_t elt_sz, bool is_pod) {
walk_vec2(is_pod, get_fixedvec_data_range(n_elts, elt_sz, dp));
}

View file

@ -91,6 +91,10 @@ class irc : public shape::data<irc,shape::ptr> {
walk_vec2(is_pod, get_vec_data_range(dp));
}
void walk_unboxed_vec2(bool is_pod) {
walk_vec2(is_pod, get_unboxed_vec_data_range(dp));
}
void walk_slice2(bool is_pod, bool is_str) {
walk_vec2(is_pod, get_slice_data_range(is_str, dp));
}
@ -341,6 +345,10 @@ class mark : public shape::data<mark,shape::ptr> {
walk_vec2(is_pod, get_vec_data_range(dp));
}
void walk_unboxed_vec2(bool is_pod) {
walk_vec2(is_pod, get_unboxed_vec_data_range(dp));
}
void walk_slice2(bool is_pod, bool is_str) {
walk_vec2(is_pod, get_slice_data_range(is_str, dp));
}

View file

@ -263,6 +263,11 @@ public:
walk_vec2(is_pod, get_vec_data_range(dp));
}
void walk_unboxed_vec2(bool is_pod) {
walk_vec2(is_pod, get_unboxed_vec_data_range(dp));
}
void walk_slice2(bool is_pod, bool is_str) {
// Slices compare just like vecs.
walk_vec2(is_pod, get_slice_data_range(is_str, dp));

View file

@ -58,6 +58,7 @@ const uint8_t SHAPE_SEND_TYDESC = 29u;
const uint8_t SHAPE_RPTR = 31u;
const uint8_t SHAPE_FIXEDVEC = 32u;
const uint8_t SHAPE_SLICE = 33u;
const uint8_t SHAPE_UNBOXED_VEC = 34u;
#ifdef _LP64
const uint8_t SHAPE_PTR = SHAPE_U64;
@ -263,9 +264,9 @@ protected:
private:
void walk_vec0();
void walk_unboxed_vec0();
void walk_tag0();
void walk_box0();
void walk_box_old0();
void walk_uniq0();
void walk_struct0();
void walk_res0();
@ -318,6 +319,7 @@ ctxt<T>::walk() {
case SHAPE_RPTR: walk_rptr0(); break;
case SHAPE_FIXEDVEC: walk_fixedvec0(); break;
case SHAPE_SLICE: walk_slice0(); break;
case SHAPE_UNBOXED_VEC: walk_unboxed_vec0(); break;
default: abort();
}
}
@ -375,6 +377,19 @@ ctxt<T>::walk_vec0() {
sp = end_sp;
}
template<typename T>
void
ctxt<T>::walk_unboxed_vec0() {
bool is_pod = *sp++;
uint16_t sp_size = get_u16_bump(sp);
const uint8_t *end_sp = sp + sp_size;
static_cast<T *>(this)->walk_unboxed_vec1(is_pod);
sp = end_sp;
}
template<typename T>
void
ctxt<T>::walk_tag0() {
@ -516,6 +531,9 @@ public:
void walk_vec1(bool is_pod) {
DPRINT("vec<"); walk(); DPRINT(">");
}
void walk_unboxed_vec1(bool is_pod) {
DPRINT("unboxed_vec<"); walk(); DPRINT(">");
}
void walk_uniq1() {
DPRINT("~<"); walk(); DPRINT(">");
}
@ -603,6 +621,11 @@ public:
sa.set(sizeof(void *), sizeof(void *));
}
void walk_unboxed_vec1(bool is_pod) {
assert(false &&
"trying to compute size of dynamically sized unboxed vector");
}
void walk_res1(const rust_fn *dtor, const uint8_t *end_sp) {
abort(); // TODO
}
@ -849,6 +872,12 @@ protected:
static std::pair<uint8_t *,uint8_t *> get_vec_data_range(ptr dp);
static std::pair<ptr_pair,ptr_pair> get_vec_data_range(ptr_pair &dp);
static std::pair<uint8_t *,uint8_t *> get_unboxed_vec_data_range(ptr dp);
static std::pair<ptr_pair,ptr_pair>
get_unboxed_vec_data_range(ptr_pair &dp);
static ptr get_unboxed_vec_end(ptr dp);
static ptr_pair get_unboxed_vec_end(ptr_pair &dp);
static std::pair<uint8_t *,uint8_t *> get_slice_data_range(bool is_str,
ptr dp);
static std::pair<ptr_pair,ptr_pair> get_slice_data_range(bool is_str,
@ -880,6 +909,13 @@ public:
DATA_SIMPLE(void *, walk_vec2(is_pod));
}
void walk_unboxed_vec1(bool is_pod) {
// align?
U next_dp = get_unboxed_vec_end(dp);
static_cast<T *>(this)->walk_unboxed_vec2(is_pod);
dp = next_dp;
}
void walk_slice1(bool is_pod, bool is_str) {
DATA_SIMPLE(void *, walk_slice2(is_pod, is_str));
}
@ -955,7 +991,7 @@ data<T,U>::walk_uniq_contents1() {
if (body_td) {
U body_dp(dp.box_body());
arena arena;
T sub(*static_cast<T *>(this), body_td->shape,
T sub(*static_cast<T *>(this), /*body_td->shape,*/ this->sp,
body_td->shape_tables, body_dp);
sub.align = true;
static_cast<T *>(this)->walk_uniq_contents2(sub);
@ -1000,6 +1036,38 @@ data<T,U>::get_vec_data_range(ptr_pair &dp) {
return std::make_pair(start, end);
}
template<typename T,typename U>
std::pair<uint8_t *,uint8_t *>
data<T,U>::get_unboxed_vec_data_range(ptr dp) {
rust_vec* ptr = (rust_vec*)dp;
uint8_t* data = &ptr->data[0];
return std::make_pair(data, data + ptr->fill);
}
template<typename T,typename U>
std::pair<ptr_pair,ptr_pair>
data<T,U>::get_unboxed_vec_data_range(ptr_pair &dp) {
std::pair<uint8_t *,uint8_t *> fst =
get_unboxed_vec_data_range(shape::ptr(dp.fst));
std::pair<uint8_t *,uint8_t *> snd =
get_unboxed_vec_data_range(shape::ptr(dp.snd));
ptr_pair start(fst.first, snd.first);
ptr_pair end(fst.second, snd.second);
return std::make_pair(start, end);
}
template<typename T,typename U>
ptr data<T,U>::get_unboxed_vec_end(ptr dp) {
rust_vec* ptr = (rust_vec*)dp;
return dp + sizeof(rust_vec) + ptr->fill;
}
template<typename T,typename U>
ptr_pair data<T,U>::get_unboxed_vec_end(ptr_pair &dp) {
return ptr_pair(get_unboxed_vec_end(ptr(dp.fst)),
get_unboxed_vec_end(ptr(dp.snd)));
}
template<typename T,typename U>
std::pair<uint8_t *,uint8_t *>
data<T,U>::get_slice_data_range(bool is_str, ptr dp) {
@ -1135,6 +1203,10 @@ private:
walk_vec2(is_pod, get_vec_data_range(dp));
}
void walk_unboxed_vec2(bool is_pod) {
walk_vec2(is_pod, get_unboxed_vec_data_range(dp));
}
void walk_slice2(bool is_pod, bool is_str) {
walk_vec2(is_pod, get_slice_data_range(is_str, dp));
out << "/&";

View file

@ -93,6 +93,7 @@ const shape_send_tydesc: u8 = 29u8;
const shape_rptr: u8 = 31u8;
const shape_fixedvec: u8 = 32u8;
const shape_slice: u8 = 33u8;
const shape_unboxed_vec: u8 = 34u8;
fn mk_global(ccx: @crate_ctxt, name: str, llval: ValueRef, internal: bool) ->
ValueRef {
@ -225,6 +226,9 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
ty::ty_float(ast::ty_f64) { [shape_f64] }
ty::ty_estr(ty::vstore_uniq) |
ty::ty_str {
// FIXME: we want to emit this as a unique pointer to an unboxed vec,
// but it doesn't work at the moment, since trans doesn't put
// tydescs in string boxes...
let mut s = [shape_vec];
add_bool(s, true); // type is POD
let unit_ty = ty::mk_mach_uint(ccx.tcx, ast::ty_u8);
@ -267,9 +271,11 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
}
ty::ty_evec(mt, ty::vstore_uniq) |
ty::ty_vec(mt) {
let mut s = [shape_vec];
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
add_substr(s, shape_of(ccx, mt.ty));
let mut s_inner = [shape_unboxed_vec];
add_bool(s_inner, ty::type_is_pod(ccx.tcx, mt.ty));
add_substr(s_inner, shape_of(ccx, mt.ty));
let mut s = [shape_uniq];
add_substr(s, s_inner);
s
}

View file

@ -1,4 +1,4 @@
fn main() {
assert "[1, 2, 3]" == sys::log_str([1, 2, 3]);
assert #fmt["%?/%5?", [1, 2, 3], "hi"] == "[1, 2, 3]/ \"hi\"";
assert "~[1, 2, 3]" == sys::log_str([1, 2, 3]);
assert #fmt["%?/%5?", [1, 2, 3], "hi"] == "~[1, 2, 3]/ \"hi\"";
}