Skip to content

Commit f159364

Browse files
committed
---
yaml --- r: 142639 b: refs/heads/try2 c: 5e7c5d6 h: refs/heads/master i: 142637: b456ab7 142635: 20bfd1e 142631: dff7057 142623: b0de1fd v: v3
1 parent 6c2873d commit f159364

File tree

10 files changed

+103
-133
lines changed

10 files changed

+103
-133
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: a09972db3545344048b90e90d1f1821b621a38b9
8+
refs/heads/try2: 5e7c5d6c3d532e7b536b76044cd47b72b8eadaad
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/cleanup.rs

Lines changed: 13 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -13,107 +13,14 @@
1313
use libc::{c_char, c_void, intptr_t, uintptr_t};
1414
use ptr::mut_null;
1515
use repr::BoxRepr;
16+
use rt;
17+
use rt::OldTaskContext;
1618
use sys::TypeDesc;
1719
use cast::transmute;
18-
#[cfg(not(test))] use rt::borrowck::clear_task_borrow_list;
1920

2021
#[cfg(not(test))] use ptr::to_unsafe_ptr;
2122

22-
/**
23-
* Runtime structures
24-
*
25-
* NB: These must match the representation in the C++ runtime.
26-
*/
27-
2823
type DropGlue<'self> = &'self fn(**TypeDesc, *c_void);
29-
type FreeGlue<'self> = &'self fn(**TypeDesc, *c_void);
30-
31-
type TaskID = uintptr_t;
32-
33-
struct StackSegment { priv opaque: () }
34-
struct Scheduler { priv opaque: () }
35-
struct SchedulerLoop { priv opaque: () }
36-
struct Kernel { priv opaque: () }
37-
struct Env { priv opaque: () }
38-
struct AllocHeader { priv opaque: () }
39-
struct MemoryRegion { priv opaque: () }
40-
41-
#[cfg(target_arch="x86")]
42-
struct Registers {
43-
data: [u32, ..16]
44-
}
45-
46-
#[cfg(target_arch="arm")]
47-
#[cfg(target_arch="mips")]
48-
struct Registers {
49-
data: [u32, ..32]
50-
}
51-
52-
#[cfg(target_arch="x86")]
53-
#[cfg(target_arch="arm")]
54-
#[cfg(target_arch="mips")]
55-
struct Context {
56-
regs: Registers,
57-
next: *Context,
58-
pad: [u32, ..3]
59-
}
60-
61-
#[cfg(target_arch="x86_64")]
62-
struct Registers {
63-
data: [u64, ..22]
64-
}
65-
66-
#[cfg(target_arch="x86_64")]
67-
struct Context {
68-
regs: Registers,
69-
next: *Context,
70-
pad: uintptr_t
71-
}
72-
73-
struct BoxedRegion {
74-
env: *Env,
75-
backing_region: *MemoryRegion,
76-
live_allocs: *BoxRepr
77-
}
78-
79-
#[cfg(target_arch="x86")]
80-
#[cfg(target_arch="arm")]
81-
#[cfg(target_arch="mips")]
82-
struct Task {
83-
// Public fields
84-
refcount: intptr_t, // 0
85-
id: TaskID, // 4
86-
pad: [u32, ..2], // 8
87-
ctx: Context, // 16
88-
stack_segment: *StackSegment, // 96
89-
runtime_sp: uintptr_t, // 100
90-
scheduler: *Scheduler, // 104
91-
scheduler_loop: *SchedulerLoop, // 108
92-
93-
// Fields known only to the runtime
94-
kernel: *Kernel, // 112
95-
name: *c_char, // 116
96-
list_index: i32, // 120
97-
boxed_region: BoxedRegion // 128
98-
}
99-
100-
#[cfg(target_arch="x86_64")]
101-
struct Task {
102-
// Public fields
103-
refcount: intptr_t,
104-
id: TaskID,
105-
ctx: Context,
106-
stack_segment: *StackSegment,
107-
runtime_sp: uintptr_t,
108-
scheduler: *Scheduler,
109-
scheduler_loop: *SchedulerLoop,
110-
111-
// Fields known only to the runtime
112-
kernel: *Kernel,
113-
name: *c_char,
114-
list_index: i32,
115-
boxed_region: BoxedRegion
116-
}
11724

