@@ -137,126 +137,9 @@ rust_task::~rust_task()
137
137
138
138
void
139
139
rust_task::start (uintptr_t exit_task_glue,
140
- uintptr_t spawnee_abi,
141
140
uintptr_t spawnee_fn,
142
141
uintptr_t args,
143
142
size_t callsz)
144
- {
145
- if (spawnee_abi == ABI_X86_RUSTBOOT_CDECL)
146
- start_rustboot (exit_task_glue, spawnee_fn, args, callsz);
147
- else
148
- start_rustc (exit_task_glue, spawnee_fn, args, callsz);
149
- }
150
-
151
- void
152
- rust_task::start_rustboot (uintptr_t exit_task_glue,
153
- uintptr_t spawnee_fn,
154
- uintptr_t args,
155
- size_t callsz)
156
- {
157
- LOGPTR (dom, " exit-task glue" , exit_task_glue);
158
- LOGPTR (dom, " from spawnee" , spawnee_fn);
159
-
160
- // Set sp to last uintptr_t-sized cell of segment
161
- rust_sp -= sizeof (uintptr_t );
162
-
163
- // NB: Darwin needs "16-byte aligned" stacks *at the point of the call
164
- // instruction in the caller*. This means that the address at which the
165
- // word before retpc is pushed must always be 16-byte aligned.
166
- //
167
- // see: "Mac OS X ABI Function Call Guide"
168
-
169
-
170
- // Begin synthesizing frames. There are two: a "fully formed"
171
- // exit-task frame at the top of the stack -- that pretends to be
172
- // mid-execution -- and a just-starting frame beneath it that
173
- // starts executing the first instruction of the spawnee. The
174
- // spawnee *thinks* it was called by the exit-task frame above
175
- // it. It wasn't; we put that fake frame in place here, but the
176
- // illusion is enough for the spawnee to return to the exit-task
177
- // frame when it's done, and exit.
178
- uintptr_t *spp = (uintptr_t *)rust_sp;
179
-
180
-
181
- // The exit_task_glue frame we synthesize above the frame we activate:
182
- make_aligned_room_for_bytes (spp, 2 * sizeof (uintptr_t ));
183
- *spp-- = (uintptr_t ) 0 ; // closure-or-obj
184
- *spp-- = (uintptr_t ) this ; // task
185
- I (dom, spp == align_down (spp));
186
- *spp-- = (uintptr_t ) 0x0 ; // output
187
- *spp-- = (uintptr_t ) 0x0 ; // retpc
188
-
189
- uintptr_t exit_task_frame_base = 0 ;
190
-
191
- for (size_t j = 0 ; j < n_callee_saves; ++j) {
192
-
193
- // We want 'frame_base' to point to the old fp in this (exit-task)
194
- // frame, because we're going to inject this frame-pointer into
195
- // the callee-save frame pointer value in the *next* (spawnee)
196
- // frame. A cheap trick, but this means the spawnee frame will
197
- // restore the proper frame pointer of the glue frame as it runs
198
- // its epilogue.
199
- if (j == callee_save_fp)
200
- exit_task_frame_base = (uintptr_t )spp;
201
-
202
- *spp-- = 0 ;
203
- }
204
-
205
- *spp-- = (uintptr_t ) dom->root_crate ; // crate ptr
206
- *spp-- = (uintptr_t ) 0 ; // frame_glue_fns
207
-
208
- I (dom, args);
209
- make_aligned_room_for_bytes (spp, callsz - sizeof (uintptr_t ));
210
-
211
- // Copy args from spawner to spawnee.
212
- uintptr_t *src = (uintptr_t *)args;
213
- src += 1 ; // spawn-call output slot
214
- src += 1 ; // spawn-call task slot
215
- src += 1 ; // spawn-call closure-or-obj slot
216
-
217
- // Undo previous sp-- so we're pointing at the last word pushed.
218
- ++spp;
219
-
220
- // Memcpy all but the task, output and env pointers
221
- callsz -= (3 * sizeof (uintptr_t ));
222
- spp = (uintptr_t *) (((uintptr_t )spp) - callsz);
223
- memcpy (spp, src, callsz);
224
-
225
- // Move sp down to point to last implicit-arg cell (env).
226
- spp--;
227
-
228
- // The *implicit* incoming args to the spawnee frame we're
229
- // activating:
230
- *spp-- = (uintptr_t ) 0x0 ; // closure-or-obj
231
-
232
- // in CDECL mode we write the task + outptr to the spawnee stack.
233
- *spp-- = (uintptr_t ) this ; // task
234
- *spp-- = (uintptr_t ) 0 ; // output addr
235
-
236
- I (dom, spp+1 == align_down (spp+1 ));
237
- *spp-- = (uintptr_t ) exit_task_glue; // retpc
238
-
239
- // The context the activate_glue needs to switch stack.
240
- *spp-- = (uintptr_t ) spawnee_fn; // instruction to start at
241
- for (size_t j = 0 ; j < n_callee_saves; ++j) {
242
- // callee-saves to carry in when we activate
243
- if (j == callee_save_fp)
244
- *spp-- = exit_task_frame_base;
245
- else
246
- *spp-- = (uintptr_t )NULL ;
247
- }
248
-
249
- // Back up one, we overshot where sp should be.
250
- rust_sp = (uintptr_t ) (spp+1 );
251
-
252
- transition (&dom->newborn_tasks , &dom->running_tasks );
253
- }
254
-
255
- void
256
- rust_task::start_rustc (uintptr_t exit_task_glue,
257
- uintptr_t spawnee_fn,
258
- uintptr_t args,
259
- size_t callsz)
260
143
{
261
144
LOGPTR (dom, " exit-task glue" , exit_task_glue);
262
145
LOGPTR (dom, " from spawnee" , spawnee_fn);
0 commit comments