diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 168 |
1 files changed, 101 insertions, 67 deletions
diff --git a/src/alloc.c b/src/alloc.c index f57e22d9cc0..b35f7c4333f 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -1280,28 +1280,32 @@ mark_interval (register INTERVAL i, Lisp_Object dummy) | |||
| 1280 | 1280 | ||
| 1281 | #define LARGE_STRING_BYTES 1024 | 1281 | #define LARGE_STRING_BYTES 1024 |
| 1282 | 1282 | ||
| 1283 | /* Struct or union describing string memory sub-allocated from an sblock. | 1283 | /* The SDATA typedef is a struct or union describing string memory |
| 1284 | This is where the contents of Lisp strings are stored. */ | 1284 | sub-allocated from an sblock. This is where the contents of Lisp |
| 1285 | strings are stored. */ | ||
| 1285 | 1286 | ||
| 1286 | #ifdef GC_CHECK_STRING_BYTES | 1287 | struct sdata |
| 1287 | |||
| 1288 | typedef struct | ||
| 1289 | { | 1288 | { |
| 1290 | /* Back-pointer to the string this sdata belongs to. If null, this | 1289 | /* Back-pointer to the string this sdata belongs to. If null, this |
| 1291 | structure is free, and the NBYTES member of the union below | 1290 | structure is free, and NBYTES (in this structure or in the union below) |
| 1292 | contains the string's byte size (the same value that STRING_BYTES | 1291 | contains the string's byte size (the same value that STRING_BYTES |
| 1293 | would return if STRING were non-null). If non-null, STRING_BYTES | 1292 | would return if STRING were non-null). If non-null, STRING_BYTES |
| 1294 | (STRING) is the size of the data, and DATA contains the string's | 1293 | (STRING) is the size of the data, and DATA contains the string's |
| 1295 | contents. */ | 1294 | contents. */ |
| 1296 | struct Lisp_String *string; | 1295 | struct Lisp_String *string; |
| 1297 | 1296 | ||
| 1297 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1298 | ptrdiff_t nbytes; | 1298 | ptrdiff_t nbytes; |
| 1299 | #endif | ||
| 1300 | |||
| 1299 | unsigned char data[FLEXIBLE_ARRAY_MEMBER]; | 1301 | unsigned char data[FLEXIBLE_ARRAY_MEMBER]; |
| 1300 | } sdata; | 1302 | }; |
| 1303 | |||
| 1304 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1301 | 1305 | ||
| 1306 | typedef struct sdata sdata; | ||
| 1302 | #define SDATA_NBYTES(S) (S)->nbytes | 1307 | #define SDATA_NBYTES(S) (S)->nbytes |
| 1303 | #define SDATA_DATA(S) (S)->data | 1308 | #define SDATA_DATA(S) (S)->data |
| 1304 | #define SDATA_SELECTOR(member) member | ||
| 1305 | 1309 | ||
| 1306 | #else | 1310 | #else |
| 1307 | 1311 | ||
| @@ -1309,12 +1313,16 @@ typedef union | |||
| 1309 | { | 1313 | { |
| 1310 | struct Lisp_String *string; | 1314 | struct Lisp_String *string; |
| 1311 | 1315 | ||
| 1312 | /* When STRING is non-null. */ | 1316 | /* When STRING is nonnull, this union is actually of type 'struct sdata', |
| 1313 | struct | 1317 | which has a flexible array member. However, if implemented by |
| 1314 | { | 1318 | giving this union a member of type 'struct sdata', the union |
| 1315 | struct Lisp_String *string; | 1319 | could not be the last (flexible) member of 'struct sblock', |
| 1316 | unsigned char data[FLEXIBLE_ARRAY_MEMBER]; | 1320 | because C99 prohibits a flexible array member from having a type |
| 1317 | } u; | 1321 | that is itself a flexible array. So, comment this member out here, |
| 1322 | but remember that the option's there when using this union. */ | ||
| 1323 | #if 0 | ||
| 1324 | struct sdata u; | ||
| 1325 | #endif | ||
| 1318 | 1326 | ||
| 1319 | /* When STRING is null. */ | 1327 | /* When STRING is null. */ |
| 1320 | struct | 1328 | struct |
| @@ -1325,13 +1333,11 @@ typedef union | |||
| 1325 | } sdata; | 1333 | } sdata; |
| 1326 | 1334 | ||
| 1327 | #define SDATA_NBYTES(S) (S)->n.nbytes | 1335 | #define SDATA_NBYTES(S) (S)->n.nbytes |
| 1328 | #define SDATA_DATA(S) (S)->u.data | 1336 | #define SDATA_DATA(S) ((struct sdata *) (S))->data |
| 1329 | #define SDATA_SELECTOR(member) u.member | ||
| 1330 | 1337 | ||
| 1331 | #endif /* not GC_CHECK_STRING_BYTES */ | 1338 | #endif /* not GC_CHECK_STRING_BYTES */ |
| 1332 | 1339 | ||
| 1333 | #define SDATA_DATA_OFFSET offsetof (sdata, SDATA_SELECTOR (data)) | 1340 | enum { SDATA_DATA_OFFSET = offsetof (struct sdata, data) }; |
| 1334 | |||
| 1335 | 1341 | ||
| 1336 | /* Structure describing a block of memory which is sub-allocated to | 1342 | /* Structure describing a block of memory which is sub-allocated to |
| 1337 | obtain string data memory for strings. Blocks for small strings | 1343 | obtain string data memory for strings. Blocks for small strings |
| @@ -1347,8 +1353,8 @@ struct sblock | |||
| 1347 | of the sblock if there isn't any space left in this block. */ | 1353 | of the sblock if there isn't any space left in this block. */ |
| 1348 | sdata *next_free; | 1354 | sdata *next_free; |
| 1349 | 1355 | ||
| 1350 | /* Start of data. */ | 1356 | /* String data. */ |
| 1351 | sdata first_data; | 1357 | sdata data[FLEXIBLE_ARRAY_MEMBER]; |
| 1352 | }; | 1358 | }; |
| 1353 | 1359 | ||
| 1354 | /* Number of Lisp strings in a string_block structure. The 1020 is | 1360 | /* Number of Lisp strings in a string_block structure. The 1020 is |
| @@ -1464,7 +1470,7 @@ static ptrdiff_t const STRING_BYTES_MAX = | |||
| 1464 | min (STRING_BYTES_BOUND, | 1470 | min (STRING_BYTES_BOUND, |
| 1465 | ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD | 1471 | ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD |
| 1466 | - GC_STRING_EXTRA | 1472 | - GC_STRING_EXTRA |
| 1467 | - offsetof (struct sblock, first_data) | 1473 | - offsetof (struct sblock, data) |
| 1468 | - SDATA_DATA_OFFSET) | 1474 | - SDATA_DATA_OFFSET) |
| 1469 | & ~(sizeof (EMACS_INT) - 1))); | 1475 | & ~(sizeof (EMACS_INT) - 1))); |
| 1470 | 1476 | ||
| @@ -1507,7 +1513,7 @@ check_sblock (struct sblock *b) | |||
| 1507 | 1513 | ||
| 1508 | end = b->next_free; | 1514 | end = b->next_free; |
| 1509 | 1515 | ||
| 1510 | for (from = &b->first_data; from < end; from = from_end) | 1516 | for (from = b->data; from < end; from = from_end) |
| 1511 | { | 1517 | { |
| 1512 | /* Compute the next FROM here because copying below may | 1518 | /* Compute the next FROM here because copying below may |
| 1513 | overwrite data we need to compute it. */ | 1519 | overwrite data we need to compute it. */ |
| @@ -1535,7 +1541,7 @@ check_string_bytes (bool all_p) | |||
| 1535 | 1541 | ||
| 1536 | for (b = large_sblocks; b; b = b->next) | 1542 | for (b = large_sblocks; b; b = b->next) |
| 1537 | { | 1543 | { |
| 1538 | struct Lisp_String *s = b->first_data.string; | 1544 | struct Lisp_String *s = b->data[0].string; |
| 1539 | if (s) | 1545 | if (s) |
| 1540 | string_bytes (s); | 1546 | string_bytes (s); |
| 1541 | } | 1547 | } |
| @@ -1669,7 +1675,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1669 | 1675 | ||
| 1670 | if (nbytes > LARGE_STRING_BYTES) | 1676 | if (nbytes > LARGE_STRING_BYTES) |
| 1671 | { | 1677 | { |
| 1672 | size_t size = offsetof (struct sblock, first_data) + needed; | 1678 | size_t size = offsetof (struct sblock, data) + needed; |
| 1673 | 1679 | ||
| 1674 | #ifdef DOUG_LEA_MALLOC | 1680 | #ifdef DOUG_LEA_MALLOC |
| 1675 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed | 1681 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed |
| @@ -1691,8 +1697,8 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1691 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 1697 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 1692 | #endif | 1698 | #endif |
| 1693 | 1699 | ||
| 1694 | b->next_free = &b->first_data; | 1700 | b->next_free = b->data; |
| 1695 | b->first_data.string = NULL; | 1701 | b->data[0].string = NULL; |
| 1696 | b->next = large_sblocks; | 1702 | b->next = large_sblocks; |
| 1697 | large_sblocks = b; | 1703 | large_sblocks = b; |
| 1698 | } | 1704 | } |
| @@ -1703,8 +1709,8 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1703 | { | 1709 | { |
| 1704 | /* Not enough room in the current sblock. */ | 1710 | /* Not enough room in the current sblock. */ |
| 1705 | b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP); | 1711 | b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP); |
| 1706 | b->next_free = &b->first_data; | 1712 | b->next_free = b->data; |
| 1707 | b->first_data.string = NULL; | 1713 | b->data[0].string = NULL; |
| 1708 | b->next = NULL; | 1714 | b->next = NULL; |
| 1709 | 1715 | ||
| 1710 | if (current_sblock) | 1716 | if (current_sblock) |
| @@ -1858,7 +1864,7 @@ free_large_strings (void) | |||
| 1858 | { | 1864 | { |
| 1859 | next = b->next; | 1865 | next = b->next; |
| 1860 | 1866 | ||
| 1861 | if (b->first_data.string == NULL) | 1867 | if (b->data[0].string == NULL) |
| 1862 | lisp_free (b); | 1868 | lisp_free (b); |
| 1863 | else | 1869 | else |
| 1864 | { | 1870 | { |
| @@ -1885,7 +1891,7 @@ compact_small_strings (void) | |||
| 1885 | to, and TB_END is the end of TB. */ | 1891 | to, and TB_END is the end of TB. */ |
| 1886 | tb = oldest_sblock; | 1892 | tb = oldest_sblock; |
| 1887 | tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); | 1893 | tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); |
| 1888 | to = &tb->first_data; | 1894 | to = tb->data; |
| 1889 | 1895 | ||
| 1890 | /* Step through the blocks from the oldest to the youngest. We | 1896 | /* Step through the blocks from the oldest to the youngest. We |
| 1891 | expect that old blocks will stabilize over time, so that less | 1897 | expect that old blocks will stabilize over time, so that less |
| @@ -1895,7 +1901,7 @@ compact_small_strings (void) | |||
| 1895 | end = b->next_free; | 1901 | end = b->next_free; |
| 1896 | eassert ((char *) end <= (char *) b + SBLOCK_SIZE); | 1902 | eassert ((char *) end <= (char *) b + SBLOCK_SIZE); |
| 1897 | 1903 | ||
| 1898 | for (from = &b->first_data; from < end; from = from_end) | 1904 | for (from = b->data; from < end; from = from_end) |
| 1899 | { | 1905 | { |
| 1900 | /* Compute the next FROM here because copying below may | 1906 | /* Compute the next FROM here because copying below may |
| 1901 | overwrite data we need to compute it. */ | 1907 | overwrite data we need to compute it. */ |
| @@ -1932,7 +1938,7 @@ compact_small_strings (void) | |||
| 1932 | tb->next_free = to; | 1938 | tb->next_free = to; |
| 1933 | tb = tb->next; | 1939 | tb = tb->next; |
| 1934 | tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); | 1940 | tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); |
| 1935 | to = &tb->first_data; | 1941 | to = tb->data; |
| 1936 | to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); | 1942 | to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); |
| 1937 | } | 1943 | } |
| 1938 | 1944 | ||
| @@ -2606,16 +2612,35 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |||
| 2606 | Vector Allocation | 2612 | Vector Allocation |
| 2607 | ***********************************************************************/ | 2613 | ***********************************************************************/ |
| 2608 | 2614 | ||
| 2615 | /* Sometimes a vector's contents are merely a pointer internally used | ||
| 2616 | in vector allocation code. Usually you don't want to touch this. */ | ||
| 2617 | |||
| 2618 | static struct Lisp_Vector * | ||
| 2619 | next_vector (struct Lisp_Vector *v) | ||
| 2620 | { | ||
| 2621 | return XUNTAG (v->contents[0], 0); | ||
| 2622 | } | ||
| 2623 | |||
| 2624 | static void | ||
| 2625 | set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p) | ||
| 2626 | { | ||
| 2627 | v->contents[0] = make_lisp_ptr (p, 0); | ||
| 2628 | } | ||
| 2629 | |||
| 2609 | /* This value is balanced well enough to avoid too much internal overhead | 2630 | /* This value is balanced well enough to avoid too much internal overhead |
| 2610 | for the most common cases; it's not required to be a power of two, but | 2631 | for the most common cases; it's not required to be a power of two, but |
| 2611 | it's expected to be a mult-of-ROUNDUP_SIZE (see below). */ | 2632 | it's expected to be a mult-of-ROUNDUP_SIZE (see below). */ |
| 2612 | 2633 | ||
| 2613 | #define VECTOR_BLOCK_SIZE 4096 | 2634 | #define VECTOR_BLOCK_SIZE 4096 |
| 2614 | 2635 | ||
| 2615 | /* Align allocation request sizes to be a multiple of ROUNDUP_SIZE. */ | ||
| 2616 | enum | 2636 | enum |
| 2617 | { | 2637 | { |
| 2618 | roundup_size = COMMON_MULTIPLE (word_size, USE_LSB_TAG ? GCALIGNMENT : 1) | 2638 | /* Alignment of struct Lisp_Vector objects. */ |
| 2639 | vector_alignment = COMMON_MULTIPLE (ALIGNOF_STRUCT_LISP_VECTOR, | ||
| 2640 | USE_LSB_TAG ? GCALIGNMENT : 1), | ||
| 2641 | |||
| 2642 | /* Vector size requests are a multiple of this. */ | ||
| 2643 | roundup_size = COMMON_MULTIPLE (vector_alignment, word_size) | ||
| 2619 | }; | 2644 | }; |
| 2620 | 2645 | ||
| 2621 | /* Verify assumptions described above. */ | 2646 | /* Verify assumptions described above. */ |
| @@ -2663,26 +2688,37 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); | |||
| 2663 | eassert ((nbytes) % roundup_size == 0); \ | 2688 | eassert ((nbytes) % roundup_size == 0); \ |
| 2664 | (tmp) = VINDEX (nbytes); \ | 2689 | (tmp) = VINDEX (nbytes); \ |
| 2665 | eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ | 2690 | eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ |
| 2666 | v->u.next = vector_free_lists[tmp]; \ | 2691 | set_next_vector (v, vector_free_lists[tmp]); \ |
| 2667 | vector_free_lists[tmp] = (v); \ | 2692 | vector_free_lists[tmp] = (v); \ |
| 2668 | total_free_vector_slots += (nbytes) / word_size; \ | 2693 | total_free_vector_slots += (nbytes) / word_size; \ |
| 2669 | } while (0) | 2694 | } while (0) |
| 2670 | 2695 | ||
| 2671 | /* This internal type is used to maintain the list of large vectors | 2696 | /* This internal type is used to maintain the list of large vectors |
| 2672 | which are allocated at their own, e.g. outside of vector blocks. */ | 2697 | which are allocated at their own, e.g. outside of vector blocks. |
| 2698 | |||
| 2699 | struct large_vector itself cannot contain a struct Lisp_Vector, as | ||
| 2700 | the latter contains a flexible array member and C99 does not allow | ||
| 2701 | such structs to be nested. Instead, each struct large_vector | ||
| 2702 | object LV is followed by a struct Lisp_Vector, which is at offset | ||
| 2703 | large_vector_offset from LV, and whose address is therefore | ||
| 2704 | large_vector_vec (&LV). */ | ||
| 2673 | 2705 | ||
| 2674 | struct large_vector | 2706 | struct large_vector |
| 2675 | { | 2707 | { |
| 2676 | union { | 2708 | struct large_vector *next; |
| 2677 | struct large_vector *vector; | ||
| 2678 | #if USE_LSB_TAG | ||
| 2679 | /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */ | ||
| 2680 | unsigned char c[vroundup_ct (sizeof (struct large_vector *))]; | ||
| 2681 | #endif | ||
| 2682 | } next; | ||
| 2683 | struct Lisp_Vector v; | ||
| 2684 | }; | 2709 | }; |
| 2685 | 2710 | ||
| 2711 | enum | ||
| 2712 | { | ||
| 2713 | large_vector_offset = ROUNDUP (sizeof (struct large_vector), vector_alignment) | ||
| 2714 | }; | ||
| 2715 | |||
| 2716 | static struct Lisp_Vector * | ||
| 2717 | large_vector_vec (struct large_vector *p) | ||
| 2718 | { | ||
| 2719 | return (struct Lisp_Vector *) ((char *) p + large_vector_offset); | ||
| 2720 | } | ||
| 2721 | |||
| 2686 | /* This internal type is used to maintain an underlying storage | 2722 | /* This internal type is used to maintain an underlying storage |
| 2687 | for small vectors. */ | 2723 | for small vectors. */ |
| 2688 | 2724 | ||
| @@ -2760,7 +2796,7 @@ allocate_vector_from_block (size_t nbytes) | |||
| 2760 | if (vector_free_lists[index]) | 2796 | if (vector_free_lists[index]) |
| 2761 | { | 2797 | { |
| 2762 | vector = vector_free_lists[index]; | 2798 | vector = vector_free_lists[index]; |
| 2763 | vector_free_lists[index] = vector->u.next; | 2799 | vector_free_lists[index] = next_vector (vector); |
| 2764 | total_free_vector_slots -= nbytes / word_size; | 2800 | total_free_vector_slots -= nbytes / word_size; |
| 2765 | return vector; | 2801 | return vector; |
| 2766 | } | 2802 | } |
| @@ -2774,7 +2810,7 @@ allocate_vector_from_block (size_t nbytes) | |||
| 2774 | { | 2810 | { |
| 2775 | /* This vector is larger than requested. */ | 2811 | /* This vector is larger than requested. */ |
| 2776 | vector = vector_free_lists[index]; | 2812 | vector = vector_free_lists[index]; |
| 2777 | vector_free_lists[index] = vector->u.next; | 2813 | vector_free_lists[index] = next_vector (vector); |
| 2778 | total_free_vector_slots -= nbytes / word_size; | 2814 | total_free_vector_slots -= nbytes / word_size; |
| 2779 | 2815 | ||
| 2780 | /* Excess bytes are used for the smaller vector, | 2816 | /* Excess bytes are used for the smaller vector, |
| @@ -2933,7 +2969,7 @@ sweep_vectors (void) | |||
| 2933 | 2969 | ||
| 2934 | for (lv = large_vectors; lv; lv = *lvprev) | 2970 | for (lv = large_vectors; lv; lv = *lvprev) |
| 2935 | { | 2971 | { |
| 2936 | vector = &lv->v; | 2972 | vector = large_vector_vec (lv); |
| 2937 | if (VECTOR_MARKED_P (vector)) | 2973 | if (VECTOR_MARKED_P (vector)) |
| 2938 | { | 2974 | { |
| 2939 | VECTOR_UNMARK (vector); | 2975 | VECTOR_UNMARK (vector); |
| @@ -2949,11 +2985,11 @@ sweep_vectors (void) | |||
| 2949 | else | 2985 | else |
| 2950 | total_vector_slots | 2986 | total_vector_slots |
| 2951 | += header_size / word_size + vector->header.size; | 2987 | += header_size / word_size + vector->header.size; |
| 2952 | lvprev = &lv->next.vector; | 2988 | lvprev = &lv->next; |
| 2953 | } | 2989 | } |
| 2954 | else | 2990 | else |
| 2955 | { | 2991 | { |
| 2956 | *lvprev = lv->next.vector; | 2992 | *lvprev = lv->next; |
| 2957 | lisp_free (lv); | 2993 | lisp_free (lv); |
| 2958 | } | 2994 | } |
| 2959 | } | 2995 | } |
| @@ -2987,12 +3023,12 @@ allocate_vectorlike (ptrdiff_t len) | |||
| 2987 | else | 3023 | else |
| 2988 | { | 3024 | { |
| 2989 | struct large_vector *lv | 3025 | struct large_vector *lv |
| 2990 | = lisp_malloc ((offsetof (struct large_vector, v.u.contents) | 3026 | = lisp_malloc ((large_vector_offset + header_size |
| 2991 | + len * word_size), | 3027 | + len * word_size), |
| 2992 | MEM_TYPE_VECTORLIKE); | 3028 | MEM_TYPE_VECTORLIKE); |
| 2993 | lv->next.vector = large_vectors; | 3029 | lv->next = large_vectors; |
| 2994 | large_vectors = lv; | 3030 | large_vectors = lv; |
| 2995 | p = &lv->v; | 3031 | p = large_vector_vec (lv); |
| 2996 | } | 3032 | } |
| 2997 | 3033 | ||
| 2998 | #ifdef DOUG_LEA_MALLOC | 3034 | #ifdef DOUG_LEA_MALLOC |
| @@ -3041,7 +3077,7 @@ allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag) | |||
| 3041 | 3077 | ||
| 3042 | /* Only the first lisplen slots will be traced normally by the GC. */ | 3078 | /* Only the first lisplen slots will be traced normally by the GC. */ |
| 3043 | for (i = 0; i < lisplen; ++i) | 3079 | for (i = 0; i < lisplen; ++i) |
| 3044 | v->u.contents[i] = Qnil; | 3080 | v->contents[i] = Qnil; |
| 3045 | 3081 | ||
| 3046 | XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); | 3082 | XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); |
| 3047 | return v; | 3083 | return v; |
| @@ -3129,7 +3165,7 @@ See also the function `vector'. */) | |||
| 3129 | p = allocate_vector (XFASTINT (length)); | 3165 | p = allocate_vector (XFASTINT (length)); |
| 3130 | sizei = XFASTINT (length); | 3166 | sizei = XFASTINT (length); |
| 3131 | for (i = 0; i < sizei; i++) | 3167 | for (i = 0; i < sizei; i++) |
| 3132 | p->u.contents[i] = init; | 3168 | p->contents[i] = init; |
| 3133 | 3169 | ||
| 3134 | XSETVECTOR (vector, p); | 3170 | XSETVECTOR (vector, p); |
| 3135 | return vector; | 3171 | return vector; |
| @@ -3147,7 +3183,7 @@ usage: (vector &rest OBJECTS) */) | |||
| 3147 | register struct Lisp_Vector *p = XVECTOR (val); | 3183 | register struct Lisp_Vector *p = XVECTOR (val); |
| 3148 | 3184 | ||
| 3149 | for (i = 0; i < nargs; i++) | 3185 | for (i = 0; i < nargs; i++) |
| 3150 | p->u.contents[i] = args[i]; | 3186 | p->contents[i] = args[i]; |
| 3151 | return val; | 3187 | return val; |
| 3152 | } | 3188 | } |
| 3153 | 3189 | ||
| @@ -3156,14 +3192,14 @@ make_byte_code (struct Lisp_Vector *v) | |||
| 3156 | { | 3192 | { |
| 3157 | /* Don't allow the global zero_vector to become a byte code object. */ | 3193 | /* Don't allow the global zero_vector to become a byte code object. */ |
| 3158 | eassert(0 < v->header.size); | 3194 | eassert(0 < v->header.size); |
| 3159 | if (v->header.size > 1 && STRINGP (v->u.contents[1]) | 3195 | if (v->header.size > 1 && STRINGP (v->contents[1]) |
| 3160 | && STRING_MULTIBYTE (v->u.contents[1])) | 3196 | && STRING_MULTIBYTE (v->contents[1])) |
| 3161 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | 3197 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the |
| 3162 | earlier because they produced a raw 8-bit string for byte-code | 3198 | earlier because they produced a raw 8-bit string for byte-code |
| 3163 | and now such a byte-code string is loaded as multibyte while | 3199 | and now such a byte-code string is loaded as multibyte while |
| 3164 | raw 8-bit characters converted to multibyte form. Thus, now we | 3200 | raw 8-bit characters converted to multibyte form. Thus, now we |
| 3165 | must convert them back to the original unibyte form. */ | 3201 | must convert them back to the original unibyte form. */ |
| 3166 | v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]); | 3202 | v->contents[1] = Fstring_as_unibyte (v->contents[1]); |
| 3167 | XSETPVECTYPE (v, PVEC_COMPILED); | 3203 | XSETPVECTYPE (v, PVEC_COMPILED); |
| 3168 | } | 3204 | } |
| 3169 | 3205 | ||
| @@ -3198,7 +3234,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3198 | to be setcar'd). */ | 3234 | to be setcar'd). */ |
| 3199 | 3235 | ||
| 3200 | for (i = 0; i < nargs; i++) | 3236 | for (i = 0; i < nargs; i++) |
| 3201 | p->u.contents[i] = args[i]; | 3237 | p->contents[i] = args[i]; |
| 3202 | make_byte_code (p); | 3238 | make_byte_code (p); |
| 3203 | XSETCOMPILED (val, p); | 3239 | XSETCOMPILED (val, p); |
| 3204 | return val; | 3240 | return val; |
| @@ -4256,9 +4292,7 @@ live_vector_p (struct mem_node *m, void *p) | |||
| 4256 | vector = ADVANCE (vector, vector_nbytes (vector)); | 4292 | vector = ADVANCE (vector, vector_nbytes (vector)); |
| 4257 | } | 4293 | } |
| 4258 | } | 4294 | } |
| 4259 | else if (m->type == MEM_TYPE_VECTORLIKE | 4295 | else if (m->type == MEM_TYPE_VECTORLIKE && p == large_vector_vec (m->start)) |
| 4260 | && (char *) p == ((char *) m->start | ||
| 4261 | + offsetof (struct large_vector, v))) | ||
| 4262 | /* This memory node corresponds to a large vector. */ | 4296 | /* This memory node corresponds to a large vector. */ |
| 4263 | return 1; | 4297 | return 1; |
| 4264 | return 0; | 4298 | return 0; |
| @@ -5189,7 +5223,7 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 5189 | size &= PSEUDOVECTOR_SIZE_MASK; | 5223 | size &= PSEUDOVECTOR_SIZE_MASK; |
| 5190 | vec = XVECTOR (make_pure_vector (size)); | 5224 | vec = XVECTOR (make_pure_vector (size)); |
| 5191 | for (i = 0; i < size; i++) | 5225 | for (i = 0; i < size; i++) |
| 5192 | vec->u.contents[i] = Fpurecopy (AREF (obj, i)); | 5226 | vec->contents[i] = Fpurecopy (AREF (obj, i)); |
| 5193 | if (COMPILEDP (obj)) | 5227 | if (COMPILEDP (obj)) |
| 5194 | { | 5228 | { |
| 5195 | XSETPVECTYPE (vec, PVEC_COMPILED); | 5229 | XSETPVECTYPE (vec, PVEC_COMPILED); |
| @@ -5710,7 +5744,7 @@ mark_vectorlike (struct Lisp_Vector *ptr) | |||
| 5710 | The distinction is used e.g. by Lisp_Process which places extra | 5744 | The distinction is used e.g. by Lisp_Process which places extra |
| 5711 | non-Lisp_Object fields at the end of the structure... */ | 5745 | non-Lisp_Object fields at the end of the structure... */ |
| 5712 | for (i = 0; i < size; i++) /* ...and then mark its elements. */ | 5746 | for (i = 0; i < size; i++) /* ...and then mark its elements. */ |
| 5713 | mark_object (ptr->u.contents[i]); | 5747 | mark_object (ptr->contents[i]); |
| 5714 | } | 5748 | } |
| 5715 | 5749 | ||
| 5716 | /* Like mark_vectorlike but optimized for char-tables (and | 5750 | /* Like mark_vectorlike but optimized for char-tables (and |
| @@ -5727,7 +5761,7 @@ mark_char_table (struct Lisp_Vector *ptr) | |||
| 5727 | VECTOR_MARK (ptr); | 5761 | VECTOR_MARK (ptr); |
| 5728 | for (i = 0; i < size; i++) | 5762 | for (i = 0; i < size; i++) |
| 5729 | { | 5763 | { |
| 5730 | Lisp_Object val = ptr->u.contents[i]; | 5764 | Lisp_Object val = ptr->contents[i]; |
| 5731 | 5765 | ||
| 5732 | if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) | 5766 | if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) |
| 5733 | continue; | 5767 | continue; |
| @@ -5956,10 +5990,10 @@ mark_object (Lisp_Object arg) | |||
| 5956 | VECTOR_MARK (ptr); | 5990 | VECTOR_MARK (ptr); |
| 5957 | for (i = 0; i < size; i++) | 5991 | for (i = 0; i < size; i++) |
| 5958 | if (i != COMPILED_CONSTANTS) | 5992 | if (i != COMPILED_CONSTANTS) |
| 5959 | mark_object (ptr->u.contents[i]); | 5993 | mark_object (ptr->contents[i]); |
| 5960 | if (size > COMPILED_CONSTANTS) | 5994 | if (size > COMPILED_CONSTANTS) |
| 5961 | { | 5995 | { |
| 5962 | obj = ptr->u.contents[COMPILED_CONSTANTS]; | 5996 | obj = ptr->contents[COMPILED_CONSTANTS]; |
| 5963 | goto loop; | 5997 | goto loop; |
| 5964 | } | 5998 | } |
| 5965 | } | 5999 | } |