Changeset 10105
- Timestamp:
- Jul 18, 2008, 8:55:27 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/lisp-kernel/x86-gc.c
r10104 r10105 43 43 case fulltag_even_fixnum: 44 44 case fulltag_odd_fixnum: 45 #ifdef X8632 46 case fulltag_imm: 47 #endif 48 #ifdef X8664 45 49 case fulltag_imm_0: 46 50 case fulltag_imm_1: 51 #endif 47 52 return; 48 53 54 #ifdef X8664 49 55 case fulltag_nil: 50 56 if (n != lisp_nil) { … … 52 58 } 53 59 return; 54 55 60 #endif 61 62 #ifdef X8632 63 case fulltag_nodeheader: 64 case fulltag_immheader: 65 #endif 66 #ifdef X8664 56 67 case fulltag_nodeheader_0: 57 68 case fulltag_nodeheader_1: … … 59 70 case fulltag_immheader_1: 60 71 case fulltag_immheader_2: 72 #endif 61 73 Bug(NULL, "Header not expected : 0x%lx", n); 62 74 return; 63 75 76 #ifdef X8632 77 case fulltag_tra: 78 #endif 79 #ifdef X8664 64 80 case fulltag_tra_0: 65 81 case fulltag_tra_1: 82 #endif 66 83 a = heap_area_containing((BytePtr)ptr_from_lispobj(n)); 67 84 if (a == NULL) { … … 76 93 check the function it (should) identify. 77 94 */ 95 #ifdef X8632 96 { 97 LispObj fun = 0; 98 99 if (*(unsigned char *)n == RECOVER_FN_OPCODE) 100 fun = *(LispObj *)(n + 1); 101 if (fun == 0 || 102 (header_subtag(header_of(fun)) != subtag_function) || 103 (heap_area_containing((BytePtr)ptr_from_lispobj(fun)) != a)) { 104 Bug(NULL, "TRA at 0x%x has bad function address 0x%x\n", n, fun); 105 } 106 n = fun; 107 } 108 #endif 109 #ifdef X8664 78 110 { 79 111 int disp = 0; … … 91 123 } 92 124 } 125 #endif 93 126 /* Otherwise, fall through and check the header on the function 94 127 that the tra references */ … … 96 129 case fulltag_misc: 97 130 case fulltag_cons: 131 #ifdef X8664 98 132 case fulltag_symbol: 99 133 case fulltag_function: 134 #endif 100 135 a = heap_area_containing((BytePtr)ptr_from_lispobj(n)); 101 136 … … 163 198 elements = header_element_count(node) | 1; 164 199 if (header_subtag(node) == subtag_function) { 200 #ifdef X8632 201 int skip = *(unsigned short *)current; 202 #else 165 203 int skip = *(int *)current; 204 #endif 166 205 current += skip; 167 206 elements -= skip; … … 250 289 } 251 290 291 #ifdef X8632 292 if (tag_n == fulltag_tra) { 293 if (*(unsigned char *)n == RECOVER_FN_OPCODE) { 294 n = *(LispObj *)(n + 1); 295 tag_n = fulltag_misc; 296 } else 297 return; 298 } 299 #endif 300 #ifdef X8664 252 301 if (tag_of(n) == tag_tra) { 253 302 if ((*((unsigned short *)n) == RECOVER_FN_FROM_RIP_WORD0) && … … 261 310 } 262 311 } 312 #endif 263 313 264 314 … … 292 342 tag_n = fulltag_of(header); 293 343 294 344 #ifdef X8664 295 345 if ((nodeheader_tag_p(tag_n)) || 296 346 (tag_n == ivector_class_64_bit)) { … … 308 358 } 309 359 } 360 #endif 361 #ifdef X8632 362 if ((tag_n == fulltag_nodeheader) || 363 (subtag <= max_32_bit_ivector_subtag)) { 364 total_size_in_bytes = 4 + (element_count<<2); 365 } else if (subtag <= max_8_bit_ivector_subtag) { 366 total_size_in_bytes = 4 + element_count; 367 } else if (subtag <= max_16_bit_ivector_subtag) { 368 total_size_in_bytes = 4 + (element_count<<1); 369 } else if (subtag == subtag_double_float_vector) { 370 total_size_in_bytes = 8 + (element_count<<3); 371 } else { 372 total_size_in_bytes = 4 + ((element_count+7)>>3); 373 } 374 #endif 375 310 376 311 377 suffix_dnodes = ((total_size_in_bytes+(dnode_size-1))>>dnode_shift) -1; … … 344 410 345 411 if (subtag == subtag_function) { 412 #ifdef X8632 413 prefix_nodes = (natural) ((unsigned short) deref(base,1)); 414 #else 346 415 prefix_nodes = (natural) ((int) deref(base,1)); 416 #endif 347 417 if (prefix_nodes > element_count) { 348 418 Bug(NULL, "Function 0x%lx trashed",n); … … 397 467 #ifdef X8664 398 468 #define RMARK_PREV_ROOT fulltag_imm_1 /* fulltag of 'undefined' value */ 399 #define RMARK_PREV_CAR fulltag_nil /* fulltag_ nil+ node_size. Coincidence ? I think not. */469 #define RMARK_PREV_CAR fulltag_nil /* fulltag_cons + node_size. Coincidence ? I think not. */ 400 470 #else 401 #endif 402 471 #define RMARK_PREV_ROOT fulltag_imm /* fulltag of 'undefined' value */ 472 #define RMARK_PREV_CAR fulltag_odd_fixnum 473 #endif 403 474 404 475 … … 419 490 } 420 491 492 #ifdef X8632 493 if (tag_n == fulltag_tra) { 494 if (*(unsigned char *)n == RECOVER_FN_OPCODE) { 495 n = *(LispObj *)(n + 1); 496 tag_n = fulltag_misc; 497 } else { 498 return; 499 } 500 } 501 #endif 502 #ifdef X8664 421 503 if (tag_of(n) == tag_tra) { 422 504 if ((*((unsigned short *)n) == RECOVER_FN_FROM_RIP_WORD0) && … … 429 511 } 430 512 } 513 #endif 431 514 432 515 dnode = gc_area_dnode(n); … … 456 539 tag_n = fulltag_of(header); 457 540 541 #ifdef X8664 458 542 if ((nodeheader_tag_p(tag_n)) || 459 543 (tag_n == ivector_class_64_bit)) { … … 471 555 } 472 556 } 557 #else 558 if ((tag_n == fulltag_nodeheader) || 559 (subtag <= max_32_bit_ivector_subtag)) { 560 total_size_in_bytes = 4 + (element_count<<2); 561 } else if (subtag <= max_8_bit_ivector_subtag) { 562 total_size_in_bytes = 4 + element_count; 563 } else if (subtag <= max_16_bit_ivector_subtag) { 564 total_size_in_bytes = 4 + (element_count<<1); 565 } else if (subtag == subtag_double_float_vector) { 566 total_size_in_bytes = 8 + (element_count<<3); 567 } else { 568 total_size_in_bytes = 4 + ((element_count+7)>>3); 569 } 570 #endif 571 473 572 suffix_dnodes = ((total_size_in_bytes+(dnode_size-1))>>dnode_shift)-1; 474 573 … … 513 612 514 613 if (subtag == subtag_function) { 515 if ((int)base[1] >= nmark) { 614 #ifdef X8664 615 int code_words = (int)base[1]; 616 #else 617 int code_words = (unsigned short)base[1]; 618 #endif 619 if (code_words >= nmark) { 516 620 Bug(NULL,"Bad function at 0x%lx",n); 517 621 } 518 nmark -= (int)base[1];622 nmark -= code_words; 519 623 } 520 624 … … 531 635 } 532 636 } else { 533 534 637 /* This is all a bit more complicated than the PPC version: 535 638 … … 618 721 case tag_misc: 619 722 case fulltag_misc: 723 #ifdef X8664 620 724 case tag_symbol: 621 725 case fulltag_symbol: 622 726 case tag_function: 623 727 case fulltag_function: 728 #endif 624 729 goto ClimbVector; 625 730 … … 633 738 goto ClimbCar; 634 739 635 /* default: abort() */740 default: abort(); 636 741 } 637 742 … … 642 747 MarkCons: 643 748 next = deref(this,1); 749 #ifdef X8632 750 this += (RMARK_PREV_CAR-fulltag_cons); 751 #else 644 752 this += node_size; 753 #endif 645 754 tag_n = fulltag_of(next); 646 755 if (!is_node_fulltag(tag_n)) goto MarkCdr; … … 660 769 MarkCdr: 661 770 next = deref(this, 0); 771 #ifdef X8632 772 this -= (RMARK_PREV_CAR-fulltag_cons); 773 #else 662 774 this -= node_size; 775 #endif 663 776 tag_n = fulltag_of(next); 664 777 if (!is_node_fulltag(tag_n)) goto Climb; … … 677 790 678 791 MarkVector: 792 #ifdef X8664 679 793 if ((tag_n == fulltag_tra_0) || 680 794 (tag_n == fulltag_tra_1)) { … … 717 831 } 718 832 } 833 #else 834 if (tag_n == fulltag_tra) { 835 LispObj fn = *(LispObj *)(n + 1); 836 837 base = (LispObj *)untag(fn); 838 header = *(natural *)base; 839 subtag = header_subtag(header); 840 boundary = base + (unsigned short)base[1]; 841 /* 842 * On x8632, the upper 24 bits of the boundary word are zero. 843 * Functions on x8632 can be no more than 2^16 words (or 2^24 844 * bytes) long (including the self-reference table but excluding 845 * any constants). Therefore, we can do the same basic thing 846 * that the x8664 port does: namely, we keep the byte 847 * displacement from the address of the object (tagged tra or 848 * fulltag_misc) that references the function to the address of 849 * the boundary marker in those 24 bits, recovering it when 850 * we've finished marking the function vector. 851 */ 852 *((int *)boundary) &= 0xff; 853 *((int *)boundary) |= ((this-(LispObj)boundary) << 8); 854 this = (LispObj)(base)+fulltag_misc; 855 dnode = gc_area_dnode(this); 856 set_bit(markbits,dnode); 857 } else { 858 base = (LispObj *) ptr_from_lispobj(untag(this)); 859 header = *((natural *) base); 860 subtag = header_subtag(header); 861 if (subtag == subtag_function) { 862 boundary = base + (unsigned short)base[1]; 863 *((int *)boundary) &= 0xff; 864 *((int *)boundary) |= ((this-((LispObj)boundary)) << 8); 865 } 866 } 867 element_count = header_element_count(header); 868 tag_n = fulltag_of(header); 869 870 if ((tag_n == fulltag_nodeheader) || 871 (subtag <= max_32_bit_ivector_subtag)) { 872 total_size_in_bytes = 4 + (element_count<<2); 873 } else if (subtag <= max_8_bit_ivector_subtag) { 874 total_size_in_bytes = 4 + element_count; 875 } else if (subtag <= max_16_bit_ivector_subtag) { 876 total_size_in_bytes = 4 + (element_count<<1); 877 } else if (subtag == subtag_double_float_vector) { 878 total_size_in_bytes = 8 + (element_count<<3); 879 } else { 880 total_size_in_bytes = 4 + ((element_count+7)>>3); 881 } 882 #endif 883 719 884 suffix_dnodes = ((total_size_in_bytes+(dnode_size-1))>>dnode_shift)-1; 720 885 … … 759 924 this -= node_size; 760 925 next = indirect_node(this); 926 #ifdef X8664 761 927 if ((tag_of(this) == tag_function) && 762 928 (header_subtag(next) == function_boundary_marker)) goto MarkFunctionDone; 929 #else 930 if ((tag_of(this) == tag_misc) && 931 (header_subtag(next) == function_boundary_marker)) goto MarkFunctionDone; 932 #endif 933 763 934 tag_n = fulltag_of(next); 764 935 if (nodeheader_tag_p(tag_n)) goto MarkVectorDone; … … 786 957 MarkFunctionDone: 787 958 boundary = (LispObj *)(node_aligned(this)); 959 #ifdef X8664 788 960 this = ((LispObj)boundary) + (((int *)boundary)[1]); 789 961 (((int *)boundary)[1]) = 0; 962 #else 963 this = ((LispObj)boundary) + ((*((int *)boundary)) >> 8); 964 ((int *)boundary)[0] &= 0xff; 790 965 goto Climb; 966 #endif 791 967 } 792 968 } … … 801 977 802 978 803 979 #ifdef X8664 804 980 switch (fulltag_of(header)) { 805 981 case ivector_class_64_bit: … … 820 996 } 821 997 return ptr_from_lispobj(start+(~15 & (nbytes + 8 + 15))); 822 998 #else 999 if (subtag <= max_32_bit_ivector_subtag) { 1000 nbytes = element_count << 2; 1001 } else if (subtag <= max_8_bit_ivector_subtag) { 1002 nbytes = element_count; 1003 } else if (subtag <= max_16_bit_ivector_subtag) { 1004 nbytes = element_count << 1; 1005 } else if (subtag == subtag_double_float_vector) { 1006 nbytes = 4 + (element_count << 3); 1007 } else { 1008 nbytes = (element_count+7) >> 3; 1009 } 1010 return ptr_from_lispobj(start+(~7 & (nbytes + 4 + 7))); 1011 #endif 823 1012 } 824 1013 … … 840 1029 } else { 841 1030 if (header_subtag(x1) == subtag_function) { 1031 #ifdef X8632 1032 int skip = (unsigned short)deref(start,1); 1033 #else 842 1034 int skip = (int) deref(start,1); 1035 #endif 843 1036 start += ((1+skip)&~1); 844 1037 x1 = *start; … … 1015 1208 base = start + element_count + 1; 1016 1209 if (subtag == subtag_function) { 1210 #ifdef X8632 1211 element_count -= (unsigned short)start[1]; 1212 #else 1017 1213 element_count -= (int)start[1]; 1214 #endif 1018 1215 } 1019 1216 while(element_count--) { … … 1076 1273 1077 1274 /* Mark the lisp objects in an exception frame */ 1275 #ifdef X8664 1078 1276 void 1079 1277 mark_xp(ExceptionInformation *xp) … … 1114 1312 } 1115 1313 } 1116 1117 1118 1119 1120 1121 1122 1314 #else 1315 void 1316 mark_xp(ExceptionInformation *xp, natural node_regs_mask) 1317 { 1318 natural *regs = (natural *) xpGPRvector(xp), dnode; 1319 LispObj eip; 1320 int i; 1321 1322 if (node_regs_mask & (1<<0)) mark_root(regs[REG_EAX]); 1323 if (node_regs_mask & (1<<1)) mark_root(regs[REG_EBX]); 1324 if (node_regs_mask & (1<<2)) mark_root(regs[REG_ECX]); 1325 if (node_regs_mask & (1<<3)) mark_root(regs[REG_EDX]); 1326 if (node_regs_mask & (1<<4)) mark_root(regs[REG_ESP]); 1327 if (node_regs_mask & (1<<5)) mark_root(regs[REG_EBP]); 1328 if (node_regs_mask & (1<<6)) mark_root(regs[REG_ESI]); 1329 if (node_regs_mask & (1<<7)) mark_root(regs[REG_EDI]); 1330 1331 /* If the EIP isn't pointing into a marked function, we're probably 1332 in trouble. We can -maybe- recover from that if it's tagged as a 1333 TRA. */ 1334 eip = regs[Ieip]; 1335 dnode = gc_area_dnode(eip); 1336 if ((dnode < GCndnodes_in_area) && 1337 (! ref_bit(GCmarkbits,dnode))) { 1338 if (fulltag_of(eip) == fulltag_tra) { 1339 mark_root(eip); 1340 } else if ((fulltag_of(eip) == fulltag_misc) && 1341 (header_subtag(header_of(eip)) == subtag_function) && 1342 (*(unsigned char *)eip == RECOVER_FN_OPCODE) && 1343 (*(LispObj *)(eip + 1)) == eip) { 1344 mark_root(eip); 1345 } else { 1346 Bug(NULL, "Can't find function for eip 0x%4x", eip); 1347 } 1348 } 1349 } 1350 #endif 1123 1351 1124 1352 /* A "pagelet" contains 32 doublewords. The relocation table contains … … 1218 1446 } 1219 1447 #else 1220 1448 #ifdef X8664 1221 1449 /* Quicker, dirtier */ 1222 1450 LispObj … … 1244 1472 return new; 1245 1473 } 1474 #endif 1475 #ifdef X8632 1476 LispObj 1477 dnode_forwarding_address(natural dnode, int tag_n) 1478 { 1479 natural pagelet, nbits; 1480 unsigned short near_bits; 1481 LispObj new; 1482 1483 if (GCDebug) { 1484 if (! ref_bit(GCdynamic_markbits, dnode)) { 1485 Bug(NULL, "unmarked object being forwarded!\n"); 1486 } 1487 } 1488 1489 pagelet = dnode >> 5; 1490 nbits = dnode & 0x1f; 1491 /* On little-endian x86, we have to flip the low bit of dnode>>4 to 1492 get the near_bits from the appropriate half-word. */ 1493 near_bits = ((unsigned short *)GCdynamic_markbits)[(dnode>>4)^1]; 1494 1495 if (nbits < 16) { 1496 new = GCrelocptr[pagelet] + tag_n;; 1497 /* Increment "new" by the count of 1 bits which precede the dnode */ 1498 if (near_bits == 0xffff) { 1499 return (new + (nbits << 3)); 1500 } else { 1501 near_bits &= (0xffff0000 >> nbits); 1502 if (nbits > 7) { 1503 new += one_bits(near_bits & 0xff); 1504 } 1505 return (new + (one_bits(near_bits >> 8))); 1506 } 1507 } else { 1508 new = GCrelocptr[pagelet+1] + tag_n; 1509 nbits = 32-nbits; 1510 1511 if (near_bits == 0xffff) { 1512 return (new - (nbits << 3)); 1513 } else { 1514 near_bits &= (1<<nbits)-1; 1515 if (nbits > 7) { 1516 new -= one_bits(near_bits >> 8); 1517 } 1518 return (new - one_bits(near_bits & 0xff)); 1519 } 1520 } 1521 } 1522 #endif 1246 1523 #endif 1247 1524 … … 1316 1593 } else { 1317 1594 if (header_subtag(node) == subtag_function) { 1595 #ifdef X8632 1596 int skip = (unsigned short)(p[1]); 1597 #else 1318 1598 int skip = (int)(p[1]); 1599 #endif 1319 1600 p += skip; 1320 1601 nwords -= skip; … … 1380 1661 } 1381 1662 1382 1663 #ifdef X8664 1383 1664 void 1384 1665 forward_xp(ExceptionInformation *xp) … … 1399 1680 update_locref(&(regs[Iip])); 1400 1681 } 1682 #else 1683 void 1684 forward_xp(ExceptionInformation *xp, natural node_regs_mask) 1685 { 1686 natural *regs = (natural *) xpGPRvector(xp); 1687 1688 if (node_regs_mask & (1<<0)) update_noderef(®s[REG_EAX]); 1689 if (node_regs_mask & (1<<1)) update_noderef(®s[REG_EBX]); 1690 if (node_regs_mask & (1<<2)) update_noderef(®s[REG_ECX]); 1691 if (node_regs_mask & (1<<3)) update_noderef(®s[REG_EDX]); 1692 if (node_regs_mask & (1<<4)) update_noderef(®s[REG_ESP]); 1693 if (node_regs_mask & (1<<5)) update_noderef(®s[REG_EBP]); 1694 if (node_regs_mask & (1<<6)) update_noderef(®s[REG_ESI]); 1695 if (node_regs_mask & (1<<7)) update_noderef(®s[REG_EDI]); 1696 1697 update_locref(&(regs[Iip])); 1698 } 1699 #endif 1401 1700 1402 1701 … … 1409 1708 xp = tcr->gc_context; 1410 1709 if (xp) { 1710 #ifdef X8664 1411 1711 forward_xp(xp); 1712 #else 1713 forward_xp(xp, tcr->node_regs_mask); 1714 1715 update_noderef(&tcr->save0); 1716 update_noderef(&tcr->save1); 1717 update_noderef(&tcr->save2); 1718 update_noderef(&tcr->save3); 1719 #endif 1412 1720 } 1413 1721 for (xframes = tcr->xframe; xframes; xframes = xframes->prev) { 1722 #ifdef X8664 1414 1723 forward_xp(xframes->curr); 1415 } 1416 } 1417 1418 1419 1724 #else 1725 forward_xp(xframes->curr, xframes->node_regs_mask); 1726 #endif 1727 } 1728 } 1729 1730 1731 #ifdef X8632 1732 void 1733 update_self_references(LispObj *node) 1734 { 1735 LispObj fn = fulltag_misc + (LispObj)node; 1736 unsigned char *p = (unsigned char *)node; 1737 natural i, offset; 1738 1739 i = ((unsigned short *)node)[2]; 1740 offset = node[--i]; 1741 while (offset) { 1742 *(LispObj *)(p + offset) = fn; 1743 offset = node[--i]; 1744 } 1745 } 1746 #endif 1420 1747 1421 1748 /* … … 1480 1807 dnode += node_dnodes; 1481 1808 if (header_subtag(node) == subtag_function) { 1809 #ifdef X8632 1810 int skip = *((unsigned short *)src); 1811 LispObj *f = dest; 1812 #else 1482 1813 int skip = *((int *)src); 1814 #endif 1483 1815 *dest++ = node; 1484 1816 elements -= skip; … … 1486 1818 *dest++ = *src++; 1487 1819 } 1820 #ifdef X8632 1821 update_self_references(f); 1822 #endif 1488 1823 while(elements--) { 1489 1824 *dest++ = node_forwarding_address(*src++); … … 1541 1876 tag = header_subtag(node); 1542 1877 1543 1878 #ifdef X8664 1544 1879 switch(fulltag_of(tag)) { 1545 1880 case ivector_class_64_bit: … … 1558 1893 } 1559 1894 } 1895 #endif 1896 #ifdef X8632 1897 if (tag <= max_32_bit_ivector_subtag) { 1898 imm_dnodes = (((elements+1)+1)>>1); 1899 } else if (tag <= max_8_bit_ivector_subtag) { 1900 imm_dnodes = (((elements+4)+7)>>3); 1901 } else if (tag <= max_16_bit_ivector_subtag) { 1902 imm_dnodes = (((elements+2)+3)>>2); 1903 } else if (tag == subtag_bit_vector) { 1904 imm_dnodes = (((elements+32)+63)>>6); 1905 } else { 1906 imm_dnodes = elements+1; 1907 } 1908 #endif 1909 1560 1910 dnode += imm_dnodes; 1561 1911 while (--imm_dnodes) { … … 1572 1922 } 1573 1923 } 1574 1575 } 1576 1924 } 1577 1925 } 1578 1926 return ptr_to_lispobj(dest); … … 1607 1955 subtag = header_subtag(header); 1608 1956 1957 #ifdef X8664 1609 1958 switch(fulltag_of(header)) { 1610 1959 case ivector_class_64_bit: … … 1624 1973 } 1625 1974 } 1975 #endif 1976 #ifdef X8632 1977 if (subtag <= max_32_bit_ivector_subtag) { 1978 bytes = 4 + (elements<<2); 1979 } else if (subtag <= max_8_bit_ivector_subtag) { 1980 bytes = 4 + elements; 1981 } else if (subtag <= max_16_bit_ivector_subtag) { 1982 bytes = 4 + (elements<<1); 1983 } else if (subtag == subtag_double_float_vector) { 1984 bytes = 8 + (elements<<3); 1985 } else { 1986 bytes = 4 + ((elements+7)>>3); 1987 } 1988 #endif 1989 1626 1990 bytes = (bytes+dnode_size-1) & ~(dnode_size-1); 1627 1991 total += bytes; … … 1785 2149 } else { 1786 2150 if (header_subtag(header) == subtag_function) { 2151 #ifdef X8632 2152 int skip = (unsigned short)(start[1]); 2153 #else 1787 2154 int skip = (int)(start[1]); 2155 #endif 1788 2156 start += skip; 1789 2157 nwords -= skip;
Note: See TracChangeset
for help on using the changeset viewer.