Ticket #978: remove_pmc_sync.patch
File remove_pmc_sync.patch, 13.4 KB (added by chromatic, 12 years ago) |
---|
-
include/parrot/gc_api.h
diff --git a/include/parrot/gc_api.h b/include/parrot/gc_api.h index 9b8c71e..d393669 100644
a b 181 181 int Parrot_gc_active_sized_buffers(PARROT_INTERP) 182 182 __attribute__nonnull__(1); 183 183 184 void Parrot_gc_add_pmc_sync(PARROT_INTERP, ARGMOD(PMC *pmc))185 __attribute__nonnull__(1)186 __attribute__nonnull__(2)187 FUNC_MODIFIES(*pmc);188 189 184 void Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP, 190 185 ARGOUT(Buffer *buffer), 191 186 size_t size) … … 265 260 __attribute__nonnull__(2) 266 261 FUNC_MODIFIES(*pmc); 267 262 268 void Parrot_gc_free_pmc_sync(PARROT_INTERP, ARGMOD(PMC *p))269 __attribute__nonnull__(1)270 __attribute__nonnull__(2)271 FUNC_MODIFIES(*p);272 273 263 void Parrot_gc_free_string_header(PARROT_INTERP, ARGMOD(STRING *s)) 274 264 __attribute__nonnull__(1) 275 265 __attribute__nonnull__(2) … … 377 367 #define ASSERT_ARGS_Parrot_gc_active_sized_buffers \ 378 368 __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 379 369 PARROT_ASSERT_ARG(interp) 380 #define ASSERT_ARGS_Parrot_gc_add_pmc_sync __attribute__unused__ int _ASSERT_ARGS_CHECK = \381 PARROT_ASSERT_ARG(interp) \382 || PARROT_ASSERT_ARG(pmc)383 370 #define ASSERT_ARGS_Parrot_gc_allocate_buffer_storage_aligned \ 384 371 __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 385 372 PARROT_ASSERT_ARG(interp) \ … … 430 417 #define ASSERT_ARGS_Parrot_gc_free_pmc_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 431 418 PARROT_ASSERT_ARG(interp) \ 432 419 || PARROT_ASSERT_ARG(pmc) 433 #define ASSERT_ARGS_Parrot_gc_free_pmc_sync __attribute__unused__ int _ASSERT_ARGS_CHECK = \434 PARROT_ASSERT_ARG(interp) \435 || PARROT_ASSERT_ARG(p)436 420 #define ASSERT_ARGS_Parrot_gc_free_string_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 437 421 PARROT_ASSERT_ARG(interp) \ 438 422 || PARROT_ASSERT_ARG(s) -
include/parrot/pobj.h
diff --git a/include/parrot/pobj.h b/include/parrot/pobj.h index f40ce93..fd95c57 100644
a b 102 102 DPOINTER *data; 103 103 104 104 PMC *_metadata; /* properties */ 105 /*106 * PMC access synchronization for shared PMCs107 * s. parrot/thread.h108 */109 struct _Sync *_synchronize;110 111 /* This flag determines the next PMC in the 'used' list during112 dead object detection in the GC. It is a linked list, which is113 only valid in trace_active_PMCs. Also, the linked list is114 guaranteed to have the tail element's _next_for_GC point to itself,115 which makes much of the logic and checks simpler. We then have to116 check for PMC->_next_for_GC == PMC to find the end of list. */117 105 PMC *_next_for_GC; 118 106 119 107 /* Yeah, the GC data should be out of … … 134 122 #define PMC_data0_typed(pmc) (type)(1 ? (pmc)->data : 0) 135 123 #define PMC_metadata(pmc) ((pmc)->_metadata) 136 124 #define PMC_next_for_GC(pmc) ((pmc)->_next_for_GC) 137 #define PMC_sync(pmc) ((pmc)->_synchronize)138 125 139 126 #define POBJ_FLAG(n) ((UINTVAL)1 << (n)) 140 127 /* PObj flags */ -
include/parrot/thread.h
diff --git a/include/parrot/thread.h b/include/parrot/thread.h index fb314ea..f0497b8 100644
a b 1 1 /* thread.h 2 * Copyright (C) 2001-200 7, Parrot Foundation.2 * Copyright (C) 2001-2009, Parrot Foundation. 3 3 * SVN Info 4 4 * $Id$ 5 5 * Overview: … … 147 147 /* TODO use thread pools instead */ 148 148 VAR_SCOPE Shared_gc_info *shared_gc_info; 149 149 150 typedef struct _Sync {151 Parrot_Interp owner; /* that interpreter, that owns152 the arena, where the PMC is in */153 Parrot_mutex pmc_lock; /* for wr access to PMCs content */154 } Sync;155 156 150 /* HEADERIZER BEGIN: src/thread.c */ 157 151 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 158 152 -
src/gc/api.c
diff --git a/src/gc/api.c b/src/gc/api.c index acf8308..426934f 100644
a b 104 104 static void cleanup_next_for_GC_pool(ARGIN(Small_Object_Pool *pool)) 105 105 __attribute__nonnull__(1); 106 106 107 static void fix_pmc_syncs(108 ARGMOD(Interp *dest_interp),109 ARGIN(Small_Object_Pool *pool))110 __attribute__nonnull__(1)111 __attribute__nonnull__(2)112 FUNC_MODIFIES(*dest_interp);113 114 107 static void free_pool(ARGMOD(Small_Object_Pool *pool)) 115 108 __attribute__nonnull__(1) 116 109 FUNC_MODIFIES(*pool); … … 149 142 150 143 #define ASSERT_ARGS_cleanup_next_for_GC_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 151 144 PARROT_ASSERT_ARG(pool) 152 #define ASSERT_ARGS_fix_pmc_syncs __attribute__unused__ int _ASSERT_ARGS_CHECK = \153 PARROT_ASSERT_ARG(dest_interp) \154 || PARROT_ASSERT_ARG(pool)155 145 #define ASSERT_ARGS_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 156 146 PARROT_ASSERT_ARG(pool) 157 147 #define ASSERT_ARGS_get_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \ … … 334 324 335 325 flags |= PObj_is_special_PMC_FLAG; 336 326 337 if (flags & PObj_is_PMC_shared_FLAG)338 Parrot_gc_add_pmc_sync(interp, pmc);339 340 327 PObj_get_FLAGS(pmc) = PObj_is_PMC_FLAG|flags; 341 328 pmc->vtable = NULL; 342 329 PMC_data(pmc) = NULL; … … 368 355 pool->num_free_objects++; 369 356 } 370 357 371 /*372 373 =item C<void Parrot_gc_free_pmc_sync(PARROT_INTERP, PMC *p)>374 375 Frees the PMC_sync field of the PMC, if one exists.376 377 =cut378 379 */380 381 void382 Parrot_gc_free_pmc_sync(PARROT_INTERP, ARGMOD(PMC *p))383 {384 ASSERT_ARGS(Parrot_gc_free_pmc_sync)385 386 if (PObj_is_PMC_shared_TEST(p) && PMC_sync(p)) {387 MUTEX_DESTROY(PMC_sync(p)->pmc_lock);388 mem_internal_free(PMC_sync(p));389 PMC_sync(p) = NULL;390 }391 }392 393 /*394 395 =item C<void Parrot_gc_add_pmc_sync(PARROT_INTERP, PMC *pmc)>396 397 Adds a C<Sync*> structure to the given C<PMC>. Initializes the PMC's owner398 field and the synchronization mutext. Throws an exception if Sync allocation399 fails.400 401 =cut402 403 */404 405 void406 Parrot_gc_add_pmc_sync(PARROT_INTERP, ARGMOD(PMC *pmc))407 {408 ASSERT_ARGS(Parrot_gc_add_pmc_sync)409 410 /* This mutex already exists, leave it alone. */411 if (PMC_sync(pmc))412 return;413 414 PMC_sync(pmc) = mem_allocate_typed(Sync);415 416 if (!PMC_sync(pmc))417 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,418 "Parrot VM: PMC Sync allocation failed!\n");419 420 PMC_sync(pmc)->owner = interp;421 MUTEX_INIT(PMC_sync(pmc)->pmc_lock);422 }423 358 424 359 /* 425 360 … … 837 772 UINTVAL i; 838 773 839 774 /* heavily borrowed from forall_header_pools */ 840 fix_pmc_syncs(dest_interp, source_arena->constant_pmc_pool);841 775 Parrot_gc_merge_buffer_pools(dest_interp, dest_arena->constant_pmc_pool, 842 776 source_arena->constant_pmc_pool); 843 777 844 fix_pmc_syncs(dest_interp, source_arena->pmc_pool);845 778 Parrot_gc_merge_buffer_pools(dest_interp, dest_arena->pmc_pool, 846 779 source_arena->pmc_pool); 847 780 … … 935 868 source->num_free_objects = 0; 936 869 } 937 870 938 /*939 940 =item C<static void fix_pmc_syncs(Interp *dest_interp, Small_Object_Pool *pool)>941 942 Walks through the given arena, looking for all live and shared PMCs,943 transferring their sync values to the destination interpreter.944 945 =cut946 947 */948 949 static void950 fix_pmc_syncs(ARGMOD(Interp *dest_interp), ARGIN(Small_Object_Pool *pool))951 {952 ASSERT_ARGS(fix_pmc_syncs)953 Small_Object_Arena *cur_arena;954 const UINTVAL object_size = pool->object_size;955 956 for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) {957 PMC *p = (PMC *)((char*)cur_arena->start_objects + GC_HEADER_SIZE);958 size_t i;959 960 for (i = 0; i < cur_arena->used; i++) {961 if (!PObj_on_free_list_TEST(p) && PObj_is_PMC_TEST(p)) {962 if (PObj_is_PMC_shared_TEST(p))963 PMC_sync(p)->owner = dest_interp;964 else965 Parrot_ex_throw_from_c_args(dest_interp, NULL,966 EXCEPTION_INTERP_ERROR,967 "Unshared PMC still alive after interpreter"968 "destruction. address=%p, base_type=%d\n",969 p, p->vtable->base_type);970 }971 972 p = (PMC *)((char *)p + object_size);973 }974 }975 }976 871 977 872 /* 978 873 -
src/gc/mark_sweep.c
diff --git a/src/gc/mark_sweep.c b/src/gc/mark_sweep.c index 8f03796..9f4a4b7 100644
a b 414 414 * the object. 415 415 */ 416 416 if (PObj_is_PMC_shared_TEST(obj)) { 417 interp = PMC_sync(obj)->owner;417 /* TODO: assign interp to owning interpreter */ 418 418 PARROT_ASSERT(interp); 419 419 420 420 if (!interp->arena_base->gc_mark_ptr) -
src/hll.c
diff --git a/src/hll.c b/src/hll.c index 0756470..a74cbac 100644
a b 53 53 #define END_READ_HLL_INFO(interp, hll_info) 54 54 #define START_WRITE_HLL_INFO(interp, hll_info) \ 55 55 do { \ 56 if (PObj_is_PMC_shared_TEST(hll_info) && PMC_sync((interp)->HLL_info)) { \56 if (PObj_is_PMC_shared_TEST(hll_info)) { \ 57 57 (hll_info) = (interp)->HLL_info = \ 58 58 Parrot_clone((interp), (interp)->HLL_info); \ 59 if (PMC_sync((interp)->HLL_info)) \60 mem_internal_free(PMC_sync((interp)->HLL_info)); \61 59 } \ 62 60 } while (0) 63 61 #define END_WRITE_HLL_INFO(interp, hll_info) … … 363 361 364 362 /* the type might already be registered in a non-conflicting way, in which 365 363 * ca se we can avoid copying */ 366 if (PObj_is_PMC_shared_TEST(hll_info) && PMC_sync(hll_info)) {364 if (PObj_is_PMC_shared_TEST(hll_info)) { 367 365 if (hll_type == Parrot_get_HLL_type(interp, hll_id, core_type)) 368 366 return; 369 367 } -
src/ops/set.ops
diff --git a/src/ops/set.ops b/src/ops/set.ops index e17ec39..78e88c5 100644
a b 512 512 /* don't let the clone's destruction destroy the destination's data */ 513 513 PObj_active_destroy_CLEAR(clone); 514 514 PMC_data(clone) = NULL; 515 PMC_sync(clone) = NULL;516 515 PMC_metadata(clone) = NULL; 517 516 PMC_next_for_GC(clone) = NULL; 518 517 -
src/pmc.c
diff --git a/src/pmc.c b/src/pmc.c index 627aa32..9251d25 100644
a b 118 118 PObj_custom_mark_CLEAR(pmc); 119 119 PObj_live_CLEAR(pmc); 120 120 121 if (PObj_is_PMC_shared_TEST(pmc) && PMC_sync(pmc))122 Parrot_gc_free_pmc_sync(interp, pmc);123 124 121 if (pmc->vtable->attr_size) { 125 122 if (PMC_data(pmc)) { 126 123 #if GC_USE_FIXED_SIZE_ALLOCATOR … … 832 829 && (_class == _class->vtable->pmc_class)) 833 830 interp->vtables[type]->pmc_class = _class; 834 831 else { 835 Parrot_gc_free_pmc_sync(interp, _class);836 832 gc_flag_CLEAR(is_special_PMC, _class); 837 833 PObj_is_PMC_shared_CLEAR(_class); 838 834 interp->vtables[type]->pmc_class = _class; -
src/pmc/object.pmc
diff --git a/src/pmc/object.pmc b/src/pmc/object.pmc index 046809f..9bf425a 100644
a b 756 756 VTABLE_set_integer_native(INTERP, _true, 1); 757 757 VTABLE_setprop(INTERP, ret, CONST_STRING(interp, "_ro"), _true); 758 758 SELF->vtable->pmc_class = master->vtables[type_num]->pmc_class; 759 Parrot_gc_add_pmc_sync(INTERP, ret);760 759 PObj_is_PMC_shared_SET(ret); 761 760 762 761 data = PARROT_CLASS(classobj)->parents; -
src/pmc/parrotinterpreter.pmc
diff --git a/src/pmc/parrotinterpreter.pmc b/src/pmc/parrotinterpreter.pmc index df2c484..edd5ed5 100644
a b 67 67 if (flags & PARROT_CLONE_HLL) { 68 68 /* we'd like to share the HLL data. Give it a PMC_sync structure 69 69 if it doesn't have one already */ 70 Parrot_gc_add_pmc_sync(s, s->HLL_info);71 70 d->HLL_info = s->HLL_info; 72 71 Parrot_regenerate_HLL_namespaces(d); 73 72 } -
src/pmc/scalar.pmc
diff --git a/src/pmc/scalar.pmc b/src/pmc/scalar.pmc index ff2f876..a415f87 100644
a b 1375 1375 VTABLE_setprop(INTERP, ret, CONST_STRING(INTERP, "_ro"), _true); 1376 1376 1377 1377 /* We're sharing this, so make sure it has a PMC_sync */ 1378 Parrot_gc_add_pmc_sync(INTERP, ret);1379 1378 PObj_is_PMC_shared_SET(ret); 1380 1379 1381 1380 /* XXX FIXME workaround lack of metadata sharing*/ -
src/thread.c
diff --git a/src/thread.c b/src/thread.c index eedea3d..6d43be5 100644
a b 352 352 if (is_ro) 353 353 pmc->vtable = pmc->vtable->ro_variant_vtable; 354 354 355 Parrot_gc_add_pmc_sync(interp, pmc);356 357 355 PObj_is_PMC_shared_SET(pmc); 358 356 359 357 /* make sure metadata doesn't go away unexpectedly */