#include "Rts.h" #include "RtsAPI.h" #include "rts/Messages.h" #include void expectStacksToBeEqual(StgStack *clonedStack, StgTSO *tso) { StgStack *liveStack = tso->stackobj; if(liveStack->header.info != clonedStack->header.info){ barf("info table pointer not equal! Expected same pointer address, but got %p and %p", liveStack->header.info, clonedStack->header.info); } StgInfoTable *info = INFO_PTR_TO_STRUCT(liveStack->header.info); if (info->type != STACK) { barf("Expected a closure of type STACK!"); } if(liveStack->stack_size != clonedStack->stack_size){ barf("Expected same stack_size!"); } if(liveStack->marking != clonedStack->marking){ barf("Expected same marking flags!"); } for(StgWord i = liveStack->stack_size - 1; (liveStack->stack + i) >= liveStack->sp; i--){ if(liveStack->stack[i] != clonedStack->stack[i]){ barf("Expected stack word %lu to be equal on both stacks.", i); } } } void expectStackToBeNotDirty(StgStack *stack) { if(stack->dirty != 0) { barf("Expected stack to be not dirty. But dirty flag was set to %u", stack->dirty); } } void expectClosureTypes(StgStack *stack, unsigned int types[], size_t typesSize){ StgPtr sp = stack->sp; StgPtr spBottom = stack->stack + stack->stack_size; for (StgWord i = 0; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp), i++) { const StgInfoTable *info = get_itbl((StgClosure *)sp); if(i >= typesSize) { barf("Stack size exceeds expectation!"); } if(info->type != types[i]) { barf("Wrong closure type on stack! Expected %u but got %u in position %lu", types[i], info->type, i); } } } // Count all (#I 1) closures of the RET_BIG closure's payload. static int countOnes(StgPtr spBottom, StgPtr payload, StgLargeBitmap *large_bitmap, uint32_t size) { StgWord bmp; uint32_t i, j; int ones = 0; i = 0; for (bmp = 0; i < size; bmp++) { StgWord bitmap = large_bitmap->bitmap[bmp]; j = 0; for (; i < size && j < BITS_IN(W_); j++, i++, bitmap >>= 1) { if ((bitmap & 1) == 0) { const StgClosure *closure = UNTAG_CLOSURE((StgClosure *)payload[i]); const StgInfoTable *info = get_itbl(closure); switch (info->type) { case CONSTR_0_1: { const StgConInfoTable *con_info = get_con_itbl(closure); if (strcmp(GET_CON_DESC(con_info), "ghc-prim:GHC.Types.I#") == 0 && closure->payload[0] == (StgClosure*) 1) { ones++; } break; } default: { break; } } } } } return ones; } void expectSixtyFourOnesInRetBigFrame(StgStack *stack) { StgPtr sp = stack->sp; StgPtr spBottom = stack->stack + stack->stack_size; for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) { const StgInfoTable *info = get_itbl((StgClosure *)sp); if (info->type == RET_BIG) { StgLargeBitmap *bitmap = GET_LARGE_BITMAP(info); int ones = countOnes(spBottom, (StgPtr)((StgClosure *)sp)->payload, bitmap, bitmap->size); if (ones != 64) { barf("Expected 64 ones, got %i!", ones); } } } }