Skip to content

Commit d324014

Browse files
committed
auto merge of #7521 : thestinger/rust/vec, r=Aatch
continued from #7495
2 parents 6a2ad08 + 5b40f2a commit d324014

File tree

6 files changed

+69
-48
lines changed

6 files changed

+69
-48
lines changed

src/librustc/middle/trans/base.rs

+37-19
Original file line numberDiff line numberDiff line change
@@ -258,25 +258,43 @@ pub fn malloc_raw_dyn(bcx: block,
258258
}
259259
};
260260

261-
// Grab the TypeRef type of box_ptr_ty.
262-
let box_ptr_ty = mk_fn(bcx.tcx(), t);
263-
let llty = type_of(ccx, box_ptr_ty);
264-
265-
// Get the tydesc for the body:
266-
let static_ti = get_tydesc(ccx, t);
267-
glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
268-
269-
// Allocate space:
270-
let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p());
271-
let rval = alloca(bcx, Type::i8p());
272-
let bcx = callee::trans_lang_call(
273-
bcx,
274-
langcall,
275-
[tydesc, size],
276-
expr::SaveIn(rval));
277-
let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty));
278-
maybe_set_managed_unique_rc(r.bcx, r.val, heap);
279-
r
261+
if heap == heap_exchange {
262+
// Grab the TypeRef type of box_ptr_ty.
263+
let box_ptr_ty = mk_fn(bcx.tcx(), t);
264+
let llty = type_of(ccx, box_ptr_ty);
265+
266+
let llty_value = type_of::type_of(ccx, t);
267+
let llalign = llalign_of_min(ccx, llty_value);
268+
269+
// Allocate space:
270+
let rval = alloca(bcx, Type::i8p());
271+
let bcx = callee::trans_lang_call(
272+
bcx,
273+
langcall,
274+
[C_i32(llalign as i32), size],
275+
expr::SaveIn(rval));
276+
rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty))
277+
} else {
278+
// Grab the TypeRef type of box_ptr_ty.
279+
let box_ptr_ty = mk_fn(bcx.tcx(), t);
280+
let llty = type_of(ccx, box_ptr_ty);
281+
282+
// Get the tydesc for the body:
283+
let static_ti = get_tydesc(ccx, t);
284+
glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
285+
286+
// Allocate space:
287+
let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p());
288+
let rval = alloca(bcx, Type::i8p());
289+
let bcx = callee::trans_lang_call(
290+
bcx,
291+
langcall,
292+
[tydesc, size],
293+
expr::SaveIn(rval));
294+
let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty));
295+
maybe_set_managed_unique_rc(r.bcx, r.val, heap);
296+
r
297+
}
280298
}
281299

282300
// malloc_raw: expects an unboxed type and returns a pointer to

