1
/* -----------------------------------------------------------------------------
3
* (c) The University of Glasgow 2004
5
* This file is included at the top of all .cmm source files (and
6
* *only* .cmm files). It defines a collection of useful macros for
7
* making .cmm code a bit less error-prone to write, and a bit easier
8
* on the eye for the reader.
10
* For the syntax of .cmm files, see the parser in ghc/compiler/cmm/CmmParse.y.
12
* If you're used to the old HC file syntax, here's a quick cheat sheet
13
* for converting HC code:
16
* - Remove all type casts
18
* - STGFUN(foo) { ... } ==> foo { ... }
19
* - FN_(foo) { ... } ==> foo { ... }
20
* - JMP_(e) ==> jump e;
21
* - Remove EXTFUN(foo)
24
* - Sp += n ==> Sp_adj(n)
25
* - Hp += n ==> Hp_adj(n)
26
* - R1.i ==> R1 (similarly for R1.w, R1.cl etc.)
27
* - You need to explicitly dereference variables; eg.
28
* alloc_blocks ==> CInt[alloc_blocks]
29
* - convert all word offsets into byte offsets:
31
* - sizeofW(StgFoo) ==> SIZEOF_StgFoo
32
* - ENTRY_CODE(e) ==> %ENTRY_CODE(e)
33
* - get_itbl(c) ==> %GET_STD_INFO(c)
34
* - Change liveness masks in STK_CHK_GEN, HP_CHK_GEN:
35
* R1_PTR | R2_PTR ==> R1_PTR & R2_PTR
37
* - Declarations like 'StgPtr p;' become just 'W_ p;'
38
* - e->payload[n] ==> PAYLOAD(e,n)
39
* - Be very careful with comparisons: the infix versions (>, >=, etc.)
40
* are unsigned, so use %lt(a,b) to get signed less-than for example.
42
* Accessing fields of structures defined in the RTS header files is
43
* done via automatically-generated macros in DerivedConstants.h. For
44
* example, where previously we used
46
* CurrentTSO->what_next = x
50
* StgTSO_what_next(CurrentTSO) = x
52
* where the StgTSO_what_next() macro is automatically generated by
53
* mkDerivedConstnants.c. If you need to access a field that doesn't
54
* already have a macro, edit that file (it's pretty self-explanatory).
56
* -------------------------------------------------------------------------- */
62
* In files that are included into both C and C-- (and perhaps
63
* Haskell) sources, we sometimes need to conditionally compile bits
64
* depending on the language. CMINUSMINUS==1 in .cmm sources:
68
#include "ghcconfig.h"
70
/* -----------------------------------------------------------------------------
73
The following synonyms for C-- types are declared here:
75
I8, I16, I32, I64 MachRep-style names for convenience
77
W_ is shorthand for the word type (== StgWord)
78
F_ shorthand for float (F_ == StgFloat == C's float)
79
D_ shorthand for double (D_ == StgDouble == C's double)
81
CInt has the same size as an int in C on this platform
82
CLong has the same size as a long in C on this platform
84
--------------------------------------------------------------------------- */
92
#if SIZEOF_VOID_P == 4
94
/* Maybe it's better to include MachDeps.h */
96
#elif SIZEOF_VOID_P == 8
98
/* Maybe it's better to include MachDeps.h */
101
#error Unknown word size
105
* The RTS must sometimes UNTAG a pointer before dereferencing it.
106
* See the wiki page Commentary/Rts/HaskellExecution/PointerTagging
108
#define TAG_MASK ((1 << TAG_BITS) - 1)
109
#define UNTAG(p) (p & ~TAG_MASK)
110
#define GETTAG(p) (p & TAG_MASK)
114
#elif SIZEOF_INT == 8
117
#error Unknown int size
122
#elif SIZEOF_LONG == 8
125
#error Unknown long size
132
#define SIZEOF_StgDouble 8
133
#define SIZEOF_StgWord64 8
135
/* -----------------------------------------------------------------------------
137
-------------------------------------------------------------------------- */
141
#define STRING(name,str) \
143
name : bits8[] str; \
146
#ifdef TABLES_NEXT_TO_CODE
147
#define RET_LBL(f) f##_info
149
#define RET_LBL(f) f##_ret
152
#ifdef TABLES_NEXT_TO_CODE
153
#define ENTRY_LBL(f) f##_info
155
#define ENTRY_LBL(f) f##_entry
158
/* -----------------------------------------------------------------------------
161
Everything in C-- is in byte offsets (well, most things). We use
162
some macros to allow us to express offsets in words and to try to
163
avoid byte/word confusion.
164
-------------------------------------------------------------------------- */
166
#define SIZEOF_W SIZEOF_VOID_P
167
#define W_MASK (SIZEOF_W-1)
175
/* Converting quantities of words to bytes */
176
#define WDS(n) ((n)*SIZEOF_W)
179
* Converting quantities of bytes to words
180
* NB. these work on *unsigned* values only
182
#define BYTES_TO_WDS(n) ((n) / SIZEOF_W)
183
#define ROUNDUP_BYTES_TO_WDS(n) (((n) + SIZEOF_W - 1) / SIZEOF_W)
185
/* TO_W_(n) converts n to W_ type from a smaller type */
187
#define TO_W_(x) %sx32(x)
188
#define HALF_W_(x) %lobits16(x)
190
#define TO_W_(x) %sx64(x)
191
#define HALF_W_(x) %lobits32(x)
194
#if SIZEOF_INT == 4 && SIZEOF_W == 8
195
#define W_TO_INT(x) %lobits32(x)
196
#elif SIZEOF_INT == SIZEOF_W
197
#define W_TO_INT(x) (x)
200
/* -----------------------------------------------------------------------------
201
Heap/stack access, and adjusting the heap/stack pointers.
202
-------------------------------------------------------------------------- */
204
#define Sp(n) W_[Sp + WDS(n)]
205
#define Hp(n) W_[Hp + WDS(n)]
207
#define Sp_adj(n) Sp = Sp + WDS(n)
208
#define Hp_adj(n) Hp = Hp + WDS(n)
210
/* -----------------------------------------------------------------------------
211
Assertions and Debuggery
212
-------------------------------------------------------------------------- */
215
#define ASSERT(predicate) \
219
foreign "C" _assertFail(NULL, __LINE__); \
222
#define ASSERT(p) /* nothing */
226
#define DEBUG_ONLY(s) s
228
#define DEBUG_ONLY(s) /* nothing */
232
* The IF_DEBUG macro is useful for debug messages that depend on one
233
* of the RTS debug options. For example:
235
* IF_DEBUG(RtsFlags_DebugFlags_apply,
236
* foreign "C" fprintf(stderr, stg_ap_0_ret_str));
238
* Note the syntax is slightly different to the C version of this macro.
241
#define IF_DEBUG(c,s) if (RtsFlags_DebugFlags_##c(RtsFlags) != 0::I32) { s; }
243
#define IF_DEBUG(c,s) /* nothing */
246
/* -----------------------------------------------------------------------------
249
It isn't safe to "enter" every closure. Functions in particular
250
have no entry code as such; their entry point contains the code to
253
ToDo: range should end in N_CLOSURE_TYPES-1, not N_CLOSURE_TYPES,
254
but switch doesn't allow us to use exprs there yet.
256
If R1 points to a tagged object it points either to
258
* A function with arity <= TAG_MASK.
259
In both cases the right thing to do is to return.
260
Note: it is rather lucky that we can use the tag bits to do this
261
for both objects. Maybe it points to a brittle design?
263
Indirections can contain tagged pointers, so their tag is checked.
264
-------------------------------------------------------------------------- */
268
// When profiling, we cannot shortcut ENTER() by checking the tag,
269
// because LDV profiling relies on entering closures to mark them as
273
info = %INFO_PTR(UNTAG(P1));
281
if (GETTAG(P1) != 0) { \
282
jump %ENTRY_CODE(Sp(0)); \
284
info = %INFO_PTR(P1);
286
#define UNTAG_R1 /* nothing */
294
switch [INVALID_OBJECT .. N_CLOSURE_TYPES] \
295
(TO_W_( %INFO_TYPE(%STD_INFO(info)) )) { \
301
P1 = StgInd_indirectee(P1); \
315
jump %ENTRY_CODE(Sp(0)); \
320
jump %ENTRY_CODE(info); \
324
// The FUN cases almost never happen: a pointer to a non-static FUN
325
// should always be tagged. This unfortunately isn't true for the
326
// interpreter right now, which leaves untagged FUNs on the stack.
328
/* -----------------------------------------------------------------------------
330
-------------------------------------------------------------------------- */
332
#include "rts/Constants.h"
333
#include "DerivedConstants.h"
334
#include "rts/storage/ClosureTypes.h"
335
#include "rts/storage/FunTypes.h"
336
#include "rts/storage/SMPClosureOps.h"
337
#include "rts/OSThreads.h"
340
* Need MachRegs, because some of the RTS code is conditionally
341
* compiled based on REG_R1, REG_R2, etc.
343
#define STOLEN_X86_REGS 4
344
#include "stg/MachRegs.h"
346
#include "rts/storage/Liveness.h"
347
#include "rts/prof/LDV.h"
351
#include "rts/storage/Block.h" /* For Bdescr() */
354
#define MyCapability() (BaseReg - OFFSET_Capability_r)
356
/* -------------------------------------------------------------------------
357
Allocation and garbage collection
358
------------------------------------------------------------------------- */
361
* ALLOC_PRIM is for allocating memory on the heap for a primitive
362
* object. It is used all over PrimOps.cmm.
364
* We make the simplifying assumption that the "admin" part of a
365
* primitive closure is just the header when calculating sizes for
366
* ticky-ticky. It's not clear whether eg. the size field of an array
367
* should be counted as "admin", or the various fields of a BCO.
369
#define ALLOC_PRIM(bytes,liveness,reentry) \
370
HP_CHK_GEN_TICKY(bytes,liveness,reentry); \
371
TICK_ALLOC_PRIM(SIZEOF_StgHeader,bytes-SIZEOF_StgHeader,0); \
374
/* CCS_ALLOC wants the size in words, because ccs->mem_alloc is in words */
375
#define CCCS_ALLOC(__alloc) CCS_ALLOC(BYTES_TO_WDS(__alloc), W_[CCCS])
377
#define HP_CHK_GEN_TICKY(alloc,liveness,reentry) \
378
HP_CHK_GEN(alloc,liveness,reentry); \
379
TICK_ALLOC_HEAP_NOCTR(alloc);
381
// allocate() allocates from the nursery, so we check to see
382
// whether the nursery is nearly empty in any function that uses
383
// allocate() - this includes many of the primops.
384
#define MAYBE_GC(liveness,reentry) \
385
if (bdescr_link(CurrentNursery) == NULL || \
386
generation_n_new_large_blocks(W_[g0]) >= CInt[alloc_blocks_lim]) { \
390
jump stg_gc_gen_hp; \
393
/* -----------------------------------------------------------------------------
395
-------------------------------------------------------------------------- */
398
* This is really ugly, since we don't do the rest of StgHeader this
399
* way. The problem is that values from DerivedConstants.h cannot be
400
* dependent on the way (SMP, PROF etc.). For SIZEOF_StgHeader we get
401
* the value from GHC, but it seems like too much trouble to do that
402
* for StgThunkHeader.
404
#define SIZEOF_StgThunkHeader SIZEOF_StgHeader+SIZEOF_StgSMPThunkHeader
406
#define StgThunk_payload(__ptr__,__ix__) \
407
W_[__ptr__+SIZEOF_StgThunkHeader+ WDS(__ix__)]
409
/* -----------------------------------------------------------------------------
411
-------------------------------------------------------------------------- */
413
/* The offset of the payload of an array */
414
#define BYTE_ARR_CTS(arr) ((arr) + SIZEOF_StgArrWords)
416
/* The number of words allocated in an array payload */
417
#define BYTE_ARR_WDS(arr) ROUNDUP_BYTES_TO_WDS(StgArrWords_bytes(arr))
419
/* Getting/setting the info pointer of a closure */
420
#define SET_INFO(p,info) StgHeader_info(p) = info
421
#define GET_INFO(p) StgHeader_info(p)
423
/* Determine the size of an ordinary closure from its info table */
424
#define sizeW_fromITBL(itbl) \
425
SIZEOF_StgHeader + WDS(%INFO_PTRS(itbl)) + WDS(%INFO_NPTRS(itbl))
427
/* NB. duplicated from InfoTables.h! */
428
#define BITMAP_SIZE(bitmap) ((bitmap) & BITMAP_SIZE_MASK)
429
#define BITMAP_BITS(bitmap) ((bitmap) >> BITMAP_BITS_SHIFT)
431
/* Debugging macros */
432
#define LOOKS_LIKE_INFO_PTR(p) \
434
LOOKS_LIKE_INFO_PTR_NOT_NULL(p))
436
#define LOOKS_LIKE_INFO_PTR_NOT_NULL(p) \
437
( (TO_W_(%INFO_TYPE(%STD_INFO(p))) != INVALID_OBJECT) && \
438
(TO_W_(%INFO_TYPE(%STD_INFO(p))) < N_CLOSURE_TYPES))
440
#define LOOKS_LIKE_CLOSURE_PTR(p) (LOOKS_LIKE_INFO_PTR(GET_INFO(UNTAG(p))))
443
* The layout of the StgFunInfoExtra part of an info table changes
444
* depending on TABLES_NEXT_TO_CODE. So we define field access
445
* macros which use the appropriate version here:
447
#ifdef TABLES_NEXT_TO_CODE
449
* when TABLES_NEXT_TO_CODE, slow_apply is stored as an offset
450
* instead of the normal pointer.
453
#define StgFunInfoExtra_slow_apply(fun_info) \
454
(TO_W_(StgFunInfoExtraRev_slow_apply_offset(fun_info)) \
455
+ (fun_info) + SIZEOF_StgFunInfoExtraRev + SIZEOF_StgInfoTable)
457
#define StgFunInfoExtra_fun_type(i) StgFunInfoExtraRev_fun_type(i)
458
#define StgFunInfoExtra_arity(i) StgFunInfoExtraRev_arity(i)
459
#define StgFunInfoExtra_bitmap(i) StgFunInfoExtraRev_bitmap(i)
461
#define StgFunInfoExtra_slow_apply(i) StgFunInfoExtraFwd_slow_apply(i)
462
#define StgFunInfoExtra_fun_type(i) StgFunInfoExtraFwd_fun_type(i)
463
#define StgFunInfoExtra_arity(i) StgFunInfoExtraFwd_arity(i)
464
#define StgFunInfoExtra_bitmap(i) StgFunInfoExtraFwd_bitmap(i)
467
#define mutArrPtrsCardWords(n) \
468
ROUNDUP_BYTES_TO_WDS(((n) + (1 << MUT_ARR_PTRS_CARD_BITS) - 1) >> MUT_ARR_PTRS_CARD_BITS)
470
/* -----------------------------------------------------------------------------
471
Voluntary Yields/Blocks
473
We only have a generic version of this at the moment - if it turns
474
out to be slowing us down we can make specialised ones.
475
-------------------------------------------------------------------------- */
477
#define YIELD(liveness,reentry) \
482
#define BLOCK(liveness,reentry) \
487
/* -----------------------------------------------------------------------------
489
-------------------------------------------------------------------------- */
492
#define TICK_BUMP_BY(ctr,n) CLong[ctr] = CLong[ctr] + n
494
#define TICK_BUMP_BY(ctr,n) /* nothing */
497
#define TICK_BUMP(ctr) TICK_BUMP_BY(ctr,1)
499
#define TICK_ENT_DYN_IND() TICK_BUMP(ENT_DYN_IND_ctr)
500
#define TICK_ENT_DYN_THK() TICK_BUMP(ENT_DYN_THK_ctr)
501
#define TICK_ENT_VIA_NODE() TICK_BUMP(ENT_VIA_NODE_ctr)
502
#define TICK_ENT_STATIC_IND() TICK_BUMP(ENT_STATIC_IND_ctr)
503
#define TICK_ENT_PERM_IND() TICK_BUMP(ENT_PERM_IND_ctr)
504
#define TICK_ENT_PAP() TICK_BUMP(ENT_PAP_ctr)
505
#define TICK_ENT_AP() TICK_BUMP(ENT_AP_ctr)
506
#define TICK_ENT_AP_STACK() TICK_BUMP(ENT_AP_STACK_ctr)
507
#define TICK_ENT_BH() TICK_BUMP(ENT_BH_ctr)
508
#define TICK_UNKNOWN_CALL() TICK_BUMP(UNKNOWN_CALL_ctr)
509
#define TICK_UPDF_PUSHED() TICK_BUMP(UPDF_PUSHED_ctr)
510
#define TICK_CATCHF_PUSHED() TICK_BUMP(CATCHF_PUSHED_ctr)
511
#define TICK_UPDF_OMITTED() TICK_BUMP(UPDF_OMITTED_ctr)
512
#define TICK_UPD_NEW_IND() TICK_BUMP(UPD_NEW_IND_ctr)
513
#define TICK_UPD_NEW_PERM_IND() TICK_BUMP(UPD_NEW_PERM_IND_ctr)
514
#define TICK_UPD_OLD_IND() TICK_BUMP(UPD_OLD_IND_ctr)
515
#define TICK_UPD_OLD_PERM_IND() TICK_BUMP(UPD_OLD_PERM_IND_ctr)
517
#define TICK_SLOW_CALL_FUN_TOO_FEW() TICK_BUMP(SLOW_CALL_FUN_TOO_FEW_ctr)
518
#define TICK_SLOW_CALL_FUN_CORRECT() TICK_BUMP(SLOW_CALL_FUN_CORRECT_ctr)
519
#define TICK_SLOW_CALL_FUN_TOO_MANY() TICK_BUMP(SLOW_CALL_FUN_TOO_MANY_ctr)
520
#define TICK_SLOW_CALL_PAP_TOO_FEW() TICK_BUMP(SLOW_CALL_PAP_TOO_FEW_ctr)
521
#define TICK_SLOW_CALL_PAP_CORRECT() TICK_BUMP(SLOW_CALL_PAP_CORRECT_ctr)
522
#define TICK_SLOW_CALL_PAP_TOO_MANY() TICK_BUMP(SLOW_CALL_PAP_TOO_MANY_ctr)
524
#define TICK_SLOW_CALL_v() TICK_BUMP(SLOW_CALL_v_ctr)
525
#define TICK_SLOW_CALL_p() TICK_BUMP(SLOW_CALL_p_ctr)
526
#define TICK_SLOW_CALL_pv() TICK_BUMP(SLOW_CALL_pv_ctr)
527
#define TICK_SLOW_CALL_pp() TICK_BUMP(SLOW_CALL_pp_ctr)
528
#define TICK_SLOW_CALL_ppp() TICK_BUMP(SLOW_CALL_ppp_ctr)
529
#define TICK_SLOW_CALL_pppp() TICK_BUMP(SLOW_CALL_pppp_ctr)
530
#define TICK_SLOW_CALL_ppppp() TICK_BUMP(SLOW_CALL_ppppp_ctr)
531
#define TICK_SLOW_CALL_pppppp() TICK_BUMP(SLOW_CALL_pppppp_ctr)
533
/* NOTE: TICK_HISTO_BY and TICK_HISTO
534
currently have no effect.
535
The old code for it didn't typecheck and I
536
just commented it out to get ticky to work.
539
#define TICK_HISTO_BY(histo,n,i) /* nothing */
541
#define TICK_HISTO(histo,n) TICK_HISTO_BY(histo,n,1)
543
/* An unboxed tuple with n components. */
544
#define TICK_RET_UNBOXED_TUP(n) \
545
TICK_BUMP(RET_UNBOXED_TUP_ctr++); \
546
TICK_HISTO(RET_UNBOXED_TUP,n)
549
* A slow call with n arguments. In the unevald case, this call has
550
* already been counted once, so don't count it again.
552
#define TICK_SLOW_CALL(n) \
553
TICK_BUMP(SLOW_CALL_ctr); \
554
TICK_HISTO(SLOW_CALL,n)
557
* This slow call was found to be to an unevaluated function; undo the
558
* ticks we did in TICK_SLOW_CALL.
560
#define TICK_SLOW_CALL_UNEVALD(n) \
561
TICK_BUMP(SLOW_CALL_UNEVALD_ctr); \
562
TICK_BUMP_BY(SLOW_CALL_ctr,-1); \
563
TICK_HISTO_BY(SLOW_CALL,n,-1);
565
/* Updating a closure with a new CON */
566
#define TICK_UPD_CON_IN_NEW(n) \
567
TICK_BUMP(UPD_CON_IN_NEW_ctr); \
568
TICK_HISTO(UPD_CON_IN_NEW,n)
570
#define TICK_ALLOC_HEAP_NOCTR(n) \
571
TICK_BUMP(ALLOC_HEAP_ctr); \
572
TICK_BUMP_BY(ALLOC_HEAP_tot,n)
574
/* -----------------------------------------------------------------------------
576
-------------------------------------------------------------------------- */
578
#define NO_TREC stg_NO_TREC_closure
579
#define END_TSO_QUEUE stg_END_TSO_QUEUE_closure
580
#define END_INVARIANT_CHECK_QUEUE stg_END_INVARIANT_CHECK_QUEUE_closure
582
#define recordMutableCap(p, gen, regs) \
585
mut_list = Capability_mut_lists(MyCapability()) + WDS(gen); \
586
__bd = W_[mut_list]; \
587
if (bdescr_free(__bd) >= bdescr_start(__bd) + BLOCK_SIZE) { \
589
("ptr" __new_bd) = foreign "C" allocBlock_lock() [regs]; \
590
bdescr_link(__new_bd) = __bd; \
592
W_[mut_list] = __bd; \
595
free = bdescr_free(__bd); \
597
bdescr_free(__bd) = free + WDS(1);
599
#define recordMutable(p, regs) \
604
__bd = Bdescr(__p); \
605
__gen = TO_W_(bdescr_gen_no(__bd)); \
606
if (__gen > 0) { recordMutableCap(__p, __gen, regs); }