Skip to content

Commit 2d4edd7

Browse files
committed
---
yaml --- r: 5079 b: refs/heads/master c: 614a930 h: refs/heads/master i: 5077: 0358fc3 5075: 581942d 5071: 93a88ab v: v3
1 parent 27fa520 commit 2d4edd7

File tree

8 files changed

+75
-26
lines changed

8 files changed

+75
-26
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 729437d2c07cfaf3d924df59a9341b3ac2efa1d6
2+
refs/heads/master: 614a930c51d8e8f66e6893261616a449d9ab0754

trunk/src/comp/back/upcall.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
109109
[taskptr_type, T_ptr(tydesc_type), T_ptr(T_i8()), T_i32()],
110110
T_void()),
111111
dynastack_mark: d(~"dynastack_mark", [], T_ptr(T_i8())),
112-
dynastack_alloc: d(~"dynastack_alloc", [T_size_t()], T_ptr(T_i8())),
112+
dynastack_alloc: d(~"dynastack_alloc_2",
113+
[T_size_t(), T_ptr(tydesc_type)], T_ptr(T_i8())),
113114
dynastack_free: d(~"dynastack_free", [T_ptr(T_i8())], T_void())};
114115
}
115116
//

trunk/src/comp/middle/trans.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,8 @@ fn alloca(cx: &@block_ctxt, t: TypeRef) -> ValueRef {
471471
ret Alloca(new_raw_block_ctxt(cx.fcx, cx.fcx.llstaticallocas), t);
472472
}
473473

