Mercurial > projects > ldc
comparison tango/lib/compiler/llvmdc/aaA.d @ 163:a8cd9bc1021a trunk
[svn r179] lots and lots of fixes, much more of tango now compiles/works.
author | lindquist |
---|---|
date | Mon, 05 May 2008 07:36:29 +0200 |
parents | 1700239cab2e |
children |
comparison
equal
deleted
inserted
replaced
162:1856c62af24b | 163:a8cd9bc1021a |
---|---|
27 * distribution. | 27 * distribution. |
28 */ | 28 */ |
29 | 29 |
30 /* | 30 /* |
31 * Modified by Sean Kelly <sean@f4.ca> for use with Tango. | 31 * Modified by Sean Kelly <sean@f4.ca> for use with Tango. |
32 * Modified by Tomas Lindquist Olsen <tomas@famolsen.dk> for use with LLVMDC. | |
32 */ | 33 */ |
33 | 34 |
34 private | 35 private |
35 { | 36 { |
36 import tango.stdc.stdarg; | 37 import tango.stdc.stdarg; |
59 6291469UL, 25165843UL, | 60 6291469UL, 25165843UL, |
60 100663319UL, 402653189UL, | 61 100663319UL, 402653189UL, |
61 1610612741UL, 4294967291UL | 62 1610612741UL, 4294967291UL |
62 ]; | 63 ]; |
63 | 64 |
64 /* This is the type of the return value for dynamic arrays. | 65 // This is the type of the return value for dynamic arrays. |
65 * It should be a type that is returned in registers. | |
66 * Although DMD will return types of Array in registers, | |
67 * gcc will not, so we instead use a 'long'. | |
68 */ | |
69 alias long ArrayRet_t; | |
70 | |
71 struct Array | 66 struct Array |
72 { | 67 { |
73 size_t length; | 68 size_t length; |
74 void* ptr; | 69 void* ptr; |
75 } | 70 } |
91 | 86 |
92 /* This is the type actually seen by the programmer, although | 87 /* This is the type actually seen by the programmer, although |
93 * it is completely opaque. | 88 * it is completely opaque. |
94 */ | 89 */ |
95 | 90 |
96 struct AA | 91 // LLVMDC doesn't pass structs in registers so no need to wrap it ... |
97 { | 92 alias BB* AA; |
98 BB* a; | |
99 } | |
100 | 93 |
101 /********************************** | 94 /********************************** |
102 * Align to next pointer boundary, so that | 95 * Align to next pointer boundary, so that |
103 * GC won't be faced with misaligned pointers | 96 * GC won't be faced with misaligned pointers |
104 * in value. | 97 * in value. |
208 break; | 201 break; |
209 len++; | 202 len++; |
210 } | 203 } |
211 } | 204 } |
212 | 205 |
213 if (aa.a) | 206 if (aa) |
214 { | 207 { |
215 foreach (e; aa.a.b) | 208 foreach (e; aa.b) |
216 { | 209 { |
217 if (e) | 210 if (e) |
218 _aaLen_x(e); | 211 _aaLen_x(e); |
219 } | 212 } |
220 } | 213 } |
222 | 215 |
223 //printf("_aaLen()-\n"); | 216 //printf("_aaLen()-\n"); |
224 } | 217 } |
225 body | 218 body |
226 { | 219 { |
227 return aa.a ? aa.a.nodes : 0; | 220 return aa ? aa.nodes : 0; |
228 } | 221 } |
229 | 222 |
230 | 223 |
231 /************************************************* | 224 /************************************************* |
232 * Get pointer to value in associative array indexed by key. | 225 * Get pointer to value in associative array indexed by key. |
233 * Add entry for key if it is not already there. | 226 * Add entry for key if it is not already there. |
234 */ | 227 */ |
235 | 228 |
236 void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, ...) | 229 void* _aaGet(AA* aa_arg, TypeInfo keyti, size_t valuesize, void* pkey) |
237 in | 230 in |
238 { | 231 { |
239 assert(aa); | 232 assert(aa_arg); |
240 } | 233 } |
241 out (result) | 234 out (result) |
242 { | 235 { |
243 assert(result); | 236 assert(result); |
244 assert(aa.a); | 237 assert(*aa_arg); |
245 assert(aa.a.b.length); | 238 assert((*aa_arg).b.length); |
246 //assert(_aaInAh(*aa.a, key)); | 239 //assert(_aaInAh(*aa, key)); |
247 } | 240 } |
248 body | 241 body |
249 { | 242 { |
250 auto pkey = cast(void *)(&valuesize + 1); | 243 //auto pkey = cast(void *)(&valuesize + 1); |
251 size_t i; | 244 size_t i; |
252 aaA *e; | 245 aaA *e; |
253 auto keysize = aligntsize(keyti.tsize()); | 246 auto keysize = aligntsize(keyti.tsize()); |
254 | 247 |
255 if (!aa.a) | 248 if (!*aa_arg) |
256 aa.a = new BB(); | 249 *aa_arg = new BB(); |
257 | 250 auto aa = *aa_arg; |
258 if (!aa.a.b.length) | 251 |
252 if (!aa.b.length) | |
259 { | 253 { |
260 alias aaA *pa; | 254 alias aaA *pa; |
261 auto len = prime_list[0]; | 255 auto len = prime_list[0]; |
262 | 256 |
263 aa.a.b = new pa[len]; | 257 aa.b = new pa[len]; |
264 } | 258 } |
265 | 259 |
266 auto key_hash = keyti.getHash(pkey); | 260 auto key_hash = keyti.getHash(pkey); |
267 //printf("hash = %d\n", key_hash); | 261 //printf("hash = %d\n", key_hash); |
268 i = key_hash % aa.a.b.length; | 262 i = key_hash % aa.b.length; |
269 auto pe = &aa.a.b[i]; | 263 auto pe = &aa.b[i]; |
270 while ((e = *pe) !is null) | 264 while ((e = *pe) !is null) |
271 { | 265 { |
272 if (key_hash == e.hash) | 266 if (key_hash == e.hash) |
273 { | 267 { |
274 auto c = keyti.compare(pkey, e + 1); | 268 auto c = keyti.compare(pkey, e + 1); |
290 e = cast(aaA *) gc_calloc(size, bits); | 284 e = cast(aaA *) gc_calloc(size, bits); |
291 memcpy(e + 1, pkey, keysize); | 285 memcpy(e + 1, pkey, keysize); |
292 e.hash = key_hash; | 286 e.hash = key_hash; |
293 *pe = e; | 287 *pe = e; |
294 | 288 |
295 auto nodes = ++aa.a.nodes; | 289 auto nodes = ++aa.nodes; |
296 //printf("length = %d, nodes = %d\n", (*aa.a).length, nodes); | 290 //printf("length = %d, nodes = %d\n", (*aa).length, nodes); |
297 if (nodes > aa.a.b.length * 4) | 291 if (nodes > aa.b.length * 4) |
298 { | 292 { |
299 _aaRehash(aa,keyti); | 293 _aaRehash(aa_arg,keyti); |
300 } | 294 } |
301 | 295 |
302 Lret: | 296 Lret: |
303 return cast(void *)(e + 1) + keysize; | 297 return cast(void *)(e + 1) + keysize; |
304 } | 298 } |
307 /************************************************* | 301 /************************************************* |
308 * Get pointer to value in associative array indexed by key. | 302 * Get pointer to value in associative array indexed by key. |
309 * Returns null if it is not already there. | 303 * Returns null if it is not already there. |
310 */ | 304 */ |
311 | 305 |
312 void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, ...) | 306 void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void *pkey) |
313 { | 307 { |
314 //printf("_aaGetRvalue(valuesize = %u)\n", valuesize); | 308 //printf("_aaGetRvalue(valuesize = %u)\n", valuesize); |
315 if (!aa.a) | 309 if (!aa) |
316 return null; | 310 return null; |
317 | 311 |
318 auto pkey = cast(void *)(&valuesize + 1); | 312 //auto pkey = cast(void *)(&valuesize + 1); |
319 auto keysize = aligntsize(keyti.tsize()); | 313 auto keysize = aligntsize(keyti.tsize()); |
320 auto len = aa.a.b.length; | 314 auto len = aa.b.length; |
321 | 315 |
322 if (len) | 316 if (len) |
323 { | 317 { |
324 auto key_hash = keyti.getHash(pkey); | 318 auto key_hash = keyti.getHash(pkey); |
325 //printf("hash = %d\n", key_hash); | 319 //printf("hash = %d\n", key_hash); |
326 size_t i = key_hash % len; | 320 size_t i = key_hash % len; |
327 auto e = aa.a.b[i]; | 321 auto e = aa.b[i]; |
328 while (e !is null) | 322 while (e !is null) |
329 { | 323 { |
330 if (key_hash == e.hash) | 324 if (key_hash == e.hash) |
331 { | 325 { |
332 auto c = keyti.compare(pkey, e + 1); | 326 auto c = keyti.compare(pkey, e + 1); |
347 * Returns: | 341 * Returns: |
348 * null not in aa | 342 * null not in aa |
349 * !=null in aa, return pointer to value | 343 * !=null in aa, return pointer to value |
350 */ | 344 */ |
351 | 345 |
352 void* _aaIn(AA aa, TypeInfo keyti, ...) | 346 void* _aaIn(AA aa, TypeInfo keyti, void *pkey) |
353 in | 347 in |
354 { | 348 { |
355 } | 349 } |
356 out (result) | 350 out (result) |
357 { | 351 { |
358 //assert(result == 0 || result == 1); | 352 //assert(result == 0 || result == 1); |
359 } | 353 } |
360 body | 354 body |
361 { | 355 { |
362 if (aa.a) | 356 if (aa) |
363 { | 357 { |
364 auto pkey = cast(void *)(&keyti + 1); | 358 //auto pkey = cast(void *)(&keyti + 1); |
365 | 359 |
366 //printf("_aaIn(), .length = %d, .ptr = %x\n", aa.a.length, cast(uint)aa.a.ptr); | 360 //printf("_aaIn(), .length = %d, .ptr = %x\n", aa.length, cast(uint)aa.ptr); |
367 auto len = aa.a.b.length; | 361 auto len = aa.b.length; |
368 | 362 |
369 if (len) | 363 if (len) |
370 { | 364 { |
371 auto key_hash = keyti.getHash(pkey); | 365 auto key_hash = keyti.getHash(pkey); |
372 //printf("hash = %d\n", key_hash); | 366 //printf("hash = %d\n", key_hash); |
373 size_t i = key_hash % len; | 367 size_t i = key_hash % len; |
374 auto e = aa.a.b[i]; | 368 auto e = aa.b[i]; |
375 while (e !is null) | 369 while (e !is null) |
376 { | 370 { |
377 if (key_hash == e.hash) | 371 if (key_hash == e.hash) |
378 { | 372 { |
379 auto c = keyti.compare(pkey, e + 1); | 373 auto c = keyti.compare(pkey, e + 1); |
394 /************************************************* | 388 /************************************************* |
395 * Delete key entry in aa[]. | 389 * Delete key entry in aa[]. |
396 * If key is not in aa[], do nothing. | 390 * If key is not in aa[], do nothing. |
397 */ | 391 */ |
398 | 392 |
399 void _aaDel(AA aa, TypeInfo keyti, ...) | 393 void _aaDel(AA aa, TypeInfo keyti, void *pkey) |
400 { | 394 { |
401 auto pkey = cast(void *)(&keyti + 1); | 395 //auto pkey = cast(void *)(&keyti + 1); |
402 aaA *e; | 396 aaA *e; |
403 | 397 |
404 if (aa.a && aa.a.b.length) | 398 if (aa && aa.b.length) |
405 { | 399 { |
406 auto key_hash = keyti.getHash(pkey); | 400 auto key_hash = keyti.getHash(pkey); |
407 //printf("hash = %d\n", key_hash); | 401 //printf("hash = %d\n", key_hash); |
408 size_t i = key_hash % aa.a.b.length; | 402 size_t i = key_hash % aa.b.length; |
409 auto pe = &aa.a.b[i]; | 403 auto pe = &aa.b[i]; |
410 while ((e = *pe) !is null) // null means not found | 404 while ((e = *pe) !is null) // null means not found |
411 { | 405 { |
412 if (key_hash == e.hash) | 406 if (key_hash == e.hash) |
413 { | 407 { |
414 auto c = keyti.compare(pkey, e + 1); | 408 auto c = keyti.compare(pkey, e + 1); |
437 while (*pe); | 431 while (*pe); |
438 *pe = e.right; | 432 *pe = e.right; |
439 e.right = null; | 433 e.right = null; |
440 } | 434 } |
441 | 435 |
442 aa.a.nodes--; | 436 aa.nodes--; |
443 | 437 |
444 // Should notify GC that e can be free'd now | 438 // Should notify GC that e can be free'd now |
445 break; | 439 break; |
446 } | 440 } |
447 pe = (c < 0) ? &e.left : &e.right; | 441 pe = (c < 0) ? &e.left : &e.right; |
455 | 449 |
456 /******************************************** | 450 /******************************************** |
457 * Produce array of values from aa. | 451 * Produce array of values from aa. |
458 */ | 452 */ |
459 | 453 |
460 ArrayRet_t _aaValues(AA aa, size_t keysize, size_t valuesize) | 454 Array _aaValues(AA aa, size_t keysize, size_t valuesize) |
461 in | 455 in |
462 { | 456 { |
463 assert(keysize == aligntsize(keysize)); | 457 assert(keysize == aligntsize(keysize)); |
464 } | 458 } |
465 body | 459 body |
484 } | 478 } |
485 e = e.right; | 479 e = e.right; |
486 } while (e !is null); | 480 } while (e !is null); |
487 } | 481 } |
488 | 482 |
489 if (aa.a) | 483 if (aa) |
490 { | 484 { |
491 a.length = _aaLen(aa); | 485 a.length = _aaLen(aa); |
492 a.ptr = cast(byte*) gc_malloc(a.length * valuesize, | 486 a.ptr = cast(byte*) gc_malloc(a.length * valuesize, |
493 valuesize < (void*).sizeof && | 487 valuesize < (void*).sizeof && |
494 valuesize > (void).sizeof ? BlkAttr.NO_SCAN : 0); | 488 valuesize > (void).sizeof ? BlkAttr.NO_SCAN : 0); |
495 resi = 0; | 489 resi = 0; |
496 foreach (e; aa.a.b) | 490 foreach (e; aa.b) |
497 { | 491 { |
498 if (e) | 492 if (e) |
499 _aaValues_x(e); | 493 _aaValues_x(e); |
500 } | 494 } |
501 assert(resi == a.length); | 495 assert(resi == a.length); |
502 } | 496 } |
503 return *cast(ArrayRet_t*)(&a); | 497 return a; |
504 } | 498 } |
505 | 499 |
506 | 500 |
507 /******************************************** | 501 /******************************************** |
508 * Rehash an array. | 502 * Rehash an array. |
565 olde = left; | 559 olde = left; |
566 } | 560 } |
567 } | 561 } |
568 | 562 |
569 //printf("Rehash\n"); | 563 //printf("Rehash\n"); |
570 if (paa.a) | 564 if (*paa) |
571 { | 565 { |
572 auto aa = paa.a; | 566 auto aa = *paa; |
573 auto len = _aaLen(*paa); | 567 auto len = _aaLen(aa); |
574 if (len) | 568 if (len) |
575 { size_t i; | 569 { size_t i; |
576 | 570 |
577 for (i = 0; i < prime_list.length - 1; i++) | 571 for (i = 0; i < prime_list.length - 1; i++) |
578 { | 572 { |
586 { | 580 { |
587 if (e) | 581 if (e) |
588 _aaRehash_x(e); | 582 _aaRehash_x(e); |
589 } | 583 } |
590 | 584 |
591 newb.nodes = aa.nodes; | 585 newb.nodes = (*aa).nodes; |
592 } | 586 } |
593 | 587 |
594 *paa.a = newb; | 588 **paa = newb; |
595 } | 589 } |
596 return (*paa).a; | 590 return *paa; |
597 } | 591 } |
598 | 592 |
599 | 593 |
600 /******************************************** | 594 /******************************************** |
601 * Produce array of N byte keys from aa. | 595 * Produce array of N byte keys from aa. |
602 */ | 596 */ |
603 | 597 |
604 ArrayRet_t _aaKeys(AA aa, size_t keysize) | 598 Array _aaKeys(AA aa, size_t keysize) |
605 { | 599 { |
606 byte[] res; | 600 byte[] res; |
607 size_t resi; | 601 size_t resi; |
608 | 602 |
609 void _aaKeys_x(aaA* e) | 603 void _aaKeys_x(aaA* e) |
623 } while (e !is null); | 617 } while (e !is null); |
624 } | 618 } |
625 | 619 |
626 auto len = _aaLen(aa); | 620 auto len = _aaLen(aa); |
627 if (!len) | 621 if (!len) |
628 return 0; | 622 return Array(); |
629 res = (cast(byte*) gc_malloc(len * keysize, | 623 res = (cast(byte*) gc_malloc(len * keysize, |
630 keysize < (void*).sizeof && | 624 keysize < (void*).sizeof && |
631 keysize > (void).sizeof ? BlkAttr.NO_SCAN : 0))[0 .. len * keysize]; | 625 keysize > (void).sizeof ? BlkAttr.NO_SCAN : 0))[0 .. len * keysize]; |
632 resi = 0; | 626 resi = 0; |
633 foreach (e; aa.a.b) | 627 foreach (e; aa.b) |
634 { | 628 { |
635 if (e) | 629 if (e) |
636 _aaKeys_x(e); | 630 _aaKeys_x(e); |
637 } | 631 } |
638 assert(resi == len); | 632 assert(resi == len); |
639 | 633 |
640 Array a; | 634 return Array(len, res.ptr); |
641 a.length = len; | |
642 a.ptr = res.ptr; | |
643 return *cast(ArrayRet_t*)(&a); | |
644 } | 635 } |
645 | 636 |
646 | 637 |
647 /********************************************** | 638 /********************************************** |
648 * 'apply' for associative arrays - to support foreach | 639 * 'apply' for associative arrays - to support foreach |
657 assert(aligntsize(keysize) == keysize); | 648 assert(aligntsize(keysize) == keysize); |
658 } | 649 } |
659 body | 650 body |
660 { int result; | 651 { int result; |
661 | 652 |
662 //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa.a, keysize, dg); | 653 //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg); |
663 | 654 |
664 int treewalker(aaA* e) | 655 int treewalker(aaA* e) |
665 { int result; | 656 { int result; |
666 | 657 |
667 do | 658 do |
684 } while (e); | 675 } while (e); |
685 | 676 |
686 return result; | 677 return result; |
687 } | 678 } |
688 | 679 |
689 if (aa.a) | 680 if (aa) |
690 { | 681 { |
691 foreach (e; aa.a.b) | 682 foreach (e; aa.b) |
692 { | 683 { |
693 if (e) | 684 if (e) |
694 { | 685 { |
695 result = treewalker(e); | 686 result = treewalker(e); |
696 if (result) | 687 if (result) |
710 assert(aligntsize(keysize) == keysize); | 701 assert(aligntsize(keysize) == keysize); |
711 } | 702 } |
712 body | 703 body |
713 { int result; | 704 { int result; |
714 | 705 |
715 //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa.a, keysize, dg); | 706 //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg); |
716 | 707 |
717 int treewalker(aaA* e) | 708 int treewalker(aaA* e) |
718 { int result; | 709 { int result; |
719 | 710 |
720 do | 711 do |
737 } while (e); | 728 } while (e); |
738 | 729 |
739 return result; | 730 return result; |
740 } | 731 } |
741 | 732 |
742 if (aa.a) | 733 if (aa) |
743 { | 734 { |
744 foreach (e; aa.a.b) | 735 foreach (e; aa.b) |
745 { | 736 { |
746 if (e) | 737 if (e) |
747 { | 738 { |
748 result = treewalker(e); | 739 result = treewalker(e); |
749 if (result) | 740 if (result) |