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 * context_switch ==> CInt[context_switch]
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 * -------------------------------------------------------------------------- */
61 // In files that are included into both C and C-- (and perhaps
62 // Haskell) sources, we sometimes need to conditionally compile bits
63 // depending on the language. CMINUSMINUS==1 in .cmm sources:
66 #include "ghcconfig.h"
67 #include "RtsConfig.h"
69 /* -----------------------------------------------------------------------------
72 The following synonyms for C-- types are declared here:
74 I8, I16, I32, I64 MachRep-style names for convenience
76 W_ is shorthand for the word type (== StgWord)
77 F_ shorthand for float (F_ == StgFloat == C's float)
78 D_ shorthand for double (D_ == StgDouble == C's double)
80 CInt has the same size as an int in C on this platform
81 CLong has the same size as a long in C on this platform
83 --------------------------------------------------------------------------- */
90 #if SIZEOF_VOID_P == 4
92 #elif SIZEOF_VOID_P == 8
95 #error Unknown word size
103 #error Unknown int size
108 #elif SIZEOF_LONG = 8
111 #error Unknown long size
118 #define SIZEOF_StgDouble 8
119 #define SIZEOF_StgWord64 8
121 /* -----------------------------------------------------------------------------
123 -------------------------------------------------------------------------- */
127 #define STRING(name,str) \
129 name : bits8[] str; \
132 /* -----------------------------------------------------------------------------
135 Everything in C-- is in byte offsets (well, most things). We use
136 some macros to allow us to express offsets in words and to try to
137 avoid byte/word confusion.
138 -------------------------------------------------------------------------- */
140 #define SIZEOF_W SIZEOF_VOID_P
141 #define W_MASK (SIZEOF_W-1)
149 // Converting quantities of words to bytes
150 #define WDS(n) ((n)*SIZEOF_W)
152 // Converting quantities of bytes to words
153 // NB. these work on *unsigned* values only
154 #define BYTES_TO_WDS(n) ((n) / SIZEOF_W)
155 #define ROUNDUP_BYTES_TO_WDS(n) (((n) + SIZEOF_W - 1) / SIZEOF_W)
157 // TO_W_(n) converts n to W_ type from a smaller type
159 #define TO_W_(x) %sx32(x)
160 #define HALF_W_(x) %lobits16(x)
162 #define TO_W_(x) %sx64(x)
163 #define HALF_W_(x) %lobits32(x)
166 /* -----------------------------------------------------------------------------
167 Heap/stack access, and adjusting the heap/stack pointers.
168 -------------------------------------------------------------------------- */
170 #define Sp(n) W_[Sp + WDS(n)]
171 #define Hp(n) W_[Hp + WDS(n)]
173 #define Sp_adj(n) Sp = Sp + WDS(n)
174 #define Hp_adj(n) Hp = Hp + WDS(n)
176 /* -----------------------------------------------------------------------------
177 Assertions and Debuggery
178 -------------------------------------------------------------------------- */
181 #define ASSERT(predicate) \
185 foreign "C" _stgAssert(NULL, __LINE__); \
188 #define ASSERT(p) /* nothing */
192 #define DEBUG_ONLY(s) s
194 #define DEBUG_ONLY(s) /* nothing */
198 // The IF_DEBUG macro is useful for debug messages that depend on one
199 // of the RTS debug options. For example:
201 // IF_DEBUG(RtsFlags_DebugFlags_apply,
202 // foreign "C" fprintf(stderr, stg_ap_0_ret_str));
204 // Note the syntax is slightly different to the C version of this macro.
207 #define IF_DEBUG(c,s) if (RtsFlags_DebugFlags_##c(RtsFlags)) { s; }
209 #define IF_DEBUG(c,s) /* nothing */
212 /* -----------------------------------------------------------------------------
215 It isn't safe to "enter" every closure. Functions in particular
216 have no entry code as such; their entry point contains the code to
219 ToDo: range should end in N_CLOSURE_TYPES-1, not N_CLOSURE_TYPES,
220 but switch doesn't allow us to use exprs there yet.
221 -------------------------------------------------------------------------- */
225 switch [INVALID_OBJECT .. N_CLOSURE_TYPES] \
226 (TO_W_( %INFO_TYPE(%GET_STD_INFO(R1)) )) { \
234 R1 = StgInd_indirectee(R1); \
248 jump %ENTRY_CODE(Sp(0)); \
252 jump %GET_ENTRY(R1); \
256 /* -----------------------------------------------------------------------------
258 -------------------------------------------------------------------------- */
260 #include "Constants.h"
261 #include "DerivedConstants.h"
262 #include "ClosureTypes.h"
266 // Need MachRegs, because some of the RTS code is conditionally
267 // compiled based on REG_R1, REG_R2, etc.
269 #define STOLEN_X86_REGS 4
270 #include "MachRegs.h"
272 #include "Liveness.h"
273 #include "StgLdvProf.h"
277 #include "Block.h" // For Bdescr()
280 // Can't think of a better place to put this.
281 #if SIZEOF_mp_limb_t != SIZEOF_VOID_P
282 #error mp_limb_t != StgWord: assumptions in PrimOps.cmm are now false
285 /* -------------------------------------------------------------------------
286 Allocation and garbage collection
287 ------------------------------------------------------------------------- */
289 // ALLOC_PRIM is for allocating memory on the heap for a primitive
290 // object. It is used all over PrimOps.cmm.
292 // We make the simplifying assumption that the "admin" part of a
293 // primitive closure is just the header when calculating sizes for
294 // ticky-ticky. It's not clear whether eg. the size field of an array
295 // should be counted as "admin", or the various fields of a BCO.
297 #define ALLOC_PRIM(bytes,liveness,reentry) \
298 HP_CHK_GEN_TICKY(bytes,liveness,reentry); \
299 TICK_ALLOC_PRIM(SIZEOF_StgHeader,bytes-SIZEOF_StgHeader,0); \
302 // CCS_ALLOC wants the size in words, because ccs->mem_alloc is in words
303 #define CCCS_ALLOC(__alloc) CCS_ALLOC(BYTES_TO_WDS(__alloc), W_[CCCS])
305 #define HP_CHK_GEN_TICKY(alloc,liveness,reentry) \
306 HP_CHK_GEN(alloc,liveness,reentry); \
307 TICK_ALLOC_HEAP_NOCTR(alloc);
309 #define MAYBE_GC(liveness,reentry) \
310 if (CInt[alloc_blocks] >= CInt[alloc_blocks_lim]) { \
313 jump stg_gc_gen_hp; \
316 /* -----------------------------------------------------------------------------
318 -------------------------------------------------------------------------- */
320 // The offset of the payload of an array
321 #define BYTE_ARR_CTS(arr) ((arr) + SIZEOF_StgArrWords)
323 // Getting/setting the info pointer of a closure
324 #define SET_INFO(p,info) StgHeader_info(p) = info
325 #define GET_INFO(p) StgHeader_info(p)
327 // Determine the size of an ordinary closure from its info table
328 #define sizeW_fromITBL(itbl) \
329 SIZEOF_StgHeader + WDS(%INFO_PTRS(itbl)) + WDS(%INFO_NPTRS(itbl))
331 // NB. duplicated from InfoTables.h!
332 #define BITMAP_SIZE(bitmap) ((bitmap) & BITMAP_SIZE_MASK)
333 #define BITMAP_BITS(bitmap) ((bitmap) >> BITMAP_BITS_SHIFT)
336 #define LOOKS_LIKE_INFO_PTR(p) \
338 (TO_W_(%INFO_TYPE(%STD_INFO(p))) != INVALID_OBJECT) && \
339 (TO_W_(%INFO_TYPE(%STD_INFO(p))) < N_CLOSURE_TYPES))
341 #define LOOKS_LIKE_CLOSURE_PTR(p) (LOOKS_LIKE_INFO_PTR(GET_INFO(p)))
344 // The layout of the StgFunInfoExtra part of an info table changes
345 // depending on TABLES_NEXT_TO_CODE. So we define field access
346 // macros which use the appropriate version here:
348 #ifdef TABLES_NEXT_TO_CODE
349 // when TABLES_NEXT_TO_CODE, slow_apply is stored as an offset
350 // instead of the normal pointer.
352 #define StgFunInfoExtra_slow_apply(fun_info) \
353 (StgFunInfoExtraRev_slow_apply_offset(fun_info) \
354 + (fun_info) + SIZEOF_StgFunInfoExtraRev + SIZEOF_StgInfoTable)
356 #define StgFunInfoExtra_fun_type(i) StgFunInfoExtraRev_fun_type(i)
357 #define StgFunInfoExtra_arity(i) StgFunInfoExtraRev_arity(i)
358 #define StgFunInfoExtra_bitmap(i) StgFunInfoExtraRev_bitmap(i)
360 #define StgFunInfoExtra_slow_apply(i) StgFunInfoExtraFwd_slow_apply(i)
361 #define StgFunInfoExtra_fun_type(i) StgFunInfoExtraFwd_fun_type(i)
362 #define StgFunInfoExtra_arity(i) StgFunInfoExtraFwd_arity(i)
363 #define StgFunInfoExtra_bitmap(i) StgFunInfoExtraFwd_bitmap(i)
366 /* -----------------------------------------------------------------------------
367 Voluntary Yields/Blocks
369 We only have a generic version of this at the moment - if it turns
370 out to be slowing us down we can make specialised ones.
371 -------------------------------------------------------------------------- */
373 #define YIELD(liveness,reentry) \
378 #define BLOCK(liveness,reentry) \
383 /* -----------------------------------------------------------------------------
385 -------------------------------------------------------------------------- */
388 #define TICK_BUMP_BY(ctr,n) CLong[ctr] = CLong[ctr] + n
390 #define TICK_BUMP_BY(ctr,n) /* nothing */
393 #define TICK_BUMP(ctr) TICK_BUMP_BY(ctr,1)
395 #define TICK_ENT_DYN_IND() TICK_BUMP(ENT_DYN_IND_ctr)
396 #define TICK_ENT_DYN_THK() TICK_BUMP(ENT_DYN_THK_ctr)
397 #define TICK_ENT_VIA_NODE() TICK_BUMP(ENT_VIA_NODE_ctr)
398 #define TICK_ENT_STATIC_IND() TICK_BUMP(ENT_STATIC_IND_ctr)
399 #define TICK_ENT_PERM_IND() TICK_BUMP(ENT_PERM_IND_ctr)
400 #define TICK_ENT_PAP() TICK_BUMP(ENT_PAP_ctr)
401 #define TICK_ENT_AP() TICK_BUMP(ENT_AP_ctr)
402 #define TICK_ENT_AP_STACK() TICK_BUMP(ENT_AP_STACK_ctr)
403 #define TICK_ENT_BH() TICK_BUMP(ENT_BH_ctr)
404 #define TICK_UNKNOWN_CALL() TICK_BUMP(UNKNOWN_CALL_ctr)
405 #define TICK_UPDF_PUSHED() TICK_BUMP(UPDF_PUSHED_ctr)
406 #define TICK_CATCHF_PUSHED() TICK_BUMP(CATCHF_PUSHED_ctr)
407 #define TICK_UPDF_OMITTED() TICK_BUMP(UPDF_OMITTED_ctr)
408 #define TICK_UPD_NEW_IND() TICK_BUMP(UPD_NEW_IND_ctr)
409 #define TICK_UPD_NEW_PERM_IND() TICK_BUMP(UPD_NEW_PERM_IND_ctr)
410 #define TICK_UPD_OLD_IND() TICK_BUMP(UPD_OLD_IND_ctr)
411 #define TICK_UPD_OLD_PERM_IND() TICK_BUMP(UPD_OLD_PERM_IND_ctr)
413 #define TICK_SLOW_CALL_FUN_TOO_FEW() TICK_BUMP(SLOW_CALL_FUN_TOO_FEW_ctr)
414 #define TICK_SLOW_CALL_FUN_CORRECT() TICK_BUMP(SLOW_CALL_FUN_CORRECT_ctr)
415 #define TICK_SLOW_CALL_FUN_TOO_MANY() TICK_BUMP(SLOW_CALL_FUN_TOO_MANY_ctr)
416 #define TICK_SLOW_CALL_PAP_TOO_FEW() TICK_BUMP(SLOW_CALL_PAP_TOO_FEW_ctr)
417 #define TICK_SLOW_CALL_PAP_CORRECT() TICK_BUMP(SLOW_CALL_PAP_CORRECT_ctr)
418 #define TICK_SLOW_CALL_PAP_TOO_MANY() TICK_BUMP(SLOW_CALL_PAP_TOO_MANY_ctr)
420 #define TICK_SLOW_CALL_v() TICK_BUMP(SLOW_CALL_v_ctr)
421 #define TICK_SLOW_CALL_p() TICK_BUMP(SLOW_CALL_p_ctr)
422 #define TICK_SLOW_CALL_pv() TICK_BUMP(SLOW_CALL_pv_ctr)
423 #define TICK_SLOW_CALL_pp() TICK_BUMP(SLOW_CALL_pp_ctr)
424 #define TICK_SLOW_CALL_ppp() TICK_BUMP(SLOW_CALL_ppp_ctr)
425 #define TICK_SLOW_CALL_pppp() TICK_BUMP(SLOW_CALL_pppp_ctr)
426 #define TICK_SLOW_CALL_ppppp() TICK_BUMP(SLOW_CALL_ppppp_ctr)
427 #define TICK_SLOW_CALL_pppppp() TICK_BUMP(SLOW_CALL_pppppp_ctr)
430 #define TICK_HISTO_BY(histo,n,i) \
436 CLong[histo##_hst + _idx*SIZEOF_LONG] \
437 = histo##_hst + __idx*SIZEOF_LONG] + i;
439 #define TICK_HISTO_BY(histo,n,i) /* nothing */
442 #define TICK_HISTO(histo,n) TICK_HISTO_BY(histo,n,1)
444 // An unboxed tuple with n components.
445 #define TICK_RET_UNBOXED_TUP(n) \
446 TICK_BUMP(RET_UNBOXED_TUP_ctr++); \
447 TICK_HISTO(RET_UNBOXED_TUP,n)
449 // A slow call with n arguments. In the unevald case, this call has
450 // already been counted once, so don't count it again.
451 #define TICK_SLOW_CALL(n) \
452 TICK_BUMP(SLOW_CALL_ctr); \
453 TICK_HISTO(SLOW_CALL,n)
455 // This slow call was found to be to an unevaluated function; undo the
456 // ticks we did in TICK_SLOW_CALL.
457 #define TICK_SLOW_CALL_UNEVALD(n) \
458 TICK_BUMP(SLOW_CALL_UNEVALD_ctr); \
459 TICK_BUMP_BY(SLOW_CALL_ctr,-1); \
460 TICK_HISTO_BY(SLOW_CALL,n,-1);
462 // Updating a closure with a new CON
463 #define TICK_UPD_CON_IN_NEW(n) \
464 TICK_BUMP(UPD_CON_IN_NEW_ctr); \
465 TICK_HISTO(UPD_CON_IN_NEW,n)
467 #define TICK_ALLOC_HEAP_NOCTR(n) \
468 TICK_BUMP(ALLOC_HEAP_ctr); \
469 TICK_BUMP_BY(ALLOC_HEAP_tot,n)