src/libstd/libc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1945,7 +1945,7 @@ pub mod funcs {
19451945
#[fast_ffi]
19461946
unsafe fn malloc(size: size_t) -> *c_void;
19471947
#[fast_ffi]
1948-
unsafe fn realloc(p: *c_void, size: size_t) -> *c_void;
1948+
unsafe fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
19491949
#[fast_ffi]
19501950
unsafe fn free(p: *c_void);
19511951
unsafe fn abort() -> !;

src/libstd/rt/global_heap.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use libc::{c_char, c_void, size_t, uintptr_t, free, malloc};
11+
use libc::{c_char, c_void, size_t, uintptr_t, free, malloc, realloc};
1212
use managed::raw::{BoxHeaderRepr, BoxRepr};
1313
use unstable::intrinsics::TyDesc;
1414
use sys::size_of;
@@ -18,6 +18,7 @@ extern {
1818
fn abort();
1919
}
2020

21+
#[inline]
2122
fn get_box_size(body_size: uint, body_align: uint) -> uint {
2223
let header_size = size_of::<BoxHeaderRepr>();
2324
// FIXME (#2699): This alignment calculation is suspicious. Is it right?
@@ -27,12 +28,14 @@ fn get_box_size(body_size: uint, body_align: uint) -> uint {
2728

2829
// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power
2930
// of two.
31+
#[inline]
3032
fn align_to(size: uint, align: uint) -> uint {
3133
assert!(align != 0);
3234
(size + align - 1) & !(align - 1)
3335
}
3436

3537
/// A wrapper around libc::malloc, aborting on out-of-memory
38+
#[inline]
3639
pub unsafe fn malloc_raw(size: uint) -> *c_void {
3740
let p = malloc(size as size_t);
3841
if p.is_null() {
@@ -42,6 +45,17 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void {
4245
p
4346
}
4447

48+
/// A wrapper around libc::realloc, aborting on out-of-memory
49+
#[inline]
50+
pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void {
51+
let p = realloc(ptr, size as size_t);
52+
if p.is_null() {
53+
// we need a non-allocating way to print an error here
54+
abort();
55+
}
56+
p
57+
}
58+
4559
// FIXME #4942: Make these signatures agree with exchange_alloc's signatures
4660
#[cfg(stage0, not(test))]
4761
#[lang="exchange_malloc"]
@@ -66,13 +80,8 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
6680
#[cfg(not(stage0), not(test))]
6781
#[lang="exchange_malloc"]
6882
#[inline]
69-
pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
70-
let td = td as *TyDesc;
71-
let size = size as uint;
72-
73-
assert!(td.is_not_null());
74-
75-
let total_size = get_box_size(size, (*td).align);
83+
pub unsafe fn exchange_malloc(align: u32, size: uintptr_t) -> *c_char {
84+
let total_size = get_box_size(size as uint, align as uint);
7685
malloc_raw(total_size as uint) as *c_char
7786
}
7887

src/libstd/vec.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ use iterator::{FromIterator, Iterator, IteratorUtil};
2222
use iter::FromIter;
2323
use kinds::Copy;
2424
use libc;
25+
use libc::c_void;
2526
use num::Zero;
2627
use ops::Add;
2728
use option::{None, Option, Some};
2829
use ptr::to_unsafe_ptr;
2930
use ptr;
3031
use ptr::RawPtr;
32+
use rt::global_heap::realloc_raw;
3133
use sys;
3234
use sys::size_of;
3335
use uint;
@@ -52,12 +54,6 @@ pub mod rustrt {
5254

5355
#[abi = "cdecl"]
5456
pub extern {
55-
// These names are terrible. reserve_shared applies
56-
// to ~[] and reserve_shared_actual applies to @[].
57-
#[fast_ffi]
58-
unsafe fn vec_reserve_shared(t: *TyDesc,
59-
v: **raw::VecRepr,
60-
n: libc::size_t);
6157
#[fast_ffi]
6258
unsafe fn vec_reserve_shared_actual(t: *TyDesc,
6359
v: **raw::VecRepr,
@@ -1248,13 +1244,16 @@ impl<T> OwnedVector<T> for ~[T] {
12481244
use managed;
12491245
if self.capacity() < n {
12501246
unsafe {
1251-
let ptr: **raw::VecRepr = cast::transmute(self);
1247+
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
12521248
let td = get_tydesc::<T>();
12531249
if ((**ptr).box_header.ref_count ==
12541250
managed::raw::RC_MANAGED_UNIQUE) {
1255-
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
1251+
rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t);
12561252
} else {
1257-
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
1253+
let alloc = n * sys::nonzero_size_of::<T>();
1254+
*ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
1255+
as *mut raw::VecRepr;
1256+
(**ptr).unboxed.alloc = alloc;
12581257
}
12591258
}
12601259
}
@@ -1276,12 +1275,15 @@ impl<T> OwnedVector<T> for ~[T] {
12761275
// Only make the (slow) call into the runtime if we have to
12771276
if self.capacity() < n {
12781277
unsafe {
1279-
let ptr: **raw::VecRepr = cast::transmute(self);
1278+
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
12801279
let td = get_tydesc::<T>();
12811280
if contains_managed::<T>() {
1282-
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
1281+
rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t);
12831282
} else {
1284-
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
1283+
let alloc = n * sys::nonzero_size_of::<T>();
1284+
*ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
1285+
as *mut raw::VecRepr;
1286+
(**ptr).unboxed.alloc = alloc;
12851287
}
12861288
}
12871289
}

src/rt/rust_builtin.cpp

-7
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,6 @@ vec_reserve_shared_actual(type_desc* ty, rust_vec_box** vp,
7575
reserve_vec_exact_shared(task, vp, n_elts * ty->size);
7676
}
7777

78-
// This is completely misnamed.
79-
extern "C" CDECL void
80-
vec_reserve_shared(type_desc* ty, rust_vec_box** vp,
81-
size_t n_elts) {
82-
reserve_vec_exact(vp, n_elts * ty->size);
83-
}
84-
8578
extern "C" CDECL size_t
8679
rand_seed_size() {
8780
return rng_seed_size();

src/rt/rustrt.def.in

-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ rust_get_c_stack
5555
rust_log_str
5656
start_task
5757
vec_reserve_shared_actual
58-
vec_reserve_shared
5958
task_clear_event_reject
6059
task_wait_event
6160
task_signal_event

0 commit comments

Comments
 (0)