History

Fix performance issue regarding all built-in types type descriptors. Check in md5sum program written entirely in limbo.

arr committed 10 years ago

Commit 754ca821 parent 096b0c72 files · +267 −14Browse files

Unified · Split

2 files
  1. limbo/md5sum.b +197 −0
  2. src/vm/vm_memory.cpp +70 −14
limbo/md5sum.b+197−0
@@ -0,0 +1,197 @@
1implement Exec;
2
3include "sys.m";
4include "Exec.m";
5
6sys : Sys;
7
8block_size : con 64;
9max_32 : con int 16rffffffff;
10
11shift_map := array [] of {
12 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
13 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
14 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
15 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
16
17sine_table := array [] of {
18 int 16rd76aa478, int 16re8c7b756, int 16r242070db, int 16rc1bdceee,
19 int 16rf57c0faf, int 16r4787c62a, int 16ra8304613, int 16rfd469501,
20 int 16r698098d8, int 16r8b44f7af, int 16rffff5bb1, int 16r895cd7be,
21 int 16r6b901122, int 16rfd987193, int 16ra679438e, int 16r49b40821,
22 int 16rf61e2562, int 16rc040b340, int 16r265e5a51, int 16re9b6c7aa,
23 int 16rd62f105d, int 16r02441453, int 16rd8a1e681, int 16re7d3fbc8,
24 int 16r21e1cde6, int 16rc33707d6, int 16rf4d50d87, int 16r455a14ed,
25 int 16ra9e3e905, int 16rfcefa3f8, int 16r676f02d9, int 16r8d2a4c8a,
26 int 16rfffa3942, int 16r8771f681, int 16r6d9d6122, int 16rfde5380c,
27 int 16ra4beea44, int 16r4bdecfa9, int 16rf6bb4b60, int 16rbebfbc70,
28 int 16r289b7ec6, int 16reaa127fa, int 16rd4ef3085, int 16r04881d05,
29 int 16rd9d4d039, int 16re6db99e5, int 16r1fa27cf8, int 16rc4ac5665,
30 int 16rf4292244, int 16r432aff97, int 16rab9423a7, int 16rfc93a039,
31 int 16r655b59c3, int 16r8f0ccc92, int 16rffeff47d, int 16r85845dd1,
32 int 16r6fa87e4f, int 16rfe2ce6e0, int 16ra3014314, int 16r4e0811a1,
33 int 16rf7537e82, int 16rbd3af235, int 16r2ad7d2bb, int 16reb86d391};
34
35leftrotate(x, c : int) : int
36{
37 # Limbo doesn't have an unsigned int so all right
38 # shifts are arithmetic, not logical.
39 addMask := 0;
40 x1 := x;
41 if (x1 < 0)
42 {
43 x1 = x1 & 16r7fffffff;
44 addMask = 2 ** (c - 1);
45 }
46
47 return (x << c) | (x1 >> (32 - c)) | addMask;
48}
49
50md5_acc(block: array of byte, result: array of int)
51{
52 a := result[0];
53 b := result[1];
54 c := result[2];
55 d := result[3];
56
57 for (i := 0; i < block_size; i++)
58 {
59 f : int;
60 g : int;
61 case i
62 {
63 0 to 15 =>
64 f = (b & c) | ((max_32 ^ b) & d);
65 g = i;
66 16 to 31 =>
67 f = (b & d) | (c & (max_32 ^ d));
68 g = ((5 * i) + 1) % 16;
69 32 to 47 =>
70 f = b ^ (c ^ d);
71 g = ((3 * i) + 5) % 16;
72 48 to 63 =>
73 f = c ^ (b | (max_32 ^ d));
74 g = (7 * i) % 16;
75 }
76
77 tmp := d;
78 d = c;
79 c = b;
80 m := block[(g * 4):];
81 v := int m[0] | (int m[1] << 8) | (int m[2] << 16) | (int m[3] << 24);
82 b = b + leftrotate((a + f + sine_table[i] + v), shift_map[i]);
83 a = tmp;
84 }
85
86 result[0] += a;
87 result[1] += b;
88 result[2] += c;
89 result[3] += d;
90}
91
92pad_block(block: array of byte, curr_block_size: int, msg_size_bytes: big): array of byte
93{
94 if (curr_block_size > len(block) || len(block) != block_size) {
95 raise "Invalid block or pad size";
96 }
97
98 # Zero out the excess block space
99 for (i := curr_block_size; i < len(block); i++) {
100 block[i] = byte 0;
101 }
102
103 aux_block : array of byte;
104 pad_count := block_size - curr_block_size;
105
106 # Check if there is room for the last bit and message size
107 if (pad_count < 9) {
108 aux_block = array [block_size] of byte;
109 }
110
111 # Set the last bit
112 if (pad_count < 1) {
113 aux_block[0] = byte 16r80;
114 } else {
115 block[curr_block_size] = byte 16r80;
116 pad_count--;
117 curr_block_size++;
118 }
119
120 # Set the message size in bits
121 msg_size_bits_target : array of byte;
122 msg_size_bits := (msg_size_bytes * big 8);
123 if (pad_count < 8) {
124 msg_size_bits_target = aux_block[56:];
125 } else {
126 msg_size_bits_target = block[56:];
127 }
128
129 mask : con byte 16rff;
130 msg_size_bits_target[0] = byte msg_size_bits & mask;
131 msg_size_bits_target[1] = byte (msg_size_bits >> 8) & mask;
132 msg_size_bits_target[2] = byte (msg_size_bits >> 16) & mask;
133 msg_size_bits_target[3] = byte (msg_size_bits >> 24) & mask;
134 msg_size_bits_target[4] = byte (msg_size_bits >> 32) & mask;
135 msg_size_bits_target[5] = byte (msg_size_bits >> 40) & mask;
136 msg_size_bits_target[6] = byte (msg_size_bits >> 48) & mask;
137 msg_size_bits_target[7] = byte (msg_size_bits >> 56) & mask;
138
139 return aux_block;
140}
141
142print_block(name: string, block: array of byte)
143{
144 sys->print("%s\n", name);
145
146 for (i := 0; i < len(block); i++)
147 {
148 if (i != 0 && i % 16 == 0)
149 sys->print("\n");
150
151 sys->print("%d ", int block[i]);
152 }
153 sys->print("\n");
154}
155
156init(args: list of string)
157{
158 sys = load Sys Sys->PATH;
159 if (len(args) == 1) {
160 sys->print("Usage: md5sum <file>");
161 return;
162 }
163
164 fd := sys->open(hd tl args, sys->OREAD);
165 if (fd == nil) {
166 raise "Failed to open file";
167 }
168
169 checksum := array [] of {
170 int 16r67452301,
171 int 16refcdab89,
172 int 16r98badcfe,
173 int 16r10325476 };
174
175 msg_size_bytes := big 0;
176 block := array [block_size] of byte;
177 c := sys->read(fd, block, block_size);
178 while (c == block_size) {
179 msg_size_bytes += big c;
180 md5_acc(block, checksum);
181 c = sys->read(fd, block, block_size);
182 }
183
184 msg_size_bytes += big c;
185
186 # Pad the last block
187 aux_block := pad_block(block, c, msg_size_bytes);
188 md5_acc(block, checksum);
189 if (aux_block != nil) {
190 md5_acc(aux_block, checksum);
191 }
192
193 for (i := 0; i < len (checksum); ++i) {
194 v := checksum[i];
195 sys->print("%02x%02x%02x%02x", v & 16rff, (v >> 8) & 16rff, (v >> 16) & 16rff, (v >> 24) & 16rff);
196 }
197}
src/vm/vm_memory.cpp+70−14
@@ -355,46 +355,102 @@ namespace · 354 unmodified lines
355}355}
356 356
357template<>357template<>
358static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<byte_t>() { return{ &hidden_type_desc::byte, hidden_type_desc::deleter }; }358static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<byte_t>()
359{
360 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::byte, hidden_type_desc::deleter };
361 return t;
362}
359 363
360template<>364template<>
361static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<short_word_t>() { return{ &hidden_type_desc::short_word, hidden_type_desc::deleter }; }365static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<short_word_t>()
366{
367 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::short_word, hidden_type_desc::deleter };
368 return t;
369}
362 370
363template<>371template<>
364static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<word_t>() { return{ &hidden_type_desc::word, hidden_type_desc::deleter }; }372static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<word_t>()
373{
374 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::word, hidden_type_desc::deleter };
375 return t;
376}
365 377
366template<>378template<>
367static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<short_real_t>() { return{ &hidden_type_desc::short_real, hidden_type_desc::deleter }; }379static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<short_real_t>()
380{
381 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::short_real, hidden_type_desc::deleter };
382 return t;
383}
368 384
369template<>385template<>
370static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<real_t>() { return{ &hidden_type_desc::real, hidden_type_desc::deleter }; }386static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<real_t>()
387{
388 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::real, hidden_type_desc::deleter };
389 return t;
390}
371 391
372template<>392template<>
373static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<big_t>() { return{ &hidden_type_desc::big, hidden_type_desc::deleter }; }393static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<big_t>()
394{
395 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::big, hidden_type_desc::deleter };
396 return t;
397}
374 398
375template<>399template<>
376static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<pointer_t>() { return{ &hidden_type_desc::pointer, hidden_type_desc::deleter }; }400static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<pointer_t>()
401{
402 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::pointer, hidden_type_desc::deleter };
403 return t;
404}
377 405
378template<>406template<>
379static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_array_t>() { return{ &hidden_type_desc::vm_array, hidden_type_desc::deleter }; }407static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_array_t>()
408{
409 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::vm_array, hidden_type_desc::deleter };
410 return t;
411}
380 412
381template<>413template<>
382static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_list_t>() { return{ &hidden_type_desc::vm_list, hidden_type_desc::deleter }; }414static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_list_t>()
415{
416 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::vm_list, hidden_type_desc::deleter };
417 return t;
418}
383 419
384template<>420template<>
385static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_channel_t>() { return{ &hidden_type_desc::vm_channel, hidden_type_desc::deleter }; }421static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_channel_t>()
422{
423 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::vm_channel, hidden_type_desc::deleter };
424 return t;
425}
386 426
387template<>427template<>
388static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_string_t>() { return{ &hidden_type_desc::vm_string, hidden_type_desc::deleter }; }428static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_string_t>()
429{
430 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::vm_string, hidden_type_desc::deleter };
431 return t;
432}
389 433
390template<>434template<>
391static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_module_ref_t>() { return{ &hidden_type_desc::vm_module_ref, hidden_type_desc::deleter }; }435static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_module_ref_t>()
436{
437 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::vm_module_ref, hidden_type_desc::deleter };
438 return t;
439}
392 440
393template<>441template<>
394static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_stack_t>() { return{ &hidden_type_desc::vm_stack, hidden_type_desc::deleter }; }442static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_stack_t>()
443{
444 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::vm_stack, hidden_type_desc::deleter };
445 return t;
446}
395 447
396template<>448template<>
397static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_thread_t>() { return{ &hidden_type_desc::vm_thread, hidden_type_desc::deleter }; }449static std::shared_ptr<const type_descriptor_t> intrinsic_type_desc::type<vm_thread_t>()
450{
451 static std::shared_ptr<const type_descriptor_t> t = { &hidden_type_desc::vm_thread, hidden_type_desc::deleter };
452 return t;
453}
398 454
399vm_alloc_instance_finalizer_t type_descriptor_t::no_finalizer = nullptr;455vm_alloc_instance_finalizer_t type_descriptor_t::no_finalizer = nullptr;
400 456