Skip to content

Commit b4cdae8

Browse files
committed
---
yaml --- r: 1925 b: refs/heads/master c: 3e7b991 h: refs/heads/master i: 1923: 23fcba2 v: v3
1 parent 3856e59 commit b4cdae8

File tree

3 files changed

+51
-24
lines changed

3 files changed

+51
-24
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: b5a43364872dbfa8e036e51599c73e882dfd13c2
2+
refs/heads/master: 3e7b991d4957a13e8049c1a4d1893a685f47d9ae

trunk/src/comp/middle/trans.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6272,7 +6272,7 @@ fn trans_exit_task_glue(@glue_fns glues,
62726272
let vec[ValueRef] V_args = vec();
62736273

62746274
auto llfn = glues.exit_task_glue;
6275-
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 3u);
6275+
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 4u);
62766276

62776277
auto entrybb = llvm.LLVMAppendBasicBlock(llfn, _str.buf("entry"));
62786278
auto build = new_builder(entrybb);
@@ -6731,6 +6731,7 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
67316731
*/
67326732
exit_task_glue = decl_cdecl_fn(llmod, abi.exit_task_glue_name(),
67336733
T_fn(vec(T_int(),
6734+
T_int(),
67346735
T_int(),
67356736
T_int(),
67366737
T_taskptr(tn)),

trunk/src/rt/rust_task.cpp

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ align_down(uintptr_t sp)
5858
return sp & ~(16 - 1);
5959
}
6060

61+
static uintptr_t*
62+
align_down(uintptr_t* sp)
63+
{
64+
return (uintptr_t*) align_down((uintptr_t)sp);
65+
}
66+
67+
68+
static void
69+
make_aligned_room_for_bytes(uintptr_t*& sp, size_t n)
70+
{
71+
uintptr_t tmp = (uintptr_t) sp;
72+
tmp = align_down(tmp - n) + n;
73+
sp = (uintptr_t*) tmp;
74+
}
75+
6176

6277
rust_task::rust_task(rust_dom *dom, rust_task_list *state,
6378
rust_task *spawner, const char *name) :
@@ -131,9 +146,15 @@ rust_task::start(uintptr_t exit_task_glue,
131146
dom->logptr("exit-task glue", exit_task_glue);
132147
dom->logptr("from spawnee", spawnee_fn);
133148

134-
// Set sp to last uintptr_t-sized cell of segment and align down.
149+
// Set sp to last uintptr_t-sized cell of segment
135150
rust_sp -= sizeof(uintptr_t);
136-
rust_sp = align_down(rust_sp);
151+
152+
// NB: Darwin needs "16-byte aligned" stacks *at the point of the call
153+
// instruction in the caller*. This means that the address at which a
154+
// retpc is pushed must always be 16-byte aligned.
155+
//
156+
// see: "Mac OS X ABI Function Call Guide"
157+
137158

138159
// Begin synthesizing frames. There are two: a "fully formed"
139160
// exit-task frame at the top of the stack -- that pretends to be
@@ -145,10 +166,13 @@ rust_task::start(uintptr_t exit_task_glue,
145166
// frame when it's done, and exit.
146167
uintptr_t *spp = (uintptr_t *)rust_sp;
147168

169+
148170
// The exit_task_glue frame we synthesize above the frame we activate:
171+
make_aligned_room_for_bytes(spp, 3 * sizeof(uintptr_t));
149172
*spp-- = (uintptr_t) 0; // closure-or-obj
150173
*spp-- = (uintptr_t) this; // task
151174
*spp-- = (uintptr_t) 0x0; // output
175+
I(dom, spp == align_down(spp));
152176
*spp-- = (uintptr_t) 0x0; // retpc
153177

154178
uintptr_t exit_task_frame_base;
@@ -172,27 +196,28 @@ rust_task::start(uintptr_t exit_task_glue,
172196
*spp-- = (uintptr_t) 0; // frame_glue_fns
173197
}
174198

199+
I(dom, args);
200+
if (spawnee_abi == ABI_X86_RUSTBOOT_CDECL)
201+
make_aligned_room_for_bytes(spp, callsz);
202+
else
203+
make_aligned_room_for_bytes(spp, callsz - 2 * sizeof(uintptr_t));
204+
175205
// Copy args from spawner to spawnee.
176-
if (args) {
177-
uintptr_t *src = (uintptr_t *)args;
178-
src += 1; // spawn-call output slot
179-
src += 1; // spawn-call task slot
180-
src += 1; // spawn-call closure-or-obj slot
181-
182-
// Undo previous sp-- so we're pointing at the last word pushed.
183-
++spp;
184-
185-
// Memcpy all but the task, output and env pointers
186-
callsz -= (3 * sizeof(uintptr_t));
187-
spp = (uintptr_t*) (((uintptr_t)spp) - callsz);
188-
memcpy(spp, src, callsz);
189-
190-
// Move sp down to point to last implicit-arg cell (env).
191-
spp--;
192-
} else {
193-
// We're at root, starting up.
194-
I(dom, callsz==0);
195-
}
206+
uintptr_t *src = (uintptr_t *)args;
207+
src += 1; // spawn-call output slot
208+
src += 1; // spawn-call task slot
209+
src += 1; // spawn-call closure-or-obj slot
210+
211+
// Undo previous sp-- so we're pointing at the last word pushed.
212+
++spp;
213+
214+
// Memcpy all but the task, output and env pointers
215+
callsz -= (3 * sizeof(uintptr_t));
216+
spp = (uintptr_t*) (((uintptr_t)spp) - callsz);
217+
memcpy(spp, src, callsz);
218+
219+
// Move sp down to point to last implicit-arg cell (env).
220+
spp--;
196221

197222
// The *implicit* incoming args to the spawnee frame we're
198223
// activating:
@@ -208,6 +233,7 @@ rust_task::start(uintptr_t exit_task_glue,
208233
I(dom, spawnee_abi == ABI_X86_RUSTC_FASTCALL);
209234
}
210235

236+
I(dom, spp == align_down(spp));
211237
*spp-- = (uintptr_t) exit_task_glue; // retpc
212238

213239
// The context the activate_glue needs to switch stack.

0 commit comments

Comments
 (0)