Ticket #549: killunionvalpatch2.patch
File killunionvalpatch2.patch, 106.6 KB (added by jessevdam, 12 years ago) |
---|
-
src/jit/i386/jit_defs.c
### Eclipse Workspace Patch 1.0 #P parrot
2265 2265 break; 2266 2266 case 'v': 2267 2267 break; 2268 case 'b': /* buffer (void*) pass PObj_bufstart(SReg) */2268 case 'b': /* buffer (void*) pass Buffer_bufstart(SReg) */ 2269 2269 emitm_call_cfunc(pc, get_nci_S); 2270 2270 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 2271 (size_t) & PObj_bufstart((STRING *) NULL));2271 (size_t) &Buffer_bufstart((STRING *) NULL)); 2272 2272 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 2273 2273 break; 2274 case 'B': /* buffer (void**) pass & PObj_bufstart(SReg) */2274 case 'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */ 2275 2275 emitm_call_cfunc(pc, get_nci_S); 2276 2276 emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 2277 (size_t) & PObj_bufstart((STRING *) NULL));2277 (size_t) &Buffer_bufstart((STRING *) NULL)); 2278 2278 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 2279 2279 break; 2280 2280 case 'S': -
src/gc/gc_private.h
47 47 larger then sizeof(PObj), thus creating overflow. However PObjs are never 48 48 used by themselves, things like PMCs and STRINGs are cast to PObj in the 49 49 GC, so we should have plenty of space. */ 50 typedef unionGC_MS_PObj_Wrapper {51 PObj obj;52 PObj *next_ptr;50 typedef struct GC_MS_PObj_Wrapper { 51 size_t flags; 52 struct GC_MS_PObj_Wrapper * next_ptr; 53 53 } GC_MS_PObj_Wrapper; 54 54 55 55 typedef struct Small_Object_Arena { … … 152 152 size_t num_free_objects; /* number of resources in the free pool */ 153 153 int skip; 154 154 size_t replenish_level; 155 void *free_list;155 GC_MS_PObj_Wrapper * free_list; 156 156 /* adds a free object to the pool's free list */ 157 157 add_free_object_fn_type add_free_object; 158 158 get_free_object_fn_type get_free_object; … … 184 184 Memory_Pool *constant_string_pool; 185 185 struct Small_Object_Pool *string_header_pool; 186 186 struct Small_Object_Pool *pmc_pool; 187 struct Small_Object_Pool *pmc_ext_pool;188 187 struct Small_Object_Pool *constant_pmc_pool; 189 struct Small_Object_Pool *buffer_header_pool;188 // struct Small_Object_Pool *buffer_header_pool; 190 189 struct Small_Object_Pool *constant_string_header_pool; 191 190 struct Small_Object_Pool **sized_header_pools; 192 191 size_t num_sized; … … 225 224 during collection */ 226 225 UINTVAL num_early_gc_PMCs; /* how many PMCs want immediate destruction */ 227 226 UINTVAL num_early_PMCs_seen; /* how many such PMCs has GC seen */ 228 UINTVAL num_extended_PMCs; /* active PMCs having pmc_ext */229 227 PMC* gc_mark_start; /* first PMC marked during a GC run */ 230 228 PMC* gc_mark_ptr; /* last PMC marked during a GC run */ 231 229 PMC* gc_trace_ptr; /* last PMC trace_children was called on */ … … 550 548 __attribute__nonnull__(2) 551 549 FUNC_MODIFIES(*dest) 552 550 FUNC_MODIFIES(*source); 551 552 void check_memory_system(PARROT_INTERP) 553 __attribute__nonnull__(1); 554 555 void check_memory_system(PARROT_INTERP) 556 __attribute__nonnull__(1); 557 558 void check_small_object_pool(Small_Object_Pool * pool) 559 __attribute__nonnull__(1); 553 560 561 void 562 check_memory_pool(Memory_Pool *pool) 563 __attribute__nonnull__(1); 564 565 void 566 check_buffer_ptr(Buffer * pobj,Memory_Pool * pool) 567 __attribute__nonnull__(1) 568 __attribute__nonnull__(2); 569 554 570 #define ASSERT_ARGS_aligned_mem __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 555 571 PARROT_ASSERT_ARG(buffer) \ 556 572 || PARROT_ASSERT_ARG(mem) … … 652 668 /* HEADERIZER BEGIN: src/gc/gc_ms.c */ 653 669 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 654 670 655 void gc_ms_pmc_ext_pool_init(ARGMOD(Small_Object_Pool *pool))656 __attribute__nonnull__(1)657 FUNC_MODIFIES(*pool);658 659 671 void Parrot_gc_ms_init(PARROT_INTERP) 660 672 __attribute__nonnull__(1); 661 673 662 #define ASSERT_ARGS_gc_ms_pmc_ext_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \663 PARROT_ASSERT_ARG(pool)664 674 #define ASSERT_ARGS_Parrot_gc_ms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 665 675 PARROT_ASSERT_ARG(interp) 666 676 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ -
include/parrot/pobj.h
15 15 16 16 #include "parrot/config.h" 17 17 18 typedef union UnionVal {19 struct _b { /* One Buffer structure */20 void * _bufstart;21 size_t _buflen;22 } _b;23 struct _ptrs { /* or two pointers, both are defines */24 DPOINTER * _struct_val;25 PMC * _pmc_val;26 } _ptrs;27 struct _i {28 INTVAL _int_val; /* or 2 intvals */29 INTVAL _int_val2;30 } _i;31 FLOATVAL _num_val; /* or one float */32 struct parrot_string_t * _string_val; /* or a pointer to a string */33 } UnionVal;34 35 #define UVal_ptr(u) (u)._ptrs._struct_val36 #define UVal_pmc(u) (u)._ptrs._pmc_val37 #define UVal_int(u) (u)._i._int_val38 #define UVal_int2(u) (u)._i._int_val239 #define UVal_num(u) (u)._num_val40 #define UVal_str(u) (u)._string_val41 42 18 /* Parrot Object - base class for all others */ 43 19 typedef struct pobj_t { 44 UnionVal u;45 20 Parrot_UInt flags; 46 } pobj_t;21 } PObj; 47 22 48 /* plain Buffer is the smallest Parrot Obj */ 49 typedef struct Buffer { 50 UnionVal cache; 23 typedef struct buffer_t { 51 24 Parrot_UInt flags; 25 void * _bufstart; 26 size_t _buflen; 52 27 } Buffer; 53 28 54 typedef Buffer PObj; 55 56 #define PObj_bufstart(pmc) (pmc)->cache._b._bufstart 57 #define PObj_buflen(pmc) (pmc)->cache._b._buflen 29 #define Buffer_bufstart(buffer) (buffer)->_bufstart 30 #define Buffer_buflen(buffer) (buffer)->_buflen 58 31 59 32 /* See src/gc/alloc_resources.c. the basic idea is that buffer memory is 60 33 set up as follows: … … 84 57 v v v v 85 58 86 59 */ 87 typedef struct Buffer_alloc_unit {88 INTVAL ref_count;89 UnionVal buffer[1]; /* Guarantee it's suitably aligned */90 } Buffer_alloc_unit;91 60 92 61 /* Given a pointer to the buffer, find the ref_count and the actual start of 93 62 the allocated space. Setting ref_count is clunky because we avoid lvalue 94 63 casts. */ 95 64 #ifdef GC_IS_MALLOC /* see src/gc/res_lea.c */ 96 65 # define Buffer_alloc_offset (offsetof(Buffer_alloc_unit, buffer)) 97 # define PObj_bufallocstart(b) ((char *)PObj_bufstart(b) - Buffer_alloc_offset)98 # define PObj_bufrefcount(b) (((Buffer_alloc_unit *)PObj_bufallocstart(b))->ref_count)99 # define PObj_bufrefcountptr(b) (&PObj_bufrefcount(b))66 # define Buffer_bufallocstart(b) ((char *)Buffer_bufstart(b) - Buffer_alloc_offset) 67 # define Buffer_bufrefcount(b) (((Buffer_alloc_unit *)Buffer_bufallocstart(b))->ref_count) 68 # define Buffer_bufrefcountptr(b) (&Buffer_bufrefcount(b)) 100 69 #else /* see src/gc/alloc_resources.c */ 101 70 # define Buffer_alloc_offset sizeof (INTVAL) 102 # define PObj_bufallocstart(b) ((char *)PObj_bufstart(b) - Buffer_alloc_offset)103 # define PObj_bufrefcount(b) (*(INTVAL *)PObj_bufallocstart(b))104 # define PObj_bufrefcountptr(b) ((INTVAL *)PObj_bufallocstart(b))71 # define Buffer_bufallocstart(b) ((char *)Buffer_bufstart(b) - Buffer_alloc_offset) 72 # define Buffer_bufrefcount(b) (*(INTVAL *)Buffer_bufallocstart(b)) 73 # define Buffer_bufrefcountptr(b) ((INTVAL *)Buffer_bufallocstart(b)) 105 74 #endif 106 75 107 76 typedef enum { … … 112 81 } parrot_string_representation_t; 113 82 114 83 struct parrot_string_t { 115 UnionVal cache;116 84 Parrot_UInt flags; 85 void * _bufstart; 86 size_t _buflen; 87 117 88 char *strstart; 118 89 UINTVAL bufused; 119 90 UINTVAL strlen; … … 124 95 const struct _charset *charset; 125 96 }; 126 97 98 struct _Sync; /* forward decl */ 99 127 100 /* note that cache and flags are isomorphic with Buffer and PObj */ 128 101 struct PMC { 129 UnionVal cache;130 102 Parrot_UInt flags; 131 103 VTABLE *vtable; 132 104 DPOINTER *data; 133 struct PMC_EXT *pmc_ext;134 };135 136 struct _Sync; /* forward decl */137 105 138 typedef struct PMC_EXT {139 106 PMC *_metadata; /* properties */ 140 107 /* 141 108 * PMC access synchronization for shared PMCs … … 160 127 stuff, which'd merit an extra dereference when setting, but let 161 128 us memset the actual GC data in a big block 162 129 */ 163 } PMC_EXT;130 }; 164 131 165 #ifdef NDEBUG166 # define PMC_ext_checked(pmc) (pmc)->pmc_ext167 #else168 # define PMC_ext_checked(pmc) (PARROT_ASSERT((pmc)->pmc_ext), (pmc)->pmc_ext)169 #endif /* NDEBUG */170 132 #define PMC_data(pmc) (pmc)->data 171 133 #define PMC_data_typed(pmc, type) (type)(pmc)->data 172 134 /* do not allow PMC_data2 as lvalue */ 173 135 #define PMC_data0(pmc) (1 ? (pmc)->data : 0) 174 136 #define PMC_data0_typed(pmc) (type)(1 ? (pmc)->data : 0) 175 #define PMC_metadata(pmc) PMC_ext_checked(pmc)->_metadata176 #define PMC_next_for_GC(pmc) PMC_ext_checked(pmc)->_next_for_GC177 #define PMC_sync(pmc) PMC_ext_checked(pmc)->_synchronize137 #define PMC_metadata(pmc) pmc->_metadata 138 #define PMC_next_for_GC(pmc) pmc->_next_for_GC 139 #define PMC_sync(pmc) pmc->_synchronize 178 140 179 141 #define POBJ_FLAG(n) ((UINTVAL)1 << (n)) 180 142 /* PObj flags */ -
src/pmc_freeze.c
463 463 str_append(PARROT_INTERP, ARGMOD(STRING *s), ARGIN(const void *b), size_t len) 464 464 { 465 465 ASSERT_ARGS(str_append) 466 466 467 const size_t used = s->bufused; 467 const int need_free = (int) PObj_buflen(s) - used - len;468 const int need_free = (int)Buffer_buflen(s) - used - len; 468 469 /* 469 470 * grow by factor 1.5 or such 470 471 */ 471 472 if (need_free <= 16) { 472 size_t new_size = (size_t) ( PObj_buflen(s) * 1.5);473 if (new_size < PObj_buflen(s) - need_free + 512)474 new_size = PObj_buflen(s) - need_free + 512;473 size_t new_size = (size_t) (Buffer_buflen(s) * 1.5); 474 if (new_size < Buffer_buflen(s) - need_free + 512) 475 new_size = Buffer_buflen(s) - need_free + 512; 475 476 Parrot_gc_reallocate_string_storage(interp, s, new_size); 476 PARROT_ASSERT( PObj_buflen(s) - used - len >= 15);477 PARROT_ASSERT(Buffer_buflen(s) - used - len >= 15); 477 478 } 478 479 mem_sys_memcopy((void *)((ptrcast_t)s->strstart + used), b, len); 479 480 s->bufused += len; … … 591 592 shift_ascii_integer(SHIM_INTERP, ARGIN(IMAGE_IO *io)) 592 593 { 593 594 ASSERT_ARGS(shift_ascii_integer) 595 594 596 char * const start = (char*)io->image->strstart; 595 597 char *p = start; 596 598 const INTVAL i = strtoul(p, &p, 10); … … 599 601 PARROT_ASSERT(p <= start + io->image->bufused); 600 602 io->image->strstart = p; 601 603 io->image->bufused -= (p - start); 604 io->image->strlen -= (p - start); 602 605 PARROT_ASSERT((int)io->image->bufused >= 0); 606 603 607 return i; 604 608 } 605 609 … … 617 621 shift_ascii_number(SHIM_INTERP, ARGIN(IMAGE_IO *io)) 618 622 { 619 623 ASSERT_ARGS(shift_ascii_number) 624 620 625 char * const start = (char*)io->image->strstart; 621 626 char *p = start; 622 627 const FLOATVAL f = (FLOATVAL) strtod(p, &p); … … 625 630 PARROT_ASSERT(p <= start + io->image->bufused); 626 631 io->image->strstart = p; 627 632 io->image->bufused -= (p - start); 633 io->image->strlen -= (p - start); 628 634 PARROT_ASSERT((int)io->image->bufused >= 0); 635 629 636 return f; 630 637 } 631 638 … … 656 663 PARROT_ASSERT(p <= start + io->image->bufused); 657 664 io->image->strstart = p; 658 665 io->image->bufused -= (p - start); 666 io->image->strlen -= (p - start); 659 667 PARROT_ASSERT((int)io->image->bufused >= 0); 660 668 s = string_make(interp, start, p - start - 1, "iso-8859-1", 0); 661 669 /* s = string_make(interp, start, p - start - 1, "UTF-8", 0); */ 670 662 671 return s; 663 672 } 664 673 … … 678 687 shift_ascii_pmc(SHIM_INTERP, ARGIN(IMAGE_IO *io)) 679 688 { 680 689 ASSERT_ARGS(shift_ascii_pmc) 690 681 691 char * const start = (char*)io->image->strstart; 682 692 char *p = start; 683 693 const unsigned long i = strtoul(p, &p, 16); … … 685 695 PARROT_ASSERT(p <= start + io->image->bufused); 686 696 io->image->strstart = p; 687 697 io->image->bufused -= (p - start); 698 io->image->strlen -= (p - start); 688 699 PARROT_ASSERT((int)io->image->bufused >= 0); 700 689 701 return (PMC*) i; 690 702 } 691 703 … … 712 724 { 713 725 ASSERT_ARGS(op_check_size) 714 726 const size_t used = s->bufused; 715 const int need_free = (int)PObj_buflen(s) - used - len; 727 const int need_free = (int)Buffer_buflen(s) - used - len; 728 716 729 /* 717 730 * grow by factor 1.5 or such 718 731 */ 719 732 if (need_free <= 16) { 720 size_t new_size = (size_t) ( PObj_buflen(s) * 1.5);721 if (new_size < PObj_buflen(s) - need_free + 512)722 new_size = PObj_buflen(s) - need_free + 512;733 size_t new_size = (size_t) (Buffer_buflen(s) * 1.5); 734 if (new_size < Buffer_buflen(s) - need_free + 512) 735 new_size = Buffer_buflen(s) - need_free + 512; 723 736 Parrot_gc_reallocate_string_storage(interp, s, new_size); 724 PARROT_ASSERT( PObj_buflen(s) - used - len >= 15);737 PARROT_ASSERT(Buffer_buflen(s) - used - len >= 15); 725 738 } 726 739 #ifndef DISABLE_GC_DEBUG 727 740 Parrot_gc_compact_memory_pool(interp); … … 785 798 push_opcode_number(PARROT_INTERP, ARGIN(IMAGE_IO *io), FLOATVAL v) 786 799 { 787 800 ASSERT_ARGS(push_opcode_number) 801 788 802 const size_t len = PF_size_number() * sizeof (opcode_t); 789 803 STRING * const s = io->image; 790 804 const size_t used = s->bufused; … … 812 826 push_opcode_string(PARROT_INTERP, ARGIN(IMAGE_IO *io), ARGIN(STRING *v)) 813 827 { 814 828 ASSERT_ARGS(push_opcode_string) 829 815 830 const size_t len = PF_size_string(v) * sizeof (opcode_t); 816 831 STRING * const s = io->image; 817 832 const size_t used = s->bufused; … … 862 877 (const opcode_t **)opcode); 863 878 864 879 io->image->bufused -= ((char *)io->image->strstart - start); 880 io->image->strlen -= ((char *)io->image->strstart - start); 865 881 PARROT_ASSERT((int)io->image->bufused >= 0); 866 882 867 883 return i; … … 903 919 shift_opcode_number(SHIM_INTERP, ARGIN(IMAGE_IO *io)) 904 920 { 905 921 ASSERT_ARGS(shift_opcode_number) 922 906 923 const char * const start = (const char *)io->image->strstart; 907 924 char **opcode = &io->image->strstart; 908 925 const FLOATVAL f = PF_fetch_number(io->pf, 909 926 (const opcode_t **)opcode); 910 927 911 928 io->image->bufused -= ((char *)io->image->strstart - start); 929 io->image->strlen -= ((char *)io->image->strstart - start); 912 930 PARROT_ASSERT((int)io->image->bufused >= 0); 913 931 914 932 return f; … … 930 948 shift_opcode_string(PARROT_INTERP, ARGIN(IMAGE_IO *io)) 931 949 { 932 950 ASSERT_ARGS(shift_opcode_string) 951 933 952 char * const start = (char*)io->image->strstart; 934 char **opcode = &io->image->strstart;953 char * opcode = io->image->strstart; 935 954 STRING * const s = PF_fetch_string(interp, io->pf, 936 (const opcode_t **) opcode);955 (const opcode_t **)&opcode); 937 956 938 io->image->bufused -= ((char *)io->image->strstart - start); 957 io->image->strstart = opcode; 958 io->image->bufused -= (opcode - start); 959 io->image->strlen -= (opcode - start); 939 960 PARROT_ASSERT((int)io->image->bufused >= 0); 940 961 941 962 return s; … … 1019 1040 16 - PACKFILE_HEADER_BYTES % 16 : 0); 1020 1041 1021 1042 info->image_io = mem_allocate_typed(IMAGE_IO); 1043 1022 1044 info->image_io->image = s = info->image; 1023 1045 #if FREEZE_ASCII 1024 1046 info->image_io->vtable = &ascii_funcs; … … 1026 1048 info->image_io->vtable = &opcode_funcs; 1027 1049 #endif 1028 1050 pf = info->image_io->pf = PackFile_new(interp, 0); 1051 1029 1052 if (info->what == VISIT_FREEZE_NORMAL || 1030 1053 info->what == VISIT_FREEZE_AT_DESTRUCT) { 1031 1054 … … 1052 1075 mem_sys_memcopy(pf->header, s->strstart, PACKFILE_HEADER_BYTES); 1053 1076 PackFile_assign_transforms(pf); 1054 1077 s->bufused -= header_length; 1078 s->strlen -= header_length; 1055 1079 LVALUE_CAST(char *, s->strstart) += header_length; 1056 1080 } 1057 1081 … … 1171 1195 1172 1196 info->extra_flags = EXTRA_IS_NULL; 1173 1197 n = VTABLE_shift_pmc(interp, io); 1198 1174 1199 if (((UINTVAL) n & 3) == 3) { 1175 1200 /* pmc has extra data */ 1176 1201 info->extra_flags = VTABLE_shift_integer(interp, io); … … 1194 1219 *type = enum_class_Class; 1195 1220 } 1196 1221 } 1222 1197 1223 *id = (UINTVAL) n; 1198 1224 return seen; 1199 1225 } … … 1356 1382 } 1357 1383 list_assign(interp, (List *)PMC_data(info->id_list), id, pmc, enum_type_PMC); 1358 1384 /* remember nested aggregates depth first */ 1359 if ( pmc->pmc_ext)1385 if (PObj_is_PMC_EXT_TEST(pmc)) 1360 1386 list_unshift(interp, (List *)PMC_data(info->todo), pmc, enum_type_PMC); 1361 1387 } 1362 1388 … … 1396 1422 add_pmc_next_for_GC(SHIM_INTERP, ARGIN(PMC *pmc), ARGOUT(visit_info *info)) 1397 1423 { 1398 1424 ASSERT_ARGS(add_pmc_next_for_GC) 1399 if ( pmc->pmc_ext) {1425 if (PObj_is_PMC_EXT_TEST(pmc)) { 1400 1426 PMC_next_for_GC(info->mark_ptr) = pmc; 1401 1427 info->mark_ptr = PMC_next_for_GC(pmc) = pmc; 1402 1428 } … … 1433 1459 * we can only remember PMCs with a next_for_GC pointer 1434 1460 * which is located in pmc_ext 1435 1461 */ 1436 if ( pmc->pmc_ext) {1462 if (PObj_is_PMC_EXT_TEST(pmc)) { 1437 1463 /* already seen? */ 1438 1464 if (!PMC_IS_NULL(PMC_next_for_GC(pmc))) { 1439 1465 seen = 1; … … 1500 1526 parrot_hash_put(interp, 1501 1527 (Hash *)VTABLE_get_pointer(interp, info->seen), pmc, (void*)*id); 1502 1528 /* remember containers */ 1503 if ( pmc->pmc_ext)1529 if (PObj_is_PMC_EXT_TEST(pmc)) 1504 1530 list_unshift(interp, (List *)PMC_data(info->todo), pmc, enum_type_PMC); 1505 1531 return 0; 1506 1532 } … … 1607 1633 { 1608 1634 ASSERT_ARGS(visit_loop_next_for_GC) 1609 1635 visit_next_for_GC(interp, current, info); 1610 if ( current->pmc_ext) {1636 if (PObj_is_PMC_EXT_TEST(current)) { 1611 1637 PMC *prev = NULL; 1612 1638 1613 1639 while (current != prev) { … … 1797 1823 */ 1798 1824 LVALUE_CAST(char *, image->strstart) -= bufused; 1799 1825 image->bufused = bufused; 1800 PARROT_ASSERT(image->strstart >= (char *)PObj_bufstart(image)); 1826 image->strlen += bufused; 1827 PARROT_ASSERT(image->strstart >= (char *)Buffer_bufstart(image)); 1801 1828 1802 1829 if (gc_block) { 1803 1830 Parrot_unblock_GC_mark(interp); -
src/pmc/unmanagedstruct.pmc
382 382 ret = *(PMC**) p; 383 383 384 384 /* now check if initializer has a signature attached */ 385 if ( ptr->pmc_ext&& PMC_metadata(ptr)) {385 if (PObj_is_PMC_EXT_TEST(ptr) && PMC_metadata(ptr)) { 386 386 STRING *signature_str = CONST_STRING(interp, "_signature"); 387 387 PMC *sig = VTABLE_getprop(interp, ptr, signature_str); 388 388 if (VTABLE_defined(interp, sig)) { … … 398 398 /* check the metadata for an initializer */ 399 399 400 400 /* grab the struct from the metadata */ 401 if ( ptr->pmc_ext&& PMC_metadata(ptr)) {401 if (PObj_is_PMC_EXT_TEST(ptr) && PMC_metadata(ptr)) { 402 402 ret = VTABLE_getprop(interp, ptr, CONST_STRING(interp, "_struct")); 403 403 } 404 404 else { -
src/pmc/key.pmc
278 278 VTABLE PMC *shift_pmc() { 279 279 PMC *next_key; 280 280 281 if (! SELF->pmc_ext)281 if (!PObj_is_PMC_EXT_TEST(SELF)) 282 282 return NULL; 283 283 284 284 GET_ATTR_next_key(INTERP, SELF, next_key); -
src/key.c
544 544 ASSERT_ARGS(key_next) 545 545 PMC *next_key; 546 546 547 if (VTABLE_isa(interp, key, CONST_STRING(interp, "Key")) && key->pmc_ext) {547 if (VTABLE_isa(interp, key, CONST_STRING(interp, "Key")) && PObj_is_PMC_EXT_TEST(key)) { 548 548 GETATTR_Key_next_key(interp, key, next_key); 549 549 return next_key; 550 550 } -
src/debug.c
3371 3371 if (!s) 3372 3372 return; 3373 3373 3374 Parrot_io_eprintf(interp, "\tBuflen =\t%12ld\n", PObj_buflen(s));3374 Parrot_io_eprintf(interp, "\tBuflen =\t%12ld\n", Buffer_buflen(s)); 3375 3375 Parrot_io_eprintf(interp, "\tFlags =\t%12ld\n", PObj_get_FLAGS(s)); 3376 3376 Parrot_io_eprintf(interp, "\tBufused =\t%12ld\n", s->bufused); 3377 3377 Parrot_io_eprintf(interp, "\tStrlen =\t%12ld\n", s->strlen); 3378 3378 Parrot_io_eprintf(interp, "\tOffset =\t%12ld\n", 3379 (char*) s->strstart - (char*) PObj_bufstart(s));3379 (char*) s->strstart - (char*) Buffer_bufstart(s)); 3380 3380 Parrot_io_eprintf(interp, "\tString =\t%S\n", s); 3381 3381 } 3382 3382 -
src/string/api.c
89 89 * also be sure not to allocate from the constant pool 90 90 */ 91 91 PObj_flags_CLEARALL(&for_alloc); 92 Parrot_gc_allocate_string_storage(interp, &for_alloc, PObj_buflen(s));92 Parrot_gc_allocate_string_storage(interp, &for_alloc, Buffer_buflen(s)); 93 93 94 94 /* now copy memory over */ 95 95 mem_sys_memcopy(for_alloc.strstart, s->strstart, s->bufused); 96 96 97 97 /* and finally use that string memory */ 98 98 99 PObj_bufstart(s) = PObj_bufstart(&for_alloc);99 Buffer_bufstart(s) = Buffer_bufstart(&for_alloc); 100 100 s->strstart = for_alloc.strstart; 101 PObj_buflen(s) = PObj_buflen(&for_alloc);101 Buffer_buflen(s) = Buffer_buflen(&for_alloc); 102 102 103 103 /* COW_FLAG | external_FLAG */ 104 104 PObj_is_external_CLEARALL(s); … … 148 148 /* XXX FIXME hack to avoid cross-interpreter issue until it 149 149 * is fixed correctly. */ 150 150 if (n_interpreters > 1 && PObj_is_movable_TESTALL(s) && 151 !Parrot_gc_ptr_in_memory_pool(interp, PObj_bufstart(s))) {151 !Parrot_gc_ptr_in_memory_pool(interp, Buffer_bufstart(s))) { 152 152 Parrot_str_write_COW(interp, d); 153 153 Parrot_io_eprintf(interp, "cross-interpreter copy of " 154 154 "relocatable string '%Ss' into tid %d\n", … … 215 215 if (dest) { /* && dest != src */ 216 216 /* they are different, dest is not an external string */ 217 217 #ifdef GC_IS_MALLOC 218 if (!PObj_is_cowed_TESTALL(dest) && PObj_bufstart(dest)) {219 mem_sys_free( PObj_bufallocstart(dest));218 if (!PObj_is_cowed_TESTALL(dest) && Buffer_bufstart(dest)) { 219 mem_sys_free(Buffer_bufallocstart(dest)); 220 220 } 221 221 #endif 222 222 dest = Parrot_str_reuse_COW(interp, src, dest); … … 338 338 { 339 339 ASSERT_ARGS(string_capacity) 340 340 341 return ((ptrcast_t) PObj_bufstart(s) + PObj_buflen(s) -341 return ((ptrcast_t)Buffer_bufstart(s) + Buffer_buflen(s) - 342 342 (ptrcast_t)s->strstart); 343 343 } 344 344 … … 524 524 return a; 525 525 526 526 /* Is A real? */ 527 if (a == NULL || PObj_bufstart(a) == NULL)527 if (a == NULL || Buffer_bufstart(a) == NULL) 528 528 return Parrot_str_copy(interp, b); 529 529 530 530 saneify_string(a); … … 806 806 it was safe by setting PObj_external_FLAG. 807 807 (The cast is necessary to pacify TenDRA's tcc.) 808 808 */ 809 PObj_bufstart(s) = s->strstart = PARROT_const_cast(char *, buffer);810 PObj_buflen(s) = s->bufused = len;809 Buffer_bufstart(s) = s->strstart = PARROT_const_cast(char *, buffer); 810 Buffer_buflen(s) = s->bufused = len; 811 811 812 812 if (encoding == Parrot_fixed_8_encoding_ptr) 813 813 s->strlen = len; … … 855 855 856 856 /* Don't check buflen, if we are here, we already checked. */ 857 857 Parrot_gc_reallocate_string_storage(interp, 858 s, PObj_buflen(s) + string_max_bytes(interp, s, addlen));858 s, Buffer_buflen(s) + string_max_bytes(interp, s, addlen)); 859 859 return s; 860 860 } 861 861 … … 1328 1328 diff = (end_byte - start_byte) - rep->bufused; 1329 1329 1330 1330 if (diff >= 0 1331 || ((INTVAL)src->bufused - (INTVAL) PObj_buflen(src)) <= diff) {1331 || ((INTVAL)src->bufused - (INTVAL)Buffer_buflen(src)) <= diff) { 1332 1332 Parrot_str_write_COW(interp, src); 1333 1333 1334 1334 if (diff != 0) { … … 2479 2479 */ 2480 2480 Parrot_str_write_COW(interp, s); 2481 2481 2482 size = PObj_buflen(s);2482 size = Buffer_buflen(s); 2483 2483 memory = (char *)mem_sys_allocate(size); 2484 2484 2485 mem_sys_memcopy(memory, PObj_bufstart(s), size);2486 PObj_bufstart(s) = memory;2485 mem_sys_memcopy(memory, Buffer_bufstart(s), size); 2486 Buffer_bufstart(s) = memory; 2487 2487 s->strstart = memory; 2488 2488 2489 2489 /* Mark the memory as both from the system and immobile */ … … 2516 2516 return; 2517 2517 2518 2518 Parrot_str_write_COW(interp, s); 2519 size = PObj_buflen(s);2519 size = Buffer_buflen(s); 2520 2520 2521 2521 /* We need a handle on the fixed memory so we can get rid of it later */ 2522 memory = PObj_bufstart(s);2522 memory = Buffer_bufstart(s); 2523 2523 2524 2524 /* Reallocate it the same size 2525 2525 * NOTE can't use Parrot_gc_reallocate_string_storage because of the LEA … … 2530 2530 Parrot_block_GC_sweep(interp); 2531 2531 Parrot_gc_allocate_string_storage(interp, s, size); 2532 2532 Parrot_unblock_GC_sweep(interp); 2533 mem_sys_memcopy( PObj_bufstart(s), memory, size);2533 mem_sys_memcopy(Buffer_bufstart(s), memory, size); 2534 2534 2535 2535 /* Mark the memory as neither immobile nor system allocated */ 2536 2536 PObj_sysmem_CLEAR(s); … … 2722 2722 i += hex->strlen; 2723 2723 2724 2724 /* and usable len */ 2725 charlen = PObj_buflen(result);2725 charlen = Buffer_buflen(result); 2726 2726 dp = (unsigned char *)result->strstart; 2727 2727 2728 2728 PARROT_ASSERT(i <= charlen); -
src/string/encoding/fixed_8.c
634 634 { 635 635 ASSERT_ARGS(fixed8_set_position) 636 636 iter->bytepos = iter->charpos = pos; 637 PARROT_ASSERT(pos <= PObj_buflen(iter->str));637 PARROT_ASSERT(pos <= Buffer_buflen(iter->str)); 638 638 } 639 639 640 640 -
src/gc/alloc_resources.c
54 54 __attribute__nonnull__(1) 55 55 __attribute__nonnull__(2); 56 56 57 static void debug_print_buf(PARROT_INTERP, ARGIN(const PObj*b))57 static void debug_print_buf(PARROT_INTERP, ARGIN(const Buffer *b)) 58 58 __attribute__nonnull__(1) 59 59 __attribute__nonnull__(2); 60 60 … … 285 285 */ 286 286 287 287 static void 288 debug_print_buf(PARROT_INTERP, ARGIN(const PObj*b))288 debug_print_buf(PARROT_INTERP, ARGIN(const Buffer *b)) 289 289 { 290 290 ASSERT_ARGS(debug_print_buf) 291 291 fprintf(stderr, "found %p, len %d, flags 0x%08x at %s\n", 292 b, (int) PObj_buflen(b), (uint)PObj_get_FLAGS(b),292 b, (int)Buffer_buflen(b), (uint)PObj_get_FLAGS(b), 293 293 buffer_location(interp, b)); 294 294 } 295 295 #endif … … 407 407 INTVAL *ref_count = NULL; 408 408 409 409 /* ! (on_free_list | constant | external | sysmem) */ 410 if ( PObj_buflen(b) && PObj_is_movable_TESTALL(b)) {410 if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) { 411 411 ptrdiff_t offset = 0; 412 412 #if RESOURCE_DEBUG 413 if ( PObj_buflen(b) >= RESOURCE_DEBUG_SIZE)413 if (Buffer_buflen(b) >= RESOURCE_DEBUG_SIZE) 414 414 debug_print_buf(interp, b); 415 415 #endif 416 416 417 417 /* we can't perform the math all the time, because 418 418 * strstart might be in unallocated memory */ 419 419 if (PObj_is_COWable_TEST(b)) { 420 ref_count = PObj_bufrefcountptr(b);420 ref_count = Buffer_bufrefcountptr(b); 421 421 422 422 if (PObj_is_string_TEST(b)) { 423 423 offset = (ptrdiff_t)((STRING *)b)->strstart - 424 (ptrdiff_t) PObj_bufstart(b);424 (ptrdiff_t)Buffer_bufstart(b); 425 425 } 426 426 } 427 427 … … 429 429 if (PObj_COW_TEST(b) && 430 430 (ref_count && *ref_count & Buffer_moved_FLAG)) { 431 431 /* Find out who else references our data */ 432 Buffer * const hdr = *(Buffer **)(PObj_bufstart(b)); 432 Buffer * const hdr = *((Buffer **)Buffer_bufstart(b)); 433 433 434 434 435 PARROT_ASSERT(PObj_is_COWable_TEST(b)); 435 436 … … 438 439 439 440 /* TODO incr ref_count, after fixing string too 440 441 * Now make sure we point to where the other guy does */ 441 PObj_bufstart(b) = PObj_bufstart(hdr);442 Buffer_bufstart(b) = Buffer_bufstart(hdr); 442 443 443 444 /* And if we're a string, update strstart */ 444 445 /* Somewhat of a hack, but if we get per-pool 445 446 * collections, it should help ease the pain */ 446 447 if (PObj_is_string_TEST(b)) { 447 ((STRING *)b)->strstart = (char *) PObj_bufstart(b) +448 ((STRING *)b)->strstart = (char *)Buffer_bufstart(b) + 448 449 offset; 449 450 } 450 451 } … … 457 458 } 458 459 459 460 /* Copy our memory to the new pool */ 460 memcpy(cur_spot, PObj_bufstart(b), PObj_buflen(b));461 memcpy(cur_spot, Buffer_bufstart(b), Buffer_buflen(b)); 461 462 462 463 /* If we're COW */ 463 464 if (PObj_COW_TEST(b)) { 464 465 PARROT_ASSERT(PObj_is_COWable_TEST(b)); 465 466 466 467 /* Let the old buffer know how to find us */ 467 *( Buffer **)(PObj_bufstart(b)) = b;468 *((Buffer **)Buffer_bufstart(b)) = b; 468 469 469 470 /* No guarantees that our data is still COW, so 470 471 * assume not, and let the above code fix-up */ … … 477 478 *ref_count |= Buffer_moved_FLAG; 478 479 } 479 480 480 PObj_bufstart(b) = cur_spot;481 Buffer_bufstart(b) = cur_spot; 481 482 482 483 if (PObj_is_string_TEST(b)) { 483 ((STRING *)b)->strstart = (char *) PObj_bufstart(b) +484 ((STRING *)b)->strstart = (char *)Buffer_bufstart(b) + 484 485 offset; 485 486 } 486 487 487 cur_spot += PObj_buflen(b);488 cur_spot += Buffer_buflen(b); 488 489 } 489 490 } 490 491 b = (Buffer *)((char *)b + object_size); … … 676 677 677 678 /* Constant strings - not compacted */ 678 679 arena_base->constant_string_pool = new_memory_pool(POOL_SIZE, NULL); 679 680 680 alloc_new_block(interp, POOL_SIZE, arena_base->constant_string_pool, "init"); 681 681 } 682 682 … … 743 743 */ 744 744 745 745 /* 746 747 =item C<void check_memory_system(PARROT_INTERP)> 748 749 Checks the memory system of parrot on any corruptions, including 750 the string system. 751 752 =cut 753 754 */ 755 756 void 757 check_memory_system(PARROT_INTERP) 758 { 759 size_t i; 760 Arenas * const arena_base = interp->arena_base; 761 762 check_memory_pool(arena_base->memory_pool); 763 check_memory_pool(arena_base->constant_string_pool); 764 check_small_object_pool(arena_base->pmc_pool); 765 check_small_object_pool(arena_base->constant_pmc_pool); 766 check_small_object_pool(arena_base->string_header_pool); 767 check_small_object_pool(arena_base->constant_string_header_pool); 768 769 for(i = 0;i < arena_base->num_sized;i++) 770 { 771 Small_Object_Pool * pool = arena_base->sized_header_pools[i]; 772 if(pool != NULL && pool != arena_base->string_header_pool) 773 check_small_object_pool(pool); 774 } 775 } 776 777 /* 778 779 =item C<void check_small_object_pool(Small_Object_Pool * pool)> 780 781 Checks a small object pool, if it contains buffer it checks the buffers also. 782 783 =cut 784 785 */ 786 787 void 788 check_small_object_pool(Small_Object_Pool * pool) 789 { 790 size_t total_objects; 791 size_t last_free_list_count; 792 Small_Object_Arena * arena_walker; 793 size_t free_objects; 794 PObj * object; 795 size_t i; 796 size_t count; 797 GC_MS_PObj_Wrapper * pobj_walker; 798 799 count = 10000000; /*detect unendless loop just use big enough number*/ 800 801 total_objects = pool->total_objects; 802 last_free_list_count = 1; 803 free_objects = 0; 804 805 arena_walker = pool->last_Arena; 806 while(arena_walker != NULL) 807 { 808 total_objects -= arena_walker->total_objects; 809 object = (PObj*)arena_walker->start_objects; 810 for(i = 0;i < arena_walker->total_objects;++i) 811 { 812 if(PObj_on_free_list_TEST(object)) 813 { 814 ++free_objects; 815 pobj_walker = (GC_MS_PObj_Wrapper*)object; 816 if(pobj_walker->next_ptr == NULL) 817 { 818 --last_free_list_count; //should happen only ones at the end 819 } 820 else 821 { /*next item on free list should also be flaged as free item*/ 822 pobj_walker = (GC_MS_PObj_Wrapper*)pobj_walker->next_ptr; 823 PARROT_ASSERT(PObj_on_free_list_TEST((PObj*)pobj_walker)); 824 } 825 } 826 else if(pool->mem_pool != NULL) /*then it means we are a buffer*/ 827 { 828 check_buffer_ptr((Buffer*)object,pool->mem_pool); 829 } 830 object = (PObj*)((char *)object + pool->object_size); 831 PARROT_ASSERT(--count); 832 } 833 /*check the list*/ 834 if(arena_walker->prev != NULL) 835 { 836 PARROT_ASSERT(arena_walker->prev->next == arena_walker); 837 } 838 arena_walker = arena_walker->prev; 839 PARROT_ASSERT(--count); 840 } 841 842 count = 10000000; 843 844 PARROT_ASSERT(free_objects == pool->num_free_objects); 845 846 pobj_walker = (GC_MS_PObj_Wrapper*)pool->free_list; 847 while(pobj_walker != NULL) 848 { 849 PARROT_ASSERT(pool->start_arena_memory <= (size_t)pobj_walker); 850 PARROT_ASSERT(pool->end_arena_memory > (size_t)pobj_walker); 851 PARROT_ASSERT(PObj_on_free_list_TEST((PObj*)pobj_walker)); 852 --free_objects; 853 pobj_walker = (GC_MS_PObj_Wrapper*)pobj_walker->next_ptr; 854 PARROT_ASSERT(--count); 855 } 856 857 PARROT_ASSERT(total_objects == 0); 858 PARROT_ASSERT(last_free_list_count == 0 || pool->num_free_objects == 0); 859 PARROT_ASSERT(free_objects == 0); 860 } 861 862 /* 863 864 =item C<void check_memory_pool(Memory_Pool *pool)> 865 866 Checks a memory pool, containing buffer data 867 868 =cut 869 870 */ 871 872 void 873 check_memory_pool(Memory_Pool *pool) 874 { 875 size_t count; 876 Memory_Block * block_walker; 877 count = 10000000; /*detect unendless loop just use big enough number*/ 878 879 block_walker = (Memory_Block *)pool->top_block; 880 while(block_walker != NULL) 881 { 882 PARROT_ASSERT(block_walker->start == (char *)block_walker + sizeof (Memory_Block)); 883 PARROT_ASSERT((size_t)(block_walker->top - block_walker->start) == block_walker->size - block_walker->free); 884 885 /*check the list*/ 886 if(block_walker->prev != NULL) 887 { 888 PARROT_ASSERT(block_walker->prev->next == block_walker); 889 } 890 block_walker = block_walker->prev; 891 PARROT_ASSERT(--count); 892 } 893 } 894 895 /* 896 897 =item C<void check_buffer_ptr(Buffer * pobj,Memory_Pool * pool)> 898 899 Checks wether the buffer is within the bounds of the memory pool 900 901 =cut 902 903 */ 904 905 void 906 check_buffer_ptr(Buffer * pobj,Memory_Pool * pool) 907 { 908 Memory_Block * cur_block = pool->top_block; 909 char * bufstart; 910 911 bufstart = (char*)Buffer_bufstart(pobj); 912 913 if(bufstart == NULL && Buffer_buflen(pobj) == 0) 914 return; 915 916 if(PObj_external_TEST(pobj)) /*buffer does not come from the memory pool*/ 917 { 918 if (PObj_is_string_TEST(pobj)) 919 { 920 PARROT_ASSERT(((STRING *) pobj)->strstart >= (char *) Buffer_bufstart(pobj)); 921 PARROT_ASSERT(((STRING *) pobj)->strstart + ((STRING *) pobj)->strlen <= (char *) Buffer_bufstart(pobj) + Buffer_buflen(pobj)); 922 } 923 return; 924 } 925 926 if(PObj_is_COWable_TEST(pobj)) 927 bufstart -= sizeof (void*); 928 929 while (cur_block) 930 { 931 if ((char *)bufstart >= cur_block->start && 932 (char *)Buffer_bufstart(pobj) + Buffer_buflen(pobj) < cur_block->start + cur_block->size) 933 { 934 if (PObj_is_string_TEST(pobj)) 935 { 936 PARROT_ASSERT(((STRING *)pobj)->strstart >= (char *)Buffer_bufstart(pobj)); 937 PARROT_ASSERT(((STRING *)pobj)->strstart + ((STRING *)pobj)->strlen <= (char *)Buffer_bufstart(pobj) + Buffer_buflen(pobj)); 938 } 939 return; 940 } 941 cur_block = cur_block->prev; 942 } 943 PARROT_ASSERT(0); 944 } 945 946 /* 746 947 * Local variables: 747 948 * c-file-style: "parrot" 748 949 * End: -
src/call/pcc.c
1665 1665 * RT #54860 and others 1666 1666 * Save current value while setting the optional 1667 1667 */ 1668 const Union Val old_value = st->val;1668 const UnionCallStateVal old_value = st->val; 1669 1669 1670 1670 while (dest->sig & PARROT_ARG_OPTIONAL) { 1671 1671 null_val(st->dest.sig, st); -
src/gc/mark_sweep.c
33 33 34 34 static void free_buffer(SHIM_INTERP, 35 35 ARGMOD(Small_Object_Pool *pool), 36 ARGMOD( PObj*b))36 ARGMOD(Buffer *b)) 37 37 __attribute__nonnull__(2) 38 38 __attribute__nonnull__(3) 39 39 FUNC_MODIFIES(*pool) … … 41 41 42 42 static void free_buffer_malloc(SHIM_INTERP, 43 43 SHIM(Small_Object_Pool *pool), 44 ARGMOD( PObj*b))44 ARGMOD(Buffer *b)) 45 45 __attribute__nonnull__(3) 46 46 FUNC_MODIFIES(*b); 47 47 … … 54 54 55 55 PARROT_WARN_UNUSED_RESULT 56 56 PARROT_CANNOT_RETURN_NULL 57 static Small_Object_Pool * new_buffer_pool(PARROT_INTERP)58 __attribute__nonnull__(1);59 60 PARROT_WARN_UNUSED_RESULT61 PARROT_CANNOT_RETURN_NULL62 57 static Small_Object_Pool * new_bufferlike_pool(PARROT_INTERP, 63 58 size_t actual_buffer_size) 64 59 __attribute__nonnull__(1); … … 98 93 #define ASSERT_ARGS_free_pmc_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 99 94 PARROT_ASSERT_ARG(interp) \ 100 95 || PARROT_ASSERT_ARG(p) 101 #define ASSERT_ARGS_new_buffer_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \102 PARROT_ASSERT_ARG(interp)103 96 #define ASSERT_ARGS_new_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 104 97 PARROT_ASSERT_ARG(interp) 105 98 #define ASSERT_ARGS_new_pmc_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ … … 140 133 arena_base->gc_trace_ptr = NULL; 141 134 arena_base->gc_mark_start = NULL; 142 135 arena_base->num_early_PMCs_seen = 0; 143 arena_base->num_extended_PMCs = 0;144 136 } 145 137 146 138 /* … … 281 273 Parrot_gc_sweep_pool(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool)) 282 274 { 283 275 ASSERT_ARGS(Parrot_gc_sweep_pool) 276 PObj *b; 277 UINTVAL i; 284 278 UINTVAL total_used = 0; 285 279 const UINTVAL object_size = pool->object_size; 286 280 … … 301 295 } 302 296 #endif 303 297 304 /* Run through all the bufferheader pools and mark */298 /* Run through all the PObj header pools and mark */ 305 299 for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) { 306 Buffer *b = (Buffer *)cur_arena->start_objects; 307 UINTVAL i; 300 b = (PObj*)cur_arena->start_objects; 308 301 309 302 /* loop only while there are objects in the arena */ 310 303 for (i = cur_arena->total_objects; i; i--) { … … 349 342 pool->add_free_object(interp, pool, b); 350 343 } 351 344 next: 352 b = ( Buffer*)((char *)b + object_size);345 b = (PObj *)((char *)b + object_size); 353 346 } 354 347 } 355 348 … … 443 436 else 444 437 hi_prio = 0; 445 438 446 if ( obj->pmc_ext) {439 if (PObj_is_PMC_EXT_TEST(obj)) { 447 440 PMC * const tptr = arena_base->gc_trace_ptr; 448 449 ++arena_base->num_extended_PMCs;450 441 /* 451 442 * XXX this basically invalidates the high-priority marking 452 443 * of PMCs by putting all PMCs onto the front of the list. … … 803 794 804 795 #ifndef NDEBUG 805 796 806 pmc->pmc_ext = (PMC_EXT *)0xdeadbeef;807 797 pmc->vtable = (VTABLE *)0xdeadbeef; 808 798 809 799 #endif … … 835 825 Small_Object_Pool * const pool = 836 826 new_small_object_pool(buffer_size, num_headers); 837 827 838 pool->gc_object = NULL; 828 #ifdef GC_IS_MALLOC 829 pool->gc_object = free_buffer_malloc; 830 #else 831 pool->gc_object = (gc_object_fn_type)free_buffer; 832 #endif 833 839 834 pool->mem_pool = interp->arena_base->memory_pool; 840 835 (interp->arena_base->init_pool)(interp, pool); 841 836 return pool; … … 872 867 return pool; 873 868 } 874 869 875 876 877 870 /* 878 871 879 =item C<static Small_Object_Pool * new_buffer_pool(PARROT_INTERP)> 880 881 Creates a new C<Small_Object_Pool> structure for managing buffer objects. 872 =item C<static Small_Object_Pool * new_string_pool(PARROT_INTERP, INTVAL 873 constant)> 882 874 883 Non-constant strings and plain Buffers are stored in the sized header pools. 875 Creates a new pool for C<STRING>s and returns it. This calls 876 C<get_bufferlike_pool> internally, which in turn calls C<new_bufferlike_pool>. 884 877 885 878 =cut 886 879 … … 889 882 PARROT_WARN_UNUSED_RESULT 890 883 PARROT_CANNOT_RETURN_NULL 891 884 static Small_Object_Pool * 892 new_ buffer_pool(PARROT_INTERP)885 new_string_pool(PARROT_INTERP, INTVAL constant) 893 886 { 894 ASSERT_ARGS(new_buffer_pool) 895 Small_Object_Pool * const pool = get_bufferlike_pool(interp, sizeof (Buffer)); 887 ASSERT_ARGS(new_string_pool) 888 Small_Object_Pool *pool; 889 if (constant) { 890 pool = new_bufferlike_pool(interp, sizeof (STRING)); 891 pool->gc_object = NULL; 892 pool->mem_pool = interp->arena_base->constant_string_pool; 893 } 894 else 895 pool = get_bufferlike_pool(interp, sizeof (STRING)); 896 896 897 #ifdef GC_IS_MALLOC 898 pool->gc_object = free_buffer_malloc; 899 #else 900 pool->gc_object = free_buffer; 901 #endif 897 pool->objects_per_alloc = STRING_HEADERS_PER_ALLOC; 902 898 903 899 return pool; 904 900 } … … 918 914 919 915 static void 920 916 free_buffer_malloc(SHIM_INTERP, SHIM(Small_Object_Pool *pool), 921 ARGMOD( PObj*b))917 ARGMOD(Buffer *b)) 922 918 { 923 919 ASSERT_ARGS(free_buffer_malloc) 924 920 /* free allocated space at (int *)bufstart - 1, but not if it used COW or is 925 921 * external */ 926 PObj_buflen(b) = 0;922 Buffer_buflen(b) = 0; 927 923 928 if (! PObj_bufstart(b) || PObj_is_external_or_free_TESTALL(b))924 if (!Buffer_bufstart(b) || PObj_is_external_or_free_TESTALL(b)) 929 925 return; 930 926 931 927 if (PObj_COW_TEST(b)) { 932 INTVAL * const refcount = PObj_bufrefcountptr(b);928 INTVAL * const refcount = Buffer_bufrefcountptr(b); 933 929 934 930 if (--(*refcount) == 0) { 935 931 mem_sys_free(refcount); /* the actual bufstart */ 936 932 } 937 933 } 938 934 else 939 mem_sys_free( PObj_bufrefcountptr(b));935 mem_sys_free(Buffer_bufrefcountptr(b)); 940 936 } 941 937 942 938 /* … … 952 948 */ 953 949 954 950 static void 955 free_buffer(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGMOD( PObj*b))951 free_buffer(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGMOD(Buffer *b)) 956 952 { 957 953 ASSERT_ARGS(free_buffer) 958 954 Memory_Pool * const mem_pool = (Memory_Pool *)pool->mem_pool; … … 961 957 * shouldn't happen */ 962 958 if (mem_pool) { 963 959 if (!PObj_COW_TEST(b)) 964 mem_pool->guaranteed_reclaimable += PObj_buflen(b);960 mem_pool->guaranteed_reclaimable += Buffer_buflen(b); 965 961 966 mem_pool->possibly_reclaimable += PObj_buflen(b);962 mem_pool->possibly_reclaimable += Buffer_buflen(b); 967 963 } 968 964 969 PObj_buflen(b) = 0;965 Buffer_buflen(b) = 0; 970 966 } 971 967 972 968 973 969 /* 974 970 975 =item C<static Small_Object_Pool * new_string_pool(PARROT_INTERP, INTVAL976 constant)>977 978 Creates a new pool for C<STRING>s and returns it. This calls979 C<get_bufferlike_pool> internally, which in turn calls C<new_bufferlike_pool>.980 981 =cut982 983 */984 985 PARROT_WARN_UNUSED_RESULT986 PARROT_CANNOT_RETURN_NULL987 static Small_Object_Pool *988 new_string_pool(PARROT_INTERP, INTVAL constant)989 {990 ASSERT_ARGS(new_string_pool)991 Small_Object_Pool *pool;992 if (constant) {993 pool = new_bufferlike_pool(interp, sizeof (STRING));994 pool->mem_pool = interp->arena_base->constant_string_pool;995 }996 else997 pool = get_bufferlike_pool(interp, sizeof (STRING));998 999 pool->objects_per_alloc = STRING_HEADERS_PER_ALLOC;1000 1001 return pool;1002 }1003 1004 1005 /*1006 1007 971 =item C<Small_Object_Pool * get_bufferlike_pool(PARROT_INTERP, size_t 1008 972 buffer_size)> 1009 973 … … 1076 1040 * The buffer_header_pool and the string_header_pool actually live in the 1077 1041 * sized_header_pools. These pool pointers only provide faster access in 1078 1042 * new_*_header */ 1079 arena_base->buffer_header_pool = new_buffer_pool(interp);1080 arena_base->buffer_header_pool->name = "buffer_header";1043 // arena_base->buffer_header_pool = new_buffer_pool(interp); 1044 // arena_base->buffer_header_pool->name = "buffer_header"; 1081 1045 1082 1046 /* Init the string header pool */ 1083 1047 arena_base->string_header_pool = new_string_pool(interp, 0); … … 1087 1051 arena_base->pmc_pool = new_pmc_pool(interp); 1088 1052 arena_base->pmc_pool->name = "pmc"; 1089 1053 1090 /* pmc extension buffer */1091 arena_base->pmc_ext_pool =1092 new_small_object_pool(sizeof (PMC_EXT), 1024);1093 1094 #if PARROT_GC_MS1095 /*1096 * pmc_ext isn't a managed item. If a PMC has a pmc_ext structure1097 * it is returned to the pool instantly - the structure is never1098 * marked.1099 * Use GS MS pool functions1100 */1101 gc_ms_pmc_ext_pool_init(arena_base->pmc_ext_pool);1102 #elif PARROT_GC_INF1103 arena_base->init_pool(interp, arena_base->pmc_ext_pool);1104 #else1105 /* rational, consistant behavior (as yet unwritten) */1106 #endif1107 1108 arena_base->pmc_ext_pool->name = "pmc_ext";1109 1110 1054 /* constant PMCs */ 1111 1055 arena_base->constant_pmc_pool = new_pmc_pool(interp); 1112 1056 arena_base->constant_pmc_pool->name = "constant_pmc"; -
src/jit_debug_xcoff.c
118 118 fprintf(stabs, ".stabx \"STRING:t%d=*%d\"" 119 119 ",0," C_DECL ",0\n", i, i+1); 120 120 ++i; 121 fprintf(stabs, ".stab x \"Parrot_String:T%d=s%d"122 "bufstart: 14,%d,%d;"123 "buflen: 6,%d,%d;" /* XXX type */124 "flags: 12,%d,%d;"125 "bufused: 12,%d,%d;"126 "strstart: 15,%d,%d;" /* fake a char* */121 fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d" 122 "bufstart:(0,14),%d,%d;" 123 "buflen:(0,6),%d,%d;" 124 "flags:(0,12),%d,%d;" 125 "bufused:(0,12),%d,%d;" 126 "strstart:(0,15),%d,%d;" 127 127 ";\"" 128 ", 0," C_DECL ",0\n", i++, BYTE_SIZE(STRING),129 BIT_OFFSET(STRING, cache._b._bufstart), BIT_SIZE(void*),130 BIT_OFFSET(STRING, cache._b._buflen), BIT_SIZE(size_t),128 "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING), 129 BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*), 130 BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t), 131 131 BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL), 132 132 BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL), 133 133 BIT_OFFSET(STRING, strstart), BIT_SIZE(void*)); 134 134 135 fprintf(stabs, ".stab x \"PMCType:T%d=e", i++);135 fprintf(stabs, ".stabs \"PMCType:T(0,%d)=e", i++); 136 136 for (j = 0; j < interp->n_vtable_max; ++j) { 137 137 if (interp->vtables[j] && interp->vtables[j]->whoami) { 138 STRING* name = interp->vtables[j]->whoami; 139 fwrite(name->strstart, name->strlen, 1, stabs); 138 STRING *name = interp->vtables[j]->whoami; 139 size_t items = fwrite(name->strstart, name->strlen, 1, stabs); 140 if (!items) 141 fprintf(stderr, "Error writing stabs!\n"); 140 142 fprintf(stabs, ":%d,", j); 141 143 } 142 144 } 143 fprintf(stabs, ";\",0," C_DECL ",0\n");144 145 145 /* PMC type */ 146 fprintf(stabs, ".stabx \"PMC:T%d=s%d", i, BYTE_SIZE(PMC)); 147 fprintf(stabs, "cache:%d,%d,%d;", 148 i + 1, BIT_OFFSET(PMC, cache), BIT_SIZE(UnionVal)); 149 fprintf(stabs, "flags:%d,%d,%d;", 150 i + 1, BIT_OFFSET(PMC, flags), BIT_SIZE(Parrot_UInt)); 151 fprintf(stabs, "vtable:*%d,%d,%d;", 152 i + 3, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*)); 153 fprintf(stabs, "data:14,%d,%d;", 154 BIT_OFFSET(PMC, data), BIT_SIZE(void*)); 155 fprintf(stabs, "pmc_ext:*%d,%d,%d;", 156 i, BIT_OFFSET(PMC, pmc_ext), BIT_SIZE(void*)); 157 fprintf(stabs, ";\""); 158 fprintf(stabs, ",0," C_DECL ",0\n"); 146 fprintf(stabs, ";\"," N_LSYM ",0,0,0\n"); 159 147 160 fprintf(stabs, ".stabx \"cache:%d,%d,%d;" 161 "flags:12,%d,%d;" 162 ";\"" 163 ",0," C_DECL ",0\n", 164 i + 2, BIT_SIZE(UnionVal), BIT_SIZE(Parrot_UInt)); 165 fprintf(stabs, ".stabx \"UnionVal:T%d=u%d" 166 "int_val:12,%d,%d;" 167 "pmc_val:*%d,%d,%d;" 148 fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d" 149 "flags:(0,12),%d,%d;" 150 "vtable:*(0,%d),%d,%d;" 151 "data:(0,14),%d,%d;" 152 "_metadata:*(0,%d),%d,%d;" 153 "_next_for_GC:*(0,%d),%d,%d;" 168 154 ";\"" 169 ",0," C_DECL ",0\n", i + 2, BYTE_SIZE(UnionVal), 170 BIT_OFFSET(UnionVal, int_val), BIT_SIZE(INTVAL), 171 i, BIT_OFFSET(UnionVal, pmc_val), BIT_SIZE(void*)); 172 fprintf(stabs, ".stabx \"VTABLE:T%d=s%d" 173 "base_type:%d,%d,%d;" 155 "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC), 156 BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL), 157 i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*), 158 BIT_OFFSET(PMC, data), BIT_SIZE(void*), 159 i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*), 160 i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*)); 161 162 i++; 163 164 //some one can add some field to this one 165 fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d" 166 "base_type:(0,12),%d,%d;" 174 167 ";\"" 175 ",0," C_DECL ",0\n", i + 3, BYTE_SIZE(UnionVal), 176 i - 1, BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); 177 i += 4; 168 "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable), 169 BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); 170 171 i++; 178 172 179 173 } 180 174 -
docs/memory_internals2.pod
1 =head1 NAME 2 3 docs/memory_internals2.pod - Memory Internals extra documentation 4 5 =head1 ABSTRACT 6 7 This explanation of the memory system gives a bit more explanation of the memory/gc 8 system used by parrot. 9 10 =head2 Used memory management systems 11 12 The memory system basically uses 3 types of memory management systems 13 14 =over 4 15 16 =item 1 The standard c allocate system 17 18 =item 2 Memory pool system. 19 20 This system has the following to purposes. 21 22 =over 8 23 24 =item * Variable sized objects are stored in a more compact way. 25 26 =item * There is a compacting function to compact the data 27 28 =back 29 30 This compacting function is working in conjunction with the small object pool system(see next section). 31 A C<Memory_pool> contains multiple C<Memory_bloc> objects. The more memory is needed 32 the more C<Memory_bloc> items are added. C<Memory_bloc> items are allocated via the c allocate system. 33 A memory pool contain variable sized buffers, such as strings. 34 35 =item 3 Smalls Object pool system. 36 37 This is used for efficient storage of small object with constant sizes 38 which are allocated and released many times. 39 40 =back 41 42 =head2 Small object pool system 43 44 All objects in the small object system are of type C<PObj> 45 46 typedef struct pobj_t { 47 Parrot_UInt flags; 48 } PObj; 49 50 This struct is "sub classed" by the following 3 structs 51 52 =over 4 53 54 =item * GC_MS_PObj_Wrapper, this struct is used when object are on the free list 55 56 typedef struct GC_MS_PObj_Wrapper { 57 size_t flags; 58 struct GC_MS_PObj_Wrapper * next_ptr; 59 } GC_MS_PObj_Wrapper; 60 61 =item * Buffer, this struct is used for object which hold a buffer 62 63 typedef struct buffer_t { 64 Parrot_UInt flags; 65 void * _bufstart; 66 size_t _buflen; 67 } Buffer; 68 69 =item * PMC, the all important pmc :) 70 71 struct PMC { 72 Parrot_UInt flags; 73 VTABLE *vtable; 74 DPOINTER *data; 75 PMC *_metadata; /* object properties */ 76 struct _Sync *_synchronize; 77 PMC *_next_for_GC; 78 }; 79 80 =back 81 82 The Buffer struct, is "sub classed" by the following 3 structs 83 84 =over 4 85 86 =item * String 87 88 struct parrot_string_t { 89 Parrot_UInt flags; 90 void * _bufstart; 91 size_t _buflen; 92 93 char *strstart; 94 UINTVAL bufused; 95 UINTVAL strlen; 96 UINTVAL hashval; /* cached hash value computation */ 97 98 /* parrot_string_representation_t representation;*/ 99 const struct _encoding *encoding; 100 const struct _charset *charset; 101 }; 102 103 =item * List_chunk 104 105 =item * List 106 107 =back 108 109 See pobj.h for information on the available flags, notice there is a flag indicating that 110 the object is on the free list. 111 112 The memory system is aware of 3 types of small object pools. 113 114 =over 4 115 116 =item 1 Those pools with a reference to a variable buffer in C<< Arenas->Memory >>. 117 118 These pools must apply to the following things 119 120 =over 8 121 122 =item * They must be present in the sized_header_pools list 123 124 =item * All object they contain must be of the type PObj 125 126 typedef struct buffer_t { 127 Parrot_UInt flags; 128 void * _bufstart; 129 size_t _buflen; 130 } Buffer; 131 132 =item * All these field are used by the compact function of the memory pool system. 133 134 =item * These objects support COW (Copy on Write) flag 135 136 =back 137 138 Currently used by 139 140 =over 8 141 142 =item * non constant Strings 143 144 =item * list.c for storage of list buffer 145 146 =back 147 148 =item 2 The pool for the constant string. 149 150 It uses the C<< Anenas->constant_string_pool >>, which is not compacted. 151 Constant strings are not released back system during runtime. 152 153 154 =item 3 The pool of objects without a reference to a variable buffer. 155 156 Currently used by 157 158 =over 8 159 160 =item * PMC items. 161 162 =item * constant PMC items. 163 164 =back 165 166 A Small_Object_Pool contains multiple Small_Object_Arena items. Arena's 167 are added as more memory is need for the pool. These Arena's are 168 allocated from the c allocate system. 169 170 =head2 Summarization of Arenas struct 171 172 A small summarize of the memory related items in the C<Arenas> struct. 173 174 typedef struct Arenas { 175 /*Memory for buffers used by the small object of type 1*/ 176 Memory_Pool *memory_pool; 177 /*Memory for buffers used by the small object of type 2 -> the constant strings */ 178 Memory_Pool *constant_string_pool; 179 /*Pool of type 1, used for storage of the string header*/ 180 struct Small_Object_Pool *string_header_pool; 181 /*Pool of type 3, used for storage of the pmc objects*/ 182 struct Small_Object_Pool *pmc_pool; 183 /*Pool of type 3, used for storage of pmc object which have constant flag*/ 184 struct Small_Object_Pool *constant_pmc_pool 185 /*Pool of type 2, used for storage of the headers of the constant strings*/ 186 struct Small_Object_Pool *constant_string_header_pool; 187 /*Containts all the Small_Object_Pool of type 1. Which are 188 1. string_header_pool 189 2. buffer storage used by list.c (struct List_chunk) 190 */ 191 struct Small_Object_Pool **sized_header_pools; 192 /*Number of elements in sized_header_pools, be aware of the fact this equal to 193 the "buffer header" / sizeof(void*) 194 size_t num_sized; 195 ... 196 197 =head2 Function summarization 198 199 Here is grouped summarization of the interesting functions of the garbage collecting system 200 to give a better overview of them. 201 202 =head3 Memory pool system 203 204 These function are responsible for the Memory pool system. 205 206 C<alloc_new_block> This function adds a new block to a memory pool 207 208 C<mem_allocate> This function allocates a buffer in a memory pool 209 210 C<compact_pool> This function compacts the memory buffer system 211 212 C<new_memory_pool> This function inits a new memory pool 213 214 C<initialize_memory_pools> This function initializes the to memory pools 215 216 C<merge_pools> This function merges to memory pools together, this is used for merging to interpreters 217 together 218 219 C<Parrot_gc_destroy_memory_pools> This function released the memory pools 220 221 C<Parrot_gc_compact_memory_pool> The public api to compact the memory pools 222 223 =head3 Garbage collecting 224 225 The garbage collecting system exits out of the following steps. See the other 226 memory internals documentation for more information. 227 228 =over 4 229 230 =item * First phase marking off all objects, follows all links except the C<< pmc->_metadata >> link 231 232 =item * Second phase marking off all objects, which follows the C<< pmc->_metadata >> links 233 234 =item * Sweep all the pools of dead objects 235 236 =back 237 238 In the first phase all object with pmc extension are put in a list which is linked via the 239 C<< pmc->_next_for_GC >> field. Then in the second phase this list is walked down, to continue the 240 marking. These 2 phased marking of objects is used for a prioritization system. (not 241 documented here) 242 243 These functions are responsible for the garbage collecting system. 244 245 C<Parrot_gc_mark_and_sweep> The public api to run a gc 246 247 C<gc_ms_mark_and_sweep> Runs the stop-the-world mark & sweep (MS) collector. 248 249 C<Parrot_gc_run_init> Clears some fields before a gc run is started 250 251 C<Parrot_gc_clear_live_bits> This function clears the live bit of all the objects in a pool, called before the mark phase 252 253 C<gc_ms_trace_active_PMCs> Calls the 2 mark phase functions 254 255 C<Parrot_gc_mark_PObj_alive> Public api to mark a given object as live 256 257 C<mark_special> Does all necessary thing to mark object as alive and walks downs the links 258 259 C<Parrot_gc_trace_root> This function perform the first phase of the marking of all the objects 260 261 C<Parrot_gc_trace_children> This function perform the second phase of the marking of all the objects 262 263 C<gc_ms_sweep_cb> This function sweeps all the pools, using the iterate util function 264 265 C<Parrot_gc_sweep_pool> Sweep a pool and releases the dead objects 266 267 =head4 C<< pmc->_next_for_GC >> cleanup 268 269 These 2 function are used to clean of the C<< pmc->_next_for_GC >> fields in the 270 small object pools. This is used by pmc_freeze.c 271 272 C<Parrot_gc_cleanup_next_for_GC> 273 C<cleanup_next_for_GC_pool> 274 275 =head3 Small object pool objects 276 277 These functions are responsible for allocation and freeing of object 278 which make use of the small object pools 279 280 C<gc_ms_add_free_object> Releases a PObj to a small object pool 281 282 C<gc_ms_get_free_object> Allocates a PObj from a small object pool 283 284 C<gc_ms_alloc_objects> Increases the small object pool with fresh arena so new free object becomes available 285 286 C<gc_ms_more_traceable_objects> Tries to free object in the small object pool by using the gc system 287 288 =head3 Small object pool Arena's 289 290 These function are responsible for the arena system in a small object pool. 291 292 C<Parrot_append_arena_in_pool> Allocates a new arena and add it to the pool 293 294 C<Parrot_add_to_free_list> Initialized a new arena pool, by adding the free space to the free list 295 296 =head3 Pmc header(ext) 297 298 These function are the public api for the pmc objects (type 3). 299 In the past there was a separate pmc_ext structure which was separately allocated, but 300 is now integrated into the pmc header. 301 302 C<Parrot_gc_new_pmc_header> Allocate/init a new pmc header 303 304 C<Parrot_gc_free_pmc_header> Releases a pmc header 305 306 C<Parrot_gc_add_pmc_ext> Adds pmc ext capabilities to a pmc 307 308 C<Parrot_gc_free_pmc_ext> Remove pmc ext capabilities from a pmc 309 310 C<Parrot_gc_add_pmc_sync> Add synchronization capability to a pmc 311 312 =head3 Buffer header (including strings) 313 314 These functions are the api function for object which have buffer capabilities (type 1 & 2) 315 These function does not allocate the buffer itself. 316 Allocation of a buffer like object, such as a string, takes place in two phases. 317 First the header is allocated from a constant memory pool and after that 318 a buffer is allocated form the Memory pool system. See next group of function 319 for actual allocation of the buffer. 320 321 C<Parrot_gc_new_string_header> Allocate a new String header 322 323 C<Parrot_gc_free_string_header> Releases the String header 324 325 C<Parrot_gc_new_bufferlike_header> Allocate a new buffer header 326 327 C<Parrot_gc_free_bufferlike_header> Allocate a new buffer header 328 329 C<get_free_buffer> Allocates/init a buffer like object of given size 330 331 The following functions are used for alignment 332 333 C<aligned_size> 334 335 C<aligned_mem> 336 337 C<aligned_string_size> 338 339 =head4 C<get_bufferlike_pool> 340 341 C<get_bufferlike_pool> Is used by the Parrot_gc_new_bufferlike_header function to get 342 the small object pool with the right size. If does not exist it creates 343 a new small object pool. The small object pool is stored in the C<< arenas->sized_header_pools >> 344 list. This list only contain small object pools which hold buffer header objects, of which the 345 buffer is stored in the C<< arena->memory pool >>. 346 347 =head3 Buffer allocation 348 349 These function are responsible for the allocation a the actual buffer of a 350 buffer object. 351 352 C<Parrot_gc_allocate_buffer_storage_aligned> 353 354 C<Parrot_gc_reallocate_buffer_storage> 355 356 C<Parrot_gc_allocate_string_storage> 357 358 C<Parrot_gc_reallocate_string_storage> 359 360 =head3 Initialization 361 362 These functions are responsible for the initialization of the gc system 363 364 365 C<Parrot_gc_initialize> The public api to initialize the gc system 366 367 C<Parrot_gc_ms_init> The init function of the gc 368 369 C<initialize_memory_pools> This function initializes the memory pools 370 371 C<initialize_header_pools> This function initializes the small object pools 372 373 C<new_pmc_pool> This function creates pool which contains pmc object 374 375 C<new_small_object_pool> This function creates a small object pool 376 377 C<gc_ms_pool_init> This function initializes a small object pool 378 379 C<new_string_pool> This function creates a small object pool for string headers 380 381 C<new_bufferlike_pool> This function creates a small object pool for buffer header 382 383 Note that C<new_bufferlike_pool> does not register the pool in the 384 C<< Arenas->sized_header_pools >> list, which must be done if 385 you make use of the C<< Arenas->memory_pool >> 386 387 =head3 Finalization 388 389 These functions are responsible for the finalization of the gc system 390 391 392 C<Parrot_gc_finalize> public api to finalize the gc system 393 394 C<gc_ms_finalize> This function finalizes the gc system 395 396 C<Parrot_gc_destroy_header_pools> This function destroys all small object pools 397 398 These two function are used to free all the object in a small object pool 399 400 C<sweep_cb_pmc> 401 402 C<sweep_cb_buf> 403 404 C<free_pool> This function released the arenas and pool back to the system 405 406 =head4 PObj removal 407 408 These function are called when a PObj in a small object pool get released by the gc system 409 410 C<free_buffer> This function frees the associated buffer in the memory pool 411 412 C<free_buffer_malloc> existing but dead at the moment 413 414 C<free_pmc_in_pool> This function releases a pmc object, does finalization if needed 415 416 =head3 Intrepreter merging 417 418 The following functions are used for merging two interpreters together 419 420 C<Parrot_gc_merge_header_pools> 421 422 C<Parrot_gc_merge_buffer_pools> 423 424 C<fix_pmc_syncs> 425 426 =head2 Util functions 427 428 These are various util functions 429 430 C<header_pools_iterate_callback> This function iterates over all the small object pools 431 432 C<Parrot_gc_ptr_in_memory_pool> 433 434 C<Parrot_gc_ptr_is_pmc> 435 436 C<Parrot_gc_get_pmc_index> 437 438 C<Parrot_gc_active_sized_buffers> 439 440 C<Parrot_gc_total_sized_buffers> 441 442 C<Parrot_gc_active_pmcs> 443 444 C<Parrot_gc_total_pmcs> 445 446 C<Parrot_gc_count_mark_runs> 447 448 C<Parrot_gc_count_collect_runs> 449 450 C<Parrot_gc_count_lazy_mark_runs> 451 452 C<Parrot_gc_total_memory_allocated> 453 454 C<Parrot_gc_headers_alloc_since_last_collect> 455 456 C<Parrot_gc_mem_alloc_since_last_collect> 457 458 C<Parrot_gc_total_copied> 459 460 C<Parrot_gc_impatient_pmcs> 461 462 C<contained_in_pool> 463 464 C<Parrot_gc_profile_start> 465 466 C<Parrot_gc_profile_end> 467 468 =head3 Blocking 469 470 The following function are used the block the gc from running 471 472 C<Parrot_block_GC_mark> 473 474 C<Parrot_unblock_GC_mark> 475 476 C<Parrot_block_GC_sweep> 477 478 C<Parrot_unblock_GC_sweep> 479 480 C<Parrot_is_blocked_GC_mark> 481 482 C<Parrot_is_blocked_GC_sweep> 483 484 C<Parrot_gc_completely_unblock> 485 486 =head3 Memory Assertion check 487 488 These functions can be used for debugging purpose to see whether the memory system is 489 not corrupted. 490 491 C<check_memory_system> Check the complete memory system 492 493 C<check_small_object_pool> Checks a small object pool 494 495 C<check_memory_pool> Check a memory pool 496 497 C<check_buffer_ptr> Check buffer header to see whether the buffer is in bounds of memory pool 498 499 =head1 AUTHOR 500 501 Jesse van Dam C<jessevdam@hotmail.com> 502 503 =head1 VERSION 504 505 0.1 Augustus 2009 506 507 -
include/parrot/gc_api.h
239 239 __attribute__nonnull__(1); 240 240 241 241 void Parrot_gc_free_bufferlike_header(PARROT_INTERP, 242 ARGMOD( PObj*obj),242 ARGMOD(Buffer *obj), 243 243 size_t size) 244 244 __attribute__nonnull__(1) 245 245 __attribute__nonnull__(2) -
src/string/charset/unicode.c
440 440 441 441 /* use all available space - see below XXX */ 442 442 /* TODO downcase, titlecase too */ 443 dest_len = PObj_buflen(src) / sizeof (UChar);443 dest_len = Buffer_buflen(src) / sizeof (UChar); 444 444 src_len = src->bufused / sizeof (UChar); 445 445 446 446 /* -
src/gc/incremental_ms.c
519 519 { 520 520 ASSERT_ARGS(gc_ims_add_free_object) 521 521 *(void **)to_add = pool->free_list; 522 pool->free_list = to_add;522 pool->free_list = (GC_MS_PObj_Wrapper*)to_add; 523 523 #if DISABLE_GC_DEBUG 524 524 UNUSED(interp); 525 525 #else … … 561 561 (*pool->alloc_objects) (interp, pool); 562 562 563 563 ptr = (PObj *)pool->free_list; 564 pool->free_list = *(void **)ptr;564 pool->free_list = (GC_MS_PObj_Wrapper*)(*(void **)ptr); 565 565 566 566 /* 567 567 * buffers are born black, PMCs not yet? … … 829 829 830 830 g_ims->state = GC_IMS_COLLECT; 831 831 g_ims->n_objects = n_objects; 832 g_ims->n_extended_PMCs = arena_base->num_extended_PMCs;833 832 } 834 833 835 834 -
include/parrot/list.h
15 15 #define PARROT_LIST_H_GUARD 16 16 17 17 typedef struct List_chunk { 18 Buffer data; /* item store 18 Buffer data; /* item store, Buffer must be first element in struct*/ 19 19 struct List_chunk *next; 20 20 struct List_chunk *prev; 21 21 UINTVAL flags; /* chunk flags */ -
src/string/encoding/utf8.c
525 525 526 526 i->bytepos += (new_pos - pos); 527 527 /* XXX possible buffer overrun exception? */ 528 PARROT_ASSERT(i->bytepos <= PObj_buflen(s));528 PARROT_ASSERT(i->bytepos <= Buffer_buflen(s)); 529 529 i->charpos++; 530 530 } 531 531 -
src/gc/api.c
229 229 mark_special(interp, p); 230 230 231 231 # ifndef NDEBUG 232 else if ( p->pmc_ext &&PMC_metadata(p))232 else if (PMC_metadata(p)) 233 233 fprintf(stderr, "GC: error obj %p (%s) has properties\n", 234 234 (void *)p, (char*)p->vtable->whoami->strstart); 235 235 # endif … … 238 238 /* buffer GC_DEBUG stuff */ 239 239 if (GC_DEBUG(interp) && PObj_report_TEST(obj)) 240 240 fprintf(stderr, "GC: buffer %p pointing to %p marked live\n", 241 obj, PObj_bufstart((Buffer *)obj));241 obj, Buffer_bufstart((Buffer *)obj)); 242 242 # endif 243 243 #endif /* PARROT_GC_GMS */ 244 244 } … … 336 336 337 337 /* clear flags, set is_PMC_FLAG */ 338 338 if (flags & PObj_is_PMC_EXT_FLAG) { 339 Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool;340 339 flags |= PObj_is_special_PMC_FLAG; 341 pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool);342 340 343 341 if (flags & PObj_is_PMC_shared_FLAG) 344 342 Parrot_gc_add_pmc_sync(interp, pmc); 345 343 } 346 else347 pmc->pmc_ext = NULL;348 344 349 345 PObj_get_FLAGS(pmc) = PObj_is_PMC_FLAG|flags; 350 346 pmc->vtable = NULL; … … 397 393 Parrot_gc_add_pmc_ext(PARROT_INTERP, ARGMOD(PMC *pmc)) 398 394 { 399 395 ASSERT_ARGS(Parrot_gc_add_pmc_ext) 400 Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool; 401 if (!pmc->pmc_ext) 402 pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool); 403 if (!pmc->pmc_ext) 404 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR, 405 "Parrot VM: PMC_EXT allocation failed!\n"); 396 406 397 PObj_is_PMC_EXT_SET(pmc); 407 398 PObj_is_special_PMC_SET(pmc); 408 399 … … 434 425 { 435 426 ASSERT_ARGS(Parrot_gc_free_pmc_ext) 436 427 /* if the PMC has a PMC_EXT structure, return it to the pool/arena */ 437 Arenas * const arena_base = interp->arena_base;438 Small_Object_Pool * const ext_pool = arena_base->pmc_ext_pool;439 428 440 if (! p->pmc_ext)429 if (!PObj_is_PMC_EXT_TEST(p)) 441 430 return; 442 431 443 432 if (PObj_is_PMC_shared_TEST(p) && PMC_sync(p)) { … … 445 434 mem_internal_free(PMC_sync(p)); 446 435 PMC_sync(p) = NULL; 447 436 } 448 ext_pool->add_free_object(interp, ext_pool, p->pmc_ext);449 ext_pool->num_free_objects++;450 p->pmc_ext = NULL;451 437 } 452 438 453 439 /* … … 499 485 Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags) 500 486 { 501 487 ASSERT_ARGS(Parrot_gc_new_string_header) 488 502 489 STRING * const string = (STRING *)get_free_buffer(interp, 503 490 (flags & PObj_constant_FLAG) 504 491 ? interp->arena_base->constant_string_header_pool … … 553 540 Parrot_gc_new_bufferlike_header(PARROT_INTERP, size_t size) 554 541 { 555 542 ASSERT_ARGS(Parrot_gc_new_bufferlike_header) 543 556 544 Small_Object_Pool * const pool = get_bufferlike_pool(interp, size); 557 545 558 546 return get_free_buffer(interp, pool); … … 576 564 get_free_buffer(PARROT_INTERP, ARGIN(Small_Object_Pool *pool)) 577 565 { 578 566 ASSERT_ARGS(get_free_buffer) 579 PObj * const buffer = (PObj*)pool->get_free_object(interp, pool);567 Buffer * const buffer = (Buffer *)pool->get_free_object(interp, pool); 580 568 581 569 /* don't mess around with flags */ 582 PObj_bufstart(buffer) = NULL;583 PObj_buflen(buffer) = 0;570 Buffer_bufstart(buffer) = NULL; 571 Buffer_buflen(buffer) = 0; 584 572 585 if (pool->object_size - GC_HEADER_SIZE > sizeof ( PObj))573 if (pool->object_size - GC_HEADER_SIZE > sizeof (Buffer)) 586 574 memset(buffer + 1, 0, 587 pool->object_size - sizeof ( PObj) - GC_HEADER_SIZE);575 pool->object_size - sizeof (Buffer) - GC_HEADER_SIZE); 588 576 589 577 return buffer; 590 578 } … … 602 590 */ 603 591 604 592 void 605 Parrot_gc_free_bufferlike_header(PARROT_INTERP, ARGMOD( PObj*obj),593 Parrot_gc_free_bufferlike_header(PARROT_INTERP, ARGMOD(Buffer *obj), 606 594 size_t size) 607 595 { 608 596 ASSERT_ARGS(Parrot_gc_free_bufferlike_header) … … 631 619 size_t new_size; 632 620 char *mem; 633 621 634 PObj_buflen(buffer) = 0;635 PObj_bufstart(buffer) = NULL;622 Buffer_buflen(buffer) = 0; 623 Buffer_bufstart(buffer) = NULL; 636 624 new_size = aligned_size(buffer, size); 637 625 mem = (char *)mem_allocate(interp, new_size, 638 626 interp->arena_base->memory_pool); 639 627 mem = aligned_mem(buffer, mem); 640 PObj_bufstart(buffer) = mem;628 Buffer_bufstart(buffer) = mem; 641 629 if (PObj_is_COWable_TEST(buffer)) 642 630 new_size -= sizeof (void*); 643 PObj_buflen(buffer) = new_size;631 Buffer_buflen(buffer) = new_size; 644 632 } 645 633 646 634 /* … … 671 659 /* 672 660 * we don't shrink buffers 673 661 */ 674 if (newsize <= PObj_buflen(buffer))662 if (newsize <= Buffer_buflen(buffer)) 675 663 return; 676 664 677 665 /* … … 683 671 * The normal case is therefore always to allocate a new block 684 672 */ 685 673 new_size = aligned_size(buffer, newsize); 686 old_size = aligned_size(buffer, PObj_buflen(buffer));674 old_size = aligned_size(buffer, Buffer_buflen(buffer)); 687 675 needed = new_size - old_size; 688 676 689 677 if ((pool->top_block->free >= needed) 690 && (pool->top_block->top == (char *) PObj_bufstart(buffer) + old_size)) {678 && (pool->top_block->top == (char *)Buffer_bufstart(buffer) + old_size)) { 691 679 pool->top_block->free -= needed; 692 680 pool->top_block->top += needed; 693 PObj_buflen(buffer) = newsize;681 Buffer_buflen(buffer) = newsize; 694 682 return; 695 683 } 696 684 697 copysize = PObj_buflen(buffer);685 copysize = Buffer_buflen(buffer); 698 686 699 687 if (!PObj_COW_TEST(buffer)) 700 688 pool->guaranteed_reclaimable += copysize; … … 706 694 /* We shouldn't ever have a 0 from size, but we do. If we can track down 707 695 * those bugs, this can be removed which would make things cheaper */ 708 696 if (copysize) 709 memcpy(mem, PObj_bufstart(buffer), copysize);697 memcpy(mem, Buffer_bufstart(buffer), copysize); 710 698 711 PObj_bufstart(buffer) = mem;699 Buffer_bufstart(buffer) = mem; 712 700 713 701 if (PObj_is_COWable_TEST(buffer)) 714 702 new_size -= sizeof (void *); 715 703 716 PObj_buflen(buffer) = new_size;704 Buffer_buflen(buffer) = new_size; 717 705 } 718 706 719 707 /* … … 739 727 Memory_Pool *pool; 740 728 char *mem; 741 729 742 PObj_buflen(str) = 0;743 PObj_bufstart(str) = NULL;730 Buffer_buflen(str) = 0; 731 Buffer_bufstart(str) = NULL; 744 732 745 733 /* there's no sense in allocating zero memory, when the overhead of 746 734 * allocating a string is one pointer; this can fill the pools in an … … 757 745 mem = (char *)mem_allocate(interp, new_size, pool); 758 746 mem += sizeof (void*); 759 747 760 PObj_bufstart(str) = str->strstart = mem;761 PObj_buflen(str) = new_size - sizeof (void*);748 Buffer_bufstart(str) = str->strstart = mem; 749 Buffer_buflen(str) = new_size - sizeof (void*); 762 750 } 763 751 764 752 /* … … 789 777 : interp->arena_base->memory_pool; 790 778 791 779 /* if the requested size is smaller then buflen, we are done */ 792 if (newsize <= PObj_buflen(str))780 if (newsize <= Buffer_buflen(str)) 793 781 return; 794 782 795 783 /* … … 798 786 * - if there is enough size, we can just move the pool's top pointer 799 787 */ 800 788 new_size = aligned_string_size(newsize); 801 old_size = aligned_string_size( PObj_buflen(str));789 old_size = aligned_string_size(Buffer_buflen(str)); 802 790 needed = new_size - old_size; 803 791 804 792 if (pool->top_block->free >= needed 805 && pool->top_block->top == (char *) PObj_bufstart(str) + old_size) {793 && pool->top_block->top == (char *)Buffer_bufstart(str) + old_size) { 806 794 pool->top_block->free -= needed; 807 795 pool->top_block->top += needed; 808 PObj_buflen(str) = new_size - sizeof (void*);796 Buffer_buflen(str) = new_size - sizeof (void*); 809 797 return; 810 798 } 811 799 … … 815 803 copysize = str->bufused; 816 804 817 805 if (!PObj_COW_TEST(str)) 818 pool->guaranteed_reclaimable += PObj_buflen(str);806 pool->guaranteed_reclaimable += Buffer_buflen(str); 819 807 820 pool->possibly_reclaimable += PObj_buflen(str);808 pool->possibly_reclaimable += Buffer_buflen(str); 821 809 822 810 mem = (char *)mem_allocate(interp, new_size, pool); 823 811 mem += sizeof (void *); 824 812 825 813 /* copy mem from strstart, *not* bufstart */ 826 814 oldmem = str->strstart; 827 PObj_bufstart(str) = (void *)mem;815 Buffer_bufstart(str) = (void *)mem; 828 816 str->strstart = mem; 829 PObj_buflen(str) = new_size - sizeof (void*);817 Buffer_buflen(str) = new_size - sizeof (void*); 830 818 831 819 /* We shouldn't ever have a 0 from size, but we do. If we can track down 832 820 * those bugs, this can be removed which would make things cheaper */ … … 907 895 dest_arena->constant_string_header_pool, 908 896 source_arena->constant_string_header_pool); 909 897 910 Parrot_gc_merge_buffer_pools(dest_interp,911 dest_arena->pmc_ext_pool, source_arena->pmc_ext_pool);912 913 898 for (i = 0; i < source_arena->num_sized; ++i) { 914 899 if (!source_arena->sized_header_pools[i]) 915 900 continue; … … 948 933 { 949 934 ASSERT_ARGS(Parrot_gc_merge_buffer_pools) 950 935 Small_Object_Arena *cur_arena; 951 void **free_list_end;936 GC_MS_PObj_Wrapper *free_list_end; 952 937 953 938 PARROT_ASSERT(dest->object_size == source->object_size); 954 939 PARROT_ASSERT((dest->name == NULL && source->name == NULL) … … 958 943 959 944 /* append new free_list to old */ 960 945 /* XXX this won't work with, e.g., gc_gms */ 961 free_list_end = &dest->free_list;946 free_list_end = dest->free_list; 962 947 963 while (*free_list_end) 964 free_list_end = (void **)*free_list_end; 948 if(free_list_end == NULL) 949 { 950 dest->free_list = source->free_list; 951 } 952 else 953 { 954 while (free_list_end->next_ptr) 955 free_list_end = free_list_end->next_ptr; 965 956 966 *free_list_end = source->free_list; 957 free_list_end->next_ptr = source->free_list; 958 } 967 959 968 960 /* now append source arenas */ 969 961 cur_arena = source->last_Arena; … … 1070 1062 (void *)pass, sweep_cb_buf); 1071 1063 } 1072 1064 1073 free_pool(interp->arena_base->pmc_ext_pool);1074 interp->arena_base->pmc_ext_pool = NULL;1075 1076 1065 mem_internal_free(interp->arena_base->sized_header_pools); 1077 1066 if (interp->arena_base->attrib_pools) 1078 1067 mem_internal_free(interp->arena_base->attrib_pools); … … 1337 1326 1338 1327 for (i = 0; i < arena->used; i++) { 1339 1328 if (!PObj_on_free_list_TEST(p)) { 1340 if (p->pmc_ext) 1341 PMC_next_for_GC(p) = PMCNULL; 1329 PMC_next_for_GC(p) = PMCNULL; 1342 1330 } 1343 1331 p++; 1344 1332 } … … 1465 1453 1466 1454 Returns the number of PMCs that are marked as needing timely destruction. 1467 1455 1468 =item C<UINTVAL Parrot_gc_extended_pmcs(PARROT_INTERP)>1469 1470 Returns the number of extended PMCs.1471 1472 =cut1473 1474 1456 */ 1475 1457 1476 1458 size_t … … 1537 1519 return arena_base->num_early_gc_PMCs; 1538 1520 } 1539 1521 1540 UINTVAL1541 Parrot_gc_extended_pmcs(PARROT_INTERP)1542 {1543 ASSERT_ARGS(Parrot_gc_extended_pmcs)1544 const Arenas * const arena_base = interp->arena_base;1545 return arena_base->num_extended_PMCs;1546 }1547 1548 1522 /* 1549 1523 1550 1524 =item C<void Parrot_block_GC_mark(PARROT_INTERP)> -
src/ops/set.ops
510 510 /* don't let the clone's destruction destroy the destination's data */ 511 511 PObj_active_destroy_CLEAR(clone); 512 512 if (PObj_is_PMC_EXT_TEST(clone)) 513 clone->pmc_ext = NULL; 513 { 514 PMC_metadata(clone) = NULL; 515 PMC_next_for_GC(clone) = NULL; 516 PMC_sync(clone) = NULL; 517 } 514 518 515 519 /* Restore metadata. */ 516 520 if (!PMC_IS_NULL(meta)) { -
src/pmc/default.pmc
230 230 make_prop_hash(PARROT_INTERP, PMC *self) { 231 231 PMC *prop; 232 232 233 if (! self->pmc_ext)233 if (!PObj_is_PMC_EXT_TEST(self)) 234 234 Parrot_gc_add_pmc_ext(interp, self); 235 235 236 236 PMC_metadata(self) = prop = pmc_new(interp, enum_class_Hash); … … 377 377 */ 378 378 379 379 VTABLE PMC *getprop(STRING *key) { 380 if ( SELF->pmc_ext&& PMC_metadata(SELF))380 if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF)) 381 381 return VTABLE_get_pmc_keyed_str(INTERP, PMC_metadata(SELF), key); 382 382 else 383 383 return check_get_std_props(interp, SELF, key); … … 397 397 if (check_set_std_props(INTERP, SELF, key, value)) 398 398 return; 399 399 400 if ( SELF->pmc_ext&& PMC_metadata(SELF)) {400 if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF)) { 401 401 VTABLE_set_pmc_keyed_str(INTERP, 402 402 PMC_metadata(SELF), key, value); 403 403 } … … 419 419 */ 420 420 421 421 VTABLE void delprop(STRING *key) { 422 if ( SELF->pmc_ext&& PMC_metadata(SELF))422 if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF)) 423 423 VTABLE_delete_keyed_str(INTERP, PMC_metadata(SELF), key); 424 424 } 425 425 … … 434 434 */ 435 435 436 436 VTABLE PMC *getprops() { 437 if (! SELF->pmc_ext)437 if (!PObj_is_PMC_EXT_TEST(SELF)) 438 438 Parrot_gc_add_pmc_ext(INTERP, SELF); 439 439 440 440 if (!PMC_metadata(SELF)) { … … 1055 1061 1056 1062 VTABLE void visit(visit_info *info) { 1057 1063 /* default - mark prop hash */ 1058 if ( SELF->pmc_ext&& PMC_metadata(SELF) &&1064 if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF) && 1059 1065 info->extra_flags != EXTRA_IS_PROP_HASH) { 1060 1066 info->extra_flags = EXTRA_IS_PROP_HASH; 1061 1067 info->extra = PMC_metadata(SELF); … … 1110 1116 VTABLE void thaw(visit_info *info) { 1111 1117 /* default - initialize the PMC */ 1112 1118 if (info->extra_flags == EXTRA_IS_PROP_HASH) { 1113 if (! SELF->pmc_ext)1119 if (!PObj_is_PMC_EXT_TEST(SELF)) 1114 1120 Parrot_gc_add_pmc_ext(INTERP, SELF); 1115 1121 1116 1122 info->thaw_ptr = &PMC_metadata(SELF); -
src/list.c
342 342 /* HEADERIZER END: static */ 343 343 344 344 #define chunk_list_size(list) \ 345 ( PObj_buflen(&(list)->chunk_list) / sizeof (List_chunk *))345 (Buffer_buflen(&(list)->chunk_list) / sizeof (List_chunk *)) 346 346 347 347 /* hide the ugly cast somehow: */ 348 348 #define chunk_list_ptr(list, idx) \ 349 ((List_chunk**) PObj_bufstart(&(list)->chunk_list))[(idx)]349 ((List_chunk**) Buffer_bufstart(&(list)->chunk_list))[(idx)] 350 350 351 351 /* 352 352 … … 381 381 chunk->next = NULL; 382 382 chunk->prev = NULL; 383 383 Parrot_gc_allocate_buffer_storage_aligned(interp, (Buffer *)chunk, size); 384 memset( PObj_bufstart((Buffer*)chunk), 0, size);384 memset(Buffer_bufstart((Buffer*)chunk), 0, size); 385 385 386 386 /* see also src/hash.c */ 387 387 if (list->container) … … 520 520 } 521 521 522 522 mem_sys_memmove( 523 (char *) PObj_bufstart(&prev->data) +523 (char *) Buffer_bufstart(&prev->data) + 524 524 prev->items * list->item_size, 525 (const char *) PObj_bufstart(&chunk->data),525 (const char *) Buffer_bufstart(&chunk->data), 526 526 (MAX_ITEMS - prev->items) * list->item_size); 527 527 mem_sys_memmove( 528 (char *) PObj_bufstart(&chunk->data),529 (const char *) PObj_bufstart(&chunk->data) +528 (char *) Buffer_bufstart(&chunk->data), 529 (const char *) Buffer_bufstart(&chunk->data) + 530 530 (MAX_ITEMS - prev->items) * list->item_size, 531 531 (chunk->items - (MAX_ITEMS - prev->items)) 532 532 * list->item_size); … … 540 540 GC_WRITE_BARRIER(interp, list->container, 0, prev); 541 541 } 542 542 mem_sys_memmove( 543 (char *) PObj_bufstart(&prev->data) +543 (char *) Buffer_bufstart(&prev->data) + 544 544 prev->items * list->item_size, 545 (const char *) PObj_bufstart(&chunk->data),545 (const char *) Buffer_bufstart(&chunk->data), 546 546 chunk->items * list->item_size); 547 547 prev->items += chunk->items; 548 548 chunk->items = 0; … … 583 583 584 584 chunk->flags = 0; 585 585 list->grow_policy = enum_grow_unknown; 586 list->cap += PObj_buflen(&chunk->data) / list->item_size - chunk->items;587 chunk->items = PObj_buflen(&chunk->data) / list->item_size;586 list->cap += Buffer_buflen(&chunk->data) / list->item_size - chunk->items; 587 chunk->items = Buffer_buflen(&chunk->data) / list->item_size; 588 588 } 589 589 590 590 /* XXX - still needed? - if last is empty and last->prev not full then … … 1227 1227 switch (type) { 1228 1228 case enum_type_sized: 1229 1229 /* copy data into list */ 1230 memcpy(&((char *) PObj_bufstart(&chunk->data))[idx * list->item_size],1230 memcpy(&((char *) Buffer_bufstart(&chunk->data))[idx * list->item_size], 1231 1231 item, list->item_size); 1232 1232 break; 1233 1233 case enum_type_char: 1234 ((char *) PObj_bufstart(&chunk->data))[idx] = (char)PTR2INTVAL(item);1234 ((char *) Buffer_bufstart(&chunk->data))[idx] = (char)PTR2INTVAL(item); 1235 1235 break; 1236 1236 case enum_type_short: 1237 ((short *) PObj_bufstart(&chunk->data))[idx] = (short)PTR2INTVAL(item);1237 ((short *) Buffer_bufstart(&chunk->data))[idx] = (short)PTR2INTVAL(item); 1238 1238 break; 1239 1239 case enum_type_int: 1240 ((int *) PObj_bufstart(&chunk->data))[idx] = (int)PTR2INTVAL(item);1240 ((int *) Buffer_bufstart(&chunk->data))[idx] = (int)PTR2INTVAL(item); 1241 1241 break; 1242 1242 case enum_type_INTVAL: 1243 ((INTVAL *) PObj_bufstart(&chunk->data))[idx] = PTR2INTVAL(item);1243 ((INTVAL *) Buffer_bufstart(&chunk->data))[idx] = PTR2INTVAL(item); 1244 1244 break; 1245 1245 case enum_type_FLOATVAL: 1246 ((FLOATVAL *) PObj_bufstart(&chunk->data))[idx] = *(FLOATVAL *)item;1246 ((FLOATVAL *) Buffer_bufstart(&chunk->data))[idx] = *(FLOATVAL *)item; 1247 1247 break; 1248 1248 case enum_type_PMC: 1249 1249 if (list->container) { 1250 1250 GC_WRITE_BARRIER(interp, list->container, 1251 ((PMC **) PObj_bufstart(&chunk->data))[idx],1251 ((PMC **) Buffer_bufstart(&chunk->data))[idx], 1252 1252 (PMC *)item); 1253 1253 } 1254 ((PMC **) PObj_bufstart(&chunk->data))[idx] = (PMC *)item;1254 ((PMC **) Buffer_bufstart(&chunk->data))[idx] = (PMC *)item; 1255 1255 break; 1256 1256 case enum_type_STRING: 1257 ((STRING **) PObj_bufstart(&chunk->data))[idx] = (STRING *)item;1257 ((STRING **) Buffer_bufstart(&chunk->data))[idx] = (STRING *)item; 1258 1258 break; 1259 1259 default: 1260 1260 Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown list entry type\n"); … … 1296 1296 switch (type) { 1297 1297 case enum_type_sized: 1298 1298 return (void *)&((char *) 1299 PObj_bufstart(&chunk->data))[idx * list->item_size];1299 Buffer_bufstart(&chunk->data))[idx * list->item_size]; 1300 1300 case enum_type_char: 1301 return (void *)&((char *) PObj_bufstart(&chunk->data))[idx];1301 return (void *)&((char *) Buffer_bufstart(&chunk->data))[idx]; 1302 1302 case enum_type_short: 1303 return (void *)&((short *) PObj_bufstart(&chunk->data))[idx];1303 return (void *)&((short *) Buffer_bufstart(&chunk->data))[idx]; 1304 1304 case enum_type_int: 1305 return (void *)&((int *) PObj_bufstart(&chunk->data))[idx];1305 return (void *)&((int *) Buffer_bufstart(&chunk->data))[idx]; 1306 1306 case enum_type_INTVAL: 1307 return (void *)&((INTVAL *) PObj_bufstart(&chunk->data))[idx];1307 return (void *)&((INTVAL *) Buffer_bufstart(&chunk->data))[idx]; 1308 1308 case enum_type_FLOATVAL: 1309 return (void *)&((FLOATVAL *) PObj_bufstart(&chunk->data))[idx];1309 return (void *)&((FLOATVAL *) Buffer_bufstart(&chunk->data))[idx]; 1310 1310 case enum_type_PMC: 1311 return (void *)&((PMC **) PObj_bufstart(&chunk->data))[idx];1311 return (void *)&((PMC **) Buffer_bufstart(&chunk->data))[idx]; 1312 1312 case enum_type_STRING: 1313 return (void *)&((STRING **) PObj_bufstart(&chunk->data))[idx];1313 return (void *)&((STRING **) Buffer_bufstart(&chunk->data))[idx]; 1314 1314 default: 1315 1315 Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown list entry type\n"); 1316 1316 } … … 1569 1569 l = list_new(interp, other->item_type); 1570 1570 1571 1571 STRUCT_COPY(l, other); 1572 PObj_buflen(&l->chunk_list) = 0;1573 PObj_bufstart(&l->chunk_list) = NULL;1572 Buffer_buflen(&l->chunk_list) = 0; 1573 Buffer_bufstart(&l->chunk_list) = NULL; 1574 1574 1575 1575 for (chunk = other->first, prev = NULL; chunk; chunk = chunk->next) { 1576 1576 List_chunk * const new_chunk = allocate_chunk(interp, l, 1577 chunk->items, PObj_buflen(&chunk->data));1577 chunk->items, Buffer_buflen(&chunk->data)); 1578 1578 1579 1579 new_chunk->flags = chunk->flags; 1580 1580 … … 1589 1589 switch (l->item_type) { 1590 1590 case enum_type_PMC: 1591 1591 for (i = 0; i < chunk->items; i++) { 1592 PMC * const op = ((PMC **) PObj_bufstart(&chunk->data))[i];1592 PMC * const op = ((PMC **) Buffer_bufstart(&chunk->data))[i]; 1593 1593 1594 1594 if (op) 1595 ((PMC **) PObj_bufstart(&new_chunk->data))[i] =1595 ((PMC **) Buffer_bufstart(&new_chunk->data))[i] = 1596 1596 VTABLE_clone(interp, op); 1597 1597 } 1598 1598 break; 1599 1599 case enum_type_STRING: 1600 1600 for (i = 0; i < chunk->items; i++) { 1601 STRING *s = ((STRING **) PObj_bufstart(&chunk->data))[i];1601 STRING *s = ((STRING **) Buffer_bufstart(&chunk->data))[i]; 1602 1602 if (s) 1603 ((STRING **) PObj_bufstart(&new_chunk->data))[i] =1603 ((STRING **) Buffer_bufstart(&new_chunk->data))[i] = 1604 1604 Parrot_str_copy(interp, s); 1605 1605 } 1606 1606 break; 1607 1607 default: 1608 mem_sys_memcopy( PObj_bufstart(&new_chunk->data),1609 PObj_bufstart(&chunk->data), PObj_buflen(&chunk->data));1608 mem_sys_memcopy(Buffer_bufstart(&new_chunk->data), 1609 Buffer_bufstart(&chunk->data), Buffer_buflen(&chunk->data)); 1610 1610 break; 1611 1611 } 1612 1612 } … … 1643 1643 if (list->item_type == enum_type_PMC 1644 1644 || list->item_type == enum_type_STRING) { 1645 1645 if (!(chunk->flags & sparse)) { 1646 PObj **p = ((PObj **) PObj_bufstart(&chunk->data));1646 PObj **p = ((PObj **) Buffer_bufstart(&chunk->data)); 1647 1647 UINTVAL i; 1648 1648 1649 1649 for (i = 0; i < chunk->items; i++, ++p) { … … 1688 1688 if (!(chunk->flags & sparse)) { 1689 1689 UINTVAL i; 1690 1690 for (i = 0; i < chunk->items && idx < n; i++, idx++) { 1691 PMC ** const pos = ((PMC **) PObj_bufstart(&chunk->data)) + i;1691 PMC ** const pos = ((PMC **) Buffer_bufstart(&chunk->data)) + i; 1692 1692 info->thaw_ptr = pos; 1693 1693 (info->visit_pmc_now)(interp, *pos, info); 1694 1694 } … … 1830 1830 1831 1831 /* copy data over */ 1832 1832 mem_sys_memmove( 1833 (char *) PObj_bufstart(&rest->data),1834 (char *) PObj_bufstart(&chunk->data) + idx * list->item_size,1833 (char *)Buffer_bufstart(&rest->data), 1834 (char *)Buffer_bufstart(&chunk->data) + idx * list->item_size, 1835 1835 items * list->item_size); 1836 1836 } 1837 1837 else { … … 1895 1895 list->item_size; 1896 1896 1897 1897 mem_sys_memmove( 1898 (char *) PObj_bufstart(&chunk->data) +1898 (char *) Buffer_bufstart(&chunk->data) + 1899 1899 idx * list->item_size, 1900 (char *) PObj_bufstart(&chunk->data) +1900 (char *) Buffer_bufstart(&chunk->data) + 1901 1901 (idx + n_items) * list->item_size, tmp_size); 1902 1902 #else 1903 1903 mem_sys_memmove( 1904 (char *) PObj_bufstart(&chunk->data) +1904 (char *) Buffer_bufstart(&chunk->data) + 1905 1905 idx * list->item_size, 1906 (char *) PObj_bufstart(&chunk->data) +1906 (char *) Buffer_bufstart(&chunk->data) + 1907 1907 (idx + n_items) * list->item_size, 1908 1908 (chunk->items - idx - n_items) * list->item_size); 1909 1909 #endif -
src/interp/inter_misc.c
252 252 case IMPATIENT_PMCS: 253 253 ret = Parrot_gc_impatient_pmcs(interp); 254 254 break; 255 case EXTENDED_PMCS:256 ret = Parrot_gc_extended_pmcs(interp);257 break;258 255 case CURRENT_RUNCORE: 259 256 ret = interp->run_core; 260 257 break; -
include/parrot/call.h
70 70 INTVAL slurp_n; /* number of :flat/:slurpy args/params to match */ 71 71 } call_state_item; 72 72 73 typedef union UnionCallStateVal { 74 struct _ptrs { //or two pointers, both are defines 75 DPOINTER * _struct_val; 76 PMC * _pmc_val; 77 } _ptrs; 78 struct _i { 79 INTVAL _int_val; // or 2 intvals 80 INTVAL _int_val2; 81 } _i; 82 FLOATVAL _num_val; // or one float 83 struct parrot_string_t * _string_val; // or a pointer to a string 84 } UnionCallStateVal; 85 86 #define UVal_ptr(u) (u)._ptrs._struct_val 87 #define UVal_pmc(u) (u)._ptrs._pmc_val 88 #define UVal_int(u) (u)._i._int_val 89 #define UVal_int2(u) (u)._i._int_val2 90 #define UVal_num(u) (u)._num_val 91 #define UVal_str(u) (u)._string_val 92 73 93 typedef struct call_state { 74 94 call_state_item src; 75 95 call_state_item dest; 76 Union Val val;96 UnionCallStateVal val; 77 97 int n_actual_args; /* arguments incl. flatten */ 78 98 int optionals; /* sum of optionals */ 79 99 int params; /* sum of params */ -
src/ops/string.ops
392 392 $1 = PTR2UINTVAL($2->strstart); 393 393 break; 394 394 case STRINGINFO_BUFLEN: 395 $1 = PObj_buflen($2);395 $1 = Buffer_buflen($2); 396 396 break; 397 397 case STRINGINFO_FLAGS: 398 398 $1 = PObj_get_FLAGS($2); -
src/pmc.c
359 359 { 360 360 ASSERT_ARGS(pmc_reuse_check_pmc_ext) 361 361 /* Do we have an extension area? */ 362 INTVAL const has_ext = (PObj_is_PMC_EXT_TEST(pmc) && pmc->pmc_ext);362 INTVAL const has_ext = (PObj_is_PMC_EXT_TEST(pmc)); 363 363 364 364 /* Do we need one? */ 365 365 if (flags & VTABLE_PMC_NEEDS_EXT) { … … 373 373 PMC_data(pmc) = NULL; 374 374 newflags &= ~PObj_is_PMC_EXT_FLAG; 375 375 PARROT_ASSERT((newflags & PObj_is_PMC_EXT_FLAG) == 0); 376 PARROT_ASSERT(pmc->pmc_ext == NULL);377 376 } 378 377 return newflags; 379 378 } -
src/string/charset/iso-8859-1.c
268 268 for (offs = 0; offs < src->strlen; ++offs) { 269 269 const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs); 270 270 271 if (iter.bytepos >= PObj_buflen(dest) - 4) {271 if (iter.bytepos >= Buffer_buflen(dest) - 4) { 272 272 UINTVAL need = (UINTVAL)((src->strlen - offs) * 1.5); 273 273 if (need < 16) 274 274 need = 16; 275 275 Parrot_gc_reallocate_string_storage(interp, dest, 276 PObj_buflen(dest) + need);276 Buffer_buflen(dest) + need); 277 277 } 278 278 iter.set_and_advance(interp, &iter, c); 279 279 } -
tools/build/nativecall.pl
405 405 /b/ && do { 406 406 push @{$temps_ref}, "STRING *t_$temp_num;"; 407 407 push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_S($reg_num);"; 408 return " PObj_bufstart(t_$temp_num)";408 return "Buffer_bufstart(t_$temp_num)"; 409 409 }; 410 410 /B/ && do { 411 411 push @{$temps_ref}, "char *s_$temp_num;\n char *t_$temp_num;\n void** v_$temp_num = (void **) &t_$temp_num;"; -
src/gc/gc_ms.c
29 29 __attribute__nonnull__(3) 30 30 FUNC_MODIFIES(*pool); 31 31 32 static void gc_ms_add_free_pmc_ext(SHIM_INTERP,33 ARGMOD(Small_Object_Pool *pool),34 ARGIN(void *to_add))35 __attribute__nonnull__(2)36 __attribute__nonnull__(3)37 FUNC_MODIFIES(*pool);38 39 32 static void gc_ms_alloc_objects(PARROT_INTERP, 40 33 ARGMOD(Small_Object_Pool *pool)) 41 34 __attribute__nonnull__(1) … … 54 47 __attribute__nonnull__(2) 55 48 FUNC_MODIFIES(*pool); 56 49 57 PARROT_CANNOT_RETURN_NULL58 PARROT_WARN_UNUSED_RESULT59 static void * gc_ms_get_free_pmc_ext(PARROT_INTERP,60 ARGMOD(Small_Object_Pool *pool))61 __attribute__nonnull__(1)62 __attribute__nonnull__(2)63 FUNC_MODIFIES(*pool);64 65 50 static void gc_ms_mark_and_sweep(PARROT_INTERP, UINTVAL flags) 66 51 __attribute__nonnull__(1); 67 52 … … 92 77 #define ASSERT_ARGS_gc_ms_add_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 93 78 PARROT_ASSERT_ARG(pool) \ 94 79 || PARROT_ASSERT_ARG(to_add) 95 #define ASSERT_ARGS_gc_ms_add_free_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \96 PARROT_ASSERT_ARG(pool) \97 || PARROT_ASSERT_ARG(to_add)98 80 #define ASSERT_ARGS_gc_ms_alloc_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 99 81 PARROT_ASSERT_ARG(interp) \ 100 82 || PARROT_ASSERT_ARG(pool) … … 104 86 #define ASSERT_ARGS_gc_ms_get_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 105 87 PARROT_ASSERT_ARG(interp) \ 106 88 || PARROT_ASSERT_ARG(pool) 107 #define ASSERT_ARGS_gc_ms_get_free_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \108 PARROT_ASSERT_ARG(interp) \109 || PARROT_ASSERT_ARG(pool)110 89 #define ASSERT_ARGS_gc_ms_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 111 90 PARROT_ASSERT_ARG(interp) 112 91 #define ASSERT_ARGS_gc_ms_more_traceable_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = \ … … 365 344 gc_ms_more_traceable_objects(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool)) 366 345 { 367 346 ASSERT_ARGS(gc_ms_more_traceable_objects) 347 368 348 if (pool->skip) 369 349 pool->skip = 0; 370 350 else { … … 398 378 ARGIN(void *to_add)) 399 379 { 400 380 ASSERT_ARGS(gc_ms_add_free_object) 401 PObj *object = (PObj*)to_add;381 GC_MS_PObj_Wrapper *object = (GC_MS_PObj_Wrapper *)to_add; 402 382 403 383 PObj_flags_SETTO(object, PObj_on_free_list_FLAG); 404 384 405 ((GC_MS_PObj_Wrapper*)object)->next_ptr = (PObj *)pool->free_list;406 pool->free_list 385 object->next_ptr = pool->free_list; 386 pool->free_list = object; 407 387 } 408 388 409 389 /* … … 438 418 ptr = free_list; 439 419 pool->free_list = ((GC_MS_PObj_Wrapper*)ptr)->next_ptr; 440 420 441 PObj_flags_SETTO(ptr, 0); 421 // PObj_flags_SETTO(ptr, 0); 422 memset(ptr, 0, pool->object_size); 442 423 443 424 --pool->num_free_objects; 444 425 … … 462 443 { 463 444 ASSERT_ARGS(gc_ms_alloc_objects) 464 445 /* Setup memory for the new objects */ 446 465 447 Small_Object_Arena * const new_arena = 466 448 mem_internal_allocate_typed(Small_Object_Arena); 467 449 … … 500 482 501 483 =back 502 484 503 =head2 MS PMC_EXT Pool functions504 505 =over 4506 507 =item C<void gc_ms_pmc_ext_pool_init(Small_Object_Pool *pool)>508 509 Initialize the PMC_EXT pool functions. This is done separately from other510 pools.511 512 485 =cut 513 486 514 487 */ 515 488 516 void517 gc_ms_pmc_ext_pool_init(ARGMOD(Small_Object_Pool *pool))518 {519 ASSERT_ARGS(gc_ms_pmc_ext_pool_init)520 pool->add_free_object = gc_ms_add_free_pmc_ext;521 pool->get_free_object = gc_ms_get_free_pmc_ext;522 pool->alloc_objects = gc_ms_alloc_objects;523 pool->more_objects = gc_ms_alloc_objects;524 }525 526 527 /*528 529 =item C<static void gc_ms_add_free_pmc_ext(PARROT_INTERP, Small_Object_Pool530 *pool, void *to_add)>531 532 Add a freed PMC_EXT structure to the free list in the PMC_EXT pool. Objects533 on the free list can be reused later.534 535 =cut536 537 */538 539 static void540 gc_ms_add_free_pmc_ext(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGIN(void *to_add))541 {542 ASSERT_ARGS(gc_ms_add_free_pmc_ext)543 PMC_EXT * const object = (PMC_EXT *)to_add;544 object->_metadata = NULL;545 546 /* yes, this cast is a hack for now, but a pointer is a pointer */547 object->_next_for_GC = (PMC *)pool->free_list;548 pool->free_list = object;549 }550 551 /*552 553 =item C<static void * gc_ms_get_free_pmc_ext(PARROT_INTERP, Small_Object_Pool554 *pool)>555 556 Get a new PMC_EXT structure from the free pool and return it.557 558 =cut559 560 */561 562 PARROT_CANNOT_RETURN_NULL563 PARROT_WARN_UNUSED_RESULT564 static void *565 gc_ms_get_free_pmc_ext(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool))566 {567 ASSERT_ARGS(gc_ms_get_free_pmc_ext)568 PMC_EXT *ptr;569 PMC_EXT *free_list = (PMC_EXT *)pool->free_list;570 571 /* if we don't have any objects */572 if (!free_list) {573 (*pool->more_objects)(interp, pool);574 free_list = (PMC_EXT *)pool->free_list;575 }576 577 ptr = free_list;578 pool->free_list = ptr->_next_for_GC;579 ptr->_next_for_GC = NULL;580 581 --pool->num_free_objects;582 583 return ptr;584 }585 586 /*587 588 =back589 590 =cut591 592 */593 594 489 /* 595 490 * Local variables: 596 491 * c-file-style: "parrot" -
include/parrot/hash.h
28 28 29 29 /* 30 30 * hash_entry is currently unused in the hash structure 31 */31 32 32 typedef struct _hash_entry { 33 33 HashEntryType type; 34 34 UnionVal val; 35 35 } HashEntry; 36 */ 36 37 37 38 /* A BucketIndex is an index into the pool of available buckets. */ 38 39 typedef UINTVAL BucketIndex; -
src/jit_debug.c
106 106 static void 107 107 write_types(FILE *stabs, PARROT_INTERP) 108 108 { 109 //It would be create if this function would be auto generated :) 109 110 int i, j; 110 111 /* borrowed from mono */ 111 112 static BaseTypes base_types[] = { … … 152 153 ++i; 153 154 fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d" 154 155 "bufstart:(0,14),%d,%d;" 155 "buflen:(0,6),%d,%d;" /* XXX type */156 "buflen:(0,6),%d,%d;" 156 157 "flags:(0,12),%d,%d;" 157 158 "bufused:(0,12),%d,%d;" 158 "strstart:(0,15),%d,%d;" /* fake a char* */159 "strstart:(0,15),%d,%d;" 159 160 ";\"" 160 161 "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING), 161 BIT_OFFSET(STRING, cache._b._bufstart), BIT_SIZE(void*),162 BIT_OFFSET(STRING, cache._b._buflen), BIT_SIZE(size_t),162 BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*), 163 BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t), 163 164 BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL), 164 165 BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL), 165 166 BIT_OFFSET(STRING, strstart), BIT_SIZE(void*)); … … 177 178 178 179 fprintf(stabs, ";\"," N_LSYM ",0,0,0\n"); 179 180 180 /* PMC type */ 181 fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d", i, BYTE_SIZE(PMC)); 182 fprintf(stabs, "cache:(0,%d),%d,%d;", 183 i + 1, BIT_OFFSET(PMC, cache), BIT_SIZE(UnionVal)); 184 fprintf(stabs, "flags:(0,%d),%d,%d;", 185 i + 1, BIT_OFFSET(PMC, flags), BIT_SIZE(Parrot_UInt)); 186 fprintf(stabs, "vtable:*(0,%d),%d,%d;", 187 i + 3, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*)); 188 fprintf(stabs, "data:(0,14),%d,%d;", 189 BIT_OFFSET(PMC, data), BIT_SIZE(void*)); 190 fprintf(stabs, "pmc_ext:*(0,%d),%d,%d;", 191 i, BIT_OFFSET(PMC, pmc_ext), BIT_SIZE(void*)); 192 fprintf(stabs, ";\""); 193 fprintf(stabs, "," N_LSYM ",0,0,0\n"); 194 195 fprintf(stabs, ".stabs \"UnionVal:T(0,%d)=u%d" 196 "int_val:(0,12),%d,%d;" 197 "pmc_val:*(0,%d),%d,%d;" 181 fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d" 182 "flags:(0,12),%d,%d;" 183 "vtable:*(0,%d),%d,%d;" 184 "data:(0,14),%d,%d;" 185 "_metadata:*(0,%d),%d,%d;" 186 "_next_for_GC:*(0,%d),%d,%d;" 198 187 ";\"" 199 "," N_LSYM ",0,0,0\n", i + 2, BYTE_SIZE(UnionVal), 200 BIT_OFFSET(UnionVal, _i._int_val), BIT_SIZE(INTVAL), 201 i, BIT_OFFSET(UnionVal, _ptrs._pmc_val), BIT_SIZE(void*)); 188 "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC), 189 BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL), 190 i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*), 191 BIT_OFFSET(PMC, data), BIT_SIZE(void*), 192 i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*), 193 i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*)); 194 195 i++; 196 197 //some one can add some field to this one 202 198 fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d" 203 "base_type:(0, %d),%d,%d;"199 "base_type:(0,12),%d,%d;" 204 200 ";\"" 205 "," N_LSYM ",0,0,0\n", i + 3, BYTE_SIZE(UnionVal), 206 i - 1, BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); 207 i += 4; 201 "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable), 202 BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); 208 203 204 i++; 209 205 } 210 206 211 207 /*