Skip to content

Commit f4effaf

Browse files
committed
---
yaml --- r: 7073 b: refs/heads/master c: 822acdd h: refs/heads/master i: 7071: ad75807 v: v3
1 parent ea01b4b commit f4effaf

File tree

8 files changed

+82
-7
lines changed

8 files changed

+82
-7
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: d23e2052e0187e57b2fe626e5354a77ced29d0cf
2+
refs/heads/master: 822acdd1703af1714cb084a76c10937713339f6d

trunk/src/comp/back/upcall.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import driver::session;
33
import middle::trans;
44
import middle::trans_common::{T_fn, T_i1, T_i8, T_i32,
5-
T_int, T_nil,
5+
T_int, T_nil, T_dict,
66
T_opaque_vec, T_ptr,
77
T_size_t, T_void};
88
import lib::llvm::type_names;
@@ -20,6 +20,7 @@ type upcalls =
2020
create_shared_type_desc: ValueRef,
2121
free_shared_type_desc: ValueRef,
2222
get_type_desc: ValueRef,
23+
intern_dict: ValueRef,
2324
vec_grow: ValueRef,
2425
vec_push: ValueRef,
2526
cmp_type: ValueRef,
@@ -76,6 +77,8 @@ fn declare_upcalls(targ_cfg: @session::config,
7677
size_t, size_t,
7778
T_ptr(T_ptr(tydesc_type)), int_t],
7879
T_ptr(tydesc_type)),
80+
intern_dict:
81+
d("intern_dict", [size_t, T_ptr(T_dict())], T_ptr(T_dict())),
7982
vec_grow:
8083
dv("vec_grow", [T_ptr(T_ptr(opaque_vec_t)), int_t]),
8184
vec_push:

