Skip to content

Commit b1ad382

Browse files
committed
---
yaml --- r: 88860 b: refs/heads/snap-stage3 c: 9f00586 h: refs/heads/master v: v3
1 parent 725447b commit b1ad382

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: deeca5d586bfaa4aa60246f671a8d611d38f6248
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: f25c81a51a752786ce8936b503c16912478a89fd
4+
refs/heads/snap-stage3: 9f005866e59246bbe2721fc5a6c993c5ae7e1431
55
refs/heads/try: b160761e35efcd1207112b3b782c06633cf441a8
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libgreen/context.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use stack::StackSegment;
2424
// then misalign the regs again.
2525
pub struct Context {
2626
/// The context entry point, saved here for later destruction
27-
priv start: ~Option<proc()>,
27+
priv start: Option<~proc()>,
2828
/// Hold the registers while the task or scheduler is suspended
2929
priv regs: ~Registers,
3030
/// Lower bound and upper bound for the stack
@@ -34,7 +34,7 @@ pub struct Context {
3434
impl Context {
3535
pub fn empty() -> Context {
3636
Context {
37-
start: ~None,
37+
start: None,
3838
regs: new_regs(),
3939
stack_bounds: None,
4040
}
@@ -43,8 +43,26 @@ impl Context {
4343
/// Create a new context that will resume execution by running proc()
4444
pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
4545
// The C-ABI function that is the task entry point
46-
extern fn task_start_wrapper(f: &mut Option<proc()>) {
47-
f.take_unwrap()()
46+
//
47+
// Note that this function is a little sketchy. We're taking a
48+
// procedure, transmuting it to a stack-closure, and then calling to
49+
// closure. This leverages the fact that the representation of these two
50+
// types is the same.
51+
//
52+
// The reason that we're doing this is that this procedure is expected
53+
// to never return. The codegen which frees the environment of the
54+
// procedure occurs *after* the procedure has completed, and this means
55+
// that we'll never actually free the procedure.
56+
//
57+
// To solve this, we use this transmute (to not trigger the procedure
58+
// deallocation here), and then store a copy of the procedure in the
59+
// `Context` structure returned. When the `Context` is deallocated, then
60+
// the entire procedure box will be deallocated as well.
61+
extern fn task_start_wrapper(f: &proc()) {
62+
unsafe {
63+
let f: &|| = transmute(f);
64+
(*f)()
65+
}
4866
}
4967

5068
let sp: *uint = stack.end();
@@ -60,10 +78,10 @@ impl Context {
6078
// FIXME #7767: Putting main into a ~ so it's a thin pointer and can
6179
// be passed to the spawn function. Another unfortunate
6280
// allocation
63-
let box = ~Some(start);
81+
let start = ~start;
6482
initialize_call_frame(&mut *regs,
6583
task_start_wrapper as *c_void,
66-
unsafe { transmute(&*box) },
84+
unsafe { transmute(&*start) },
6785
sp);
6886

6987
// Scheduler tasks don't have a stack in the "we allocated it" sense,
@@ -78,7 +96,7 @@ impl Context {
7896
Some((stack_base as uint, sp as uint))
7997
};
8098
return Context {
81-
start: box,
99+
start: Some(start),
82100
regs: regs,
83101
stack_bounds: bounds,
84102
}

0 commit comments

Comments
 (0)