474-
fn array_alloca(cx: &@block_ctxt, t: TypeRef, n: ValueRef) -> ValueRef {
474+
fn dynastack_alloca(cx: &@block_ctxt, t: TypeRef, n: ValueRef, ty: ty::t)
475+
-> ValueRef {
475476
let bcx = cx;
476477
let dy_cx = new_raw_block_ctxt(cx.fcx, cx.fcx.lldynamicallocas);
477478
let lltaskptr = bcx_fcx(bcx).lltaskptr;
@@ -485,7 +486,11 @@ fn array_alloca(cx: &@block_ctxt, t: TypeRef, n: ValueRef) -> ValueRef {
485486

486487
let dynastack_alloc = bcx_ccx(bcx).upcalls.dynastack_alloc;
487488
let llsz = Mul(dy_cx, C_uint(llsize_of_real(bcx_ccx(bcx), t)), n);
488-
let llresult = Call(dy_cx, dynastack_alloc, [lltaskptr, llsz]);
489+
490+
let ti = none;
491+
let lltydesc = get_tydesc(cx, ty, false, tps_normal, ti).result.val;
492+
493+
let llresult = Call(dy_cx, dynastack_alloc, [lltaskptr, llsz, lltydesc]);
489494
ret PointerCast(dy_cx, llresult, T_ptr(t));
490495
}
491496

@@ -4868,8 +4873,10 @@ fn alloc_ty(cx: &@block_ctxt, t: ty::t) -> result {
48684873

48694874
let n = size_of(llderivedtydescs_block_ctxt(bcx.fcx), t);
48704875
bcx.fcx.llderivedtydescs = n.bcx.llbb;
4871-
val = array_alloca(bcx, T_i8(), n.val);
4872-
} else { val = alloca(bcx, type_of(bcx_ccx(cx), cx.sp, t)); }
4876+
val = dynastack_alloca(bcx, T_i8(), n.val, t);
4877+
} else {
4878+
val = alloca(bcx, type_of(bcx_ccx(cx), cx.sp, t));
4879+
}
48734880
// NB: since we've pushed all size calculations in this
48744881
// function up to the alloca block, we actually return the
48754882
// block passed into us unmodified; it doesn't really

trunk/src/comp/middle/trans_ivec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import lib::llvm::llvm::{ValueRef, TypeRef};
55
import back::abi;
66
import trans::{call_memmove, trans_shared_malloc, llsize_of,
77
type_of_or_i8, incr_ptr, INIT, copy_val, load_if_immediate,
8-
alloca, array_alloca, size_of, llderivedtydescs_block_ctxt,
8+
alloca, size_of, llderivedtydescs_block_ctxt,
99
lazily_emit_tydesc_glue, get_tydesc, load_inbounds,
1010
move_val_if_temp, trans_lval, node_id_type,
1111
new_sub_block_ctxt, tps_normal, do_spill};

trunk/src/rt/rust_obstack.cpp

+39-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <algorithm>
44
#include <cassert>
55
#include <cstdlib>
6+
#include <new>
67
#include <stdint.h>
78

89
#include "rust_internal.h"
@@ -18,9 +19,20 @@
1819
#define DPRINT(fmt,...)
1920

2021
//const size_t DEFAULT_CHUNK_SIZE = 4096;
21-
const size_t DEFAULT_CHUNK_SIZE = 300000;
22+
const size_t DEFAULT_CHUNK_SIZE = 500000;
2223
const size_t DEFAULT_ALIGNMENT = 16;
2324

25+
// A single type-tagged allocation in a chunk.
26+
struct rust_obstack_alloc {
27+
size_t len;
28+
const type_desc *tydesc;
29+
uint8_t data[];
30+
31+
rust_obstack_alloc(size_t in_len, const type_desc *in_tydesc)
32+
: len(in_len), tydesc(in_tydesc) {}
33+
};
34+
35+
// A contiguous set of allocations.
2436
struct rust_obstack_chunk {
2537
rust_obstack_chunk *prev;
2638
size_t size;
@@ -31,22 +43,24 @@ struct rust_obstack_chunk {
3143
rust_obstack_chunk(rust_obstack_chunk *in_prev, size_t in_size)
3244
: prev(in_prev), size(in_size), alen(0) {}
3345

34-
void *alloc(size_t len);
46+
void *alloc(size_t len, type_desc *tydesc);
3547
bool free(void *ptr);
48+
void *mark();
3649
};
3750

3851
void *
39-
rust_obstack_chunk::alloc(size_t len) {
52+
rust_obstack_chunk::alloc(size_t len, type_desc *tydesc) {
4053
alen = align_to(alen, DEFAULT_ALIGNMENT);
4154

42-
if (len > size - alen) {
55+
if (sizeof(rust_obstack_alloc) + len > size - alen) {
4356
DPRINT("Not enough space, len=%lu!\n", len);
4457
assert(0);
4558
return NULL; // Not enough space.
4659
}
47-
void *result = data + alen;
48-
alen += len;
49-
return result;
60+
61+
rust_obstack_alloc *a = new(data + alen) rust_obstack_alloc(len, tydesc);
62+
alen += sizeof(*a) + len;
63+
return &a->data;
5064
}
5165

5266
bool
@@ -59,14 +73,20 @@ rust_obstack_chunk::free(void *ptr) {
5973
return true;
6074
}
6175

76+
void *
77+
rust_obstack_chunk::mark() {
78+
return data + alen;
79+
}
80+
6281
// Allocates the given number of bytes in a new chunk.
6382
void *
64-
rust_obstack::alloc_new(size_t len) {
65-
size_t chunk_size = std::max(len, DEFAULT_CHUNK_SIZE);
83+
rust_obstack::alloc_new(size_t len, type_desc *tydesc) {
84+
size_t chunk_size = std::max(sizeof(rust_obstack_alloc) + len,
85+
DEFAULT_CHUNK_SIZE);
6686
void *ptr = task->malloc(sizeof(chunk) + chunk_size, "obstack");
6787
DPRINT("making new chunk at %p, len %lu\n", ptr, chunk_size);
6888
chunk = new(ptr) rust_obstack_chunk(chunk, chunk_size);
69-
return chunk->alloc(len);
89+
return chunk->alloc(len, tydesc);
7090
}
7191

7292
rust_obstack::~rust_obstack() {
@@ -78,14 +98,14 @@ rust_obstack::~rust_obstack() {
7898
}
7999

80100
void *
81-
rust_obstack::alloc(size_t len) {
101+
rust_obstack::alloc(size_t len, type_desc *tydesc) {
82102
if (!chunk)
83-
return alloc_new(len);
103+
return alloc_new(len, tydesc);
84104

85105
DPRINT("alloc sz %u", (uint32_t)len);
86106

87-
void *ptr = chunk->alloc(len);
88-
ptr = ptr ? ptr : alloc_new(len);
107+
void *ptr = chunk->alloc(len, tydesc);
108+
ptr = ptr ? ptr : alloc_new(len, tydesc);
89109

90110
return ptr;
91111
}
@@ -107,3 +127,8 @@ rust_obstack::free(void *ptr) {
107127
}
108128
}
109129

130+
void *
131+
rust_obstack::mark() {
132+
return chunk ? chunk->mark() : NULL;
133+
}
134+

trunk/src/rt/rust_obstack.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@
55

66
struct rust_obstack_chunk;
77
struct rust_task;
8+
struct type_desc;
89

910
class rust_obstack {
1011
rust_obstack_chunk *chunk;
1112
rust_task *task;
1213

1314
// Allocates the given number of bytes in a new chunk.
14-
void *alloc_new(size_t len);
15+
void *alloc_new(size_t len, type_desc *tydesc);
1516

1617
public:
1718
rust_obstack(rust_task *in_task) : chunk(NULL), task(in_task) {}
1819
~rust_obstack();
1920

20-
void *alloc(size_t len);
21+
void *alloc(size_t len, type_desc *tydesc);
2122
void free(void *ptr);
23+
void *mark();
2224
};
2325

2426
#endif

trunk/src/rt/rust_upcall.cpp

+16-3
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,26 @@ upcall_vec_push(rust_task* task, rust_vec** vp, type_desc* elt_ty,
368368
*/
369369
extern "C" CDECL void *
370370
upcall_dynastack_mark(rust_task *task) {
371-
return task->dynastack.alloc(0);
371+
return task->dynastack.mark();
372372
}
373373

374-
/** Allocates space in the dynamic stack and returns it. */
374+
/**
375+
* Allocates space in the dynamic stack and returns it.
376+
*
377+
* FIXME: Deprecated since dynamic stacks need to be self-describing for GC.
378+
*/
375379
extern "C" CDECL void *
376380
upcall_dynastack_alloc(rust_task *task, size_t sz) {
377-
return sz ? task->dynastack.alloc(sz) : NULL;
381+
return sz ? task->dynastack.alloc(sz, NULL) : NULL;
382+
}
383+
384+
/**
385+
* Allocates space associated with a type descriptor in the dynamic stack and
386+
* returns it.
387+
*/
388+
extern "C" CDECL void *
389+
upcall_dynastack_alloc_2(rust_task *task, size_t sz, type_desc *ty) {
390+
return sz ? task->dynastack.alloc(sz, ty) : NULL;
378391
}
379392

380393
/** Frees space in the dynamic stack. */

trunk/src/rt/rustrt.def.in

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ task_join
7777
unsupervise
7878
upcall_cmp_type
7979
upcall_dynastack_alloc
80+
upcall_dynastack_alloc_2
8081
upcall_dynastack_free
8182
upcall_dynastack_mark
8283
upcall_exit

0 commit comments

Comments
 (0)