Skip to content

Commit 7d6394b

Browse files
committed
amazing size optimizations by tleydxdy
2 parents 18476db + 22e1871 commit 7d6394b

File tree

4 files changed

+276
-21
lines changed

4 files changed

+276
-21
lines changed

asm.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
nasm -f bin -o httpd httpd.asm

httpd.asm

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
; elf header see http://muppetlabs.com/~breadbox/software/tiny/teensy.html
2+
3+
BITS 64
4+
5+
org 0x08048000
6+
7+
ehdr: ; Elf32_Ehdr
8+
db 0x7F, "ELF", 2, 1, 1, 0 ; e_ident
9+
?_033:
10+
db "usage: ", 0
11+
dw 2 ; e_type
12+
dw 62 ; e_machine
13+
dd 1 ; e_version
14+
dq _start ; e_entry
15+
dq phdr - $$ ; e_phoff
16+
?_034:
17+
db " port fi" ; e_shoff
18+
db "le", 10, 0 ; e_flags
19+
dw ehdrsize ; e_ehsize
20+
dw phdrsize ; e_phentsize
21+
phdr: ; Elf32_Phdr
22+
dd 1 ; e_phnum ; p_type
23+
; e_shentsize
24+
dd 5 ; e_shnum ; p_flags
25+
; e_shstrndx
26+
27+
ehdrsize equ $ - ehdr
28+
29+
dq 0 ; p_offset
30+
dq $$ ; p_vaddr
31+
dq $$ ; p_paddr
32+
dq filesize ; p_filesz
33+
dq filesize ; p_memsz
34+
dq 0x1000 ; p_align
35+
36+
phdrsize equ $ - phdr
37+
38+
_start:
39+
xor rbp, rbp
40+
xor r9, r9
41+
pop rdi
42+
mov rsi, rsp
43+
push r14
44+
push r13
45+
push r12
46+
push rbp
47+
push rbx
48+
mov rbx, rsi
49+
sub rsp, 8224
50+
cmp edi, 3
51+
jnz ?_004
52+
mov rcx, qword [rsi+8H]
53+
xor eax, eax
54+
?_002: movsx dx, byte [rcx]
55+
test dl, dl
56+
jz ?_003
57+
lea esi, [rdx-30H]
58+
cmp sil, 9
59+
ja ?_004
60+
imul eax, eax, 10
61+
inc rcx
62+
lea eax, [rax+rdx-30H]
63+
jmp ?_002
64+
65+
?_003: xchg al, ah
66+
test ax, ax
67+
jnz ?_007
68+
?_004: mov rbp, qword [rbx]
69+
mov edx, 7
70+
mov edi, 1
71+
lea rsi, [rel ?_033]
72+
call ?_027
73+
mov rdx, rbp
74+
?_005: cmp byte [rdx], 0
75+
jz ?_006
76+
inc rdx
77+
jmp ?_005
78+
79+
?_006: sub rdx, rbp
80+
mov rsi, rbp
81+
mov edi, 1
82+
call ?_027
83+
mov edx, 11
84+
mov edi, 1
85+
lea rsi, [rel ?_034]
86+
call ?_027
87+
mov edi, 1
88+
call ?_017
89+
xor eax, eax
90+
?_007: xorps xmm0, xmm0
91+
lea rsi, [rsp+0CH]
92+
lea rdi, [rsp+10H]
93+
mov edx, 4
94+
movups oword [rsp+10H], xmm0
95+
mov dword [rsp+0CH], 1
96+
mov word [rsp+10H], 2
97+
mov word [rsp+12H], ax
98+
call ?_029
99+
mov r13d, eax
100+
?_008: xor edx, edx
101+
xor esi, esi
102+
mov edi, r13d
103+
call ?_023
104+
mov ebp, eax
105+
test eax, eax
106+
js ?_008
107+
xor eax, eax
108+
call ?_018
109+
mov r12d, eax
110+
test eax, eax
111+
jnz ?_008
112+
mov r14, qword [rbx+10H]
113+
lea r13, [rsp+20H]
114+
?_009: mov edx, 8192
115+
mov rsi, r13
116+
mov edi, ebp
117+
call ?_028
118+
mov ebx, eax
119+
test eax, eax
120+
jle ?_010
121+
mov edx, ebx
122+
mov rsi, r13
123+
mov edi, 1
124+
call ?_027
125+
movsxd rax, ebx
126+
lea rax, [r13+rax-3H]
127+
cmp ebx, 2
128+
jg ?_011
129+
?_010: xor esi, esi
130+
mov rdi, r14
131+
call ?_026
132+
mov ebx, eax
133+
test eax, eax
134+
jns ?_012
135+
mov edx, 39
136+
lea rsi, [rel ?_035]
137+
mov edi, ebp
138+
call ?_027
139+
jmp ?_015
140+
141+
?_011: cmp byte [rax], 10
142+
jnz ?_009
143+
cmp byte [rax+1H], 13
144+
jnz ?_009
145+
cmp byte [rax+2H], 10
146+
jnz ?_009
147+
jmp ?_010
148+
149+
?_012: mov edx, 19
150+
lea rsi, [rel ?_036]
151+
mov edi, ebp
152+
call ?_027
153+
?_013: mov edx, 8192
154+
mov rsi, r13
155+
mov edi, ebx
156+
call ?_028
157+
mov edx, eax
158+
test eax, eax
159+
jle ?_014
160+
mov rsi, r13
161+
mov edi, ebp
162+
call ?_027
163+
test eax, eax
164+
jns ?_013
165+
jmp ?_015
166+
167+
?_014: mov edi, ebp
168+
mov esi, 2
169+
call ?_022
170+
mov edi, ebp
171+
call ?_025
172+
jmp ?_016
173+
174+
?_015: mov r12d, 1
175+
?_016: add rsp, 8224
176+
mov eax, r12d
177+
pop rbx
178+
pop rbp
179+
pop r12
180+
pop r13
181+
pop r14
182+
call ?_017
183+
184+
?_017:
185+
add r9, 3
186+
?_018: add r9, 3
187+
?_019: add r9, 4
188+
?_020: add r9, 1
189+
?_021: add r9, 1
190+
?_022: add r9, 5
191+
?_023: add r9, 2
192+
?_024: add r9, 38
193+
?_025: add r9, 1
194+
?_026: add r9, 1
195+
?_027: add r9, 1
196+
?_028: mov r10, rcx
197+
mov rax, r9
198+
xor r9, r9
199+
syscall
200+
ret
201+
202+
203+
?_029:
204+
push r13
205+
mov r13, rsi
206+
mov esi, 1
207+
push r12
208+
push rbp
209+
mov rbp, rdi
210+
mov edi, 2
211+
sub rsp, 16
212+
mov dword [rsp+0CH], edx
213+
mov edx, 6
214+
call ?_024
215+
mov r8d, dword [rsp+0CH]
216+
test eax, eax
217+
mov r12d, eax
218+
jns ?_031
219+
?_030: mov edi, 1
220+
call ?_017
221+
jmp ?_032
222+
223+
?_031: mov rcx, r13
224+
mov edx, 2
225+
mov esi, 1
226+
mov edi, eax
227+
call ?_019
228+
test eax, eax
229+
jnz ?_030
230+
mov edx, 16
231+
mov rsi, rbp
232+
mov edi, r12d
233+
call ?_021
234+
test eax, eax
235+
jnz ?_030
236+
mov esi, 10
237+
mov edi, r12d
238+
call ?_020
239+
test eax, eax
240+
jnz ?_030
241+
?_032: add rsp, 16
242+
mov eax, r12d
243+
pop rbp
244+
pop r12
245+
pop r13
246+
ret
247+
248+
?_035:
249+
db "HTTP/1.1 404 Not Found"
250+
db 0DH, 0AH, 0DH, 0AH
251+
db "404 Not Found", 0
252+
253+
?_036:
254+
db "HTTP/1.1 200 OK"
255+
db 0DH, 0AH, 0DH, 0AH, 0
256+
257+
filesize equ $ - $$

