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)