@@ -1229,14 +1229,63 @@ let stack_growth_check
1229
1229
Il. patch_jump e bypass_grow_upcall_jmp_pc e.Il. emit_pc
1230
1230
;;
1231
1231
1232
- let fn_prologue
1233
- (e :Il.emitter )
1232
+ let n_glue_args = Int64. of_int Abi. worst_case_glue_call_args;;
1233
+ let n_glue_words = Int64. mul word_sz n_glue_args;;
1234
+
1235
+ let combined_frame_size
1234
1236
(framesz :size )
1235
1237
(callsz :size )
1238
+ : size =
1239
+ (*
1240
+ * We double the reserved callsz because we need a 'temporary tail-call
1241
+ * region' above the actual call region, in case there's a drop call at the
1242
+ * end of assembling the tail-call args and before copying them to callee
1243
+ * position.
1244
+ *)
1245
+
1246
+ let callsz = add_sz callsz callsz in
1247
+
1248
+ (*
1249
+ * Add in *another* word to handle an extra-awkward spill of the
1250
+ * callee address that might occur during an indirect tail call.
1251
+ *)
1252
+ let callsz = add_sz (SIZE_fixed word_sz) callsz in
1253
+
1254
+ (*
1255
+ * Add in enough words for a glue-call (these occur underneath esp)
1256
+ *)
1257
+ let callsz = add_sz (SIZE_fixed n_glue_words) callsz in
1258
+
1259
+ add_sz callsz framesz
1260
+ ;;
1261
+
1262
+ let minimal_fn_prologue
1263
+ (e :Il.emitter )
1264
+ (call_and_frame_sz :Asm.expr64 )
1265
+ : unit =
1266
+
1267
+ let emit = Il. emit e in
1268
+ let mov dst src = emit (Il. umov dst src) in
1269
+ let add dst src = emit (Il. binary Il. ADD dst (Il. Cell dst) src) in
1270
+ let sub dst src = emit (Il. binary Il. SUB dst (Il. Cell dst) src) in
1271
+
1272
+ (* See diagram and explanation in full_fn_prologue, below. *)
1273
+ save_callee_saves e;
1274
+ mov (rc ebp) (ro esp); (* Establish frame base. *)
1275
+ sub (rc esp) (imm call_and_frame_sz); (* Establish a frame. *)
1276
+ mov (rc edi) (ro esp); (* Zero the frame. *)
1277
+ mov (rc ecx) (imm call_and_frame_sz);
1278
+ emit (Il. unary Il. ZERO (word_at (h edi)) (ro ecx));
1279
+ (* Move esp back up over the glue region. *)
1280
+ add (rc esp) (immi n_glue_words);
1281
+ ;;
1282
+
1283
+ let full_fn_prologue
1284
+ (e :Il.emitter )
1285
+ (call_and_frame_sz :size )
1236
1286
(nabi :nabi )
1237
1287
(grow_task_fixup :fixup )
1238
1288
(is_obj_fn :bool )
1239
- (_ (* minimal*) :bool )
1240
1289
: unit =
1241
1290
1242
1291
let esi_n = word_n (h esi) in
@@ -1299,33 +1348,6 @@ let fn_prologue
1299
1348
* callee-saves) before we perform the next check.
1300
1349
*)
1301
1350
1302
- (*
1303
- * We double the reserved callsz because we need a 'temporary tail-call
1304
- * region' above the actual call region, in case there's a drop call at the
1305
- * end of assembling the tail-call args and before copying them to callee
1306
- * position.
1307
- *)
1308
-
1309
- let callsz = add_sz callsz callsz in
1310
- let n_glue_args = Int64. of_int Abi. worst_case_glue_call_args in
1311
- let n_glue_words = Int64. mul word_sz n_glue_args in
1312
-
1313
- (*
1314
- * Add in *another* word to handle an extra-awkward spill of the
1315
- * callee address that might occur during an indirect tail call.
1316
- *)
1317
- let callsz = add_sz (SIZE_fixed word_sz) callsz in
1318
-
1319
- (*
1320
- * Add in enough words for a glue-call (these occur underneath esp)
1321
- *)
1322
- let callsz = add_sz (SIZE_fixed n_glue_words) callsz in
1323
-
1324
- (*
1325
- * Cumulative dynamic-frame size.
1326
- *)
1327
- let call_and_frame_sz = add_sz callsz framesz in
1328
-
1329
1351
(* Already have room to save regs on entry. *)
1330
1352
save_callee_saves e;
1331
1353
@@ -1393,6 +1415,30 @@ let fn_prologue
1393
1415
add (rc esp) (immi n_glue_words);
1394
1416
;;
1395
1417
1418
+ let fn_prologue
1419
+ (e :Il.emitter )
1420
+ (framesz :size )
1421
+ (callsz :size )
1422
+ (nabi :nabi )
1423
+ (grow_task_fixup :fixup )
1424
+ (is_obj_fn :bool )
1425
+ (minimal :bool )
1426
+ : unit =
1427
+
1428
+ let call_and_frame_sz = combined_frame_size framesz callsz in
1429
+
1430
+ let full _ =
1431
+ full_fn_prologue e call_and_frame_sz nabi grow_task_fixup is_obj_fn
1432
+ in
1433
+
1434
+ if minimal
1435
+ then
1436
+ match Il. size_to_expr64 call_and_frame_sz with
1437
+ None -> full()
1438
+ | Some sz -> minimal_fn_prologue e sz
1439
+ else
1440
+ full()
1441
+ ;;
1396
1442
1397
1443
let fn_epilogue (e :Il.emitter ) : unit =
1398
1444
0 commit comments