11825
/*
11926
* Box annihilation
@@ -132,9 +39,9 @@ unsafe fn each_live_alloc(read_next_before: bool,
13239
//! Walks the internal list of allocations
13340
13441
use managed;
42+
use rt::local_heap;
13543

136-
let task: *Task = transmute(rustrt::rust_get_task());
137-
let box = (*task).boxed_region.live_allocs;
44+
let box = local_heap::live_allocs();
13845
let mut box: *mut BoxRepr = transmute(copy box);
13946
while box != mut_null() {
14047
let next_before = transmute(copy (*box).header.next);
@@ -156,7 +63,11 @@ unsafe fn each_live_alloc(read_next_before: bool,
15663

15764
#[cfg(unix)]
15865
fn debug_mem() -> bool {
159-
::rt::env::get().debug_mem
66+
// XXX: Need to port the environment struct to newsched
67+
match rt::context() {
68+
OldTaskContext => ::rt::env::get().debug_mem,
69+
_ => false
70+
}
16071
}
16172

16273
#[cfg(windows)]
@@ -165,13 +76,12 @@ fn debug_mem() -> bool {
16576
}
16677

16778
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
168-
#[cfg(not(test))]
169-
#[lang="annihilate"]
17079
pub unsafe fn annihilate() {
171-
use unstable::lang::local_free;
80+
use rt::local_heap::local_free;
17281
use io::WriterUtil;
17382
use io;
17483
use libc;
84+
use rt::borrowck;
17585
use sys;
17686
use managed;
17787

@@ -183,7 +93,7 @@ pub unsafe fn annihilate() {
18393

18494
// Quick hack: we need to free this list upon task exit, and this
18595
// is a convenient place to do it.
186-
clear_task_borrow_list();
96+
borrowck::clear_task_borrow_list();
18797

18898
// Pass 1: Make all boxes immortal.
18999
//
@@ -207,7 +117,7 @@ pub unsafe fn annihilate() {
207117
if !uniq {
208118
let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
209119
let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
210-
drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));
120+
drop_glue(&tydesc, transmute(&(*box).data));
211121
}
212122
}
213123

branches/try2/src/libstd/rt/comm.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -399,12 +399,6 @@ impl<T: Owned> GenericChan<T> for SharedChan<T> {
399399
}
400400

401401
impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
402-
#[cfg(stage0)] // odd type checking errors
403-
fn try_send(&self, _val: T) -> bool {
404-
fail!()
405-
}
406-
407-
#[cfg(not(stage0))]
408402
fn try_send(&self, val: T) -> bool {
409403
unsafe {
410404
let (next_pone, next_cone) = oneshot();
@@ -448,12 +442,6 @@ impl<T: Owned> GenericPort<T> for SharedPort<T> {
448442
}
449443
}
450444

451-
#[cfg(stage0)] // odd type checking errors
452-
fn try_recv(&self) -> Option<T> {
453-
fail!()
454-
}
455-
456-
#[cfg(not(stage0))]
457445
fn try_recv(&self) -> Option<T> {
458446
unsafe {
459447
let (next_link_port, next_link_chan) = oneshot();

branches/try2/src/libstd/rt/local_heap.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,24 @@
1010

1111
//! The local, garbage collected heap
1212
13+
use libc;
1314
use libc::{c_void, uintptr_t, size_t};
1415
use ops::Drop;
16+
use repr::BoxRepr;
17+
use rt;
18+
use rt::OldTaskContext;
19+
use rt::local::Local;
20+
use rt::task::Task;
1521

1622
type MemoryRegion = c_void;
17-
type BoxedRegion = c_void;
23+
24+
struct Env { priv opaque: () }
25+
26+
struct BoxedRegion {
27+
env: *Env,
28+
backing_region: *MemoryRegion,
29+
live_allocs: *BoxRepr
30+
}
1831

1932
pub type OpaqueBox = c_void;
2033
pub type TypeDesc = c_void;
@@ -71,6 +84,40 @@ impl Drop for LocalHeap {
7184
}
7285
}
7386

87+
// A little compatibility function
88+
pub unsafe fn local_free(ptr: *libc::c_char) {
89+
match rt::context() {
90+
OldTaskContext => {
91+
rust_upcall_free_noswitch(ptr);
92+
93+
extern {
94+
#[fast_ffi]
95+
unsafe fn rust_upcall_free_noswitch(ptr: *libc::c_char);
96+
}
97+
}
98+
_ => {
99+
do Local::borrow::<Task,()> |task| {
100+
task.heap.free(ptr as *libc::c_void);
101+
}
102+
}
103+
}
104+
}
105+
106+
pub fn live_allocs() -> *BoxRepr {
107+
let region = match rt::context() {
108+
OldTaskContext => {
109+
unsafe { rust_current_boxed_region() }
110+
}
111+
_ => {
112+
do Local::borrow::<Task, *BoxedRegion> |task| {
113+
task.heap.boxed_region
114+
}
115+
}
116+
};
117+
118+
return unsafe { (*region).live_allocs };
119+
}
120+
74121
extern {
75122
fn rust_new_memory_region(synchronized: uintptr_t,
76123
detailed_leaks: uintptr_t,
@@ -86,4 +133,5 @@ extern {
86133
ptr: *OpaqueBox,
87134
size: size_t) -> *OpaqueBox;
88135
fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
136+
fn rust_current_boxed_region() -> *BoxedRegion;
89137
}

branches/try2/src/libstd/rt/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ mod thread;
124124
pub mod env;
125125

126126
/// The local, managed heap
127-
mod local_heap;
127+
pub mod local_heap;
128128

129129
/// The Logger trait and implementations
130130
pub mod logging;

branches/try2/src/libstd/rt/task.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
1616
use borrow;
1717
use cast::transmute;
18+
use cleanup;
1819
use libc::{c_void, uintptr_t};
1920
use ptr;
2021
use prelude::*;
@@ -118,6 +119,10 @@ impl Task {
118119
}
119120
_ => ()
120121
}
122+
123+
// Destroy remaining boxes
124+
unsafe { cleanup::annihilate(); }
125+
121126
self.destroyed = true;
122127
}
123128
}
@@ -269,4 +274,20 @@ mod test {
269274
assert!(res.is_err());
270275
}
271276
}
277+
278+
#[test]
279+
fn heap_cycles() {
280+
use option::{Option, Some, None};
281+
282+
do run_in_newsched_task {
283+
struct List {
284+
next: Option<@mut List>,
285+
}
286+
287+
let a = @mut List { next: None };
288+
let b = @mut List { next: Some(a) };
289+
290+
a.next = Some(b);
291+
}
292+
}
272293
}

branches/try2/src/libstd/sys.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,15 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
216216
task.logger.log(Left(outmsg.take()));
217217
}
218218
} else {
219-
rtdebug!("%s", outmsg);
219+
rterrln!("%s", outmsg);
220220
}
221221

222222
gc::cleanup_stack_for_failure();
223223

224224
let task = Local::unsafe_borrow::<Task>();
225+
if (*task).unwinder.unwinding {
226+
rtabort!("unwinding again");
227+
}
225228
(*task).unwinder.begin_unwind();
226229
}
227230
}

branches/try2/src/libstd/unstable/lang.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ pub mod rustrt {
4343
size: uintptr_t)
4444
-> *c_char;
4545

46-
#[fast_ffi]
47-
unsafe fn rust_upcall_free_noswitch(ptr: *c_char);
48-
4946
#[rust_stack]
5047
fn rust_try_get_task() -> *rust_task;
5148

@@ -105,16 +102,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
105102
// problem occurs, call exit instead.
106103
#[lang="free"]
107104
pub unsafe fn local_free(ptr: *c_char) {
108-
match context() {
109-
OldTaskContext => {
110-
rustrt::rust_upcall_free_noswitch(ptr);
111-
}
112-
_ => {
113-
do Local::borrow::<Task,()> |task| {
114-
task.heap.free(ptr as *c_void);
115-
}
116-
}
117-
}
105+
::rt::local_heap::local_free(ptr);
118106
}
119107

120108
#[lang="borrow_as_imm"]
@@ -162,6 +150,11 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str {
162150
str::raw::from_buf_len(ptr, len)
163151
}
164152

153+
#[lang="annihilate"]
154+
pub unsafe fn annihilate() {
155+
::cleanup::annihilate()
156+
}
157+
165158
#[lang="start"]
166159
pub fn start(main: *u8, argc: int, argv: **c_char,
167160
crate_map: *u8) -> int {

branches/try2/src/rt/rust_builtin.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,12 @@ rust_delete_memory_region(memory_region *region) {
882882
delete region;
883883
}
884884

885+
extern "C" CDECL boxed_region*
886+
rust_current_boxed_region() {
887+
rust_task *task = rust_get_current_task();
888+
return &task->boxed;
889+
}
890+
885891
extern "C" CDECL boxed_region*
886892
rust_new_boxed_region(memory_region *region,
887893
uintptr_t poison_on_free) {

0 commit comments

Comments
 (0)