### Eclipse Workspace Patch 1.0 #P parrot Index: src/jit/i386/jit_defs.c =================================================================== --- src/jit/i386/jit_defs.c (revision 40501) +++ src/jit/i386/jit_defs.c (working copy) @@ -2265,16 +2265,16 @@ break; case 'v': break; - case 'b': /* buffer (void*) pass PObj_bufstart(SReg) */ + case 'b': /* buffer (void*) pass Buffer_bufstart(SReg) */ emitm_call_cfunc(pc, get_nci_S); emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, - (size_t) &PObj_bufstart((STRING *) NULL)); + (size_t) &Buffer_bufstart((STRING *) NULL)); emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); break; - case 'B': /* buffer (void**) pass &PObj_bufstart(SReg) */ + case 'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */ emitm_call_cfunc(pc, get_nci_S); emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, - (size_t) &PObj_bufstart((STRING *) NULL)); + (size_t) &Buffer_bufstart((STRING *) NULL)); emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); break; case 'S': Index: src/gc/gc_private.h =================================================================== --- src/gc/gc_private.h (revision 40501) +++ src/gc/gc_private.h (working copy) @@ -47,9 +47,9 @@ larger then sizeof(PObj), thus creating overflow. However PObjs are never used by themselves, things like PMCs and STRINGs are cast to PObj in the GC, so we should have plenty of space. */ -typedef union GC_MS_PObj_Wrapper { - PObj obj; - PObj *next_ptr; +typedef struct GC_MS_PObj_Wrapper { + size_t flags; + struct GC_MS_PObj_Wrapper * next_ptr; } GC_MS_PObj_Wrapper; typedef struct Small_Object_Arena { @@ -152,7 +152,7 @@ size_t num_free_objects; /* number of resources in the free pool */ int skip; size_t replenish_level; - void *free_list; + GC_MS_PObj_Wrapper * free_list; /* adds a free object to the pool's free list */ add_free_object_fn_type add_free_object; get_free_object_fn_type get_free_object; @@ -184,9 +184,8 @@ Memory_Pool *constant_string_pool; struct Small_Object_Pool *string_header_pool; struct Small_Object_Pool *pmc_pool; - struct Small_Object_Pool *pmc_ext_pool; struct Small_Object_Pool *constant_pmc_pool; - struct Small_Object_Pool *buffer_header_pool; + // struct Small_Object_Pool *buffer_header_pool; struct Small_Object_Pool *constant_string_header_pool; struct Small_Object_Pool **sized_header_pools; size_t num_sized; @@ -225,7 +224,6 @@ during collection */ UINTVAL num_early_gc_PMCs; /* how many PMCs want immediate destruction */ UINTVAL num_early_PMCs_seen; /* how many such PMCs has GC seen */ - UINTVAL num_extended_PMCs; /* active PMCs having pmc_ext */ PMC* gc_mark_start; /* first PMC marked during a GC run */ PMC* gc_mark_ptr; /* last PMC marked during a GC run */ PMC* gc_trace_ptr; /* last PMC trace_children was called on */ @@ -550,7 +548,25 @@ __attribute__nonnull__(2) FUNC_MODIFIES(*dest) FUNC_MODIFIES(*source); + +void check_memory_system(PARROT_INTERP) + __attribute__nonnull__(1); + +void check_memory_system(PARROT_INTERP) + __attribute__nonnull__(1); + +void check_small_object_pool(Small_Object_Pool * pool) + __attribute__nonnull__(1); +void +check_memory_pool(Memory_Pool *pool) + __attribute__nonnull__(1); + +void +check_buffer_ptr(Buffer * pobj,Memory_Pool * pool) + __attribute__nonnull__(1) + __attribute__nonnull__(2); + #define ASSERT_ARGS_aligned_mem __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(buffer) \ || PARROT_ASSERT_ARG(mem) @@ -652,15 +668,9 @@ /* HEADERIZER BEGIN: src/gc/gc_ms.c */ /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ -void gc_ms_pmc_ext_pool_init(ARGMOD(Small_Object_Pool *pool)) - __attribute__nonnull__(1) - FUNC_MODIFIES(*pool); - void Parrot_gc_ms_init(PARROT_INTERP) __attribute__nonnull__(1); -#define ASSERT_ARGS_gc_ms_pmc_ext_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \ - PARROT_ASSERT_ARG(pool) #define ASSERT_ARGS_Parrot_gc_ms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp) /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ Index: include/parrot/pobj.h =================================================================== --- include/parrot/pobj.h (revision 40501) +++ include/parrot/pobj.h (working copy) @@ -15,46 +15,19 @@ #include "parrot/config.h" -typedef union UnionVal { - struct _b { /* One Buffer structure */ - void * _bufstart; - size_t _buflen; - } _b; - struct _ptrs { /* or two pointers, both are defines */ - DPOINTER * _struct_val; - PMC * _pmc_val; - } _ptrs; - struct _i { - INTVAL _int_val; /* or 2 intvals */ - INTVAL _int_val2; - } _i; - FLOATVAL _num_val; /* or one float */ - struct parrot_string_t * _string_val; /* or a pointer to a string */ -} UnionVal; - -#define UVal_ptr(u) (u)._ptrs._struct_val -#define UVal_pmc(u) (u)._ptrs._pmc_val -#define UVal_int(u) (u)._i._int_val -#define UVal_int2(u) (u)._i._int_val2 -#define UVal_num(u) (u)._num_val -#define UVal_str(u) (u)._string_val - /* Parrot Object - base class for all others */ typedef struct pobj_t { - UnionVal u; Parrot_UInt flags; -} pobj_t; +} PObj; -/* plain Buffer is the smallest Parrot Obj */ -typedef struct Buffer { - UnionVal cache; +typedef struct buffer_t { Parrot_UInt flags; + void * _bufstart; + size_t _buflen; } Buffer; -typedef Buffer PObj; - -#define PObj_bufstart(pmc) (pmc)->cache._b._bufstart -#define PObj_buflen(pmc) (pmc)->cache._b._buflen +#define Buffer_bufstart(buffer) (buffer)->_bufstart +#define Buffer_buflen(buffer) (buffer)->_buflen /* See src/gc/alloc_resources.c. the basic idea is that buffer memory is set up as follows: @@ -84,24 +57,20 @@ v v v v */ -typedef struct Buffer_alloc_unit { - INTVAL ref_count; - UnionVal buffer[1]; /* Guarantee it's suitably aligned */ -} Buffer_alloc_unit; /* Given a pointer to the buffer, find the ref_count and the actual start of the allocated space. Setting ref_count is clunky because we avoid lvalue casts. */ #ifdef GC_IS_MALLOC /* see src/gc/res_lea.c */ # define Buffer_alloc_offset (offsetof(Buffer_alloc_unit, buffer)) -# define PObj_bufallocstart(b) ((char *)PObj_bufstart(b) - Buffer_alloc_offset) -# define PObj_bufrefcount(b) (((Buffer_alloc_unit *)PObj_bufallocstart(b))->ref_count) -# define PObj_bufrefcountptr(b) (&PObj_bufrefcount(b)) +# define Buffer_bufallocstart(b) ((char *)Buffer_bufstart(b) - Buffer_alloc_offset) +# define Buffer_bufrefcount(b) (((Buffer_alloc_unit *)Buffer_bufallocstart(b))->ref_count) +# define Buffer_bufrefcountptr(b) (&Buffer_bufrefcount(b)) #else /* see src/gc/alloc_resources.c */ # define Buffer_alloc_offset sizeof (INTVAL) -# define PObj_bufallocstart(b) ((char *)PObj_bufstart(b) - Buffer_alloc_offset) -# define PObj_bufrefcount(b) (*(INTVAL *)PObj_bufallocstart(b)) -# define PObj_bufrefcountptr(b) ((INTVAL *)PObj_bufallocstart(b)) +# define Buffer_bufallocstart(b) ((char *)Buffer_bufstart(b) - Buffer_alloc_offset) +# define Buffer_bufrefcount(b) (*(INTVAL *)Buffer_bufallocstart(b)) +# define Buffer_bufrefcountptr(b) ((INTVAL *)Buffer_bufallocstart(b)) #endif typedef enum { @@ -112,8 +81,10 @@ } parrot_string_representation_t; struct parrot_string_t { - UnionVal cache; Parrot_UInt flags; + void * _bufstart; + size_t _buflen; + char *strstart; UINTVAL bufused; UINTVAL strlen; @@ -124,18 +95,14 @@ const struct _charset *charset; }; +struct _Sync; /* forward decl */ + /* note that cache and flags are isomorphic with Buffer and PObj */ struct PMC { - UnionVal cache; Parrot_UInt flags; VTABLE *vtable; DPOINTER *data; - struct PMC_EXT *pmc_ext; -}; - -struct _Sync; /* forward decl */ -typedef struct PMC_EXT { PMC *_metadata; /* properties */ /* * PMC access synchronization for shared PMCs @@ -160,21 +127,16 @@ stuff, which'd merit an extra dereference when setting, but let us memset the actual GC data in a big block */ -} PMC_EXT; +}; -#ifdef NDEBUG -# define PMC_ext_checked(pmc) (pmc)->pmc_ext -#else -# define PMC_ext_checked(pmc) (PARROT_ASSERT((pmc)->pmc_ext), (pmc)->pmc_ext) -#endif /* NDEBUG */ #define PMC_data(pmc) (pmc)->data #define PMC_data_typed(pmc, type) (type)(pmc)->data /* do not allow PMC_data2 as lvalue */ #define PMC_data0(pmc) (1 ? (pmc)->data : 0) #define PMC_data0_typed(pmc) (type)(1 ? (pmc)->data : 0) -#define PMC_metadata(pmc) PMC_ext_checked(pmc)->_metadata -#define PMC_next_for_GC(pmc) PMC_ext_checked(pmc)->_next_for_GC -#define PMC_sync(pmc) PMC_ext_checked(pmc)->_synchronize +#define PMC_metadata(pmc) pmc->_metadata +#define PMC_next_for_GC(pmc) pmc->_next_for_GC +#define PMC_sync(pmc) pmc->_synchronize #define POBJ_FLAG(n) ((UINTVAL)1 << (n)) /* PObj flags */ Index: src/pmc_freeze.c =================================================================== --- src/pmc_freeze.c (revision 40501) +++ src/pmc_freeze.c (working copy) @@ -463,17 +463,18 @@ str_append(PARROT_INTERP, ARGMOD(STRING *s), ARGIN(const void *b), size_t len) { ASSERT_ARGS(str_append) + const size_t used = s->bufused; - const int need_free = (int)PObj_buflen(s) - used - len; + const int need_free = (int)Buffer_buflen(s) - used - len; /* * grow by factor 1.5 or such */ if (need_free <= 16) { - size_t new_size = (size_t) (PObj_buflen(s) * 1.5); - if (new_size < PObj_buflen(s) - need_free + 512) - new_size = PObj_buflen(s) - need_free + 512; + size_t new_size = (size_t) (Buffer_buflen(s) * 1.5); + if (new_size < Buffer_buflen(s) - need_free + 512) + new_size = Buffer_buflen(s) - need_free + 512; Parrot_gc_reallocate_string_storage(interp, s, new_size); - PARROT_ASSERT(PObj_buflen(s) - used - len >= 15); + PARROT_ASSERT(Buffer_buflen(s) - used - len >= 15); } mem_sys_memcopy((void *)((ptrcast_t)s->strstart + used), b, len); s->bufused += len; @@ -591,6 +592,7 @@ shift_ascii_integer(SHIM_INTERP, ARGIN(IMAGE_IO *io)) { ASSERT_ARGS(shift_ascii_integer) + char * const start = (char*)io->image->strstart; char *p = start; const INTVAL i = strtoul(p, &p, 10); @@ -599,7 +601,9 @@ PARROT_ASSERT(p <= start + io->image->bufused); io->image->strstart = p; io->image->bufused -= (p - start); + io->image->strlen -= (p - start); PARROT_ASSERT((int)io->image->bufused >= 0); + return i; } @@ -617,6 +621,7 @@ shift_ascii_number(SHIM_INTERP, ARGIN(IMAGE_IO *io)) { ASSERT_ARGS(shift_ascii_number) + char * const start = (char*)io->image->strstart; char *p = start; const FLOATVAL f = (FLOATVAL) strtod(p, &p); @@ -625,7 +630,9 @@ PARROT_ASSERT(p <= start + io->image->bufused); io->image->strstart = p; io->image->bufused -= (p - start); + io->image->strlen -= (p - start); PARROT_ASSERT((int)io->image->bufused >= 0); + return f; } @@ -656,9 +663,11 @@ PARROT_ASSERT(p <= start + io->image->bufused); io->image->strstart = p; io->image->bufused -= (p - start); + io->image->strlen -= (p - start); PARROT_ASSERT((int)io->image->bufused >= 0); s = string_make(interp, start, p - start - 1, "iso-8859-1", 0); /* s = string_make(interp, start, p - start - 1, "UTF-8", 0); */ + return s; } @@ -678,6 +687,7 @@ shift_ascii_pmc(SHIM_INTERP, ARGIN(IMAGE_IO *io)) { ASSERT_ARGS(shift_ascii_pmc) + char * const start = (char*)io->image->strstart; char *p = start; const unsigned long i = strtoul(p, &p, 16); @@ -685,7 +695,9 @@ PARROT_ASSERT(p <= start + io->image->bufused); io->image->strstart = p; io->image->bufused -= (p - start); + io->image->strlen -= (p - start); PARROT_ASSERT((int)io->image->bufused >= 0); + return (PMC*) i; } @@ -712,16 +724,17 @@ { ASSERT_ARGS(op_check_size) const size_t used = s->bufused; - const int need_free = (int)PObj_buflen(s) - used - len; + const int need_free = (int)Buffer_buflen(s) - used - len; + /* * grow by factor 1.5 or such */ if (need_free <= 16) { - size_t new_size = (size_t) (PObj_buflen(s) * 1.5); - if (new_size < PObj_buflen(s) - need_free + 512) - new_size = PObj_buflen(s) - need_free + 512; + size_t new_size = (size_t) (Buffer_buflen(s) * 1.5); + if (new_size < Buffer_buflen(s) - need_free + 512) + new_size = Buffer_buflen(s) - need_free + 512; Parrot_gc_reallocate_string_storage(interp, s, new_size); - PARROT_ASSERT(PObj_buflen(s) - used - len >= 15); + PARROT_ASSERT(Buffer_buflen(s) - used - len >= 15); } #ifndef DISABLE_GC_DEBUG Parrot_gc_compact_memory_pool(interp); @@ -785,6 +798,7 @@ push_opcode_number(PARROT_INTERP, ARGIN(IMAGE_IO *io), FLOATVAL v) { ASSERT_ARGS(push_opcode_number) + const size_t len = PF_size_number() * sizeof (opcode_t); STRING * const s = io->image; const size_t used = s->bufused; @@ -812,6 +826,7 @@ push_opcode_string(PARROT_INTERP, ARGIN(IMAGE_IO *io), ARGIN(STRING *v)) { ASSERT_ARGS(push_opcode_string) + const size_t len = PF_size_string(v) * sizeof (opcode_t); STRING * const s = io->image; const size_t used = s->bufused; @@ -862,6 +877,7 @@ (const opcode_t **)opcode); io->image->bufused -= ((char *)io->image->strstart - start); + io->image->strlen -= ((char *)io->image->strstart - start); PARROT_ASSERT((int)io->image->bufused >= 0); return i; @@ -903,12 +919,14 @@ shift_opcode_number(SHIM_INTERP, ARGIN(IMAGE_IO *io)) { ASSERT_ARGS(shift_opcode_number) + const char * const start = (const char *)io->image->strstart; char **opcode = &io->image->strstart; const FLOATVAL f = PF_fetch_number(io->pf, (const opcode_t **)opcode); io->image->bufused -= ((char *)io->image->strstart - start); + io->image->strlen -= ((char *)io->image->strstart - start); PARROT_ASSERT((int)io->image->bufused >= 0); return f; @@ -930,12 +948,15 @@ shift_opcode_string(PARROT_INTERP, ARGIN(IMAGE_IO *io)) { ASSERT_ARGS(shift_opcode_string) + char * const start = (char*)io->image->strstart; - char **opcode = &io->image->strstart; + char * opcode = io->image->strstart; STRING * const s = PF_fetch_string(interp, io->pf, - (const opcode_t **)opcode); + (const opcode_t **)&opcode); - io->image->bufused -= ((char *)io->image->strstart - start); + io->image->strstart = opcode; + io->image->bufused -= (opcode - start); + io->image->strlen -= (opcode - start); PARROT_ASSERT((int)io->image->bufused >= 0); return s; @@ -1019,6 +1040,7 @@ 16 - PACKFILE_HEADER_BYTES % 16 : 0); info->image_io = mem_allocate_typed(IMAGE_IO); + info->image_io->image = s = info->image; #if FREEZE_ASCII info->image_io->vtable = &ascii_funcs; @@ -1026,6 +1048,7 @@ info->image_io->vtable = &opcode_funcs; #endif pf = info->image_io->pf = PackFile_new(interp, 0); + if (info->what == VISIT_FREEZE_NORMAL || info->what == VISIT_FREEZE_AT_DESTRUCT) { @@ -1052,6 +1075,7 @@ mem_sys_memcopy(pf->header, s->strstart, PACKFILE_HEADER_BYTES); PackFile_assign_transforms(pf); s->bufused -= header_length; + s->strlen -= header_length; LVALUE_CAST(char *, s->strstart) += header_length; } @@ -1171,6 +1195,7 @@ info->extra_flags = EXTRA_IS_NULL; n = VTABLE_shift_pmc(interp, io); + if (((UINTVAL) n & 3) == 3) { /* pmc has extra data */ info->extra_flags = VTABLE_shift_integer(interp, io); @@ -1194,6 +1219,7 @@ *type = enum_class_Class; } } + *id = (UINTVAL) n; return seen; } @@ -1356,7 +1382,7 @@ } list_assign(interp, (List *)PMC_data(info->id_list), id, pmc, enum_type_PMC); /* remember nested aggregates depth first */ - if (pmc->pmc_ext) + if (PObj_is_PMC_EXT_TEST(pmc)) list_unshift(interp, (List *)PMC_data(info->todo), pmc, enum_type_PMC); } @@ -1396,7 +1422,7 @@ add_pmc_next_for_GC(SHIM_INTERP, ARGIN(PMC *pmc), ARGOUT(visit_info *info)) { ASSERT_ARGS(add_pmc_next_for_GC) - if (pmc->pmc_ext) { + if (PObj_is_PMC_EXT_TEST(pmc)) { PMC_next_for_GC(info->mark_ptr) = pmc; info->mark_ptr = PMC_next_for_GC(pmc) = pmc; } @@ -1433,7 +1459,7 @@ * we can only remember PMCs with a next_for_GC pointer * which is located in pmc_ext */ - if (pmc->pmc_ext) { + if (PObj_is_PMC_EXT_TEST(pmc)) { /* already seen? */ if (!PMC_IS_NULL(PMC_next_for_GC(pmc))) { seen = 1; @@ -1500,7 +1526,7 @@ parrot_hash_put(interp, (Hash *)VTABLE_get_pointer(interp, info->seen), pmc, (void*)*id); /* remember containers */ - if (pmc->pmc_ext) + if (PObj_is_PMC_EXT_TEST(pmc)) list_unshift(interp, (List *)PMC_data(info->todo), pmc, enum_type_PMC); return 0; } @@ -1607,7 +1633,7 @@ { ASSERT_ARGS(visit_loop_next_for_GC) visit_next_for_GC(interp, current, info); - if (current->pmc_ext) { + if (PObj_is_PMC_EXT_TEST(current)) { PMC *prev = NULL; while (current != prev) { @@ -1797,7 +1823,8 @@ */ LVALUE_CAST(char *, image->strstart) -= bufused; image->bufused = bufused; - PARROT_ASSERT(image->strstart >= (char *)PObj_bufstart(image)); + image->strlen += bufused; + PARROT_ASSERT(image->strstart >= (char *)Buffer_bufstart(image)); if (gc_block) { Parrot_unblock_GC_mark(interp); Index: src/pmc/unmanagedstruct.pmc =================================================================== --- src/pmc/unmanagedstruct.pmc (revision 40501) +++ src/pmc/unmanagedstruct.pmc (working copy) @@ -382,7 +382,7 @@ ret = *(PMC**) p; /* now check if initializer has a signature attached */ - if (ptr->pmc_ext && PMC_metadata(ptr)) { + if (PObj_is_PMC_EXT_TEST(ptr) && PMC_metadata(ptr)) { STRING *signature_str = CONST_STRING(interp, "_signature"); PMC *sig = VTABLE_getprop(interp, ptr, signature_str); if (VTABLE_defined(interp, sig)) { @@ -398,7 +398,7 @@ /* check the metadata for an initializer */ /* grab the struct from the metadata */ - if (ptr->pmc_ext && PMC_metadata(ptr)) { + if (PObj_is_PMC_EXT_TEST(ptr) && PMC_metadata(ptr)) { ret = VTABLE_getprop(interp, ptr, CONST_STRING(interp, "_struct")); } else { Index: src/pmc/key.pmc =================================================================== --- src/pmc/key.pmc (revision 40501) +++ src/pmc/key.pmc (working copy) @@ -278,7 +278,7 @@ VTABLE PMC *shift_pmc() { PMC *next_key; - if (!SELF->pmc_ext) + if (!PObj_is_PMC_EXT_TEST(SELF)) return NULL; GET_ATTR_next_key(INTERP, SELF, next_key); Index: src/key.c =================================================================== --- src/key.c (revision 40501) +++ src/key.c (working copy) @@ -544,7 +544,7 @@ ASSERT_ARGS(key_next) PMC *next_key; - if (VTABLE_isa(interp, key, CONST_STRING(interp, "Key")) && key->pmc_ext) { + if (VTABLE_isa(interp, key, CONST_STRING(interp, "Key")) && PObj_is_PMC_EXT_TEST(key)) { GETATTR_Key_next_key(interp, key, next_key); return next_key; } Index: src/debug.c =================================================================== --- src/debug.c (revision 40501) +++ src/debug.c (working copy) @@ -3371,12 +3371,12 @@ if (!s) return; - Parrot_io_eprintf(interp, "\tBuflen =\t%12ld\n", PObj_buflen(s)); + Parrot_io_eprintf(interp, "\tBuflen =\t%12ld\n", Buffer_buflen(s)); Parrot_io_eprintf(interp, "\tFlags =\t%12ld\n", PObj_get_FLAGS(s)); Parrot_io_eprintf(interp, "\tBufused =\t%12ld\n", s->bufused); Parrot_io_eprintf(interp, "\tStrlen =\t%12ld\n", s->strlen); Parrot_io_eprintf(interp, "\tOffset =\t%12ld\n", - (char*) s->strstart - (char*) PObj_bufstart(s)); + (char*) s->strstart - (char*) Buffer_bufstart(s)); Parrot_io_eprintf(interp, "\tString =\t%S\n", s); } Index: src/string/api.c =================================================================== --- src/string/api.c (revision 40501) +++ src/string/api.c (working copy) @@ -89,16 +89,16 @@ * also be sure not to allocate from the constant pool */ PObj_flags_CLEARALL(&for_alloc); - Parrot_gc_allocate_string_storage(interp, &for_alloc, PObj_buflen(s)); + Parrot_gc_allocate_string_storage(interp, &for_alloc, Buffer_buflen(s)); /* now copy memory over */ mem_sys_memcopy(for_alloc.strstart, s->strstart, s->bufused); /* and finally use that string memory */ - PObj_bufstart(s) = PObj_bufstart(&for_alloc); + Buffer_bufstart(s) = Buffer_bufstart(&for_alloc); s->strstart = for_alloc.strstart; - PObj_buflen(s) = PObj_buflen(&for_alloc); + Buffer_buflen(s) = Buffer_buflen(&for_alloc); /* COW_FLAG | external_FLAG */ PObj_is_external_CLEARALL(s); @@ -148,7 +148,7 @@ /* XXX FIXME hack to avoid cross-interpreter issue until it * is fixed correctly. */ if (n_interpreters > 1 && PObj_is_movable_TESTALL(s) && - !Parrot_gc_ptr_in_memory_pool(interp, PObj_bufstart(s))) { + !Parrot_gc_ptr_in_memory_pool(interp, Buffer_bufstart(s))) { Parrot_str_write_COW(interp, d); Parrot_io_eprintf(interp, "cross-interpreter copy of " "relocatable string '%Ss' into tid %d\n", @@ -215,8 +215,8 @@ if (dest) { /* && dest != src */ /* they are different, dest is not an external string */ #ifdef GC_IS_MALLOC - if (!PObj_is_cowed_TESTALL(dest) && PObj_bufstart(dest)) { - mem_sys_free(PObj_bufallocstart(dest)); + if (!PObj_is_cowed_TESTALL(dest) && Buffer_bufstart(dest)) { + mem_sys_free(Buffer_bufallocstart(dest)); } #endif dest = Parrot_str_reuse_COW(interp, src, dest); @@ -338,7 +338,7 @@ { ASSERT_ARGS(string_capacity) - return ((ptrcast_t)PObj_bufstart(s) + PObj_buflen(s) - + return ((ptrcast_t)Buffer_bufstart(s) + Buffer_buflen(s) - (ptrcast_t)s->strstart); } @@ -524,7 +524,7 @@ return a; /* Is A real? */ - if (a == NULL || PObj_bufstart(a) == NULL) + if (a == NULL || Buffer_bufstart(a) == NULL) return Parrot_str_copy(interp, b); saneify_string(a); @@ -806,8 +806,8 @@ it was safe by setting PObj_external_FLAG. (The cast is necessary to pacify TenDRA's tcc.) */ - PObj_bufstart(s) = s->strstart = PARROT_const_cast(char *, buffer); - PObj_buflen(s) = s->bufused = len; + Buffer_bufstart(s) = s->strstart = PARROT_const_cast(char *, buffer); + Buffer_buflen(s) = s->bufused = len; if (encoding == Parrot_fixed_8_encoding_ptr) s->strlen = len; @@ -855,7 +855,7 @@ /* Don't check buflen, if we are here, we already checked. */ Parrot_gc_reallocate_string_storage(interp, - s, PObj_buflen(s) + string_max_bytes(interp, s, addlen)); + s, Buffer_buflen(s) + string_max_bytes(interp, s, addlen)); return s; } @@ -1328,7 +1328,7 @@ diff = (end_byte - start_byte) - rep->bufused; if (diff >= 0 - || ((INTVAL)src->bufused - (INTVAL)PObj_buflen(src)) <= diff) { + || ((INTVAL)src->bufused - (INTVAL)Buffer_buflen(src)) <= diff) { Parrot_str_write_COW(interp, src); if (diff != 0) { @@ -2479,11 +2479,11 @@ */ Parrot_str_write_COW(interp, s); - size = PObj_buflen(s); + size = Buffer_buflen(s); memory = (char *)mem_sys_allocate(size); - mem_sys_memcopy(memory, PObj_bufstart(s), size); - PObj_bufstart(s) = memory; + mem_sys_memcopy(memory, Buffer_bufstart(s), size); + Buffer_bufstart(s) = memory; s->strstart = memory; /* Mark the memory as both from the system and immobile */ @@ -2516,10 +2516,10 @@ return; Parrot_str_write_COW(interp, s); - size = PObj_buflen(s); + size = Buffer_buflen(s); /* We need a handle on the fixed memory so we can get rid of it later */ - memory = PObj_bufstart(s); + memory = Buffer_bufstart(s); /* Reallocate it the same size * NOTE can't use Parrot_gc_reallocate_string_storage because of the LEA @@ -2530,7 +2530,7 @@ Parrot_block_GC_sweep(interp); Parrot_gc_allocate_string_storage(interp, s, size); Parrot_unblock_GC_sweep(interp); - mem_sys_memcopy(PObj_bufstart(s), memory, size); + mem_sys_memcopy(Buffer_bufstart(s), memory, size); /* Mark the memory as neither immobile nor system allocated */ PObj_sysmem_CLEAR(s); @@ -2722,7 +2722,7 @@ i += hex->strlen; /* and usable len */ - charlen = PObj_buflen(result); + charlen = Buffer_buflen(result); dp = (unsigned char *)result->strstart; PARROT_ASSERT(i <= charlen); Index: src/string/encoding/fixed_8.c =================================================================== --- src/string/encoding/fixed_8.c (revision 40501) +++ src/string/encoding/fixed_8.c (working copy) @@ -634,7 +634,7 @@ { ASSERT_ARGS(fixed8_set_position) iter->bytepos = iter->charpos = pos; - PARROT_ASSERT(pos <= PObj_buflen(iter->str)); + PARROT_ASSERT(pos <= Buffer_buflen(iter->str)); } Index: src/gc/alloc_resources.c =================================================================== --- src/gc/alloc_resources.c (revision 40501) +++ src/gc/alloc_resources.c (working copy) @@ -54,7 +54,7 @@ __attribute__nonnull__(1) __attribute__nonnull__(2); -static void debug_print_buf(PARROT_INTERP, ARGIN(const PObj *b)) +static void debug_print_buf(PARROT_INTERP, ARGIN(const Buffer *b)) __attribute__nonnull__(1) __attribute__nonnull__(2); @@ -285,11 +285,11 @@ */ static void -debug_print_buf(PARROT_INTERP, ARGIN(const PObj *b)) +debug_print_buf(PARROT_INTERP, ARGIN(const Buffer *b)) { ASSERT_ARGS(debug_print_buf) fprintf(stderr, "found %p, len %d, flags 0x%08x at %s\n", - b, (int)PObj_buflen(b), (uint)PObj_get_FLAGS(b), + b, (int)Buffer_buflen(b), (uint)PObj_get_FLAGS(b), buffer_location(interp, b)); } #endif @@ -407,21 +407,21 @@ INTVAL *ref_count = NULL; /* ! (on_free_list | constant | external | sysmem) */ - if (PObj_buflen(b) && PObj_is_movable_TESTALL(b)) { + if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) { ptrdiff_t offset = 0; #if RESOURCE_DEBUG - if (PObj_buflen(b) >= RESOURCE_DEBUG_SIZE) + if (Buffer_buflen(b) >= RESOURCE_DEBUG_SIZE) debug_print_buf(interp, b); #endif /* we can't perform the math all the time, because * strstart might be in unallocated memory */ if (PObj_is_COWable_TEST(b)) { - ref_count = PObj_bufrefcountptr(b); + ref_count = Buffer_bufrefcountptr(b); if (PObj_is_string_TEST(b)) { offset = (ptrdiff_t)((STRING *)b)->strstart - - (ptrdiff_t)PObj_bufstart(b); + (ptrdiff_t)Buffer_bufstart(b); } } @@ -429,7 +429,8 @@ if (PObj_COW_TEST(b) && (ref_count && *ref_count & Buffer_moved_FLAG)) { /* Find out who else references our data */ - Buffer * const hdr = *(Buffer **)(PObj_bufstart(b)); + Buffer * const hdr = *((Buffer **)Buffer_bufstart(b)); + PARROT_ASSERT(PObj_is_COWable_TEST(b)); @@ -438,13 +439,13 @@ /* TODO incr ref_count, after fixing string too * Now make sure we point to where the other guy does */ - PObj_bufstart(b) = PObj_bufstart(hdr); + Buffer_bufstart(b) = Buffer_bufstart(hdr); /* And if we're a string, update strstart */ /* Somewhat of a hack, but if we get per-pool * collections, it should help ease the pain */ if (PObj_is_string_TEST(b)) { - ((STRING *)b)->strstart = (char *)PObj_bufstart(b) + + ((STRING *)b)->strstart = (char *)Buffer_bufstart(b) + offset; } } @@ -457,14 +458,14 @@ } /* Copy our memory to the new pool */ - memcpy(cur_spot, PObj_bufstart(b), PObj_buflen(b)); + memcpy(cur_spot, Buffer_bufstart(b), Buffer_buflen(b)); /* If we're COW */ if (PObj_COW_TEST(b)) { PARROT_ASSERT(PObj_is_COWable_TEST(b)); /* Let the old buffer know how to find us */ - *(Buffer **)(PObj_bufstart(b)) = b; + *((Buffer **)Buffer_bufstart(b)) = b; /* No guarantees that our data is still COW, so * assume not, and let the above code fix-up */ @@ -477,14 +478,14 @@ *ref_count |= Buffer_moved_FLAG; } - PObj_bufstart(b) = cur_spot; + Buffer_bufstart(b) = cur_spot; if (PObj_is_string_TEST(b)) { - ((STRING *)b)->strstart = (char *)PObj_bufstart(b) + + ((STRING *)b)->strstart = (char *)Buffer_bufstart(b) + offset; } - cur_spot += PObj_buflen(b); + cur_spot += Buffer_buflen(b); } } b = (Buffer *)((char *)b + object_size); @@ -676,7 +677,6 @@ /* Constant strings - not compacted */ arena_base->constant_string_pool = new_memory_pool(POOL_SIZE, NULL); - alloc_new_block(interp, POOL_SIZE, arena_base->constant_string_pool, "init"); } @@ -743,6 +743,206 @@ */ /* + +=item C + +Checks the memory system of parrot on any corruptions, including +the string system. + +=cut + +*/ + +void +check_memory_system(PARROT_INTERP) +{ + size_t i; + Arenas * const arena_base = interp->arena_base; + + check_memory_pool(arena_base->memory_pool); + check_memory_pool(arena_base->constant_string_pool); + check_small_object_pool(arena_base->pmc_pool); + check_small_object_pool(arena_base->constant_pmc_pool); + check_small_object_pool(arena_base->string_header_pool); + check_small_object_pool(arena_base->constant_string_header_pool); + + for(i = 0;i < arena_base->num_sized;i++) + { + Small_Object_Pool * pool = arena_base->sized_header_pools[i]; + if(pool != NULL && pool != arena_base->string_header_pool) + check_small_object_pool(pool); + } +} + +/* + +=item C + +Checks a small object pool, if it contains buffer it checks the buffers also. + +=cut + +*/ + +void +check_small_object_pool(Small_Object_Pool * pool) +{ + size_t total_objects; + size_t last_free_list_count; + Small_Object_Arena * arena_walker; + size_t free_objects; + PObj * object; + size_t i; + size_t count; + GC_MS_PObj_Wrapper * pobj_walker; + + count = 10000000; /*detect unendless loop just use big enough number*/ + + total_objects = pool->total_objects; + last_free_list_count = 1; + free_objects = 0; + + arena_walker = pool->last_Arena; + while(arena_walker != NULL) + { + total_objects -= arena_walker->total_objects; + object = (PObj*)arena_walker->start_objects; + for(i = 0;i < arena_walker->total_objects;++i) + { + if(PObj_on_free_list_TEST(object)) + { + ++free_objects; + pobj_walker = (GC_MS_PObj_Wrapper*)object; + if(pobj_walker->next_ptr == NULL) + { + --last_free_list_count; //should happen only ones at the end + } + else + { /*next item on free list should also be flaged as free item*/ + pobj_walker = (GC_MS_PObj_Wrapper*)pobj_walker->next_ptr; + PARROT_ASSERT(PObj_on_free_list_TEST((PObj*)pobj_walker)); + } + } + else if(pool->mem_pool != NULL) /*then it means we are a buffer*/ + { + check_buffer_ptr((Buffer*)object,pool->mem_pool); + } + object = (PObj*)((char *)object + pool->object_size); + PARROT_ASSERT(--count); + } + /*check the list*/ + if(arena_walker->prev != NULL) + { + PARROT_ASSERT(arena_walker->prev->next == arena_walker); + } + arena_walker = arena_walker->prev; + PARROT_ASSERT(--count); + } + + count = 10000000; + + PARROT_ASSERT(free_objects == pool->num_free_objects); + + pobj_walker = (GC_MS_PObj_Wrapper*)pool->free_list; + while(pobj_walker != NULL) + { + PARROT_ASSERT(pool->start_arena_memory <= (size_t)pobj_walker); + PARROT_ASSERT(pool->end_arena_memory > (size_t)pobj_walker); + PARROT_ASSERT(PObj_on_free_list_TEST((PObj*)pobj_walker)); + --free_objects; + pobj_walker = (GC_MS_PObj_Wrapper*)pobj_walker->next_ptr; + PARROT_ASSERT(--count); + } + + PARROT_ASSERT(total_objects == 0); + PARROT_ASSERT(last_free_list_count == 0 || pool->num_free_objects == 0); + PARROT_ASSERT(free_objects == 0); +} + +/* + +=item C + +Checks a memory pool, containing buffer data + +=cut + +*/ + +void +check_memory_pool(Memory_Pool *pool) +{ + size_t count; + count = 10000000; /*detect unendless loop just use big enough number*/ + + Memory_Block * block_walker = (Memory_Block *)pool->top_block; + while(block_walker != NULL) + { + PARROT_ASSERT(block_walker->start == (char *)block_walker + sizeof (Memory_Block)); + PARROT_ASSERT((size_t)(block_walker->top - block_walker->start) == block_walker->size - block_walker->free); + + /*check the list*/ + if(block_walker->prev != NULL) + { + PARROT_ASSERT(block_walker->prev->next == block_walker); + } + block_walker = block_walker->prev; + PARROT_ASSERT(--count); + } +} + +/* + +=item C + +Checks wether the buffer is within the bounds of the memory pool + +=cut + +*/ + +void +check_buffer_ptr(Buffer * pobj,Memory_Pool * pool) +{ + Memory_Block * cur_block = pool->top_block; + char * bufstart; + + bufstart = (char*)Buffer_bufstart(pobj); + + if(bufstart == NULL && Buffer_buflen(pobj) == 0) + return; + + if(PObj_external_TEST(pobj)) /*buffer does not come from the memory pool*/ + { + if (PObj_is_string_TEST(pobj)) + { + PARROT_ASSERT(((STRING *) pobj)->strstart >= (char *) Buffer_bufstart(pobj)); + PARROT_ASSERT(((STRING *) pobj)->strstart + ((STRING *) pobj)->strlen <= (char *) Buffer_bufstart(pobj) + Buffer_buflen(pobj)); + } + return; + } + + if(PObj_is_COWable_TEST(pobj)) + bufstart -= sizeof (void*); + + while (cur_block) + { + if ((char *)bufstart >= cur_block->start && + (char *)Buffer_bufstart(pobj) + Buffer_buflen(pobj) < cur_block->start + cur_block->size) + { + if (PObj_is_string_TEST(pobj)) + { + PARROT_ASSERT(((STRING *)pobj)->strstart >= (char *)Buffer_bufstart(pobj)); + PARROT_ASSERT(((STRING *)pobj)->strstart + ((STRING *)pobj)->strlen <= (char *)Buffer_bufstart(pobj) + Buffer_buflen(pobj)); + } + return; + } + cur_block = cur_block->prev; + } + PARROT_ASSERT(0); +} + +/* * Local variables: * c-file-style: "parrot" * End: Index: src/call/pcc.c =================================================================== --- src/call/pcc.c (revision 40501) +++ src/call/pcc.c (working copy) @@ -1665,7 +1665,7 @@ * RT #54860 and others * Save current value while setting the optional */ - const UnionVal old_value = st->val; + const UnionCallStateVal old_value = st->val; while (dest->sig & PARROT_ARG_OPTIONAL) { null_val(st->dest.sig, st); Index: src/gc/mark_sweep.c =================================================================== --- src/gc/mark_sweep.c (revision 40501) +++ src/gc/mark_sweep.c (working copy) @@ -33,7 +33,7 @@ static void free_buffer(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), - ARGMOD(PObj *b)) + ARGMOD(Buffer *b)) __attribute__nonnull__(2) __attribute__nonnull__(3) FUNC_MODIFIES(*pool) @@ -41,7 +41,7 @@ static void free_buffer_malloc(SHIM_INTERP, SHIM(Small_Object_Pool *pool), - ARGMOD(PObj *b)) + ARGMOD(Buffer *b)) __attribute__nonnull__(3) FUNC_MODIFIES(*b); @@ -54,11 +54,6 @@ PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL -static Small_Object_Pool * new_buffer_pool(PARROT_INTERP) - __attribute__nonnull__(1); - -PARROT_WARN_UNUSED_RESULT -PARROT_CANNOT_RETURN_NULL static Small_Object_Pool * new_bufferlike_pool(PARROT_INTERP, size_t actual_buffer_size) __attribute__nonnull__(1); @@ -98,8 +93,6 @@ #define ASSERT_ARGS_free_pmc_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp) \ || PARROT_ASSERT_ARG(p) -#define ASSERT_ARGS_new_buffer_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ - PARROT_ASSERT_ARG(interp) #define ASSERT_ARGS_new_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp) #define ASSERT_ARGS_new_pmc_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ @@ -140,7 +133,6 @@ arena_base->gc_trace_ptr = NULL; arena_base->gc_mark_start = NULL; arena_base->num_early_PMCs_seen = 0; - arena_base->num_extended_PMCs = 0; } /* @@ -281,6 +273,8 @@ Parrot_gc_sweep_pool(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool)) { ASSERT_ARGS(Parrot_gc_sweep_pool) + PObj *b; + UINTVAL i; UINTVAL total_used = 0; const UINTVAL object_size = pool->object_size; @@ -301,10 +295,9 @@ } #endif - /* Run through all the buffer header pools and mark */ + /* Run through all the PObj header pools and mark */ for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) { - Buffer *b = (Buffer *)cur_arena->start_objects; - UINTVAL i; + b = (PObj*)cur_arena->start_objects; /* loop only while there are objects in the arena */ for (i = cur_arena->total_objects; i; i--) { @@ -349,7 +342,7 @@ pool->add_free_object(interp, pool, b); } next: - b = (Buffer *)((char *)b + object_size); + b = (PObj *)((char *)b + object_size); } } @@ -443,10 +436,8 @@ else hi_prio = 0; - if (obj->pmc_ext) { + if (PObj_is_PMC_EXT_TEST(obj)) { PMC * const tptr = arena_base->gc_trace_ptr; - - ++arena_base->num_extended_PMCs; /* * XXX this basically invalidates the high-priority marking * of PMCs by putting all PMCs onto the front of the list. @@ -803,7 +794,6 @@ #ifndef NDEBUG - pmc->pmc_ext = (PMC_EXT *)0xdeadbeef; pmc->vtable = (VTABLE *)0xdeadbeef; #endif @@ -835,7 +825,12 @@ Small_Object_Pool * const pool = new_small_object_pool(buffer_size, num_headers); - pool->gc_object = NULL; +#ifdef GC_IS_MALLOC + pool->gc_object = free_buffer_malloc; +#else + pool->gc_object = (gc_object_fn_type)free_buffer; +#endif + pool->mem_pool = interp->arena_base->memory_pool; (interp->arena_base->init_pool)(interp, pool); return pool; @@ -872,15 +867,13 @@ return pool; } - - /* -=item C - -Creates a new C structure for managing buffer objects. +=item C -Non-constant strings and plain Buffers are stored in the sized header pools. +Creates a new pool for Cs and returns it. This calls +C internally, which in turn calls C. =cut @@ -889,16 +882,19 @@ PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL static Small_Object_Pool * -new_buffer_pool(PARROT_INTERP) +new_string_pool(PARROT_INTERP, INTVAL constant) { - ASSERT_ARGS(new_buffer_pool) - Small_Object_Pool * const pool = get_bufferlike_pool(interp, sizeof (Buffer)); + ASSERT_ARGS(new_string_pool) + Small_Object_Pool *pool; + if (constant) { + pool = new_bufferlike_pool(interp, sizeof (STRING)); + pool->gc_object = NULL; + pool->mem_pool = interp->arena_base->constant_string_pool; + } + else + pool = get_bufferlike_pool(interp, sizeof (STRING)); -#ifdef GC_IS_MALLOC - pool->gc_object = free_buffer_malloc; -#else - pool->gc_object = free_buffer; -#endif + pool->objects_per_alloc = STRING_HEADERS_PER_ALLOC; return pool; } @@ -918,25 +914,25 @@ static void free_buffer_malloc(SHIM_INTERP, SHIM(Small_Object_Pool *pool), - ARGMOD(PObj *b)) + ARGMOD(Buffer *b)) { ASSERT_ARGS(free_buffer_malloc) /* free allocated space at (int *)bufstart - 1, but not if it used COW or is * external */ - PObj_buflen(b) = 0; + Buffer_buflen(b) = 0; - if (!PObj_bufstart(b) || PObj_is_external_or_free_TESTALL(b)) + if (!Buffer_bufstart(b) || PObj_is_external_or_free_TESTALL(b)) return; if (PObj_COW_TEST(b)) { - INTVAL * const refcount = PObj_bufrefcountptr(b); + INTVAL * const refcount = Buffer_bufrefcountptr(b); if (--(*refcount) == 0) { mem_sys_free(refcount); /* the actual bufstart */ } } else - mem_sys_free(PObj_bufrefcountptr(b)); + mem_sys_free(Buffer_bufrefcountptr(b)); } /* @@ -952,7 +948,7 @@ */ static void -free_buffer(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGMOD(PObj *b)) +free_buffer(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGMOD(Buffer *b)) { ASSERT_ARGS(free_buffer) Memory_Pool * const mem_pool = (Memory_Pool *)pool->mem_pool; @@ -961,49 +957,17 @@ * shouldn't happen */ if (mem_pool) { if (!PObj_COW_TEST(b)) - mem_pool->guaranteed_reclaimable += PObj_buflen(b); + mem_pool->guaranteed_reclaimable += Buffer_buflen(b); - mem_pool->possibly_reclaimable += PObj_buflen(b); + mem_pool->possibly_reclaimable += Buffer_buflen(b); } - PObj_buflen(b) = 0; + Buffer_buflen(b) = 0; } /* -=item C - -Creates a new pool for Cs and returns it. This calls -C internally, which in turn calls C. - -=cut - -*/ - -PARROT_WARN_UNUSED_RESULT -PARROT_CANNOT_RETURN_NULL -static Small_Object_Pool * -new_string_pool(PARROT_INTERP, INTVAL constant) -{ - ASSERT_ARGS(new_string_pool) - Small_Object_Pool *pool; - if (constant) { - pool = new_bufferlike_pool(interp, sizeof (STRING)); - pool->mem_pool = interp->arena_base->constant_string_pool; - } - else - pool = get_bufferlike_pool(interp, sizeof (STRING)); - - pool->objects_per_alloc = STRING_HEADERS_PER_ALLOC; - - return pool; -} - - -/* - =item C @@ -1076,8 +1040,8 @@ * The buffer_header_pool and the string_header_pool actually live in the * sized_header_pools. These pool pointers only provide faster access in * new_*_header */ - arena_base->buffer_header_pool = new_buffer_pool(interp); - arena_base->buffer_header_pool->name = "buffer_header"; + // arena_base->buffer_header_pool = new_buffer_pool(interp); + // arena_base->buffer_header_pool->name = "buffer_header"; /* Init the string header pool */ arena_base->string_header_pool = new_string_pool(interp, 0); @@ -1087,26 +1051,6 @@ arena_base->pmc_pool = new_pmc_pool(interp); arena_base->pmc_pool->name = "pmc"; - /* pmc extension buffer */ - arena_base->pmc_ext_pool = - new_small_object_pool(sizeof (PMC_EXT), 1024); - -#if PARROT_GC_MS - /* - * pmc_ext isn't a managed item. If a PMC has a pmc_ext structure - * it is returned to the pool instantly - the structure is never - * marked. - * Use GS MS pool functions - */ - gc_ms_pmc_ext_pool_init(arena_base->pmc_ext_pool); -#elif PARROT_GC_INF - arena_base->init_pool(interp, arena_base->pmc_ext_pool); -#else - /* rational, consistant behavior (as yet unwritten) */ -#endif - - arena_base->pmc_ext_pool->name = "pmc_ext"; - /* constant PMCs */ arena_base->constant_pmc_pool = new_pmc_pool(interp); arena_base->constant_pmc_pool->name = "constant_pmc"; Index: src/jit_debug_xcoff.c =================================================================== --- src/jit_debug_xcoff.c (revision 40501) +++ src/jit_debug_xcoff.c (working copy) @@ -118,63 +118,57 @@ fprintf(stabs, ".stabx \"STRING:t%d=*%d\"" ",0," C_DECL ",0\n", i, i+1); ++i; - fprintf(stabs, ".stabx \"Parrot_String:T%d=s%d" - "bufstart:14,%d,%d;" - "buflen:6,%d,%d;" /* XXX type */ - "flags:12,%d,%d;" - "bufused:12,%d,%d;" - "strstart:15,%d,%d;" /* fake a char* */ + fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d" + "bufstart:(0,14),%d,%d;" + "buflen:(0,6),%d,%d;" + "flags:(0,12),%d,%d;" + "bufused:(0,12),%d,%d;" + "strstart:(0,15),%d,%d;" ";\"" - ",0," C_DECL ",0\n", i++, BYTE_SIZE(STRING), - BIT_OFFSET(STRING, cache._b._bufstart), BIT_SIZE(void*), - BIT_OFFSET(STRING, cache._b._buflen), BIT_SIZE(size_t), + "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING), + BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*), + BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t), BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL), BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL), BIT_OFFSET(STRING, strstart), BIT_SIZE(void*)); - fprintf(stabs, ".stabx \"PMCType:T%d=e", i++); + fprintf(stabs, ".stabs \"PMCType:T(0,%d)=e", i++); for (j = 0; j < interp->n_vtable_max; ++j) { if (interp->vtables[j] && interp->vtables[j]->whoami) { - STRING* name = interp->vtables[j]->whoami; - fwrite(name->strstart, name->strlen, 1, stabs); + STRING *name = interp->vtables[j]->whoami; + size_t items = fwrite(name->strstart, name->strlen, 1, stabs); + if (!items) + fprintf(stderr, "Error writing stabs!\n"); fprintf(stabs, ":%d,", j); } } - fprintf(stabs, ";\",0," C_DECL ",0\n"); - /* PMC type */ - fprintf(stabs, ".stabx \"PMC:T%d=s%d", i, BYTE_SIZE(PMC)); - fprintf(stabs, "cache:%d,%d,%d;", - i + 1, BIT_OFFSET(PMC, cache), BIT_SIZE(UnionVal)); - fprintf(stabs, "flags:%d,%d,%d;", - i + 1, BIT_OFFSET(PMC, flags), BIT_SIZE(Parrot_UInt)); - fprintf(stabs, "vtable:*%d,%d,%d;", - i + 3, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*)); - fprintf(stabs, "data:14,%d,%d;", - BIT_OFFSET(PMC, data), BIT_SIZE(void*)); - fprintf(stabs, "pmc_ext:*%d,%d,%d;", - i, BIT_OFFSET(PMC, pmc_ext), BIT_SIZE(void*)); - fprintf(stabs, ";\""); - fprintf(stabs, ",0," C_DECL ",0\n"); + fprintf(stabs, ";\"," N_LSYM ",0,0,0\n"); - fprintf(stabs, ".stabx \"cache:%d,%d,%d;" - "flags:12,%d,%d;" - ";\"" - ",0," C_DECL ",0\n", - i + 2, BIT_SIZE(UnionVal), BIT_SIZE(Parrot_UInt)); - fprintf(stabs, ".stabx \"UnionVal:T%d=u%d" - "int_val:12,%d,%d;" - "pmc_val:*%d,%d,%d;" + fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d" + "flags:(0,12),%d,%d;" + "vtable:*(0,%d),%d,%d;" + "data:(0,14),%d,%d;" + "_metadata:*(0,%d),%d,%d;" + "_next_for_GC:*(0,%d),%d,%d;" ";\"" - ",0," C_DECL ",0\n", i + 2, BYTE_SIZE(UnionVal), - BIT_OFFSET(UnionVal, int_val), BIT_SIZE(INTVAL), - i, BIT_OFFSET(UnionVal, pmc_val), BIT_SIZE(void*)); - fprintf(stabs, ".stabx \"VTABLE:T%d=s%d" - "base_type:%d,%d,%d;" + "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC), + BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL), + i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*), + BIT_OFFSET(PMC, data), BIT_SIZE(void*), + i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*), + i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*)); + + i++; + + //some one can add some field to this one + fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d" + "base_type:(0,12),%d,%d;" ";\"" - ",0," C_DECL ",0\n", i + 3, BYTE_SIZE(UnionVal), - i - 1, BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); - i += 4; + "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable), + BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); + + i++; } Index: docs/memory_internals2.pod =================================================================== --- docs/memory_internals2.pod (revision 0) +++ docs/memory_internals2.pod (revision 0) @@ -0,0 +1,507 @@ +=head1 NAME + +docs/memory_internals2.pod - Memory Internals extra documentation + +=head1 ABSTRACT + +This explanation of the memory system gives a bit more explanation of the memory/gc +system used by parrot. + +=head2 Used memory management systems + +The memory system basically uses 3 types of memory management systems + +=over 4 + +=item 1 The standard c allocate system + +=item 2 Memory pool system. + +This system has the following to purposes. + +=over 8 + +=item * Variable sized objects are stored in a more compact way. + +=item * There is a compacting function to compact the data + +=back + +This compacting function is working in conjunction with the small object pool system(see next section). +A C contains multiple C objects. The more memory is needed +the more C items are added. C items are allocated via the c allocate system. +A memory pool contain variable sized buffers, such as strings. + +=item 3 Smalls Object pool system. + +This is used for efficient storage of small object with constant sizes +which are allocated and released many times. + +=back + +=head2 Small object pool system + +All objects in the small object system are of type C + + typedef struct pobj_t { + Parrot_UInt flags; + } PObj; + +This struct is "sub classed" by the following 3 structs + +=over 4 + +=item * GC_MS_PObj_Wrapper, this struct is used when object are on the free list + + typedef struct GC_MS_PObj_Wrapper { + size_t flags; + struct GC_MS_PObj_Wrapper * next_ptr; + } GC_MS_PObj_Wrapper; + +=item * Buffer, this struct is used for object which hold a buffer + + typedef struct buffer_t { + Parrot_UInt flags; + void * _bufstart; + size_t _buflen; + } Buffer; + +=item * PMC, the all important pmc :) + + struct PMC { + Parrot_UInt flags; + VTABLE *vtable; + DPOINTER *data; + PMC *_metadata; /* object properties */ + struct _Sync *_synchronize; + PMC *_next_for_GC; + }; + +=back + +The Buffer struct, is "sub classed" by the following 3 structs + +=over 4 + +=item * String + + struct parrot_string_t { + Parrot_UInt flags; + void * _bufstart; + size_t _buflen; + + char *strstart; + UINTVAL bufused; + UINTVAL strlen; + UINTVAL hashval; /* cached hash value computation */ + + /* parrot_string_representation_t representation;*/ + const struct _encoding *encoding; + const struct _charset *charset; + }; + +=item * List_chunk + +=item * List + +=back + +See pobj.h for information on the available flags, notice there is a flag indicating that +the object is on the free list. + +The memory system is aware of 3 types of small object pools. + +=over 4 + +=item 1 Those pools with a reference to a variable buffer in C<< Arenas->Memory >>. + +These pools must apply to the following things + +=over 8 + +=item * They must be present in the sized_header_pools list + +=item * All object they contain must be of the type PObj + + typedef struct buffer_t { + Parrot_UInt flags; + void * _bufstart; + size_t _buflen; + } Buffer; + +=item * All these field are used by the compact function of the memory pool system. + +=item * These objects support COW (Copy on Write) flag + +=back + +Currently used by + +=over 8 + +=item * non constant Strings + +=item * list.c for storage of list buffer + +=back + +=item 2 The pool for the constant string. + +It uses the C<< Anenas->constant_string_pool >>, which is not compacted. +Constant strings are not released back system during runtime. + + +=item 3 The pool of objects without a reference to a variable buffer. + +Currently used by + +=over 8 + +=item * PMC items. + +=item * constant PMC items. + +=back + +A Small_Object_Pool contains multiple Small_Object_Arena items. Arena's +are added as more memory is need for the pool. These Arena's are +allocated from the c allocate system. + +=head2 Summarization of Arenas struct + +A small summarize of the memory related items in the C struct. + + typedef struct Arenas { + /*Memory for buffers used by the small object of type 1*/ + Memory_Pool *memory_pool; + /*Memory for buffers used by the small object of type 2 -> the constant strings */ + Memory_Pool *constant_string_pool; + /*Pool of type 1, used for storage of the string header*/ + struct Small_Object_Pool *string_header_pool; + /*Pool of type 3, used for storage of the pmc objects*/ + struct Small_Object_Pool *pmc_pool; + /*Pool of type 3, used for storage of pmc object which have constant flag*/ + struct Small_Object_Pool *constant_pmc_pool + /*Pool of type 2, used for storage of the headers of the constant strings*/ + struct Small_Object_Pool *constant_string_header_pool; + /*Containts all the Small_Object_Pool of type 1. Which are + 1. string_header_pool + 2. buffer storage used by list.c (struct List_chunk) + */ + struct Small_Object_Pool **sized_header_pools; + /*Number of elements in sized_header_pools, be aware of the fact this equal to + the "buffer header" / sizeof(void*) + size_t num_sized; + ... + +=head2 Function summarization + +Here is grouped summarization of the interesting functions of the garbage collecting system +to give a better overview of them. + +=head3 Memory pool system + +These function are responsible for the Memory pool system. + +C This function adds a new block to a memory pool + +C This function allocates a buffer in a memory pool + +C This function compacts the memory buffer system + +C This function inits a new memory pool + +C This function initializes the to memory pools + +C This function merges to memory pools together, this is used for merging to interpreters +together + +C This function released the memory pools + +C The public api to compact the memory pools + +=head3 Garbage collecting + +The garbage collecting system exits out of the following steps. See the other +memory internals documentation for more information. + +=over 4 + +=item * First phase marking off all objects, follows all links except the C<< pmc->_metadata >> link + +=item * Second phase marking off all objects, which follows the C<< pmc->_metadata >> links + +=item * Sweep all the pools of dead objects + +=back + +In the first phase all object with pmc extension are put in a list which is linked via the +C<< pmc->_next_for_GC >> field. Then in the second phase this list is walked down, to continue the +marking. These 2 phased marking of objects is used for a prioritization system. (not +documented here) + +These functions are responsible for the garbage collecting system. + +C The public api to run a gc + +C Runs the stop-the-world mark & sweep (MS) collector. + +C Clears some fields before a gc run is started + +C This function clears the live bit of all the objects in a pool, called before the mark phase + +C Calls the 2 mark phase functions + +C Public api to mark a given object as live + +C Does all necessary thing to mark object as alive and walks downs the links + +C This function perform the first phase of the marking of all the objects + +C This function perform the second phase of the marking of all the objects + +C This function sweeps all the pools, using the iterate util function + +C Sweep a pool and releases the dead objects + +=head4 C<< pmc->_next_for_GC >> cleanup + +These 2 function are used to clean of the C<< pmc->_next_for_GC >> fields in the +small object pools. This is used by pmc_freeze.c + +C +C + +=head3 Small object pool objects + +These functions are responsible for allocation and freeing of object +which make use of the small object pools + +C Releases a PObj to a small object pool + +C Allocates a PObj from a small object pool + +C Increases the small object pool with fresh arena so new free object becomes available + +C Tries to free object in the small object pool by using the gc system + +=head3 Small object pool Arena's + +These function are responsible for the arena system in a small object pool. + +C Allocates a new arena and add it to the pool + +C Initialized a new arena pool, by adding the free space to the free list + +=head3 Pmc header(ext) + +These function are the public api for the pmc objects (type 3). +In the past there was a separate pmc_ext structure which was separately allocated, but +is now integrated into the pmc header. + +C Allocate/init a new pmc header + +C Releases a pmc header + +C Adds pmc ext capabilities to a pmc + +C Remove pmc ext capabilities from a pmc + +C Add synchronization capability to a pmc + +=head3 Buffer header (including strings) + +These functions are the api function for object which have buffer capabilities (type 1 & 2) +These function does not allocate the buffer itself. +Allocation of a buffer like object, such as a string, takes place in two phases. +First the header is allocated from a constant memory pool and after that +a buffer is allocated form the Memory pool system. See next group of function +for actual allocation of the buffer. + +C Allocate a new String header + +C Releases the String header + +C Allocate a new buffer header + +C Allocate a new buffer header + +C Allocates/init a buffer like object of given size + +The following functions are used for alignment + +C + +C + +C + +=head4 C + +C Is used by the Parrot_gc_new_bufferlike_header function to get +the small object pool with the right size. If does not exist it creates +a new small object pool. The small object pool is stored in the C<< arenas->sized_header_pools >> +list. This list only contain small object pools which hold buffer header objects, of which the +buffer is stored in the C<< arena->memory pool >>. + +=head3 Buffer allocation + +These function are responsible for the allocation a the actual buffer of a +buffer object. + +C + +C + +C + +C + +=head3 Initialization + +These functions are responsible for the initialization of the gc system + + +C The public api to initialize the gc system + +C The init function of the gc + +C This function initializes the memory pools + +C This function initializes the small object pools + +C This function creates pool which contains pmc object + +C This function creates a small object pool + +C This function initializes a small object pool + +C This function creates a small object pool for string headers + +C This function creates a small object pool for buffer header + +Note that C does not register the pool in the +C<< Arenas->sized_header_pools >> list, which must be done if +you make use of the C<< Arenas->memory_pool >> + +=head3 Finalization + +These functions are responsible for the finalization of the gc system + + +C public api to finalize the gc system + +C This function finalizes the gc system + +C This function destroys all small object pools + +These two function are used to free all the object in a small object pool + +C + +C + +C This function released the arenas and pool back to the system + +=head4 PObj removal + +These function are called when a PObj in a small object pool get released by the gc system + +C This function frees the associated buffer in the memory pool + +C existing but dead at the moment + +C This function releases a pmc object, does finalization if needed + +=head3 Intrepreter merging + +The following functions are used for merging two interpreters together + +C + +C + +C + +=head2 Util functions + +These are various util functions + +C This function iterates over all the small object pools + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +C + +=head3 Blocking + +The following function are used the block the gc from running + +C + +C + +C + +C + +C + +C + +C + +=head3 Memory Assertion check + +These functions can be used for debugging purpose to see whether the memory system is +not corrupted. + +C Check the complete memory system + +C Checks a small object pool + +C Check a memory pool + +C Check buffer header to see whether the buffer is in bounds of memory pool + +=head1 AUTHOR + +Jesse van Dam C + +=head1 VERSION + +0.1 Augustus 2009 + + Index: include/parrot/gc_api.h =================================================================== --- include/parrot/gc_api.h (revision 40501) +++ include/parrot/gc_api.h (working copy) @@ -239,7 +239,7 @@ __attribute__nonnull__(1); void Parrot_gc_free_bufferlike_header(PARROT_INTERP, - ARGMOD(PObj *obj), + ARGMOD(Buffer *obj), size_t size) __attribute__nonnull__(1) __attribute__nonnull__(2) Index: src/gc/incremental_ms.c =================================================================== --- src/gc/incremental_ms.c (revision 40501) +++ src/gc/incremental_ms.c (working copy) @@ -519,7 +519,7 @@ { ASSERT_ARGS(gc_ims_add_free_object) *(void **)to_add = pool->free_list; - pool->free_list = to_add; + pool->free_list = (GC_MS_PObj_Wrapper*)to_add; #if DISABLE_GC_DEBUG UNUSED(interp); #else @@ -561,7 +561,7 @@ (*pool->alloc_objects) (interp, pool); ptr = (PObj *)pool->free_list; - pool->free_list = *(void **)ptr; + pool->free_list = (GC_MS_PObj_Wrapper*)(*(void **)ptr); /* * buffers are born black, PMCs not yet? @@ -829,7 +829,6 @@ g_ims->state = GC_IMS_COLLECT; g_ims->n_objects = n_objects; - g_ims->n_extended_PMCs = arena_base->num_extended_PMCs; } Index: include/parrot/list.h =================================================================== --- include/parrot/list.h (revision 40501) +++ include/parrot/list.h (working copy) @@ -15,7 +15,7 @@ #define PARROT_LIST_H_GUARD typedef struct List_chunk { - Buffer data; /* item store */ + Buffer data; /* item store, Buffer must be first element in struct*/ struct List_chunk *next; struct List_chunk *prev; UINTVAL flags; /* chunk flags */ Index: src/string/encoding/utf8.c =================================================================== --- src/string/encoding/utf8.c (revision 40501) +++ src/string/encoding/utf8.c (working copy) @@ -525,7 +525,7 @@ i->bytepos += (new_pos - pos); /* XXX possible buffer overrun exception? */ - PARROT_ASSERT(i->bytepos <= PObj_buflen(s)); + PARROT_ASSERT(i->bytepos <= Buffer_buflen(s)); i->charpos++; } Index: src/gc/api.c =================================================================== --- src/gc/api.c (revision 40501) +++ src/gc/api.c (working copy) @@ -229,7 +229,7 @@ mark_special(interp, p); # ifndef NDEBUG - else if (p->pmc_ext && PMC_metadata(p)) + else if (PMC_metadata(p)) fprintf(stderr, "GC: error obj %p (%s) has properties\n", (void *)p, (char*)p->vtable->whoami->strstart); # endif @@ -238,7 +238,7 @@ /* buffer GC_DEBUG stuff */ if (GC_DEBUG(interp) && PObj_report_TEST(obj)) fprintf(stderr, "GC: buffer %p pointing to %p marked live\n", - obj, PObj_bufstart((Buffer *)obj)); + obj, Buffer_bufstart((Buffer *)obj)); # endif #endif /* PARROT_GC_GMS */ } @@ -336,15 +336,11 @@ /* clear flags, set is_PMC_FLAG */ if (flags & PObj_is_PMC_EXT_FLAG) { - Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool; flags |= PObj_is_special_PMC_FLAG; - pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool); if (flags & PObj_is_PMC_shared_FLAG) Parrot_gc_add_pmc_sync(interp, pmc); } - else - pmc->pmc_ext = NULL; PObj_get_FLAGS(pmc) = PObj_is_PMC_FLAG|flags; pmc->vtable = NULL; @@ -397,12 +393,7 @@ Parrot_gc_add_pmc_ext(PARROT_INTERP, ARGMOD(PMC *pmc)) { ASSERT_ARGS(Parrot_gc_add_pmc_ext) - Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool; - if (!pmc->pmc_ext) - pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool); - if (!pmc->pmc_ext) - Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR, - "Parrot VM: PMC_EXT allocation failed!\n"); + PObj_is_PMC_EXT_SET(pmc); PObj_is_special_PMC_SET(pmc); @@ -434,10 +425,8 @@ { ASSERT_ARGS(Parrot_gc_free_pmc_ext) /* if the PMC has a PMC_EXT structure, return it to the pool/arena */ - Arenas * const arena_base = interp->arena_base; - Small_Object_Pool * const ext_pool = arena_base->pmc_ext_pool; - if (!p->pmc_ext) + if (!PObj_is_PMC_EXT_TEST(p)) return; if (PObj_is_PMC_shared_TEST(p) && PMC_sync(p)) { @@ -445,9 +434,6 @@ mem_internal_free(PMC_sync(p)); PMC_sync(p) = NULL; } - ext_pool->add_free_object(interp, ext_pool, p->pmc_ext); - ext_pool->num_free_objects++; - p->pmc_ext = NULL; } /* @@ -499,6 +485,7 @@ Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags) { ASSERT_ARGS(Parrot_gc_new_string_header) + STRING * const string = (STRING *)get_free_buffer(interp, (flags & PObj_constant_FLAG) ? interp->arena_base->constant_string_header_pool @@ -553,6 +542,7 @@ Parrot_gc_new_bufferlike_header(PARROT_INTERP, size_t size) { ASSERT_ARGS(Parrot_gc_new_bufferlike_header) + Small_Object_Pool * const pool = get_bufferlike_pool(interp, size); return get_free_buffer(interp, pool); @@ -576,15 +566,15 @@ get_free_buffer(PARROT_INTERP, ARGIN(Small_Object_Pool *pool)) { ASSERT_ARGS(get_free_buffer) - PObj * const buffer = (PObj *)pool->get_free_object(interp, pool); + Buffer * const buffer = (Buffer *)pool->get_free_object(interp, pool); /* don't mess around with flags */ - PObj_bufstart(buffer) = NULL; - PObj_buflen(buffer) = 0; + Buffer_bufstart(buffer) = NULL; + Buffer_buflen(buffer) = 0; - if (pool->object_size - GC_HEADER_SIZE > sizeof (PObj)) + if (pool->object_size - GC_HEADER_SIZE > sizeof (Buffer)) memset(buffer + 1, 0, - pool->object_size - sizeof (PObj) - GC_HEADER_SIZE); + pool->object_size - sizeof (Buffer) - GC_HEADER_SIZE); return buffer; } @@ -602,7 +592,7 @@ */ void -Parrot_gc_free_bufferlike_header(PARROT_INTERP, ARGMOD(PObj *obj), +Parrot_gc_free_bufferlike_header(PARROT_INTERP, ARGMOD(Buffer *obj), size_t size) { ASSERT_ARGS(Parrot_gc_free_bufferlike_header) @@ -631,16 +621,16 @@ size_t new_size; char *mem; - PObj_buflen(buffer) = 0; - PObj_bufstart(buffer) = NULL; + Buffer_buflen(buffer) = 0; + Buffer_bufstart(buffer) = NULL; new_size = aligned_size(buffer, size); mem = (char *)mem_allocate(interp, new_size, interp->arena_base->memory_pool); mem = aligned_mem(buffer, mem); - PObj_bufstart(buffer) = mem; + Buffer_bufstart(buffer) = mem; if (PObj_is_COWable_TEST(buffer)) new_size -= sizeof (void*); - PObj_buflen(buffer) = new_size; + Buffer_buflen(buffer) = new_size; } /* @@ -671,7 +661,7 @@ /* * we don't shrink buffers */ - if (newsize <= PObj_buflen(buffer)) + if (newsize <= Buffer_buflen(buffer)) return; /* @@ -683,18 +673,18 @@ * The normal case is therefore always to allocate a new block */ new_size = aligned_size(buffer, newsize); - old_size = aligned_size(buffer, PObj_buflen(buffer)); + old_size = aligned_size(buffer, Buffer_buflen(buffer)); needed = new_size - old_size; if ((pool->top_block->free >= needed) - && (pool->top_block->top == (char *)PObj_bufstart(buffer) + old_size)) { + && (pool->top_block->top == (char *)Buffer_bufstart(buffer) + old_size)) { pool->top_block->free -= needed; pool->top_block->top += needed; - PObj_buflen(buffer) = newsize; + Buffer_buflen(buffer) = newsize; return; } - copysize = PObj_buflen(buffer); + copysize = Buffer_buflen(buffer); if (!PObj_COW_TEST(buffer)) pool->guaranteed_reclaimable += copysize; @@ -706,14 +696,14 @@ /* We shouldn't ever have a 0 from size, but we do. If we can track down * those bugs, this can be removed which would make things cheaper */ if (copysize) - memcpy(mem, PObj_bufstart(buffer), copysize); + memcpy(mem, Buffer_bufstart(buffer), copysize); - PObj_bufstart(buffer) = mem; + Buffer_bufstart(buffer) = mem; if (PObj_is_COWable_TEST(buffer)) new_size -= sizeof (void *); - PObj_buflen(buffer) = new_size; + Buffer_buflen(buffer) = new_size; } /* @@ -739,8 +729,8 @@ Memory_Pool *pool; char *mem; - PObj_buflen(str) = 0; - PObj_bufstart(str) = NULL; + Buffer_buflen(str) = 0; + Buffer_bufstart(str) = NULL; /* there's no sense in allocating zero memory, when the overhead of * allocating a string is one pointer; this can fill the pools in an @@ -757,8 +747,8 @@ mem = (char *)mem_allocate(interp, new_size, pool); mem += sizeof (void*); - PObj_bufstart(str) = str->strstart = mem; - PObj_buflen(str) = new_size - sizeof (void*); + Buffer_bufstart(str) = str->strstart = mem; + Buffer_buflen(str) = new_size - sizeof (void*); } /* @@ -789,7 +779,7 @@ : interp->arena_base->memory_pool; /* if the requested size is smaller then buflen, we are done */ - if (newsize <= PObj_buflen(str)) + if (newsize <= Buffer_buflen(str)) return; /* @@ -798,14 +788,14 @@ * - if there is enough size, we can just move the pool's top pointer */ new_size = aligned_string_size(newsize); - old_size = aligned_string_size(PObj_buflen(str)); + old_size = aligned_string_size(Buffer_buflen(str)); needed = new_size - old_size; if (pool->top_block->free >= needed - && pool->top_block->top == (char *)PObj_bufstart(str) + old_size) { + && pool->top_block->top == (char *)Buffer_bufstart(str) + old_size) { pool->top_block->free -= needed; pool->top_block->top += needed; - PObj_buflen(str) = new_size - sizeof (void*); + Buffer_buflen(str) = new_size - sizeof (void*); return; } @@ -815,18 +805,18 @@ copysize = str->bufused; if (!PObj_COW_TEST(str)) - pool->guaranteed_reclaimable += PObj_buflen(str); + pool->guaranteed_reclaimable += Buffer_buflen(str); - pool->possibly_reclaimable += PObj_buflen(str); + pool->possibly_reclaimable += Buffer_buflen(str); mem = (char *)mem_allocate(interp, new_size, pool); mem += sizeof (void *); /* copy mem from strstart, *not* bufstart */ oldmem = str->strstart; - PObj_bufstart(str) = (void *)mem; + Buffer_bufstart(str) = (void *)mem; str->strstart = mem; - PObj_buflen(str) = new_size - sizeof (void*); + Buffer_buflen(str) = new_size - sizeof (void*); /* We shouldn't ever have a 0 from size, but we do. If we can track down * those bugs, this can be removed which would make things cheaper */ @@ -907,9 +897,6 @@ dest_arena->constant_string_header_pool, source_arena->constant_string_header_pool); - Parrot_gc_merge_buffer_pools(dest_interp, - dest_arena->pmc_ext_pool, source_arena->pmc_ext_pool); - for (i = 0; i < source_arena->num_sized; ++i) { if (!source_arena->sized_header_pools[i]) continue; @@ -948,7 +935,7 @@ { ASSERT_ARGS(Parrot_gc_merge_buffer_pools) Small_Object_Arena *cur_arena; - void **free_list_end; + GC_MS_PObj_Wrapper *free_list_end; PARROT_ASSERT(dest->object_size == source->object_size); PARROT_ASSERT((dest->name == NULL && source->name == NULL) @@ -958,12 +945,19 @@ /* append new free_list to old */ /* XXX this won't work with, e.g., gc_gms */ - free_list_end = &dest->free_list; + free_list_end = dest->free_list; - while (*free_list_end) - free_list_end = (void **)*free_list_end; + if(free_list_end == NULL) + { + dest->free_list = source->free_list; + } + else + { + while (free_list_end->next_ptr) + free_list_end = free_list_end->next_ptr; - *free_list_end = source->free_list; + free_list_end->next_ptr = source->free_list; + } /* now append source arenas */ cur_arena = source->last_Arena; @@ -1070,9 +1064,6 @@ (void *)pass, sweep_cb_buf); } - free_pool(interp->arena_base->pmc_ext_pool); - interp->arena_base->pmc_ext_pool = NULL; - mem_internal_free(interp->arena_base->sized_header_pools); if (interp->arena_base->attrib_pools) mem_internal_free(interp->arena_base->attrib_pools); @@ -1337,8 +1328,7 @@ for (i = 0; i < arena->used; i++) { if (!PObj_on_free_list_TEST(p)) { - if (p->pmc_ext) - PMC_next_for_GC(p) = PMCNULL; + PMC_next_for_GC(p) = PMCNULL; } p++; } @@ -1465,12 +1455,6 @@ Returns the number of PMCs that are marked as needing timely destruction. -=item C - -Returns the number of extended PMCs. - -=cut - */ size_t @@ -1537,14 +1521,6 @@ return arena_base->num_early_gc_PMCs; } -UINTVAL -Parrot_gc_extended_pmcs(PARROT_INTERP) -{ - ASSERT_ARGS(Parrot_gc_extended_pmcs) - const Arenas * const arena_base = interp->arena_base; - return arena_base->num_extended_PMCs; -} - /* =item C Index: src/ops/set.ops =================================================================== --- src/ops/set.ops (revision 40501) +++ src/ops/set.ops (working copy) @@ -510,7 +510,11 @@ /* don't let the clone's destruction destroy the destination's data */ PObj_active_destroy_CLEAR(clone); if (PObj_is_PMC_EXT_TEST(clone)) - clone->pmc_ext = NULL; + { + PMC_metadata(clone) = NULL; + PMC_next_for_GC(clone) = NULL; + PMC_sync(clone) = NULL; + } /* Restore metadata. */ if (!PMC_IS_NULL(meta)) { Index: src/pmc/default.pmc =================================================================== --- src/pmc/default.pmc (revision 40501) +++ src/pmc/default.pmc (working copy) @@ -230,7 +230,7 @@ make_prop_hash(PARROT_INTERP, PMC *self) { PMC *prop; - if (!self->pmc_ext) + if (!PObj_is_PMC_EXT_TEST(self)) Parrot_gc_add_pmc_ext(interp, self); PMC_metadata(self) = prop = pmc_new(interp, enum_class_Hash); @@ -377,7 +377,7 @@ */ VTABLE PMC *getprop(STRING *key) { - if (SELF->pmc_ext && PMC_metadata(SELF)) + if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF)) return VTABLE_get_pmc_keyed_str(INTERP, PMC_metadata(SELF), key); else return check_get_std_props(interp, SELF, key); @@ -397,7 +397,7 @@ if (check_set_std_props(INTERP, SELF, key, value)) return; - if (SELF->pmc_ext && PMC_metadata(SELF)) { + if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF)) { VTABLE_set_pmc_keyed_str(INTERP, PMC_metadata(SELF), key, value); } @@ -419,7 +419,7 @@ */ VTABLE void delprop(STRING *key) { - if (SELF->pmc_ext && PMC_metadata(SELF)) + if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF)) VTABLE_delete_keyed_str(INTERP, PMC_metadata(SELF), key); } @@ -434,7 +434,7 @@ */ VTABLE PMC *getprops() { - if (!SELF->pmc_ext) + if (!PObj_is_PMC_EXT_TEST(SELF)) Parrot_gc_add_pmc_ext(INTERP, SELF); if (!PMC_metadata(SELF)) { @@ -1055,7 +1061,7 @@ VTABLE void visit(visit_info *info) { /* default - mark prop hash */ - if (SELF->pmc_ext && PMC_metadata(SELF) && + if (PObj_is_PMC_EXT_TEST(SELF) && PMC_metadata(SELF) && info->extra_flags != EXTRA_IS_PROP_HASH) { info->extra_flags = EXTRA_IS_PROP_HASH; info->extra = PMC_metadata(SELF); @@ -1110,7 +1116,7 @@ VTABLE void thaw(visit_info *info) { /* default - initialize the PMC */ if (info->extra_flags == EXTRA_IS_PROP_HASH) { - if (!SELF->pmc_ext) + if (!PObj_is_PMC_EXT_TEST(SELF)) Parrot_gc_add_pmc_ext(INTERP, SELF); info->thaw_ptr = &PMC_metadata(SELF); Index: src/list.c =================================================================== --- src/list.c (revision 40501) +++ src/list.c (working copy) @@ -342,11 +342,11 @@ /* HEADERIZER END: static */ #define chunk_list_size(list) \ - (PObj_buflen(&(list)->chunk_list) / sizeof (List_chunk *)) + (Buffer_buflen(&(list)->chunk_list) / sizeof (List_chunk *)) /* hide the ugly cast somehow: */ #define chunk_list_ptr(list, idx) \ - ((List_chunk**) PObj_bufstart(&(list)->chunk_list))[(idx)] + ((List_chunk**) Buffer_bufstart(&(list)->chunk_list))[(idx)] /* @@ -381,7 +381,7 @@ chunk->next = NULL; chunk->prev = NULL; Parrot_gc_allocate_buffer_storage_aligned(interp, (Buffer *)chunk, size); - memset(PObj_bufstart((Buffer*)chunk), 0, size); + memset(Buffer_bufstart((Buffer*)chunk), 0, size); /* see also src/hash.c */ if (list->container) @@ -520,13 +520,13 @@ } mem_sys_memmove( - (char *) PObj_bufstart(&prev->data) + + (char *) Buffer_bufstart(&prev->data) + prev->items * list->item_size, - (const char *) PObj_bufstart(&chunk->data), + (const char *) Buffer_bufstart(&chunk->data), (MAX_ITEMS - prev->items) * list->item_size); mem_sys_memmove( - (char *) PObj_bufstart(&chunk->data), - (const char *) PObj_bufstart(&chunk->data) + + (char *) Buffer_bufstart(&chunk->data), + (const char *) Buffer_bufstart(&chunk->data) + (MAX_ITEMS - prev->items) * list->item_size, (chunk->items - (MAX_ITEMS - prev->items)) * list->item_size); @@ -540,9 +540,9 @@ GC_WRITE_BARRIER(interp, list->container, 0, prev); } mem_sys_memmove( - (char *) PObj_bufstart(&prev->data) + + (char *) Buffer_bufstart(&prev->data) + prev->items * list->item_size, - (const char *) PObj_bufstart(&chunk->data), + (const char *) Buffer_bufstart(&chunk->data), chunk->items * list->item_size); prev->items += chunk->items; chunk->items = 0; @@ -583,8 +583,8 @@ chunk->flags = 0; list->grow_policy = enum_grow_unknown; - list->cap += PObj_buflen(&chunk->data) / list->item_size - chunk->items; - chunk->items = PObj_buflen(&chunk->data) / list->item_size; + list->cap += Buffer_buflen(&chunk->data) / list->item_size - chunk->items; + chunk->items = Buffer_buflen(&chunk->data) / list->item_size; } /* XXX - still needed? - if last is empty and last->prev not full then @@ -1227,34 +1227,34 @@ switch (type) { case enum_type_sized: /* copy data into list */ - memcpy(&((char *) PObj_bufstart(&chunk->data))[idx * list->item_size], + memcpy(&((char *) Buffer_bufstart(&chunk->data))[idx * list->item_size], item, list->item_size); break; case enum_type_char: - ((char *) PObj_bufstart(&chunk->data))[idx] = (char)PTR2INTVAL(item); + ((char *) Buffer_bufstart(&chunk->data))[idx] = (char)PTR2INTVAL(item); break; case enum_type_short: - ((short *) PObj_bufstart(&chunk->data))[idx] = (short)PTR2INTVAL(item); + ((short *) Buffer_bufstart(&chunk->data))[idx] = (short)PTR2INTVAL(item); break; case enum_type_int: - ((int *) PObj_bufstart(&chunk->data))[idx] = (int)PTR2INTVAL(item); + ((int *) Buffer_bufstart(&chunk->data))[idx] = (int)PTR2INTVAL(item); break; case enum_type_INTVAL: - ((INTVAL *) PObj_bufstart(&chunk->data))[idx] = PTR2INTVAL(item); + ((INTVAL *) Buffer_bufstart(&chunk->data))[idx] = PTR2INTVAL(item); break; case enum_type_FLOATVAL: - ((FLOATVAL *) PObj_bufstart(&chunk->data))[idx] = *(FLOATVAL *)item; + ((FLOATVAL *) Buffer_bufstart(&chunk->data))[idx] = *(FLOATVAL *)item; break; case enum_type_PMC: if (list->container) { GC_WRITE_BARRIER(interp, list->container, - ((PMC **) PObj_bufstart(&chunk->data))[idx], + ((PMC **) Buffer_bufstart(&chunk->data))[idx], (PMC *)item); } - ((PMC **) PObj_bufstart(&chunk->data))[idx] = (PMC *)item; + ((PMC **) Buffer_bufstart(&chunk->data))[idx] = (PMC *)item; break; case enum_type_STRING: - ((STRING **) PObj_bufstart(&chunk->data))[idx] = (STRING *)item; + ((STRING **) Buffer_bufstart(&chunk->data))[idx] = (STRING *)item; break; default: Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown list entry type\n"); @@ -1296,21 +1296,21 @@ switch (type) { case enum_type_sized: return (void *)&((char *) - PObj_bufstart(&chunk->data))[idx * list->item_size]; + Buffer_bufstart(&chunk->data))[idx * list->item_size]; case enum_type_char: - return (void *)&((char *) PObj_bufstart(&chunk->data))[idx]; + return (void *)&((char *) Buffer_bufstart(&chunk->data))[idx]; case enum_type_short: - return (void *)&((short *) PObj_bufstart(&chunk->data))[idx]; + return (void *)&((short *) Buffer_bufstart(&chunk->data))[idx]; case enum_type_int: - return (void *)&((int *) PObj_bufstart(&chunk->data))[idx]; + return (void *)&((int *) Buffer_bufstart(&chunk->data))[idx]; case enum_type_INTVAL: - return (void *)&((INTVAL *) PObj_bufstart(&chunk->data))[idx]; + return (void *)&((INTVAL *) Buffer_bufstart(&chunk->data))[idx]; case enum_type_FLOATVAL: - return (void *)&((FLOATVAL *) PObj_bufstart(&chunk->data))[idx]; + return (void *)&((FLOATVAL *) Buffer_bufstart(&chunk->data))[idx]; case enum_type_PMC: - return (void *)&((PMC **) PObj_bufstart(&chunk->data))[idx]; + return (void *)&((PMC **) Buffer_bufstart(&chunk->data))[idx]; case enum_type_STRING: - return (void *)&((STRING **) PObj_bufstart(&chunk->data))[idx]; + return (void *)&((STRING **) Buffer_bufstart(&chunk->data))[idx]; default: Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown list entry type\n"); } @@ -1569,12 +1569,12 @@ l = list_new(interp, other->item_type); STRUCT_COPY(l, other); - PObj_buflen(&l->chunk_list) = 0; - PObj_bufstart(&l->chunk_list) = NULL; + Buffer_buflen(&l->chunk_list) = 0; + Buffer_bufstart(&l->chunk_list) = NULL; for (chunk = other->first, prev = NULL; chunk; chunk = chunk->next) { List_chunk * const new_chunk = allocate_chunk(interp, l, - chunk->items, PObj_buflen(&chunk->data)); + chunk->items, Buffer_buflen(&chunk->data)); new_chunk->flags = chunk->flags; @@ -1589,24 +1589,24 @@ switch (l->item_type) { case enum_type_PMC: for (i = 0; i < chunk->items; i++) { - PMC * const op = ((PMC **) PObj_bufstart(&chunk->data))[i]; + PMC * const op = ((PMC **) Buffer_bufstart(&chunk->data))[i]; if (op) - ((PMC **) PObj_bufstart(&new_chunk->data))[i] = + ((PMC **) Buffer_bufstart(&new_chunk->data))[i] = VTABLE_clone(interp, op); } break; case enum_type_STRING: for (i = 0; i < chunk->items; i++) { - STRING *s = ((STRING **) PObj_bufstart(&chunk->data))[i]; + STRING *s = ((STRING **) Buffer_bufstart(&chunk->data))[i]; if (s) - ((STRING **) PObj_bufstart(&new_chunk->data))[i] = + ((STRING **) Buffer_bufstart(&new_chunk->data))[i] = Parrot_str_copy(interp, s); } break; default: - mem_sys_memcopy(PObj_bufstart(&new_chunk->data), - PObj_bufstart(&chunk->data), PObj_buflen(&chunk->data)); + mem_sys_memcopy(Buffer_bufstart(&new_chunk->data), + Buffer_bufstart(&chunk->data), Buffer_buflen(&chunk->data)); break; } } @@ -1643,7 +1643,7 @@ if (list->item_type == enum_type_PMC || list->item_type == enum_type_STRING) { if (!(chunk->flags & sparse)) { - PObj **p = ((PObj **) PObj_bufstart(&chunk->data)); + PObj **p = ((PObj **) Buffer_bufstart(&chunk->data)); UINTVAL i; for (i = 0; i < chunk->items; i++, ++p) { @@ -1688,7 +1688,7 @@ if (!(chunk->flags & sparse)) { UINTVAL i; for (i = 0; i < chunk->items && idx < n; i++, idx++) { - PMC ** const pos = ((PMC **) PObj_bufstart(&chunk->data)) + i; + PMC ** const pos = ((PMC **) Buffer_bufstart(&chunk->data)) + i; info->thaw_ptr = pos; (info->visit_pmc_now)(interp, *pos, info); } @@ -1830,8 +1830,8 @@ /* copy data over */ mem_sys_memmove( - (char *)PObj_bufstart(&rest->data), - (char *)PObj_bufstart(&chunk->data) + idx * list->item_size, + (char *)Buffer_bufstart(&rest->data), + (char *)Buffer_bufstart(&chunk->data) + idx * list->item_size, items * list->item_size); } else { @@ -1895,15 +1895,15 @@ list->item_size; mem_sys_memmove( - (char *) PObj_bufstart(&chunk->data) + + (char *) Buffer_bufstart(&chunk->data) + idx * list->item_size, - (char *) PObj_bufstart(&chunk->data) + + (char *) Buffer_bufstart(&chunk->data) + (idx + n_items) * list->item_size, tmp_size); #else mem_sys_memmove( - (char *) PObj_bufstart(&chunk->data) + + (char *) Buffer_bufstart(&chunk->data) + idx * list->item_size, - (char *) PObj_bufstart(&chunk->data) + + (char *) Buffer_bufstart(&chunk->data) + (idx + n_items) * list->item_size, (chunk->items - idx - n_items) * list->item_size); #endif Index: src/interp/inter_misc.c =================================================================== --- src/interp/inter_misc.c (revision 40501) +++ src/interp/inter_misc.c (working copy) @@ -252,9 +252,6 @@ case IMPATIENT_PMCS: ret = Parrot_gc_impatient_pmcs(interp); break; - case EXTENDED_PMCS: - ret = Parrot_gc_extended_pmcs(interp); - break; case CURRENT_RUNCORE: ret = interp->run_core; break; Index: include/parrot/call.h =================================================================== --- include/parrot/call.h (revision 40501) +++ include/parrot/call.h (working copy) @@ -70,10 +70,30 @@ INTVAL slurp_n; /* number of :flat/:slurpy args/params to match */ } call_state_item; +typedef union UnionCallStateVal { + struct _ptrs { //or two pointers, both are defines + DPOINTER * _struct_val; + PMC * _pmc_val; + } _ptrs; + struct _i { + INTVAL _int_val; // or 2 intvals + INTVAL _int_val2; + } _i; + FLOATVAL _num_val; // or one float + struct parrot_string_t * _string_val; // or a pointer to a string +} UnionCallStateVal; + +#define UVal_ptr(u) (u)._ptrs._struct_val +#define UVal_pmc(u) (u)._ptrs._pmc_val +#define UVal_int(u) (u)._i._int_val +#define UVal_int2(u) (u)._i._int_val2 +#define UVal_num(u) (u)._num_val +#define UVal_str(u) (u)._string_val + typedef struct call_state { call_state_item src; call_state_item dest; - UnionVal val; + UnionCallStateVal val; int n_actual_args; /* arguments incl. flatten */ int optionals; /* sum of optionals */ int params; /* sum of params */ Index: src/ops/string.ops =================================================================== --- src/ops/string.ops (revision 40501) +++ src/ops/string.ops (working copy) @@ -392,7 +392,7 @@ $1 = PTR2UINTVAL($2->strstart); break; case STRINGINFO_BUFLEN: - $1 = PObj_buflen($2); + $1 = Buffer_buflen($2); break; case STRINGINFO_FLAGS: $1 = PObj_get_FLAGS($2); Index: src/pmc.c =================================================================== --- src/pmc.c (revision 40501) +++ src/pmc.c (working copy) @@ -359,7 +359,7 @@ { ASSERT_ARGS(pmc_reuse_check_pmc_ext) /* Do we have an extension area? */ - INTVAL const has_ext = (PObj_is_PMC_EXT_TEST(pmc) && pmc->pmc_ext); + INTVAL const has_ext = (PObj_is_PMC_EXT_TEST(pmc)); /* Do we need one? */ if (flags & VTABLE_PMC_NEEDS_EXT) { @@ -373,7 +373,6 @@ PMC_data(pmc) = NULL; newflags &= ~PObj_is_PMC_EXT_FLAG; PARROT_ASSERT((newflags & PObj_is_PMC_EXT_FLAG) == 0); - PARROT_ASSERT(pmc->pmc_ext == NULL); } return newflags; } Index: src/string/charset/iso-8859-1.c =================================================================== --- src/string/charset/iso-8859-1.c (revision 40501) +++ src/string/charset/iso-8859-1.c (working copy) @@ -268,12 +268,12 @@ for (offs = 0; offs < src->strlen; ++offs) { const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs); - if (iter.bytepos >= PObj_buflen(dest) - 4) { + if (iter.bytepos >= Buffer_buflen(dest) - 4) { UINTVAL need = (UINTVAL)((src->strlen - offs) * 1.5); if (need < 16) need = 16; Parrot_gc_reallocate_string_storage(interp, dest, - PObj_buflen(dest) + need); + Buffer_buflen(dest) + need); } iter.set_and_advance(interp, &iter, c); } Index: src/gc/gc_ms.c =================================================================== --- src/gc/gc_ms.c (revision 40501) +++ src/gc/gc_ms.c (working copy) @@ -29,13 +29,6 @@ __attribute__nonnull__(3) FUNC_MODIFIES(*pool); -static void gc_ms_add_free_pmc_ext(SHIM_INTERP, - ARGMOD(Small_Object_Pool *pool), - ARGIN(void *to_add)) - __attribute__nonnull__(2) - __attribute__nonnull__(3) - FUNC_MODIFIES(*pool); - static void gc_ms_alloc_objects(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool)) __attribute__nonnull__(1) @@ -54,14 +47,6 @@ __attribute__nonnull__(2) FUNC_MODIFIES(*pool); -PARROT_CANNOT_RETURN_NULL -PARROT_WARN_UNUSED_RESULT -static void * gc_ms_get_free_pmc_ext(PARROT_INTERP, - ARGMOD(Small_Object_Pool *pool)) - __attribute__nonnull__(1) - __attribute__nonnull__(2) - FUNC_MODIFIES(*pool); - static void gc_ms_mark_and_sweep(PARROT_INTERP, UINTVAL flags) __attribute__nonnull__(1); @@ -92,9 +77,6 @@ #define ASSERT_ARGS_gc_ms_add_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(pool) \ || PARROT_ASSERT_ARG(to_add) -#define ASSERT_ARGS_gc_ms_add_free_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \ - PARROT_ASSERT_ARG(pool) \ - || PARROT_ASSERT_ARG(to_add) #define ASSERT_ARGS_gc_ms_alloc_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp) \ || PARROT_ASSERT_ARG(pool) @@ -104,9 +86,6 @@ #define ASSERT_ARGS_gc_ms_get_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp) \ || PARROT_ASSERT_ARG(pool) -#define ASSERT_ARGS_gc_ms_get_free_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \ - PARROT_ASSERT_ARG(interp) \ - || PARROT_ASSERT_ARG(pool) #define ASSERT_ARGS_gc_ms_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp) #define ASSERT_ARGS_gc_ms_more_traceable_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = \ @@ -365,6 +344,7 @@ gc_ms_more_traceable_objects(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool)) { ASSERT_ARGS(gc_ms_more_traceable_objects) + if (pool->skip) pool->skip = 0; else { @@ -398,12 +378,12 @@ ARGIN(void *to_add)) { ASSERT_ARGS(gc_ms_add_free_object) - PObj *object = (PObj *)to_add; + GC_MS_PObj_Wrapper *object = (GC_MS_PObj_Wrapper *)to_add; PObj_flags_SETTO(object, PObj_on_free_list_FLAG); - ((GC_MS_PObj_Wrapper*)object)->next_ptr = (PObj *)pool->free_list; - pool->free_list = object; + object->next_ptr = pool->free_list; + pool->free_list = object; } /* @@ -438,7 +418,8 @@ ptr = free_list; pool->free_list = ((GC_MS_PObj_Wrapper*)ptr)->next_ptr; - PObj_flags_SETTO(ptr, 0); +// PObj_flags_SETTO(ptr, 0); + memset(ptr, 0, pool->object_size); --pool->num_free_objects; @@ -462,6 +443,7 @@ { ASSERT_ARGS(gc_ms_alloc_objects) /* Setup memory for the new objects */ + Small_Object_Arena * const new_arena = mem_internal_allocate_typed(Small_Object_Arena); @@ -500,97 +482,10 @@ =back -=head2 MS PMC_EXT Pool functions - -=over 4 - -=item C - -Initialize the PMC_EXT pool functions. This is done separately from other -pools. - =cut */ -void -gc_ms_pmc_ext_pool_init(ARGMOD(Small_Object_Pool *pool)) -{ - ASSERT_ARGS(gc_ms_pmc_ext_pool_init) - pool->add_free_object = gc_ms_add_free_pmc_ext; - pool->get_free_object = gc_ms_get_free_pmc_ext; - pool->alloc_objects = gc_ms_alloc_objects; - pool->more_objects = gc_ms_alloc_objects; -} - - -/* - -=item C - -Add a freed PMC_EXT structure to the free list in the PMC_EXT pool. Objects -on the free list can be reused later. - -=cut - -*/ - -static void -gc_ms_add_free_pmc_ext(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGIN(void *to_add)) -{ - ASSERT_ARGS(gc_ms_add_free_pmc_ext) - PMC_EXT * const object = (PMC_EXT *)to_add; - object->_metadata = NULL; - - /* yes, this cast is a hack for now, but a pointer is a pointer */ - object->_next_for_GC = (PMC *)pool->free_list; - pool->free_list = object; -} - -/* - -=item C - -Get a new PMC_EXT structure from the free pool and return it. - -=cut - -*/ - -PARROT_CANNOT_RETURN_NULL -PARROT_WARN_UNUSED_RESULT -static void * -gc_ms_get_free_pmc_ext(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool)) -{ - ASSERT_ARGS(gc_ms_get_free_pmc_ext) - PMC_EXT *ptr; - PMC_EXT *free_list = (PMC_EXT *)pool->free_list; - - /* if we don't have any objects */ - if (!free_list) { - (*pool->more_objects)(interp, pool); - free_list = (PMC_EXT *)pool->free_list; - } - - ptr = free_list; - pool->free_list = ptr->_next_for_GC; - ptr->_next_for_GC = NULL; - - --pool->num_free_objects; - - return ptr; -} - -/* - -=back - -=cut - -*/ - /* * Local variables: * c-file-style: "parrot" Index: include/parrot/hash.h =================================================================== --- include/parrot/hash.h (revision 40501) +++ include/parrot/hash.h (working copy) @@ -28,11 +28,12 @@ /* * hash_entry is currently unused in the hash structure - */ + typedef struct _hash_entry { HashEntryType type; UnionVal val; } HashEntry; +*/ /* A BucketIndex is an index into the pool of available buckets. */ typedef UINTVAL BucketIndex; Index: src/jit_debug.c =================================================================== --- src/jit_debug.c (revision 40501) +++ src/jit_debug.c (working copy) @@ -106,6 +106,7 @@ static void write_types(FILE *stabs, PARROT_INTERP) { + //It would be create if this function would be auto generated :) int i, j; /* borrowed from mono */ static BaseTypes base_types[] = { @@ -152,14 +153,14 @@ ++i; fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d" "bufstart:(0,14),%d,%d;" - "buflen:(0,6),%d,%d;" /* XXX type */ + "buflen:(0,6),%d,%d;" "flags:(0,12),%d,%d;" "bufused:(0,12),%d,%d;" - "strstart:(0,15),%d,%d;" /* fake a char* */ + "strstart:(0,15),%d,%d;" ";\"" "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING), - BIT_OFFSET(STRING, cache._b._bufstart), BIT_SIZE(void*), - BIT_OFFSET(STRING, cache._b._buflen), BIT_SIZE(size_t), + BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*), + BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t), BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL), BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL), BIT_OFFSET(STRING, strstart), BIT_SIZE(void*)); @@ -177,35 +178,30 @@ fprintf(stabs, ";\"," N_LSYM ",0,0,0\n"); - /* PMC type */ - fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d", i, BYTE_SIZE(PMC)); - fprintf(stabs, "cache:(0,%d),%d,%d;", - i + 1, BIT_OFFSET(PMC, cache), BIT_SIZE(UnionVal)); - fprintf(stabs, "flags:(0,%d),%d,%d;", - i + 1, BIT_OFFSET(PMC, flags), BIT_SIZE(Parrot_UInt)); - fprintf(stabs, "vtable:*(0,%d),%d,%d;", - i + 3, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*)); - fprintf(stabs, "data:(0,14),%d,%d;", - BIT_OFFSET(PMC, data), BIT_SIZE(void*)); - fprintf(stabs, "pmc_ext:*(0,%d),%d,%d;", - i, BIT_OFFSET(PMC, pmc_ext), BIT_SIZE(void*)); - fprintf(stabs, ";\""); - fprintf(stabs, "," N_LSYM ",0,0,0\n"); - - fprintf(stabs, ".stabs \"UnionVal:T(0,%d)=u%d" - "int_val:(0,12),%d,%d;" - "pmc_val:*(0,%d),%d,%d;" + fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d" + "flags:(0,12),%d,%d;" + "vtable:*(0,%d),%d,%d;" + "data:(0,14),%d,%d;" + "_metadata:*(0,%d),%d,%d;" + "_next_for_GC:*(0,%d),%d,%d;" ";\"" - "," N_LSYM ",0,0,0\n", i + 2, BYTE_SIZE(UnionVal), - BIT_OFFSET(UnionVal, _i._int_val), BIT_SIZE(INTVAL), - i, BIT_OFFSET(UnionVal, _ptrs._pmc_val), BIT_SIZE(void*)); + "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC), + BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL), + i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*), + BIT_OFFSET(PMC, data), BIT_SIZE(void*), + i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*), + i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*)); + + i++; + + //some one can add some field to this one fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d" - "base_type:(0,%d),%d,%d;" + "base_type:(0,12),%d,%d;" ";\"" - "," N_LSYM ",0,0,0\n", i + 3, BYTE_SIZE(UnionVal), - i - 1, BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); - i += 4; + "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable), + BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL)); + i++; } /*