1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include "Rts.h"
#include "RtsAPI.h"
#include "rts/Messages.h"
#include <string.h>
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);
}
}
}
}
|