Skip to content

Commit d7f5e43

Browse files
committed
core::rt: Add the local heap to newsched tasks
Reusing the existing boxed_region implementation from the runtime
1 parent 2fe118b commit d7f5e43

File tree

7 files changed

+170
-10
lines changed

7 files changed

+170
-10
lines changed

src/libcore/rt/local_heap.rs

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! The local, garbage collected heap
12+
13+
use libc::{c_void, uintptr_t, size_t};
14+
use ops::Drop;
15+
16+
type MemoryRegion = c_void;
17+
type BoxedRegion = c_void;
18+
19+
pub type OpaqueBox = c_void;
20+
pub type TypeDesc = c_void;
21+
22+
pub struct LocalHeap {
23+
memory_region: *MemoryRegion,
24+
boxed_region: *BoxedRegion
25+
}
26+
27+
impl LocalHeap {
28+
pub fn new() -> LocalHeap {
29+
unsafe {
30+
// Don't need synchronization for the single-threaded local heap
31+
let synchronized = false as uintptr_t;
32+
// XXX: These usually come from the environment
33+
let detailed_leaks = false as uintptr_t;
34+
let poison_on_free = false as uintptr_t;
35+
let region = rust_new_memory_region(synchronized, detailed_leaks, poison_on_free);
36+
assert!(region.is_not_null());
37+
let boxed = rust_new_boxed_region(region, poison_on_free);
38+
assert!(boxed.is_not_null());
39+
LocalHeap {
40+
memory_region: region,
41+
boxed_region: boxed
42+
}
43+
}
44+
}
45+
46+
pub fn alloc(&mut self, td: *TypeDesc, size: uint) -> *OpaqueBox {
47+
unsafe {
48+
return rust_boxed_region_malloc(self.boxed_region, td, size as size_t);
49+
}
50+
}
51+
52+
pub fn free(&mut self, box: *OpaqueBox) {
53+
unsafe {
54+
return rust_boxed_region_free(self.boxed_region, box);
55+
}
56+
}
57+
}
58+
59+
impl Drop for LocalHeap {
60+
fn finalize(&self) {
61+
unsafe {
62+
rust_delete_boxed_region(self.boxed_region);
63+
rust_delete_memory_region(self.memory_region);
64+
}
65+
}
66+
}
67+
68+
extern {
69+
fn rust_new_memory_region(synchronized: uintptr_t,
70+
detailed_leaks: uintptr_t,
71+
poison_on_free: uintptr_t) -> *MemoryRegion;
72+
fn rust_delete_memory_region(region: *MemoryRegion);
73+
fn rust_new_boxed_region(region: *MemoryRegion,
74+
poison_on_free: uintptr_t) -> *BoxedRegion;
75+
fn rust_delete_boxed_region(region: *BoxedRegion);
76+
fn rust_boxed_region_malloc(region: *BoxedRegion,
77+
td: *TypeDesc,
78+
size: size_t) -> *OpaqueBox;
79+
fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
80+
}
81+

src/libcore/rt/local_services.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
2121
use prelude::*;
2222
use super::sched::{Task, local_sched};
23+
use super::local_heap::LocalHeap;
2324