httpd.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ int setsockopt(int socket, int level, int option_name, const void *option_value,
3535
int fork();
3636
void exit(int status);
3737

38-
/* this is fine because forked processes are copy on write */
39-
/* so there shouldn't be any data races */
40-
static char http_buf[8192];
41-
4238
static size_t strlen(const char *s) {
4339
const char *p = s;
4440
while (*p)
@@ -78,22 +74,20 @@ static uint16_t swap_uint16(uint16_t x) {
7874
#define perror(s)
7975
#endif
8076

81-
static int tcp_listen(int port) {
82-
static int yes = 1;
83-
static sockaddr_in_t addr = {AF_INET};
84-
addr.sin_port = swap_uint16(port);
77+
int tcp_listen(const sockaddr_in_t *addr, const void *option_value,
78+
socklen_t option_len) {
8579
int sock;
8680
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 ||
87-
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) ||
88-
bind(sock, &addr, sizeof(addr)) || listen(sock, 10)) {
81+
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, option_value, option_len) ||
82+
bind(sock, addr, sizeof(sockaddr_in_t)) || listen(sock, 10)) {
8983
die("listen");
9084
}
9185
return sock;
9286
}
9387

94-
static void http_consume(int clientfd) {
88+
static void http_consume(int clientfd, char *http_buf, size_t buf_len) {
9589
int n;
96-
while ((n = read(clientfd, http_buf, sizeof(http_buf))) > 0) {
90+
while ((n = read(clientfd, http_buf, buf_len)) > 0) {
9791
printn(http_buf, n);
9892
const char *p = http_buf + (n - 3);
9993
if (n < 3 || (*p == '\n' && *(p + 1) == '\r' && *(p + 2) == '\n')) {
@@ -125,16 +119,17 @@ static void http_drop(int clientfd) {
125119

126120
#define http_code(fd, x) fprintl(fd, "HTTP/1.1 " x "\r\n\r\n" x);
127121

128-
static int http_serve(int clientfd, const char *file_path) {
122+
static int http_serve(int clientfd, const char *file_path, char *http_buf,
123+
size_t buf_len) {
129124
int f, n;
130-
http_consume(clientfd);
125+
http_consume(clientfd, http_buf, buf_len);
131126
if ((f = open(file_path, O_RDONLY)) < 0) {
132127
perror("open");
133128
http_code(clientfd, "404 Not Found");
134129
return 1;
135130
}
136131
fprintl(clientfd, "HTTP/1.1 200 OK\r\n\r\n");
137-
while ((n = read(f, http_buf, sizeof(http_buf))) > 0) {
132+
while ((n = read(f, http_buf, buf_len)) > 0) {
138133
if (write(clientfd, http_buf, n) < 0) {
139134
perror("write");
140135
return 1;
@@ -155,7 +150,7 @@ static uint16_t string2port(const char *s) {
155150
}
156151
res = res * 10 + *s - '0';
157152
}
158-
return res;
153+
return swap_uint16(res);
159154
}
160155

161156
static void usage(const char *self) {
@@ -168,18 +163,21 @@ static void usage(const char *self) {
168163
int main(int argc, char *argv[]) {
169164
int sock;
170165
uint16_t port;
166+
char http_buf[8192];
171167
if (argc != 3 || (port = string2port(argv[1])) == 0) {
172168
usage(argv[0]);
173169
}
174-
sock = tcp_listen(port);
170+
const int yes = 1;
171+
const sockaddr_in_t addr = {AF_INET, port, 0};
172+
sock = tcp_listen(&addr, &yes, sizeof(yes));
175173
while (1) {
176174
int pid, clientfd;
177175
if ((clientfd = accept(sock, 0, 0)) < 0) {
178176
perror("accept");
179177
} else if ((pid = fork()) < 0) {
180178
perror("fork");
181179
} else if (pid == 0) {
182-
return http_serve(clientfd, argv[2]);
180+
return http_serve(clientfd, argv[2], http_buf, sizeof(http_buf));
183181
}
184182
}
185183
return 0;

start.S

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ c(open, 1) /* 02 */
2323
c(write, 1) /* 01 */
2424
.global read /* 00 */
2525
read:
26-
27-
.global _syscall
28-
_syscall:
2926
mov r10,rcx
3027
mov rax,r9
3128
xor r9,r9

0 commit comments

Comments
 (0)