diff --git a/src/array.c b/src/array.c index f3d61c5937ffabcbeae31b9f177cb13a30f594ff..1c11047baeadfeaf40184a20518e6cb77073c2b2 100644 --- a/src/array.c +++ b/src/array.c @@ -30,7 +30,7 @@ /** The empty array. */ PMOD_EXPORT struct array empty_array= { - PIKE_CONSTANT_MEMOBJ_INIT(1), /* Never free */ + PIKE_CONSTANT_MEMOBJ_INIT(1, PIKE_T_ARRAY), /* Never free */ &weak_empty_array, /* Next */ 0, /* previous */ 0, /* Size = 0 */ @@ -44,7 +44,7 @@ PMOD_EXPORT struct array empty_array= /** The empty weak array. */ PMOD_EXPORT struct array weak_empty_array= { - PIKE_CONSTANT_MEMOBJ_INIT(1), + PIKE_CONSTANT_MEMOBJ_INIT(1, PIKE_T_ARRAY), 0, &empty_array, 0, 0, 0, ARRAY_WEAK_FLAG, weak_empty_array.real_item, {SVALUE_INIT_FREE}, @@ -112,7 +112,7 @@ PMOD_EXPORT struct array *real_allocate_array(ptrdiff_t size, v->malloced_size = DO_NOT_WARN((INT32)(size + extra_space)); v->item=v->real_item; v->size = DO_NOT_WARN((INT32)size); - INIT_PIKE_MEMOBJ(v); + INIT_PIKE_MEMOBJ(v, T_ARRAY); DOUBLELINK (first_array, v); { diff --git a/src/constants.c b/src/constants.c index 23f93ce1b1b66f56ed1a58c12166b8029203f673..3b6490916090d02fc81e125bb627db4c6dfde116 100644 --- a/src/constants.c +++ b/src/constants.c @@ -100,7 +100,7 @@ PMOD_EXPORT struct callable *low_make_callable(c_fun fun, docode_fun docode) { struct callable *f=alloc_callable(); - INIT_PIKE_MEMOBJ(f); + INIT_PIKE_MEMOBJ(f, T_STRUCT_CALLABLE); f->function=fun; f->name=name; f->type=type; diff --git a/src/mapping.c b/src/mapping.c index 5bed9c0cf06d40875db2b45da688526320647700..471fa0bf9c737b43fa5a16cb4e48757b958f15bd 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -149,16 +149,16 @@ static void check_mapping_type_fields(const struct mapping *m) #endif static struct mapping_data empty_data = - { PIKE_CONSTANT_MEMOBJ_INIT(1), 1, 0,0,0,0,0,0, 0, + { PIKE_CONSTANT_MEMOBJ_INIT(1, T_MAPPING_DATA), 1, 0,0,0,0,0,0, 0, IF_ELSE_KEYPAIR_LOOP((struct keypair *)&empty_data.hash, 0), {0}}; static struct mapping_data weak_ind_empty_data = - { PIKE_CONSTANT_MEMOBJ_INIT(1), 1, 0,0,0,0,0,0, MAPPING_WEAK_INDICES, + { PIKE_CONSTANT_MEMOBJ_INIT(1, T_MAPPING_DATA), 1, 0,0,0,0,0,0, MAPPING_WEAK_INDICES, IF_ELSE_KEYPAIR_LOOP((struct keypair *)&weak_ind_empty_data.hash, 0), {0}}; static struct mapping_data weak_val_empty_data = - { PIKE_CONSTANT_MEMOBJ_INIT(1), 1, 0,0,0,0,0,0, MAPPING_WEAK_VALUES, + { PIKE_CONSTANT_MEMOBJ_INIT(1, T_MAPPING_DATA), 1, 0,0,0,0,0,0, MAPPING_WEAK_VALUES, IF_ELSE_KEYPAIR_LOOP((struct keypair *)&weak_val_empty_data.hash, 0), {0}}; static struct mapping_data weak_both_empty_data = - { PIKE_CONSTANT_MEMOBJ_INIT(1), 1, 0,0,0,0,0,0, MAPPING_WEAK, + { PIKE_CONSTANT_MEMOBJ_INIT(1, T_MAPPING_DATA), 1, 0,0,0,0,0,0, MAPPING_WEAK, IF_ELSE_KEYPAIR_LOOP((struct keypair *)&weak_both_empty_data.hash, 0), {0}}; /** This function allocates the hash table and svalue space for a mapping @@ -209,6 +209,9 @@ static void init_mapping(struct mapping *m, md->flags = flags; md->size = 0; md->refs=0; +#ifdef ATOMIC_SVALUE + md->ref_type = T_MAPPING_DATA; +#endif md->valrefs=0; md->hardlinks=0; md->num_keypairs=size; @@ -246,6 +249,9 @@ PMOD_EXPORT struct mapping *debug_allocate_mapping(int size) INITIALIZE_PROT(m); init_mapping(m,size,0); +#ifdef ATOMIC_SVALUE + m->ref_type = T_MAPPING; +#endif m->refs = 0; add_ref(m); /* For DMALLOC... */ diff --git a/src/multiset.c b/src/multiset.c index 0f27c898e9c385882942dbff7fee0ca389a69db0..1119bb0dd4a1dcbb5b2f92801157f09c63489768 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -231,14 +231,26 @@ static struct multiset_data empty_indval_msd = { void free_multiset_data (struct multiset_data *msd); +#ifdef ATOMIC_SVALUE #define INIT_MULTISET(L) do { \ GC_ALLOC (L); \ INITIALIZE_PROT (L); \ + L->ref_type = T_MULTISET; \ L->refs = 0; \ add_ref(L); /* For DMALLOC... */ \ L->node_refs = 0; \ DOUBLELINK (first_multiset, L); \ } while (0) +#else /* !ATOMIC_SVALUE */ +#define INIT_MULTISET(L) do { \ + GC_ALLOC (L); \ + INITIALIZE_PROT (L); \ + L->refs = 0; \ + add_ref(L); /* For DMALLOC... */ \ + L->node_refs = 0; \ + DOUBLELINK (first_multiset, L); \ + } while (0) +#endif #undef EXIT_BLOCK #define EXIT_BLOCK(L) do { \ diff --git a/src/object.c b/src/object.c index 3248028efd0dee1815adf321524a3bccda6108b9..158e7629fd0169925665f1ad773e1f223b193b91 100644 --- a/src/object.c +++ b/src/object.c @@ -151,7 +151,7 @@ PMOD_EXPORT struct object *low_clone(struct program *p) DOUBLELINK(first_object,o); - INIT_PIKE_MEMOBJ(o); + INIT_PIKE_MEMOBJ(o, T_OBJECT); #ifdef PIKE_DEBUG o->program_id=p->id; diff --git a/src/pike_types.c b/src/pike_types.c index fcf8b61e23e0f9d26057b1d806724817d65b6d34..c0a1546bd0881d9946745a41ba7be734aa407e28 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -554,6 +554,9 @@ static inline struct pike_type *debug_mk_type(unsigned INT32 type, debug_malloc_pass(t = alloc_pike_type()); +#ifdef ATOMIC_SVALUE + t->ref_type = PIKE_T_TYPE; +#endif t->refs = 0; add_ref(t); /* For DMALLOC... */ t->type = type; diff --git a/src/pike_types.h b/src/pike_types.h index 1fca5d7c913ee3852249d6ff8d114a2e483791ae..31b7333224bed370dd71fe49f8edfe622bf0e7ad 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -24,6 +24,9 @@ void TYPE_STACK_DEBUG(const char *fun); struct pike_type { INT32 refs; +#ifdef ATOMIC_SVALUE + INT32 ref_type; +#endif unsigned INT32 hash; struct pike_type *next; unsigned INT32 flags; diff --git a/src/program.c b/src/program.c index 3ee9be937c0f8a9211b52d18cf62b78a5f5b5628..c0c5ae7be2a30754c40077559b78d55216dc1afe 100644 --- a/src/program.c +++ b/src/program.c @@ -2572,7 +2572,7 @@ struct program *low_allocate_program(void) GC_ALLOC(p); p->id=++current_program_id; - INIT_PIKE_MEMOBJ(p); + INIT_PIKE_MEMOBJ(p, T_PROGRAM); DOUBLELINK(first_program, p); GETTIMEOFDAY(& p->timestamp); diff --git a/src/stralloc.c b/src/stralloc.c index 92fdf19201bc6c60d0cc9719ee89707a7eae099b..f9e31020bc4eba87980734ffaa87b03dd6739d43 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -532,12 +532,22 @@ struct pike_string_hdr { /* Use the BLOCK_ALLOC() stuff for short strings */ #undef INIT_BLOCK +#ifdef ATOMIC_SVALUE #define INIT_BLOCK(NEW_STR) do { \ + (NEW_STR)->ref_type = T_STRING; \ (NEW_STR)->refs = 0; \ add_ref((NEW_STR)); \ (NEW_STR)->flags = \ STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; \ } while(0) +#else /* !ATOMIC_SVALUE */ +#define INIT_BLOCK(NEW_STR) do { \ + (NEW_STR)->refs = 0; \ + add_ref((NEW_STR)); \ + (NEW_STR)->flags = \ + STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; \ + } while(0) +#endif #define SHORT_STRING_BLOCK 256 #define SHORT_STRING_THRESHOLD 15 /* % 4 === -1 */ @@ -603,6 +613,9 @@ PMOD_EXPORT struct pike_string *debug_begin_shared_string(size_t len) t=(struct pike_string *)xalloc(len + 1 + sizeof(struct pike_string_hdr)); t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED; } +#ifdef ATOMIC_SVALUE + t->ref_type = T_STRING; +#endif t->refs = 0; add_ref(t); /* For DMALLOC */ t->str[len]=0; @@ -724,6 +737,9 @@ PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int s sizeof(struct pike_string_hdr)); t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED; } +#ifdef ATOMIC_SVALUE + t->ref_type = T_STRING; +#endif t->refs = 0; add_ref(t); /* For DMALLOC */ t->len=len; diff --git a/src/stralloc.h b/src/stralloc.h index 89a40b1cd739a2939ca0df7b8469dd7070056ea7..d31b043b5434e6ba38427e3489d28d121ee66660 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -18,13 +18,24 @@ #define STRUCT_PIKE_STRING_DECLARED #endif +#ifdef ATOMIC_SVALUE #define PIKE_STRING_CONTENTS \ INT32 refs; \ + INT32 ref_type; \ INT16 flags; \ INT16 size_shift; /* 14 bit waste, but good for alignment... */ \ ptrdiff_t len; /* Not counting terminating NUL. */ \ size_t hval; \ struct pike_string *next +#else /* !ATOMIC_SVALUE */ +#define PIKE_STRING_CONTENTS \ + INT32 refs; \ + INT16 flags; \ + INT16 size_shift; /* 14 bit waste, but good for alignment... */ \ + ptrdiff_t len; /* Not counting terminating NUL. */ \ + size_t hval; \ + struct pike_string *next +#endif struct pike_string { diff --git a/src/svalue.h b/src/svalue.h index a0801a51f097b828af71995931edeed0d631acbd..8c438c761942eb2930f1bfd7bb3cecc89dacf98f 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -980,32 +980,67 @@ static INLINE void assign_svalue(struct svalue *to, const struct svalue *from) * but it would cost a couple of cycles in every lock/unlock * operation instead. */ -#define PIKE_MEMORY_OBJECT_MEMBERS \ - INT32 refs \ +#ifdef ATOMIC_SVALUE +/* Atomic svalues: Store the type in the reference types, + * instead of on the stack. This allows for changing an + * svalue in a single atomic operation. + */ +#define PIKE_MEMORY_OBJECT_MEMBERS \ + INT32 refs; \ + INT32 ref_type \ + DO_IF_SECURITY(; struct object *prot) \ + IF_LOCAL_MUTEX(; PIKE_MUTEX_T mutex) + +#ifdef PIKE_SECURITY +#ifdef USE_LOCAL_MUTEX +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs, type, 0, PTHREAD_MUTEX_INITIALIZER +#else +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs, type, 0 +#endif +#else +#ifdef USE_LOCAL_MUTEX +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs, type, PTHREAD_MUTEX_INITIALIZER +#else +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs, type +#endif +#endif + +#define INIT_PIKE_MEMOBJ(X, TYPE) do { \ + struct ref_dummy *v_=(struct ref_dummy *)(X); \ + v_->ref_type = (TYPE); \ + v_->refs=0; \ + add_ref(v_); /* For DMALLOC... */ \ + DO_IF_SECURITY( INITIALIZE_PROT(v_) ); \ + IF_LOCAL_MUTEX(mt_init_recursive(&(v_->mutex))); \ +}while(0) +#else /* !ATOMIC_SVALUE */ +#define PIKE_MEMORY_OBJECT_MEMBERS \ + INT32 refs \ DO_IF_SECURITY(; struct object *prot) \ IF_LOCAL_MUTEX(; PIKE_MUTEX_T mutex) #ifdef PIKE_SECURITY #ifdef USE_LOCAL_MUTEX -#define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, 0, PTHREAD_MUTEX_INITIALIZER +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs, 0, PTHREAD_MUTEX_INITIALIZER #else -#define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, 0 +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs, 0 #endif #else #ifdef USE_LOCAL_MUTEX -#define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs, PTHREAD_MUTEX_INITIALIZER +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs, PTHREAD_MUTEX_INITIALIZER #else -#define PIKE_CONSTANT_MEMOBJ_INIT(refs) refs +#define PIKE_CONSTANT_MEMOBJ_INIT(refs, type) refs #endif #endif -#define INIT_PIKE_MEMOBJ(X) do { \ +#define INIT_PIKE_MEMOBJ(X, TYPE) do { \ struct ref_dummy *v_=(struct ref_dummy *)(X); \ v_->refs=0; \ add_ref(v_); /* For DMALLOC... */ \ DO_IF_SECURITY( INITIALIZE_PROT(v_) ); \ IF_LOCAL_MUTEX(mt_init_recursive(&(v_->mutex))); \ }while(0) +#endif /* ATOMIC_SVALUE */ #define EXIT_PIKE_MEMOBJ(X) do { \ struct ref_dummy *v_=(struct ref_dummy *)(X); \