Coverage Report

Created: 2025-10-28 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm3/source/m3_code.c
Line
Count
Source
1
//
2
//  m3_code.c
3
//
4
//  Created by Steven Massey on 4/19/19.
5
//  Copyright © 2019 Steven Massey. All rights reserved.
6
//
7
8
#include <limits.h>
9
#include "m3_code.h"
10
#include "m3_env.h"
11
12
//---------------------------------------------------------------------------------------------------------------------------------
13
14
15
IM3CodePage  NewCodePage  (IM3Runtime i_runtime, u32 i_minNumLines)
16
125
{
17
125
    IM3CodePage page;
18
19
    // check multiplication overflow
20
125
    if (i_minNumLines > UINT_MAX / sizeof (code_t)) {
21
1
        return NULL;
22
1
    }
23
124
    u32 pageSize = sizeof (M3CodePageHeader) + sizeof (code_t) * i_minNumLines;
24
25
    // check addition overflow
26
124
    if (pageSize < sizeof (M3CodePageHeader)) {
27
0
        return NULL;
28
0
    }
29
30
124
    pageSize = (pageSize + (d_m3CodePageAlignSize-1)) & ~(d_m3CodePageAlignSize-1); // align
31
    // check alignment overflow
32
124
    if (pageSize == 0) {
33
0
        return NULL;
34
0
    }
35
36
124
    page = (IM3CodePage)m3_Malloc ("M3CodePage", pageSize);
37
38
124
    if (page)
39
124
    {
40
124
        page->info.sequence = ++i_runtime->newCodePageSequence;
41
124
        page->info.numLines = (pageSize - sizeof (M3CodePageHeader)) / sizeof (code_t);
42
43
#if d_m3RecordBacktraces
44
        u32 pageSizeBt = sizeof (M3CodeMappingPage) + sizeof (M3CodeMapEntry) * page->info.numLines;
45
        page->info.mapping = (M3CodeMappingPage *)m3_Malloc ("M3CodeMappingPage", pageSizeBt);
46
47
        if (page->info.mapping)
48
        {
49
            page->info.mapping->size = 0;
50
            page->info.mapping->capacity = page->info.numLines;
51
        }
52
        else
53
        {
54
            m3_Free (page);
55
            return NULL;
56
        }
57
        page->info.mapping->basePC = GetPageStartPC(page);
58
#endif // d_m3RecordBacktraces
59
60
124
        m3log (runtime, "new page: %p; seq: %d; bytes: %d; lines: %d", GetPagePC (page), page->info.sequence, pageSize, page->info.numLines);
61
124
    }
62
63
124
    return page;
64
124
}
65
66
67
void  FreeCodePages  (IM3CodePage * io_list)
68
183
{
69
183
    IM3CodePage page = * io_list;
70
71
298
    while (page)
72
115
    {
73
115
        m3log (code, "free page: %d; %p; util: %3.1f%%", page->info.sequence, page, 100. * page->info.lineIndex / page->info.numLines);
74
75
115
        IM3CodePage next = page->info.next;
76
#if d_m3RecordBacktraces
77
        m3_Free (page->info.mapping);
78
#endif // d_m3RecordBacktraces
79
115
        m3_Free (page);
80
115
        page = next;
81
115
    }
82
83
183
    * io_list = NULL;
84
183
}
85
86
87
u32  NumFreeLines  (IM3CodePage i_page)
88
50.8k
{
89
50.8k
    d_m3Assert (i_page->info.lineIndex <= i_page->info.numLines);
90
91
50.8k
    return i_page->info.numLines - i_page->info.lineIndex;
92
50.8k
}
93
94
95
void  EmitWord_impl  (IM3CodePage i_page, void * i_word)
96
51.2k
{                                                                       d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
97
51.2k
    i_page->code [i_page->info.lineIndex++] = i_word;
98
51.2k
}
99
100
void  EmitWord32  (IM3CodePage i_page, const u32 i_word)
101
92.1k
{                                                                       d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
102
92.1k
    memcpy (& i_page->code[i_page->info.lineIndex++], & i_word, sizeof(i_word));
103
92.1k
}
104
105
void  EmitWord64  (IM3CodePage i_page, const u64 i_word)
106
3.47k
{
107
#if M3_SIZEOF_PTR == 4
108
                                                                        d_m3Assert (i_page->info.lineIndex+2 <= i_page->info.numLines);
109
    memcpy (& i_page->code[i_page->info.lineIndex], & i_word, sizeof(i_word));
110
    i_page->info.lineIndex += 2;
111
#else
112
3.47k
                                                                        d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
113
3.47k
    memcpy (& i_page->code[i_page->info.lineIndex], & i_word, sizeof(i_word));
114
3.47k
    i_page->info.lineIndex += 1;
115
3.47k
#endif
116
3.47k
}
117
118
119
#if d_m3RecordBacktraces
120
void  EmitMappingEntry  (IM3CodePage i_page, u32 i_moduleOffset)
121
{
122
    M3CodeMappingPage * page = i_page->info.mapping;
123
                                                                        d_m3Assert (page->size < page->capacity);
124
125
    M3CodeMapEntry * entry = & page->entries[page->size++];
126
    pc_t pc = GetPagePC (i_page);
127
128
    entry->pcOffset = pc - page->basePC;
129
    entry->moduleOffset = i_moduleOffset;
130
}
131
#endif // d_m3RecordBacktraces
132
133
pc_t  GetPageStartPC  (IM3CodePage i_page)
134
0
{
135
0
    return & i_page->code [0];
136
0
}
137
138
139
pc_t  GetPagePC  (IM3CodePage i_page)
140
3.49k
{
141
3.49k
    if (i_page)
142
2.88k
        return & i_page->code [i_page->info.lineIndex];
143
612
    else
144
612
        return NULL;
145
3.49k
}
146
147
148
void  PushCodePage  (IM3CodePage * i_list, IM3CodePage i_codePage)
149
604
{
150
604
    IM3CodePage next = * i_list;
151
604
    i_codePage->info.next = next;
152
604
    * i_list = i_codePage;
153
604
}
154
155
156
IM3CodePage  PopCodePage  (IM3CodePage * i_list)
157
0
{
158
0
    IM3CodePage page = * i_list;
159
0
    * i_list = page->info.next;
160
0
    page->info.next = NULL;
161
162
0
    return page;
163
0
}
164
165
166
167
u32  FindCodePageEnd  (IM3CodePage i_list, IM3CodePage * o_end)
168
0
{
169
0
    u32 numPages = 0;
170
0
    * o_end = NULL;
171
172
0
    while (i_list)
173
0
    {
174
0
        * o_end = i_list;
175
0
        ++numPages;
176
0
        i_list = i_list->info.next;
177
0
    }
178
179
0
    return numPages;
180
0
}
181
182
183
u32  CountCodePages  (IM3CodePage i_list)
184
0
{
185
0
    IM3CodePage unused;
186
0
    return FindCodePageEnd (i_list, & unused);
187
0
}
188
189
190
IM3CodePage GetEndCodePage  (IM3CodePage i_list)
191
0
{
192
0
    IM3CodePage end;
193
0
    FindCodePageEnd (i_list, & end);
194
195
0
    return end;
196
0
}
197
198
#if d_m3RecordBacktraces
199
bool  ContainsPC  (IM3CodePage i_page, pc_t i_pc)
200
{
201
    return GetPageStartPC (i_page) <= i_pc && i_pc < GetPagePC (i_page);
202
}
203
204
205
bool  MapPCToOffset  (IM3CodePage i_page, pc_t i_pc, u32 * o_moduleOffset)
206
{
207
    M3CodeMappingPage * mapping = i_page->info.mapping;
208
209
    u32 pcOffset = i_pc - mapping->basePC;
210
211
    u32 left = 0;
212
    u32 right = mapping->size;
213
214
    while (left < right)
215
    {
216
        u32 mid = left + (right - left) / 2;
217
218
        if (mapping->entries[mid].pcOffset < pcOffset)
219
        {
220
            left = mid + 1;
221
        }
222
        else if (mapping->entries[mid].pcOffset > pcOffset)
223
        {
224
            right = mid;
225
        }
226
        else
227
        {
228
            *o_moduleOffset = mapping->entries[mid].moduleOffset;
229
            return true;
230
        }
231
    }
232
233
    // Getting here means left is now one more than the element we want.
234
    if (left > 0)
235
    {
236
        left--;
237
        *o_moduleOffset = mapping->entries[left].moduleOffset;
238
        return true;
239
    }
240
    else return false;
241
}
242
#endif // d_m3RecordBacktraces
243
244
//---------------------------------------------------------------------------------------------------------------------------------
245
246