trunk/src/comp/middle/trans_closure.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -461,18 +461,24 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
461461
let (outgoing_fty_real, lltydescs, param_bounds) = alt f_res.generic {
462462
none. { (outgoing_fty, [], @[]) }
463463
some(ginfo) {
464-
for bounds in *ginfo.param_bounds {
464+
let tds = [], orig = 0u;
465+
vec::iter2(ginfo.tydescs, *ginfo.param_bounds) {|td, bounds|
466+
tds += [td];
465467
for bound in *bounds {
466468
alt bound {
467469
ty::bound_iface(_) {
468-
fail "FIXME[impl] binding bounded types not implemented";
470+
let dict = trans_impl::get_dict(
471+
bcx, option::get(ginfo.origins)[orig]);
472+
tds += [PointerCast(bcx, dict.val, val_ty(td))];
473+
orig += 1u;
474+
bcx = dict.bcx;
469475
}
470476
_ {}
471477
}
472478
}
473479
}
474480
lazily_emit_all_generic_info_tydesc_glues(cx, ginfo);
475-
(ginfo.item_type, ginfo.tydescs, ginfo.param_bounds)
481+
(ginfo.item_type, tds, ginfo.param_bounds)
476482
}
477483
};
478484

trunk/src/comp/middle/trans_impl.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,10 @@ fn dict_is_static(tcx: ty::ctxt, origin: typeck::dict_origin) -> bool {
143143
}
144144

145145
fn get_dict(bcx: @block_ctxt, origin: typeck::dict_origin) -> result {
146+
let ccx = bcx_ccx(bcx);
146147
alt origin {
147148
typeck::dict_static(impl_did, tys, sub_origins) {
148-
if dict_is_static(bcx_tcx(bcx), origin) {
149+
if dict_is_static(ccx.tcx, origin) {
149150
ret rslt(bcx, get_static_dict(bcx, origin));
150151
}
151152
let {bcx, ptrs} = get_dict_ptrs(bcx, origin);
@@ -155,7 +156,10 @@ fn get_dict(bcx: @block_ctxt, origin: typeck::dict_origin) -> result {
155156
Store(bcx, PointerCast(bcx, ptr, pty), GEPi(bcx, dict, [0, i]));
156157
i += 1;
157158
}
158-
rslt(bcx, PointerCast(bcx, dict, T_ptr(T_dict())))
159+
dict = Call(bcx, ccx.upcalls.intern_dict,
160+
[C_uint(ccx, vec::len(ptrs)),
161+
PointerCast(bcx, dict, T_ptr(T_dict()))]);
162+
rslt(bcx, dict)
159163
}
160164
typeck::dict_param(n_param, n_bound) {
161165
rslt(bcx, option::get(bcx.fcx.lltyparams[n_param].dicts)[n_bound])

trunk/src/rt/rust_crate_cache.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,30 @@ rust_crate_cache::get_type_desc(size_t size,
4545
return td;
4646
}
4747

48+
void**
49+
rust_crate_cache::get_dict(size_t n_fields, void** dict) {
50+
rust_hashable_dict *found = NULL;
51+
uintptr_t key = 0;
52+
for (size_t i = 0; i < n_fields; ++i) key ^= (uintptr_t)dict[i];
53+
size_t keysz = sizeof(uintptr_t);
54+
HASH_FIND(hh, this->dicts, &key, keysz, found);
55+
if (found) { printf("found!\n"); return &(found->fields[0]); }
56+
printf("not found\n");
57+
size_t dictsz = n_fields * sizeof(void*);
58+
found = (rust_hashable_dict*)
59+
sched->kernel->malloc(keysz + sizeof(UT_hash_handle) + dictsz,
60+
"crate cache dict");
61+
if (!found) return NULL;
62+
found->key = key;
63+
void** retptr = &(found->fields[0]);
64+
memcpy(retptr, dict, dictsz);
65+
HASH_ADD(hh, this->dicts, key, keysz, found);
66+
return retptr;
67+
}
68+
4869
rust_crate_cache::rust_crate_cache(rust_scheduler *sched)
4970
: type_descs(NULL),
71+
dicts(NULL),
5072
sched(sched),
5173
idx(0)
5274
{
@@ -62,6 +84,11 @@ rust_crate_cache::flush() {
6284
DLOG(sched, mem, "rust_crate_cache::flush() tydesc %" PRIxPTR, d);
6385
sched->kernel->free(d);
6486
}
87+
while (dicts) {
88+
rust_hashable_dict *d = dicts;
89+
HASH_DEL(dicts, d);
90+
sched->kernel->free(d);
91+
}
6592
}
6693

6794
rust_crate_cache::~rust_crate_cache()

trunk/src/rt/rust_scheduler.h

+8
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,25 @@
1111

1212
struct rust_scheduler;
1313

14+
struct rust_hashable_dict {
15+
uintptr_t key;
16+
UT_hash_handle hh;
17+
void* fields[0];
18+
};
19+
1420
class rust_crate_cache {
1521
public:
1622
type_desc *get_type_desc(size_t size,
1723
size_t align,
1824
size_t n_descs,
1925
type_desc const **descs,
2026
uintptr_t n_obj_params);
27+
void** get_dict(size_t n_fields, void** dict);
2128

2229
private:
2330

2431
type_desc *type_descs;
32+
rust_hashable_dict *dicts;
2533

2634
public:
2735

trunk/src/rt/rust_upcall.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,32 @@ upcall_get_type_desc(void *curr_crate, // ignored, legacy compat.
336336
return args.retval;
337337
}
338338

339+
/**********************************************************************
340+
* Called to get a heap-allocated dict. These are interned and kept
341+
* around indefinitely
342+
*/
343+
344+
struct s_intern_dict_args {
345+
size_t n_fields;
346+
void** dict;
347+
void** res;
348+
};
349+
350+
extern "C" CDECL void
351+
upcall_s_intern_dict(s_intern_dict_args *args) {
352+
rust_task *task = rust_scheduler::get_task();
353+
LOG_UPCALL_ENTRY(task);
354+
rust_crate_cache *cache = task->get_crate_cache();
355+
args->res = cache->get_dict(args->n_fields, args->dict);
356+
}
357+
358+
extern "C" CDECL void**
359+
upcall_intern_dict(size_t n_fields, void** dict) {
360+
s_intern_dict_args args = {n_fields, dict, 0 };
361+
UPCALL_SWITCH_STACK(&args, upcall_s_intern_dict);
362+
return args.res;
363+
}
364+
339365
/**********************************************************************/
340366

341367
struct s_vec_grow_args {

trunk/src/rt/rustrt.def.in

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ upcall_free
6262
upcall_create_shared_type_desc
6363
upcall_free_shared_type_desc
6464
upcall_get_type_desc
65+
upcall_intern_dict
6566
upcall_log_type
6667
upcall_malloc
6768
upcall_rust_personality

0 commit comments

Comments
 (0)