@@ -364,17 +364,30 @@ uint32_t zend_accel_get_class_name_map_ptr(zend_string *type_name)
364364static void zend_persist_generic_args (zend_generic_args * * args_ptr );
365365
366366static void zend_persist_type (zend_type * type ) {
367- /* Handle generic type references before the list/name iteration */
367+ /* Handle generic type references before the list/name iteration.
368+ * When inheriting from an already-persisted class/interface, the ref
369+ * may already live in SHM — use memdup_put (no free) to avoid efree
370+ * on read-only SHM memory. */
368371 if (ZEND_TYPE_IS_GENERIC_PARAM (* type )) {
369372 zend_generic_type_ref * ref = ZEND_TYPE_GENERIC_PARAM_REF (* type );
370- zend_generic_type_ref * new_ref = zend_shared_memdup_put_free (ref , sizeof (zend_generic_type_ref ));
373+ zend_generic_type_ref * new_ref ;
374+ if (zend_accel_in_shm (ref )) {
375+ new_ref = zend_shared_memdup_put (ref , sizeof (zend_generic_type_ref ));
376+ } else {
377+ new_ref = zend_shared_memdup_put_free (ref , sizeof (zend_generic_type_ref ));
378+ }
371379 zend_accel_store_interned_string (new_ref -> name );
372380 ZEND_TYPE_SET_PTR (* type , new_ref );
373381 return ;
374382 }
375383 if (ZEND_TYPE_IS_GENERIC_CLASS (* type )) {
376384 zend_generic_class_ref * ref = ZEND_TYPE_GENERIC_CLASS_REF (* type );
377- zend_generic_class_ref * new_ref = zend_shared_memdup_put_free (ref , sizeof (zend_generic_class_ref ));
385+ zend_generic_class_ref * new_ref ;
386+ if (zend_accel_in_shm (ref )) {
387+ new_ref = zend_shared_memdup_put (ref , sizeof (zend_generic_class_ref ));
388+ } else {
389+ new_ref = zend_shared_memdup_put_free (ref , sizeof (zend_generic_class_ref ));
390+ }
378391 zend_accel_store_interned_string (new_ref -> class_name );
379392 if (!ZCG (current_persistent_script )-> corrupted ) {
380393 zend_accel_get_class_name_map_ptr (new_ref -> class_name );
@@ -383,8 +396,13 @@ static void zend_persist_type(zend_type *type) {
383396 zend_persist_generic_args (& new_ref -> type_args );
384397 }
385398 if (new_ref -> wildcard_bounds && new_ref -> type_args ) {
386- new_ref -> wildcard_bounds = zend_shared_memdup_put_free (
387- new_ref -> wildcard_bounds , new_ref -> type_args -> num_args * sizeof (zend_generic_bound ));
399+ if (zend_accel_in_shm (new_ref -> wildcard_bounds )) {
400+ new_ref -> wildcard_bounds = zend_shared_memdup_put (
401+ new_ref -> wildcard_bounds , new_ref -> type_args -> num_args * sizeof (zend_generic_bound ));
402+ } else {
403+ new_ref -> wildcard_bounds = zend_shared_memdup_put_free (
404+ new_ref -> wildcard_bounds , new_ref -> type_args -> num_args * sizeof (zend_generic_bound ));
405+ }
388406 }
389407 ZEND_TYPE_SET_PTR (* type , new_ref );
390408 return ;
@@ -422,7 +440,11 @@ static void zend_persist_generic_args(zend_generic_args **args_ptr)
422440{
423441 zend_generic_args * args = * args_ptr ;
424442 size_t size = ZEND_GENERIC_ARGS_SIZE (args -> num_args );
425- args = zend_shared_memdup_put_free (args , size );
443+ if (zend_accel_in_shm (args )) {
444+ args = zend_shared_memdup_put (args , size );
445+ } else {
446+ args = zend_shared_memdup_put_free (args , size );
447+ }
426448 args -> refcount = 0 ; /* SHM: unmanaged, never freed via release */
427449 for (uint32_t i = 0 ; i < args -> num_args ; i ++ ) {
428450 zend_persist_type (& args -> args [i ]);
@@ -434,7 +456,11 @@ static void zend_persist_generic_params_info(zend_generic_params_info **info_ptr
434456{
435457 zend_generic_params_info * info = * info_ptr ;
436458 size_t size = ZEND_GENERIC_PARAMS_INFO_SIZE (info -> num_params );
437- info = zend_shared_memdup_put_free (info , size );
459+ if (zend_accel_in_shm (info )) {
460+ info = zend_shared_memdup_put (info , size );
461+ } else {
462+ info = zend_shared_memdup_put_free (info , size );
463+ }
438464 for (uint32_t i = 0 ; i < info -> num_params ; i ++ ) {
439465 zend_accel_store_interned_string (info -> params [i ].name );
440466 zend_persist_type (& info -> params [i ].constraint );
@@ -1215,28 +1241,38 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce)
12151241 zend_persist_generic_args (& ce -> bound_generic_args );
12161242 }
12171243 if (ce -> interface_bound_generic_args ) {
1218- zend_hash_persist (ce -> interface_bound_generic_args );
1219- ZEND_HASH_MAP_FOREACH_BUCKET (ce -> interface_bound_generic_args , p ) {
1220- ZEND_ASSERT (p -> key != NULL );
1221- zend_accel_store_interned_string (p -> key );
1222- zend_generic_args * args = Z_PTR (p -> val );
1223- zend_persist_generic_args (& args );
1224- Z_PTR (p -> val ) = args ;
1225- } ZEND_HASH_FOREACH_END ();
1226- ce -> interface_bound_generic_args = zend_shared_memdup_put_free (
1227- ce -> interface_bound_generic_args , sizeof (HashTable ));
1244+ if (zend_accel_in_shm (ce -> interface_bound_generic_args )) {
1245+ ce -> interface_bound_generic_args = zend_shared_memdup_put (
1246+ ce -> interface_bound_generic_args , sizeof (HashTable ));
1247+ } else {
1248+ zend_hash_persist (ce -> interface_bound_generic_args );
1249+ ZEND_HASH_MAP_FOREACH_BUCKET (ce -> interface_bound_generic_args , p ) {
1250+ ZEND_ASSERT (p -> key != NULL );
1251+ zend_accel_store_interned_string (p -> key );
1252+ zend_generic_args * args = Z_PTR (p -> val );
1253+ zend_persist_generic_args (& args );
1254+ Z_PTR (p -> val ) = args ;
1255+ } ZEND_HASH_FOREACH_END ();
1256+ ce -> interface_bound_generic_args = zend_shared_memdup_put_free (
1257+ ce -> interface_bound_generic_args , sizeof (HashTable ));
1258+ }
12281259 }
12291260 if (ce -> trait_bound_generic_args ) {
1230- zend_hash_persist (ce -> trait_bound_generic_args );
1231- ZEND_HASH_MAP_FOREACH_BUCKET (ce -> trait_bound_generic_args , p ) {
1232- ZEND_ASSERT (p -> key != NULL );
1233- zend_accel_store_interned_string (p -> key );
1234- zend_generic_args * args = Z_PTR (p -> val );
1235- zend_persist_generic_args (& args );
1236- Z_PTR (p -> val ) = args ;
1237- } ZEND_HASH_FOREACH_END ();
1238- ce -> trait_bound_generic_args = zend_shared_memdup_put_free (
1239- ce -> trait_bound_generic_args , sizeof (HashTable ));
1261+ if (zend_accel_in_shm (ce -> trait_bound_generic_args )) {
1262+ ce -> trait_bound_generic_args = zend_shared_memdup_put (
1263+ ce -> trait_bound_generic_args , sizeof (HashTable ));
1264+ } else {
1265+ zend_hash_persist (ce -> trait_bound_generic_args );
1266+ ZEND_HASH_MAP_FOREACH_BUCKET (ce -> trait_bound_generic_args , p ) {
1267+ ZEND_ASSERT (p -> key != NULL );
1268+ zend_accel_store_interned_string (p -> key );
1269+ zend_generic_args * args = Z_PTR (p -> val );
1270+ zend_persist_generic_args (& args );
1271+ Z_PTR (p -> val ) = args ;
1272+ } ZEND_HASH_FOREACH_END ();
1273+ ce -> trait_bound_generic_args = zend_shared_memdup_put_free (
1274+ ce -> trait_bound_generic_args , sizeof (HashTable ));
1275+ }
12401276 }
12411277 }
12421278
0 commit comments