Skip to content

Commit 8fd63c2

Browse files
committed
Recover some of the performance lost after moving into state obj
9d8aa11 regressed performance noticeably. The biggest problem was way too much accidental memset'ing of the heap, but the meat of the change that moved state from file local statics into a single global object also seems to hurt. I briefly investigated whether simply /GL+/LTCG would recover the difference, but it does not. Before combining: /Ox: 2.8s /Ox /GL: 2.35s After combining: /Ox: 3.2s /Ox /GL: 2.75s That is, /GL can make up for what was lost, but it also makes the non-combined version faster too. This change fixes the memset bug, but the next step is to revert this one and its predecessor (the state combining change), and work on getting a better (longer running) benchmark. Then we can go back to figuring out the embedding/error reporting situation with that available.
1 parent 9d8aa11 commit 8fd63c2

File tree

2 files changed

+37
-42
lines changed

2 files changed

+37
-42
lines changed

alloc.c

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ void __asan_unpoison_memory_region(void const volatile* addr, size_t size);
2828
CompilerState compiler_state;
2929
LinkerState linker_state;
3030

31+
#define C(x) compiler_state.alloc__##x
32+
#define L(x) linker_state.alloc__##x
33+
3134
// Reports an error and exit.
3235
void error(char* fmt, ...) {
3336
va_list ap;
@@ -37,50 +40,32 @@ void error(char* fmt, ...) {
3740
exit(1);
3841
}
3942

40-
#define ALLOC_INIT(state) \
41-
do { \
42-
ASAN_UNPOISON_MEMORY_REGION(state.alloc__heap, sizeof(state.alloc__heap)); \
43-
memset(&state, 0, sizeof(state)); \
44-
state.alloc__current_alloc_pointer = state.alloc__heap; \
45-
ASAN_POISON_MEMORY_REGION(state.alloc__heap, sizeof(state.alloc__heap)); \
46-
} while (0)
47-
48-
// This 0xdd fill could be debug-only.
49-
#define ALLOC_RESET(state) \
50-
do { \
51-
ASAN_UNPOISON_MEMORY_REGION(state.alloc__heap, sizeof(state.alloc__heap)); \
52-
memset(&state, 0xdd, sizeof(state)); \
53-
state.alloc__current_alloc_pointer = NULL; \
54-
ASAN_POISON_MEMORY_REGION(state.alloc__heap, sizeof(state.alloc__heap)); \
55-
} while (0)
56-
57-
#define ALLOC_BUMP(ret, state) \
58-
do { \
59-
ret = state.alloc__current_alloc_pointer; \
60-
state.alloc__current_alloc_pointer += toalloc; \
61-
if (state.alloc__current_alloc_pointer > state.alloc__heap + sizeof(state.alloc__heap)) { \
62-
error("heap exhausted"); \
63-
} \
64-
} while (0)
65-
6643
void alloc_init(AllocLifetime lifetime) {
6744
assert(lifetime < NUM_BUMP_HEAPS);
68-
if (lifetime == AL_Compile)
69-
ALLOC_INIT(compiler_state);
70-
else if (lifetime == AL_Link)
71-
ALLOC_INIT(linker_state);
72-
else
45+
if (lifetime == AL_Compile) {
46+
memset(&compiler_state, 0, offsetof(CompilerState, alloc__heap));
47+
C(current_alloc_pointer) = C(heap);
48+
ASAN_POISON_MEMORY_REGION(C(heap), sizeof(C(heap)));
49+
} else if (lifetime == AL_Link) {
50+
memset(&linker_state, 0, offsetof(LinkerState, alloc__heap));
51+
L(current_alloc_pointer) = L(heap);
52+
ASAN_POISON_MEMORY_REGION(L(heap), sizeof(L(heap)));
53+
} else {
7354
unreachable();
55+
}
7456
}
7557

7658
void alloc_reset(AllocLifetime lifetime) {
7759
assert(lifetime < NUM_BUMP_HEAPS);
78-
if (lifetime == AL_Compile)
79-
ALLOC_RESET(compiler_state);
80-
else if (lifetime == AL_Link)
81-
ALLOC_RESET(linker_state);
82-
else
60+
if (lifetime == AL_Compile) {
61+
C(current_alloc_pointer) = NULL;
62+
ASAN_POISON_MEMORY_REGION(C(heap), sizeof(C(heap)));
63+
} else if (lifetime == AL_Link) {
64+
L(current_alloc_pointer) = NULL;
65+
ASAN_POISON_MEMORY_REGION(L(heap), sizeof(L(heap)));
66+
} else {
8367
unreachable();
68+
}
8469
}
8570

8671
void* bumpcalloc(size_t num, size_t size, AllocLifetime lifetime) {
@@ -91,14 +76,24 @@ void* bumpcalloc(size_t num, size_t size, AllocLifetime lifetime) {
9176
assert(lifetime < NUM_BUMP_HEAPS);
9277
size_t toalloc = align_to_u(num * size, 8);
9378
char* ret;
94-
if (lifetime == AL_Compile)
95-
ALLOC_BUMP(ret, compiler_state);
96-
else if (lifetime == AL_Link)
97-
ALLOC_BUMP(ret, linker_state);
98-
else
79+
if (lifetime == AL_Compile) {
80+
ret = C(current_alloc_pointer);
81+
C(current_alloc_pointer) += toalloc;
82+
if (C(current_alloc_pointer) > C(heap) + sizeof(C(heap))) {
83+
error("heap exhausted");
84+
}
85+
} else if (lifetime == AL_Link) {
86+
ret = L(current_alloc_pointer);
87+
L(current_alloc_pointer) += toalloc;
88+
if (L(current_alloc_pointer) > L(heap) + sizeof(L(heap))) {
89+
error("heap exhausted");
90+
}
91+
} else {
9992
unreachable();
93+
}
10094

10195
ASAN_UNPOISON_MEMORY_REGION(ret, toalloc);
96+
memset(ret, 0, toalloc);
10297

10398
return ret;
10499
}

makefile.win

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
SRCS=$(SRCS) codegen.win32.c
44

55
CC=@cl
6-
CFLAGS=/nologo /Od /Zi /D_CRT_SECURE_NO_DEPRECATE /DX64WIN=1 /W4 /WX
6+
CFLAGS=/nologo /Ox /Zi /D_CRT_SECURE_NO_DEPRECATE /DX64WIN=1 /W4 /WX
77
#CC=@"C:\Program Files\LLVM\bin\clang-cl.exe"
88
#CFLAGS=/nologo /O1 /fsanitize=address /Zi /D_CRT_SECURE_NO_DEPRECATE /DX64WIN=1 /W4 /WX -Wno-missing-field-initializers -Wno-switch
99

0 commit comments

Comments
 (0)