2425
pub struct LocalServices {
2526
heap: LocalHeap,
@@ -29,7 +30,6 @@ pub struct LocalServices {
2930
unwinder: Unwinder
3031
}
3132

32-
pub struct LocalHeap;
3333
pub struct GarbageCollector;
3434
pub struct LocalStorage;
3535
pub struct Logger;
@@ -38,7 +38,7 @@ pub struct Unwinder;
3838
impl LocalServices {
3939
pub fn new() -> LocalServices {
4040
LocalServices {
41-
heap: LocalHeap,
41+
heap: LocalHeap::new(),
4242
gc: GarbageCollector,
4343
storage: LocalStorage,
4444
logger: Logger,
@@ -61,3 +61,18 @@ pub fn borrow_local_services(f: &fn(&mut LocalServices)) {
6161
}
6262
}
6363
}
64+
65+
#[cfg(test)]
66+
mod test {
67+
use rt::test::*;
68+
69+
#[test]
70+
fn local_heap() {
71+
do run_in_newsched_task() {
72+
let a = @5;
73+
let b = a;
74+
assert!(*a == 5);
75+
assert!(*b == 5);
76+
}
77+
}
78+
}

src/libcore/rt/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ mod context;
4949
mod thread;
5050
pub mod env;
5151
pub mod local_services;
52+
mod local_heap;
5253

5354
/// Tools for testing the runtime
5455
#[cfg(test)]

src/libcore/unstable/lang.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use str;
1717
use sys;
1818
use unstable::exchange_alloc;
1919
use cast::transmute;
20+
use rt::{context, OldTaskContext};
21+
use rt::local_services::borrow_local_services;
2022

2123
#[allow(non_camel_case_types)]
2224
pub type rust_task = c_void;
@@ -81,7 +83,18 @@ pub unsafe fn exchange_free(ptr: *c_char) {
8183
#[lang="malloc"]
8284
#[inline(always)]
8385
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
84-
return rustrt::rust_upcall_malloc(td, size);
86+
match context() {
87+
OldTaskContext => {
88+
return rustrt::rust_upcall_malloc(td, size);
89+
}
90+
_ => {
91+
let mut alloc = ::ptr::null();
92+
do borrow_local_services |srv| {
93+
alloc = srv.heap.alloc(td as *c_void, size as uint) as *c_char;
94+
}
95+
return alloc;
96+
}
97+
}
8598
}
8699

87100
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
@@ -90,7 +103,16 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
90103
#[lang="free"]
91104
#[inline(always)]
92105
pub unsafe fn local_free(ptr: *c_char) {
93-
rustrt::rust_upcall_free(ptr);
106+
match context() {
107+
OldTaskContext => {
108+
rustrt::rust_upcall_free(ptr);
109+
}
110+
_ => {
111+
do borrow_local_services |srv| {
112+
srv.heap.free(ptr as *c_void);
113+
}
114+
}
115+
}
94116
}
95117

96118
#[lang="borrow_as_imm"]

src/rt/boxed_region.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ rust_opaque_box *boxed_region::malloc(type_desc *td, size_t body_size) {
2727
if (live_allocs) live_allocs->prev = box;
2828
live_allocs = box;
2929

30-
LOG(rust_get_current_task(), box,
30+
/*LOG(rust_get_current_task(), box,
3131
"@malloc()=%p with td %p, size %lu==%lu+%lu, "
3232
"align %lu, prev %p, next %p\n",
3333
box, td, total_size, sizeof(rust_opaque_box), body_size,
34-
td->align, box->prev, box->next);
34+
td->align, box->prev, box->next);*/
3535

3636
return box;
3737
}
@@ -50,9 +50,9 @@ rust_opaque_box *boxed_region::realloc(rust_opaque_box *box,
5050
if (new_box->next) new_box->next->prev = new_box;
5151
if (live_allocs == box) live_allocs = new_box;
5252

53-
LOG(rust_get_current_task(), box,
53+
/*LOG(rust_get_current_task(), box,
5454
"@realloc()=%p with orig=%p, size %lu==%lu+%lu",
55-
new_box, box, total_size, sizeof(rust_opaque_box), new_size);
55+
new_box, box, total_size, sizeof(rust_opaque_box), new_size);*/
5656

5757
return new_box;
5858
}
@@ -74,9 +74,9 @@ void boxed_region::free(rust_opaque_box *box) {
7474
// double frees (kind of).
7575
assert(box->td != NULL);
7676

77-
LOG(rust_get_current_task(), box,
77+
/*LOG(rust_get_current_task(), box,
7878
"@free(%p) with td %p, prev %p, next %p\n",
79-
box, box->td, box->prev, box->next);
79+
box, box->td, box->prev, box->next);*/
8080

8181
if (box->prev) box->prev->next = box->next;
8282
if (box->next) box->next->prev = box->prev;

src/rt/rust_builtin.cpp

+35
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,41 @@ rust_initialize_global_state() {
851851
}
852852
}
853853

854+
extern "C" CDECL memory_region*
855+
rust_new_memory_region(uintptr_t synchronized,
856+
uintptr_t detailed_leaks,
857+
uintptr_t poison_on_free) {
858+
return new memory_region((bool)synchronized,
859+
(bool)detailed_leaks,
860+
(bool)poison_on_free);
861+
}
862+
863+
extern "C" CDECL void
864+
rust_delete_memory_region(memory_region *region) {
865+
delete region;
866+
}
867+
868+
extern "C" CDECL boxed_region*
869+
rust_new_boxed_region(memory_region *region,
870+
uintptr_t poison_on_free) {
871+
return new boxed_region(region, poison_on_free);
872+
}
873+
874+
extern "C" CDECL void
875+
rust_delete_boxed_region(boxed_region *region) {
876+
delete region;
877+
}
878+
879+
extern "C" CDECL rust_opaque_box*
880+
rust_boxed_region_malloc(boxed_region *region, type_desc *td, size_t size) {
881+
return region->malloc(td, size);
882+
}
883+
884+
extern "C" CDECL void
885+
rust_boxed_region_free(boxed_region *region, rust_opaque_box *box) {
886+
region->free(box);
887+
}
888+
854889
//
855890
// Local Variables:
856891
// mode: C++

src/rt/rustrt.def.in

+6
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,9 @@ rust_uv_free_ip6_addr
222222
rust_call_nullary_fn
223223
rust_initialize_global_state
224224
rust_dbg_next_port
225+
rust_new_memory_region
226+
rust_delete_memory_region
227+
rust_new_boxed_region
228+
rust_delete_boxed_region
229+
rust_boxed_region_malloc
230+
rust_boxed_region_free

0 commit comments

Comments
 (0)