Changeset 15374
- Timestamp:
- May 23, 2012, 3:00:51 AM (13 years ago)
- Location:
- trunk/source/lisp-kernel
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/lisp-kernel/arm-gc.c
r15367 r15374 790 790 791 791 792 void 793 mark_memoized_area(area *a, natural num_memo_dnodes) 794 { 795 bitvector refbits = a->refbits; 796 LispObj *p = (LispObj *) a->low, x1, x2; 797 natural inbits, outbits, bits, bitidx, *bitsp, nextbit, diff, memo_dnode = 0; 798 Boolean keep_x1, keep_x2; 799 natural hash_dnode_limit = 0; 800 hash_table_vector_header *hashp = NULL; 801 int mark_method = 3; 802 803 if (num_memo_dnodes) { 804 if (GCDebug) { 805 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits); 806 } 807 808 /* The distinction between "inbits" and "outbits" is supposed to help us 809 detect cases where "uninteresting" setfs have been memoized. Storing 810 NIL, fixnums, immediates (characters, etc.) or node pointers to static 811 or readonly areas is definitely uninteresting, but other cases are 812 more complicated (and some of these cases are hard to detect.) 813 814 Some headers are "interesting", to the forwarder if not to us. 815 816 */ 817 818 /* 819 We need to ensure that there are no bits set at or beyond 820 "num_memo_dnodes" in the bitvector. (This can happen as the EGC 821 tenures/untenures things.) We find bits by grabbing a fullword at 822 a time and doing a cntlzw instruction; and don't want to have to 823 check for (< memo_dnode num_memo_dnodes) in the loop. 824 */ 825 826 { 827 natural 828 bits_in_last_word = (num_memo_dnodes & bitmap_shift_count_mask), 829 index_of_last_word = (num_memo_dnodes >> bitmap_shift); 830 831 if (bits_in_last_word != 0) { 832 natural mask = ~((1L<<(nbits_in_word-bits_in_last_word))-1L); 833 refbits[index_of_last_word] &= mask; 834 } 835 } 836 837 set_bitidx_vars(refbits, 0, bitsp, bits, bitidx); 838 inbits = outbits = bits; 839 while (memo_dnode < num_memo_dnodes) { 840 if (bits == 0) { 841 int remain = nbits_in_word - bitidx; 842 memo_dnode += remain; 843 p += (remain+remain); 844 if (outbits != inbits) { 845 *bitsp = outbits; 846 } 847 bits = *++bitsp; 848 inbits = outbits = bits; 849 bitidx = 0; 850 } else { 851 nextbit = count_leading_zeros(bits); 852 if ((diff = (nextbit - bitidx)) != 0) { 853 memo_dnode += diff; 854 bitidx = nextbit; 855 p += (diff+diff); 856 } 857 x1 = *p++; 858 x2 = *p++; 859 bits &= ~(BIT0_MASK >> bitidx); 860 861 if (hashp) { 862 Boolean force_x1 = false; 863 if ((memo_dnode >= hash_dnode_limit) && (mark_method == 3)) { 864 /* if vector_header_count is odd, x1 might be the last word of the header */ 865 force_x1 = (hash_table_vector_header_count & 1) && (memo_dnode == hash_dnode_limit); 866 /* was marking header, switch to data */ 867 hash_dnode_limit = area_dnode(((LispObj *)hashp) 868 + 1 869 + header_element_count(hashp->header), 870 a->low); 871 /* In traditional weak method, don't mark vector entries at all. */ 872 /* Otherwise mark the non-weak elements only */ 873 mark_method = ((lisp_global(WEAK_GC_METHOD) == 0) ? 0 : 874 ((hashp->flags & nhash_weak_value_mask) 875 ? (1 + (hash_table_vector_header_count & 1)) 876 : (2 - (hash_table_vector_header_count & 1)))); 877 } 878 879 if (memo_dnode < hash_dnode_limit) { 880 /* perhaps ignore one or both of the elements */ 881 if (!force_x1 && !(mark_method & 1)) x1 = 0; 882 if (!(mark_method & 2)) x2 = 0; 883 } else { 884 hashp = NULL; 885 } 886 } 887 888 if (header_subtag(x1) == subtag_hash_vector) { 889 if (hashp) Bug(NULL, "header inside hash vector?"); 890 hash_table_vector_header *hp = (hash_table_vector_header *)(p - 2); 891 if (hp->flags & nhash_weak_mask) { 892 /* Workaround for ticket:817 */ 893 if (!(hp->flags & nhash_weak_value_mask)) { 894 /* If header_count is odd, this cuts off the last header field */ 895 /* That case is handled specially above */ 896 hash_dnode_limit = memo_dnode + ((hash_table_vector_header_count) >>1); 897 hashp = hp; 898 mark_method = 3; 899 } 900 } 901 } 902 903 keep_x1 = mark_ephemeral_root(x1); 904 keep_x2 = mark_ephemeral_root(x2); 905 if ((keep_x1 == false) && 906 (keep_x2 == false) && 907 (hashp == NULL)) { 908 outbits &= ~(BIT0_MASK >> bitidx); 909 } 910 memo_dnode++; 911 bitidx++; 912 } 913 } 914 if (GCDebug) { 915 p = (LispObj *) a->low; 916 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits); 917 } 918 } 919 } 792 920 793 921 794 -
trunk/source/lisp-kernel/gc-common.c
r15366 r15374 1354 1354 } 1355 1355 1356 void 1357 mark_memoized_area(area *a, natural num_memo_dnodes) 1358 { 1359 bitvector refbits = a->refbits; 1360 LispObj *p = (LispObj *) a->low, x1, x2; 1361 natural inbits, outbits, bits, bitidx, *bitsp, nextbit, diff, memo_dnode = 0; 1362 Boolean keep_x1, keep_x2; 1363 natural hash_dnode_limit = 0; 1364 hash_table_vector_header *hashp = NULL; 1365 int mark_method = 3; 1366 1367 if (num_memo_dnodes) { 1368 if (GCDebug) { 1369 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits); 1370 } 1371 1372 /* The distinction between "inbits" and "outbits" is supposed to help us 1373 detect cases where "uninteresting" setfs have been memoized. Storing 1374 NIL, fixnums, immediates (characters, etc.) or node pointers to static 1375 or readonly areas is definitely uninteresting, but other cases are 1376 more complicated (and some of these cases are hard to detect.) 1377 1378 Some headers are "interesting", to the forwarder if not to us. 1379 1380 */ 1381 1382 /* 1383 We need to ensure that there are no bits set at or beyond 1384 "num_memo_dnodes" in the bitvector. (This can happen as the EGC 1385 tenures/untenures things.) We find bits by grabbing a fullword at 1386 a time and doing a cntlzw instruction; and don't want to have to 1387 check for (< memo_dnode num_memo_dnodes) in the loop. 1388 */ 1389 1390 { 1391 natural 1392 bits_in_last_word = (num_memo_dnodes & bitmap_shift_count_mask), 1393 index_of_last_word = (num_memo_dnodes >> bitmap_shift); 1394 1395 if (bits_in_last_word != 0) { 1396 natural mask = ~((NATURAL1<<(nbits_in_word-bits_in_last_word))- NATURAL1); 1397 refbits[index_of_last_word] &= mask; 1398 } 1399 } 1400 1401 set_bitidx_vars(refbits, 0, bitsp, bits, bitidx); 1402 inbits = outbits = bits; 1403 while (memo_dnode < num_memo_dnodes) { 1404 if (bits == 0) { 1405 int remain = nbits_in_word - bitidx; 1406 memo_dnode += remain; 1407 p += (remain+remain); 1408 if (outbits != inbits) { 1409 *bitsp = outbits; 1410 } 1411 if (memo_dnode < num_memo_dnodes) { 1412 bits = *++bitsp; 1413 } 1414 inbits = outbits = bits; 1415 bitidx = 0; 1416 } else { 1417 nextbit = count_leading_zeros(bits); 1418 if ((diff = (nextbit - bitidx)) != 0) { 1419 memo_dnode += diff; 1420 bitidx = nextbit; 1421 p += (diff+diff); 1422 } 1423 x1 = *p++; 1424 x2 = *p++; 1425 bits &= ~(BIT0_MASK >> bitidx); 1426 1427 1428 if (hashp) { 1429 Boolean force_x1 = false; 1430 if ((memo_dnode >= hash_dnode_limit) && (mark_method == 3)) { 1431 /* if vector_header_count is odd, x1 might be the last word of the header */ 1432 force_x1 = (hash_table_vector_header_count & 1) && (memo_dnode == hash_dnode_limit); 1433 /* was marking header, switch to data */ 1434 hash_dnode_limit = area_dnode(((LispObj *)hashp) 1435 + 1 1436 + header_element_count(hashp->header), 1437 a->low); 1438 /* In traditional weak method, don't mark vector entries at all. */ 1439 /* Otherwise mark the non-weak elements only */ 1440 mark_method = ((lisp_global(WEAK_GC_METHOD) == 0) ? 0 : 1441 ((hashp->flags & nhash_weak_value_mask) 1442 ? (1 + (hash_table_vector_header_count & 1)) 1443 : (2 - (hash_table_vector_header_count & 1)))); 1444 } 1445 1446 if (memo_dnode < hash_dnode_limit) { 1447 /* perhaps ignore one or both of the elements */ 1448 if (!force_x1 && !(mark_method & 1)) x1 = 0; 1449 if (!(mark_method & 2)) x2 = 0; 1450 } else { 1451 hashp = NULL; 1452 } 1453 } 1454 1455 if (header_subtag(x1) == subtag_hash_vector) { 1456 if (hashp) Bug(NULL, "header inside hash vector?"); 1457 hash_table_vector_header *hp = (hash_table_vector_header *)(p - 2); 1458 if (hp->flags & nhash_weak_mask) { 1459 /* Work around the issue that seems to cause ticket:817, 1460 which is that tenured hash vectors that are weak on value 1461 aren't always maintained on GCweakvll. If they aren't and 1462 we process them weakly here, nothing will delete the unreferenced 1463 elements. */ 1464 if (!(hp->flags & nhash_weak_value_mask)) { 1465 /* If header_count is odd, this cuts off the last header field */ 1466 /* That case is handled specially above */ 1467 hash_dnode_limit = memo_dnode + ((hash_table_vector_header_count) >>1); 1468 hashp = hp; 1469 mark_method = 3; 1470 } 1471 } 1472 } 1473 1474 keep_x1 = mark_ephemeral_root(x1); 1475 keep_x2 = mark_ephemeral_root(x2); 1476 if ((keep_x1 == false) && 1477 (keep_x2 == false) && 1478 (hashp == NULL)) { 1479 outbits &= ~(BIT0_MASK >> bitidx); 1480 } 1481 memo_dnode++; 1482 bitidx++; 1483 } 1484 } 1485 if (GCDebug) { 1486 p = (LispObj *) a->low; 1487 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits); 1488 } 1489 } 1490 } 1491 1356 1492 extern void zero_dnodes(void *,natural); 1357 1493 -
trunk/source/lisp-kernel/ppc-gc.c
r14723 r15374 906 906 907 907 908 void909 mark_memoized_area(area *a, natural num_memo_dnodes)910 {911 bitvector refbits = a->refbits;912 LispObj *p = (LispObj *) a->low, x1, x2;913 natural inbits, outbits, bits, bitidx, *bitsp, nextbit, diff, memo_dnode = 0;914 Boolean keep_x1, keep_x2;915 natural hash_dnode_limit = 0;916 hash_table_vector_header *hashp = NULL;917 int mark_method = 3;918 919 if (GCDebug) {920 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits);921 }922 923 /* The distinction between "inbits" and "outbits" is supposed to help us924 detect cases where "uninteresting" setfs have been memoized. Storing925 NIL, fixnums, immediates (characters, etc.) or node pointers to static926 or readonly areas is definitely uninteresting, but other cases are927 more complicated (and some of these cases are hard to detect.)928 929 Some headers are "interesting", to the forwarder if not to us.930 931 */932 933 /*934 We need to ensure that there are no bits set at or beyond935 "num_memo_dnodes" in the bitvector. (This can happen as the EGC936 tenures/untenures things.) We find bits by grabbing a fullword at937 a time and doing a cntlzw instruction; and don't want to have to938 check for (< memo_dnode num_memo_dnodes) in the loop.939 */940 941 {942 natural943 bits_in_last_word = (num_memo_dnodes & bitmap_shift_count_mask),944 index_of_last_word = (num_memo_dnodes >> bitmap_shift);945 946 if (bits_in_last_word != 0) {947 natural mask = ~((1L<<(nbits_in_word-bits_in_last_word))-1L);948 refbits[index_of_last_word] &= mask;949 }950 }951 952 set_bitidx_vars(refbits, 0, bitsp, bits, bitidx);953 inbits = outbits = bits;954 while (memo_dnode < num_memo_dnodes) {955 if (bits == 0) {956 int remain = nbits_in_word - bitidx;957 memo_dnode += remain;958 p += (remain+remain);959 if (outbits != inbits) {960 *bitsp = outbits;961 }962 bits = *++bitsp;963 inbits = outbits = bits;964 bitidx = 0;965 } else {966 nextbit = count_leading_zeros(bits);967 if ((diff = (nextbit - bitidx)) != 0) {968 memo_dnode += diff;969 bitidx = nextbit;970 p += (diff+diff);971 }972 x1 = *p++;973 x2 = *p++;974 bits &= ~(BIT0_MASK >> bitidx);975 976 if (hashp) {977 Boolean force_x1 = false;978 if ((memo_dnode >= hash_dnode_limit) && (mark_method == 3)) {979 /* if vector_header_count is odd, x1 might be the last word of the header */980 force_x1 = (hash_table_vector_header_count & 1) && (memo_dnode == hash_dnode_limit);981 /* was marking header, switch to data */982 hash_dnode_limit = area_dnode(((LispObj *)hashp)983 + 1984 + header_element_count(hashp->header),985 a->low);986 /* In traditional weak method, don't mark vector entries at all. */987 /* Otherwise mark the non-weak elements only */988 mark_method = ((lisp_global(WEAK_GC_METHOD) == 0) ? 0 :989 ((hashp->flags & nhash_weak_value_mask)990 ? (1 + (hash_table_vector_header_count & 1))991 : (2 - (hash_table_vector_header_count & 1))));992 }993 994 if (memo_dnode < hash_dnode_limit) {995 /* perhaps ignore one or both of the elements */996 if (!force_x1 && !(mark_method & 1)) x1 = 0;997 if (!(mark_method & 2)) x2 = 0;998 } else {999 hashp = NULL;1000 }1001 }1002 1003 if (header_subtag(x1) == subtag_hash_vector) {1004 if (hashp) Bug(NULL, "header inside hash vector?");1005 hash_table_vector_header *hp = (hash_table_vector_header *)(p - 2);1006 /* Workaround for ticket:817 */1007 if (!(hp->flags & nhash_weak_value_mask)) {1008 if (hp->flags & nhash_weak_mask) {1009 /* If header_count is odd, this cuts off the last header field */1010 /* That case is handled specially above */1011 hash_dnode_limit = memo_dnode + ((hash_table_vector_header_count) >>1);1012 hashp = hp;1013 mark_method = 3;1014 }1015 }1016 }1017 1018 keep_x1 = mark_ephemeral_root(x1);1019 keep_x2 = mark_ephemeral_root(x2);1020 if ((keep_x1 == false) &&1021 (keep_x2 == false) &&1022 (hashp == NULL)) {1023 outbits &= ~(BIT0_MASK >> bitidx);1024 }1025 memo_dnode++;1026 bitidx++;1027 }1028 }1029 if (GCDebug) {1030 p = (LispObj *) a->low;1031 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits);1032 }1033 }1034 908 1035 909 -
trunk/source/lisp-kernel/x86-gc.c
r15368 r15374 1234 1234 1235 1235 1236 void 1237 mark_memoized_area(area *a, natural num_memo_dnodes) 1238 { 1239 bitvector refbits = a->refbits; 1240 LispObj *p = (LispObj *) a->low, x1, x2; 1241 natural inbits, outbits, bits, bitidx, *bitsp, nextbit, diff, memo_dnode = 0; 1242 Boolean keep_x1, keep_x2; 1243 natural hash_dnode_limit = 0; 1244 hash_table_vector_header *hashp = NULL; 1245 int mark_method = 3; 1246 1247 if (num_memo_dnodes) { 1248 if (GCDebug) { 1249 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits); 1250 } 1251 1252 /* The distinction between "inbits" and "outbits" is supposed to help us 1253 detect cases where "uninteresting" setfs have been memoized. Storing 1254 NIL, fixnums, immediates (characters, etc.) or node pointers to static 1255 or readonly areas is definitely uninteresting, but other cases are 1256 more complicated (and some of these cases are hard to detect.) 1257 1258 Some headers are "interesting", to the forwarder if not to us. 1259 1260 */ 1261 1262 /* 1263 We need to ensure that there are no bits set at or beyond 1264 "num_memo_dnodes" in the bitvector. (This can happen as the EGC 1265 tenures/untenures things.) We find bits by grabbing a fullword at 1266 a time and doing a cntlzw instruction; and don't want to have to 1267 check for (< memo_dnode num_memo_dnodes) in the loop. 1268 */ 1269 1270 { 1271 natural 1272 bits_in_last_word = (num_memo_dnodes & bitmap_shift_count_mask), 1273 index_of_last_word = (num_memo_dnodes >> bitmap_shift); 1274 1275 if (bits_in_last_word != 0) { 1276 natural mask = ~((NATURAL1<<(nbits_in_word-bits_in_last_word))- NATURAL1); 1277 refbits[index_of_last_word] &= mask; 1278 } 1279 } 1280 1281 set_bitidx_vars(refbits, 0, bitsp, bits, bitidx); 1282 inbits = outbits = bits; 1283 while (memo_dnode < num_memo_dnodes) { 1284 if (bits == 0) { 1285 int remain = nbits_in_word - bitidx; 1286 memo_dnode += remain; 1287 p += (remain+remain); 1288 if (outbits != inbits) { 1289 *bitsp = outbits; 1290 } 1291 bits = *++bitsp; 1292 inbits = outbits = bits; 1293 bitidx = 0; 1294 } else { 1295 nextbit = count_leading_zeros(bits); 1296 if ((diff = (nextbit - bitidx)) != 0) { 1297 memo_dnode += diff; 1298 bitidx = nextbit; 1299 p += (diff+diff); 1300 } 1301 x1 = *p++; 1302 x2 = *p++; 1303 bits &= ~(BIT0_MASK >> bitidx); 1304 1305 1306 if (hashp) { 1307 Boolean force_x1 = false; 1308 if ((memo_dnode >= hash_dnode_limit) && (mark_method == 3)) { 1309 /* if vector_header_count is odd, x1 might be the last word of the header */ 1310 force_x1 = (hash_table_vector_header_count & 1) && (memo_dnode == hash_dnode_limit); 1311 /* was marking header, switch to data */ 1312 hash_dnode_limit = area_dnode(((LispObj *)hashp) 1313 + 1 1314 + header_element_count(hashp->header), 1315 a->low); 1316 /* In traditional weak method, don't mark vector entries at all. */ 1317 /* Otherwise mark the non-weak elements only */ 1318 mark_method = ((lisp_global(WEAK_GC_METHOD) == 0) ? 0 : 1319 ((hashp->flags & nhash_weak_value_mask) 1320 ? (1 + (hash_table_vector_header_count & 1)) 1321 : (2 - (hash_table_vector_header_count & 1)))); 1322 } 1323 1324 if (memo_dnode < hash_dnode_limit) { 1325 /* perhaps ignore one or both of the elements */ 1326 if (!force_x1 && !(mark_method & 1)) x1 = 0; 1327 if (!(mark_method & 2)) x2 = 0; 1328 } else { 1329 hashp = NULL; 1330 } 1331 } 1332 1333 if (header_subtag(x1) == subtag_hash_vector) { 1334 if (hashp) Bug(NULL, "header inside hash vector?"); 1335 hash_table_vector_header *hp = (hash_table_vector_header *)(p - 2); 1336 if (hp->flags & nhash_weak_mask) { 1337 /* Work around the issue that seems to cause ticket:817, 1338 which is that tenured hash vectors that are weak on value 1339 aren't always maintained on GCweakvll. If they aren't and 1340 we process them weakly here, nothing will delete the unreferenced 1341 elements. */ 1342 if (!(hp->flags & nhash_weak_value_mask)) { 1343 /* If header_count is odd, this cuts off the last header field */ 1344 /* That case is handled specially above */ 1345 hash_dnode_limit = memo_dnode + ((hash_table_vector_header_count) >>1); 1346 hashp = hp; 1347 mark_method = 3; 1348 1349 1350 1351 1352 1353 } 1354 } 1355 } 1356 1357 keep_x1 = mark_ephemeral_root(x1); 1358 keep_x2 = mark_ephemeral_root(x2); 1359 if ((keep_x1 == false) && 1360 (keep_x2 == false) && 1361 (hashp == NULL)) { 1362 outbits &= ~(BIT0_MASK >> bitidx); 1363 } 1364 memo_dnode++; 1365 bitidx++; 1366 } 1367 } 1368 if (GCDebug) { 1369 p = (LispObj *) a->low; 1370 check_refmap_consistency(p, p+(num_memo_dnodes << 1), refbits); 1371 } 1372 } 1373 } 1236 1374 1237 1375 1238 void
Note:
See TracChangeset
for help on using the changeset viewer.
