|  | @@ -48,6 +48,7 @@
 | 
	
		
			
				|  |  |  #include "src/core/lib/iomgr/iomgr_internal.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/profiling/timers.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/slice/slice_internal.h"
 | 
	
		
			
				|  |  | +#include "src/core/lib/slice/slice_string_helpers.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/support/murmur_hash.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/support/string.h"
 | 
	
		
			
				|  |  |  #include "src/core/lib/transport/static_metadata.h"
 | 
	
	
		
			
				|  | @@ -160,12 +161,14 @@ static int is_mdelem_static(grpc_mdelem e) {
 | 
	
		
			
				|  |  |  static void ref_md_locked(mdtab_shard *shard,
 | 
	
		
			
				|  |  |                            interned_metadata *md DEBUG_ARGS) {
 | 
	
		
			
				|  |  |  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 | 
	
		
			
				|  |  | +  char *key_str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  | +  char *value_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  |    gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
 | 
	
		
			
				|  |  |            "ELM   REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
 | 
	
		
			
				|  |  |            gpr_atm_no_barrier_load(&md->refcnt),
 | 
	
		
			
				|  |  | -          gpr_atm_no_barrier_load(&md->refcnt) + 1,
 | 
	
		
			
				|  |  | -          grpc_mdstr_as_c_string((grpc_slice)md->key),
 | 
	
		
			
				|  |  | -          grpc_mdstr_as_c_string((grpc_slice)md->value));
 | 
	
		
			
				|  |  | +          gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
 | 
	
		
			
				|  |  | +  gpr_free(key_str);
 | 
	
		
			
				|  |  | +  gpr_free(value_str);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |    if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) {
 | 
	
		
			
				|  |  |      gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1);
 | 
	
	
		
			
				|  | @@ -301,10 +304,12 @@ grpc_mdelem grpc_mdelem_create(
 | 
	
		
			
				|  |  |    shard->elems[idx] = md;
 | 
	
		
			
				|  |  |    gpr_mu_init(&md->mu_user_data);
 | 
	
		
			
				|  |  |  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 | 
	
		
			
				|  |  | +  char *key_str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  | +  char *value_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  |    gpr_log(GPR_DEBUG, "ELM   NEW:%p:%zu: '%s' = '%s'", (void *)md,
 | 
	
		
			
				|  |  | -          gpr_atm_no_barrier_load(&md->refcnt),
 | 
	
		
			
				|  |  | -          grpc_mdstr_as_c_string((grpc_slice)md->key),
 | 
	
		
			
				|  |  | -          grpc_mdstr_as_c_string((grpc_slice)md->value));
 | 
	
		
			
				|  |  | +          gpr_atm_no_barrier_load(&md->refcnt), key_str, value_str);
 | 
	
		
			
				|  |  | +  gpr_free(key_str);
 | 
	
		
			
				|  |  | +  gpr_free(value_str);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |    shard->count++;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -356,12 +361,14 @@ grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
 | 
	
		
			
				|  |  |      case GRPC_MDELEM_STORAGE_INTERNED: {
 | 
	
		
			
				|  |  |        interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
 | 
	
		
			
				|  |  |  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 | 
	
		
			
				|  |  | +      char *key_str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  | +      char *value_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  |        gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
 | 
	
		
			
				|  |  |                "ELM   REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
 | 
	
		
			
				|  |  |                gpr_atm_no_barrier_load(&md->refcnt),
 | 
	
		
			
				|  |  | -              gpr_atm_no_barrier_load(&md->refcnt) + 1,
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->key),
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->value));
 | 
	
		
			
				|  |  | +              gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
 | 
	
		
			
				|  |  | +      gpr_free(key_str);
 | 
	
		
			
				|  |  | +      gpr_free(value_str);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |        /* we can assume the ref count is >= 1 as the application is calling
 | 
	
		
			
				|  |  |           this function - meaning that no adjustment to mdtab_free is necessary,
 | 
	
	
		
			
				|  | @@ -374,12 +381,14 @@ grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
 | 
	
		
			
				|  |  |      case GRPC_MDELEM_STORAGE_ALLOCATED: {
 | 
	
		
			
				|  |  |        allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
 | 
	
		
			
				|  |  |  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 | 
	
		
			
				|  |  | +      char *key_str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  | +      char *value_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  |        gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
 | 
	
		
			
				|  |  |                "ELM   REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
 | 
	
		
			
				|  |  |                gpr_atm_no_barrier_load(&md->refcnt),
 | 
	
		
			
				|  |  | -              gpr_atm_no_barrier_load(&md->refcnt) + 1,
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->key),
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->value));
 | 
	
		
			
				|  |  | +              gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
 | 
	
		
			
				|  |  | +      gpr_free(key_str);
 | 
	
		
			
				|  |  | +      gpr_free(value_str);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |        /* we can assume the ref count is >= 1 as the application is calling
 | 
	
		
			
				|  |  |           this function - meaning that no adjustment to mdtab_free is necessary,
 | 
	
	
		
			
				|  | @@ -400,12 +409,14 @@ void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem gmd DEBUG_ARGS) {
 | 
	
		
			
				|  |  |      case GRPC_MDELEM_STORAGE_INTERNED: {
 | 
	
		
			
				|  |  |        interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
 | 
	
		
			
				|  |  |  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 | 
	
		
			
				|  |  | +      char *key_str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  | +      char *value_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  |        gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
 | 
	
		
			
				|  |  |                "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
 | 
	
		
			
				|  |  |                gpr_atm_no_barrier_load(&md->refcnt),
 | 
	
		
			
				|  |  | -              gpr_atm_no_barrier_load(&md->refcnt) - 1,
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->key),
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->value));
 | 
	
		
			
				|  |  | +              gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str);
 | 
	
		
			
				|  |  | +      gpr_free(key_str);
 | 
	
		
			
				|  |  | +      gpr_free(value_str);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |        uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key),
 | 
	
		
			
				|  |  |                                           grpc_slice_hash(md->value));
 | 
	
	
		
			
				|  | @@ -422,12 +433,14 @@ void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem gmd DEBUG_ARGS) {
 | 
	
		
			
				|  |  |      case GRPC_MDELEM_STORAGE_ALLOCATED: {
 | 
	
		
			
				|  |  |        allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
 | 
	
		
			
				|  |  |  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 | 
	
		
			
				|  |  | +      char *key_str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  | +      char *value_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII);
 | 
	
		
			
				|  |  |        gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
 | 
	
		
			
				|  |  |                "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
 | 
	
		
			
				|  |  |                gpr_atm_no_barrier_load(&md->refcnt),
 | 
	
		
			
				|  |  | -              gpr_atm_no_barrier_load(&md->refcnt) - 1,
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->key),
 | 
	
		
			
				|  |  | -              grpc_mdstr_as_c_string((grpc_slice)md->value));
 | 
	
		
			
				|  |  | +              gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str);
 | 
	
		
			
				|  |  | +      gpr_free(key_str);
 | 
	
		
			
				|  |  | +      gpr_free(value_str);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |        const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
 | 
	
		
			
				|  |  |        GPR_ASSERT(prev_refcount >= 1);
 |