Codegen optimizations for hpack_parser on_hdr.

Currently, the log statements for on_hdr clobber some registers even if it is
disabled by default. Additionally, the no-error path is doing some unnecessary
jumps. This PR separates out and un-inlines the logging code, and marks the
no-error case as likely to occur.

This results in slightly faster hpack_parsing, e.g.:
BM_HpackParserParseHeader<IndexedSingleStaticElem, UnrefHeader>
23.8ns ± 0%             19.8ns ± 0%  -16.81%        (p=0.000 n=17+17)
BM_HpackParserParseHeader<AddIndexedSingleStaticElem, UnrefHeader>
160ns ± 0%              154ns ± 0%   -3.18%        (p=0.000 n=19+20)
BM_HpackParserParseHeader<KeyIndexedSingleStaticElem, UnrefHeader>
216ns ± 1%              214ns ± 2%   -0.70%        (p=0.004 n=18+18)
BM_HpackParserParseHeader<IndexedSingleInternedElem, UnrefHeader>
35.4ns ± 0%             34.4ns ± 0%   -2.93%        (p=0.000 n=16+16)
BM_HpackParserParseHeader<RepresentativeClientInitialMetadata, UnrefHeader>
140ns ± 0%              130ns ± 0%   -7.06%        (p=0.000 n=17+18)
BM_HpackParserParseHeader<MoreRepresentativeClientInitialMetadata, UnrefHeader>
644ns ± 1%              636ns ± 2%   -1.29%        (p=0.003 n=17+20)
BM_HpackParserParseHeader<RepresentativeServerInitialMetadata, UnrefHeader>
49.1ns ± 0%             38.7ns ± 0%  -21.13%        (p=0.000 n=19+18)
BM_HpackParserParseHeader<RepresentativeServerTrailingMetadata, UnrefHeader>
47.1ns ± 0%             43.2ns ± 0%   -8.17%        (p=0.000 n=20+19)
BM_HpackParserParseHeader<RepresentativeClientInitialMetadata, OnInitialHeader>
452ns ± 1%              417ns ± 1%   -7.86%        (p=0.000 n=20+20)
BM_HpackParserParseHeader<MoreRepresentativeClientInitialMetadata,
OnInitialHeader>
1.06µs ± 1%             1.02µs ± 2%   -3.42%        (p=0.000 n=19+20)
BM_HpackParserParseHeader<RepresentativeServerInitialMetadata, OnInitialHeader>
156ns ± 0%              142ns ± 1%   -9.08%        (p=0.000 n=17+19)
BM_HpackParserParseHeader<SameDeadline, OnHeaderTimeout>
117ns ± 0%              113ns ± 1%   -3.98%        (p=0.000 n=20+20)
pull/19498/head
Arjun Roy 6 years ago
parent 57d522eda3
commit 80d1aec021
  1. 96
      src/core/ext/transport/chttp2/transport/hpack_parser.cc

@ -622,33 +622,37 @@ static const uint8_t inverse_base64[256] = {
255,
};
static void GPR_ATTRIBUTE_NOINLINE on_hdr_log(grpc_mdelem md) {
char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
char* v = nullptr;
if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
} else {
v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
}
gpr_log(
GPR_INFO,
"Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
grpc_slice_is_interned(GRPC_MDKEY(md)),
grpc_slice_is_interned(GRPC_MDVALUE(md)));
gpr_free(k);
gpr_free(v);
}
/* emission helpers */
static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md,
int add_to_table) {
template <bool do_add>
static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
char* v = nullptr;
if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
} else {
v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
}
gpr_log(
GPR_INFO,
"Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
grpc_slice_is_interned(GRPC_MDKEY(md)),
grpc_slice_is_interned(GRPC_MDVALUE(md)));
gpr_free(k);
gpr_free(v);
on_hdr_log(md);
}
if (add_to_table) {
GPR_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
if (do_add) {
GPR_DEBUG_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
grpc_error* err = grpc_chttp2_hptbl_add(&p->table, md);
if (err != GRPC_ERROR_NONE) return err;
if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err;
}
if (p->on_header == nullptr) {
if (GPR_UNLIKELY(p->on_header == nullptr)) {
GRPC_MDELEM_UNREF(md);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set");
}
@ -765,7 +769,7 @@ static grpc_error* finish_indexed_field(grpc_chttp2_hpack_parser* p,
}
GRPC_MDELEM_REF(md);
GRPC_STATS_INC_HPACK_RECV_INDEXED();
grpc_error* err = on_hdr(p, md, 0);
grpc_error* err = on_hdr<false>(p, md);
if (err != GRPC_ERROR_NONE) return err;
return parse_begin(p, cur, end);
}
@ -798,11 +802,9 @@ static grpc_error* finish_lithdr_incidx(grpc_chttp2_hpack_parser* p,
grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, true)),
1);
grpc_error* err = on_hdr<true>(
p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, true)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -813,10 +815,8 @@ static grpc_error* finish_lithdr_incidx_v(grpc_chttp2_hpack_parser* p,
const uint8_t* end) {
GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, true)),
1);
on_hdr<true>(p, grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, true)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -865,11 +865,9 @@ static grpc_error* finish_lithdr_notidx(grpc_chttp2_hpack_parser* p,
grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -879,11 +877,9 @@ static grpc_error* finish_lithdr_notidx_v(grpc_chttp2_hpack_parser* p,
const uint8_t* cur,
const uint8_t* end) {
GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -932,11 +928,9 @@ static grpc_error* finish_lithdr_nvridx(grpc_chttp2_hpack_parser* p,
grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -946,11 +940,9 @@ static grpc_error* finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p,
const uint8_t* cur,
const uint8_t* end) {
GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}

Loading…
Cancel
Save