|  | @@ -178,22 +178,19 @@ static void evict_entry(grpc_chttp2_hpack_compressor *c) {
 | 
	
		
			
				|  |  |    c->table_elems--;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* add an element to the decoder table */
 | 
	
		
			
				|  |  | -static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | -                     grpc_mdelem elem, size_t elem_size, bool only_add_key) {
 | 
	
		
			
				|  |  | -  uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
 | 
	
		
			
				|  |  | -  uint32_t value_hash = only_add_key ? 0 : grpc_slice_hash(GRPC_MDVALUE(elem));
 | 
	
		
			
				|  |  | -  uint32_t elem_hash =
 | 
	
		
			
				|  |  | -      only_add_key ? 0 : GRPC_MDSTR_KV_HASH(key_hash, value_hash);
 | 
	
		
			
				|  |  | +// Reserve space in table for the new element, evict entries if needed.
 | 
	
		
			
				|  |  | +// Return the new index of the element. Return 0 to indicate not adding to
 | 
	
		
			
				|  |  | +// table.
 | 
	
		
			
				|  |  | +static uint32_t prepare_space_for_new_elem(grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | +                                           size_t elem_size) {
 | 
	
		
			
				|  |  |    uint32_t new_index = c->tail_remote_index + c->table_elems + 1;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    GPR_ASSERT(elem_size < 65536);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (elem_size > c->max_table_size) {
 | 
	
		
			
				|  |  |      while (c->table_size > 0) {
 | 
	
		
			
				|  |  |        evict_entry(c);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    return;
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /* Reserve space for this element in the remote table: if this overflows
 | 
	
	
		
			
				|  | @@ -207,6 +204,25 @@ static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  |    c->table_size = (uint16_t)(c->table_size + elem_size);
 | 
	
		
			
				|  |  |    c->table_elems++;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  return new_index;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* dummy function */
 | 
	
		
			
				|  |  | +static void add_nothing(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | +                        grpc_chttp2_hpack_compressor *c, grpc_mdelem elem,
 | 
	
		
			
				|  |  | +                        size_t elem_size) {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Add a key to the dynamic table. Both key and value will be added to table at
 | 
	
		
			
				|  |  | +// the decoder.
 | 
	
		
			
				|  |  | +static void add_key_with_index(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | +                               grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | +                               grpc_mdelem elem, uint32_t new_index) {
 | 
	
		
			
				|  |  | +  if (new_index == 0) {
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    /* Store the key into {entries,indices}_keys */
 | 
	
		
			
				|  |  |    if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)],
 | 
	
		
			
				|  |  |                      GRPC_MDKEY(elem))) {
 | 
	
	
		
			
				|  | @@ -238,37 +254,63 @@ static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  |          grpc_slice_ref_internal(GRPC_MDKEY(elem));
 | 
	
		
			
				|  |  |      c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (!only_add_key) {
 | 
	
		
			
				|  |  | -    /* Store this element into {entries,indices}_elem */
 | 
	
		
			
				|  |  | -    if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem)) {
 | 
	
		
			
				|  |  | -      /* already there: update with new index */
 | 
	
		
			
				|  |  | -      c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | -    } else if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)],
 | 
	
		
			
				|  |  | -                              elem)) {
 | 
	
		
			
				|  |  | -      /* already there (cuckoo): update with new index */
 | 
	
		
			
				|  |  | -      c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | -    } else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_2(elem_hash)])) {
 | 
	
		
			
				|  |  | -      /* not there, but a free element: add */
 | 
	
		
			
				|  |  | -      c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | -      c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | -    } else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_3(elem_hash)])) {
 | 
	
		
			
				|  |  | -      /* not there (cuckoo), but a free element: add */
 | 
	
		
			
				|  |  | -      c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | -      c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | -    } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
 | 
	
		
			
				|  |  | -               c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
 | 
	
		
			
				|  |  | -      /* not there: replace oldest */
 | 
	
		
			
				|  |  | -      GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
 | 
	
		
			
				|  |  | -      c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | -      c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | -    } else {
 | 
	
		
			
				|  |  | -      /* not there: replace oldest */
 | 
	
		
			
				|  |  | -      GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
 | 
	
		
			
				|  |  | -      c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | -      c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +/* add an element to the decoder table */
 | 
	
		
			
				|  |  | +static void add_elem_with_index(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | +                                grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | +                                grpc_mdelem elem, uint32_t new_index) {
 | 
	
		
			
				|  |  | +  if (new_index == 0) {
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  GPR_ASSERT(GRPC_MDELEM_IS_INTERNED(elem));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
 | 
	
		
			
				|  |  | +  uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
 | 
	
		
			
				|  |  | +  uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* Store this element into {entries,indices}_elem */
 | 
	
		
			
				|  |  | +  if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem)) {
 | 
	
		
			
				|  |  | +    /* already there: update with new index */
 | 
	
		
			
				|  |  | +    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | +  } else if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)],
 | 
	
		
			
				|  |  | +                            elem)) {
 | 
	
		
			
				|  |  | +    /* already there (cuckoo): update with new index */
 | 
	
		
			
				|  |  | +    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | +  } else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_2(elem_hash)])) {
 | 
	
		
			
				|  |  | +    /* not there, but a free element: add */
 | 
	
		
			
				|  |  | +    c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | +    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | +  } else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_3(elem_hash)])) {
 | 
	
		
			
				|  |  | +    /* not there (cuckoo), but a free element: add */
 | 
	
		
			
				|  |  | +    c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | +    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | +  } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
 | 
	
		
			
				|  |  | +             c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
 | 
	
		
			
				|  |  | +    /* not there: replace oldest */
 | 
	
		
			
				|  |  | +    GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
 | 
	
		
			
				|  |  | +    c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | +    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    /* not there: replace oldest */
 | 
	
		
			
				|  |  | +    GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
 | 
	
		
			
				|  |  | +    c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
 | 
	
		
			
				|  |  | +    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  add_key_with_index(exec_ctx, c, elem, new_index);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | +                     grpc_mdelem elem, size_t elem_size) {
 | 
	
		
			
				|  |  | +  uint32_t new_index = prepare_space_for_new_elem(c, elem_size);
 | 
	
		
			
				|  |  | +  add_elem_with_index(exec_ctx, c, elem, new_index);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void add_key(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | +                    grpc_mdelem elem, size_t elem_size) {
 | 
	
		
			
				|  |  | +  uint32_t new_index = prepare_space_for_new_elem(c, elem_size);
 | 
	
		
			
				|  |  | +  add_key_with_index(exec_ctx, c, elem, new_index);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void emit_indexed(grpc_exec_ctx *exec_ctx,
 | 
	
	
		
			
				|  | @@ -362,7 +404,9 @@ static void emit_lithdr_noidx(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void emit_lithdr_incidx_v(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  |                                   grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | -                                 grpc_mdelem elem, framer_state *st) {
 | 
	
		
			
				|  |  | +                                 uint32_t unused_index, grpc_mdelem elem,
 | 
	
		
			
				|  |  | +                                 framer_state *st) {
 | 
	
		
			
				|  |  | +  GPR_ASSERT(unused_index == 0);
 | 
	
		
			
				|  |  |    GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V(exec_ctx);
 | 
	
		
			
				|  |  |    GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx);
 | 
	
		
			
				|  |  |    uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
 | 
	
	
		
			
				|  | @@ -384,7 +428,9 @@ static void emit_lithdr_incidx_v(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void emit_lithdr_noidx_v(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  |                                  grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  | -                                grpc_mdelem elem, framer_state *st) {
 | 
	
		
			
				|  |  | +                                uint32_t unused_index, grpc_mdelem elem,
 | 
	
		
			
				|  |  | +                                framer_state *st) {
 | 
	
		
			
				|  |  | +  GPR_ASSERT(unused_index == 0);
 | 
	
		
			
				|  |  |    GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V(exec_ctx);
 | 
	
		
			
				|  |  |    GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx);
 | 
	
		
			
				|  |  |    uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
 | 
	
	
		
			
				|  | @@ -452,22 +498,15 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Key is not interned, emit literals.
 | 
	
		
			
				|  |  |    if (!key_interned) {
 | 
	
		
			
				|  |  | -    emit_lithdr_noidx_v(exec_ctx, c, elem, st);
 | 
	
		
			
				|  |  | +    emit_lithdr_noidx_v(exec_ctx, c, 0, elem, st);
 | 
	
		
			
				|  |  |      return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  uint32_t key_hash;
 | 
	
		
			
				|  |  | -  uint32_t value_hash;
 | 
	
		
			
				|  |  | -  uint32_t elem_hash;
 | 
	
		
			
				|  |  | -  size_t decoder_space_usage;
 | 
	
		
			
				|  |  | -  uint32_t indices_key;
 | 
	
		
			
				|  |  | -  bool should_add_elem;
 | 
	
		
			
				|  |  | -  bool should_add_key;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
 | 
	
		
			
				|  |  | +  uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
 | 
	
		
			
				|  |  | +  uint32_t elem_hash = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (elem_interned) {
 | 
	
		
			
				|  |  | -    value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
 | 
	
		
			
				|  |  | +    uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
 | 
	
		
			
				|  |  |      elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum,
 | 
	
	
		
			
				|  | @@ -492,32 +531,31 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  uint32_t indices_key;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    /* should this elem be in the table? */
 | 
	
		
			
				|  |  | -  decoder_space_usage =
 | 
	
		
			
				|  |  | +  size_t decoder_space_usage =
 | 
	
		
			
				|  |  |        grpc_mdelem_get_size_in_hpack_table(elem, st->use_true_binary_metadata);
 | 
	
		
			
				|  |  | -  should_add_elem = elem_interned &&
 | 
	
		
			
				|  |  | -                    decoder_space_usage < MAX_DECODER_SPACE_USAGE &&
 | 
	
		
			
				|  |  | -                    c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >=
 | 
	
		
			
				|  |  | -                        c->filter_elems_sum / ONE_ON_ADD_PROBABILITY;
 | 
	
		
			
				|  |  | -  should_add_key =
 | 
	
		
			
				|  |  | -      !elem_interned && decoder_space_usage < MAX_DECODER_SPACE_USAGE;
 | 
	
		
			
				|  |  | +  bool should_add_elem = elem_interned &&
 | 
	
		
			
				|  |  | +                         decoder_space_usage < MAX_DECODER_SPACE_USAGE &&
 | 
	
		
			
				|  |  | +                         c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >=
 | 
	
		
			
				|  |  | +                             c->filter_elems_sum / ONE_ON_ADD_PROBABILITY;
 | 
	
		
			
				|  |  | +  void (*maybe_add)(grpc_exec_ctx *, grpc_chttp2_hpack_compressor *,
 | 
	
		
			
				|  |  | +                    grpc_mdelem, size_t) =
 | 
	
		
			
				|  |  | +      should_add_elem ? add_elem : add_nothing;
 | 
	
		
			
				|  |  | +  void (*emit)(grpc_exec_ctx *, grpc_chttp2_hpack_compressor *, uint32_t,
 | 
	
		
			
				|  |  | +               grpc_mdelem, framer_state *) =
 | 
	
		
			
				|  |  | +      should_add_elem ? emit_lithdr_incidx : emit_lithdr_noidx;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /* no hits for the elem... maybe there's a key? */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)];
 | 
	
		
			
				|  |  |    if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)],
 | 
	
		
			
				|  |  |                      GRPC_MDKEY(elem)) &&
 | 
	
		
			
				|  |  |        indices_key > c->tail_remote_index) {
 | 
	
		
			
				|  |  |      /* HIT: key (first cuckoo hash) */
 | 
	
		
			
				|  |  | -    if (should_add_elem) {
 | 
	
		
			
				|  |  | -      emit_lithdr_incidx(exec_ctx, c, dynidx(c, indices_key), elem, st);
 | 
	
		
			
				|  |  | -      add_elem(exec_ctx, c, elem, decoder_space_usage, false);
 | 
	
		
			
				|  |  | -      return;
 | 
	
		
			
				|  |  | -    } else {
 | 
	
		
			
				|  |  | -      emit_lithdr_noidx(exec_ctx, c, dynidx(c, indices_key), elem, st);
 | 
	
		
			
				|  |  | -      return;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    GPR_UNREACHABLE_CODE(return );
 | 
	
		
			
				|  |  | +    emit(exec_ctx, c, dynidx(c, indices_key), elem, st);
 | 
	
		
			
				|  |  | +    maybe_add(exec_ctx, c, elem, decoder_space_usage);
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)];
 | 
	
	
		
			
				|  | @@ -525,28 +563,20 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
 | 
	
		
			
				|  |  |                      GRPC_MDKEY(elem)) &&
 | 
	
		
			
				|  |  |        indices_key > c->tail_remote_index) {
 | 
	
		
			
				|  |  |      /* HIT: key (first cuckoo hash) */
 | 
	
		
			
				|  |  | -    if (should_add_elem) {
 | 
	
		
			
				|  |  | -      emit_lithdr_incidx(exec_ctx, c, dynidx(c, indices_key), elem, st);
 | 
	
		
			
				|  |  | -      add_elem(exec_ctx, c, elem, decoder_space_usage, false);
 | 
	
		
			
				|  |  | -      return;
 | 
	
		
			
				|  |  | -    } else {
 | 
	
		
			
				|  |  | -      emit_lithdr_noidx(exec_ctx, c, dynidx(c, indices_key), elem, st);
 | 
	
		
			
				|  |  | -      return;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    GPR_UNREACHABLE_CODE(return );
 | 
	
		
			
				|  |  | +    emit(exec_ctx, c, dynidx(c, indices_key), elem, st);
 | 
	
		
			
				|  |  | +    maybe_add(exec_ctx, c, elem, decoder_space_usage);
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /* no elem, key in the table... fall back to literal emission */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (should_add_elem || should_add_key) {
 | 
	
		
			
				|  |  | -    emit_lithdr_incidx_v(exec_ctx, c, elem, st);
 | 
	
		
			
				|  |  | -    add_elem(exec_ctx, c, elem, decoder_space_usage, should_add_key);
 | 
	
		
			
				|  |  | -    return;
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    emit_lithdr_noidx_v(exec_ctx, c, elem, st);
 | 
	
		
			
				|  |  | -    return;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  GPR_UNREACHABLE_CODE(return );
 | 
	
		
			
				|  |  | +  bool should_add_key =
 | 
	
		
			
				|  |  | +      !elem_interned && decoder_space_usage < MAX_DECODER_SPACE_USAGE;
 | 
	
		
			
				|  |  | +  emit = (should_add_elem || should_add_key) ? emit_lithdr_incidx_v
 | 
	
		
			
				|  |  | +                                             : emit_lithdr_noidx_v;
 | 
	
		
			
				|  |  | +  maybe_add =
 | 
	
		
			
				|  |  | +      should_add_elem ? add_elem : (should_add_key ? add_key : add_nothing);
 | 
	
		
			
				|  |  | +  emit(exec_ctx, c, 0, elem, st);
 | 
	
		
			
				|  |  | +  maybe_add(exec_ctx, c, elem, decoder_space_usage);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #define STRLEN_LIT(x) (sizeof(x) - 1)
 |