Merge pull request #19662 from arjunroy/md_batch_static_idx

Reduce instruction count for CH2 metadata ops.
pull/19831/head
Arjun Roy 5 years ago committed by GitHub
commit 3695eb09e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/core/ext/transport/chttp2/transport/incoming_metadata.cc
  2. 28
      src/core/ext/transport/chttp2/transport/parsing.cc
  3. 11
      src/core/lib/slice/slice_internal.h
  4. 2
      src/core/lib/transport/metadata_batch.cc
  5. 1321
      src/core/lib/transport/static_metadata.cc
  6. 24
      src/core/lib/transport/static_metadata.h
  7. 37
      tools/codegen/core/gen_static_metadata.py

@ -38,7 +38,8 @@ grpc_error* grpc_chttp2_incoming_metadata_buffer_add(
storage = static_cast<grpc_linked_mdelem*>( storage = static_cast<grpc_linked_mdelem*>(
buffer->arena->Alloc(sizeof(grpc_linked_mdelem))); buffer->arena->Alloc(sizeof(grpc_linked_mdelem)));
} }
return grpc_metadata_batch_add_tail(&buffer->batch, storage, elem); storage->md = elem;
return grpc_metadata_batch_link_tail(&buffer->batch, storage);
} }
grpc_error* grpc_chttp2_incoming_metadata_buffer_replace_or_add( grpc_error* grpc_chttp2_incoming_metadata_buffer_replace_or_add(

@ -108,7 +108,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
/* fallthrough */ /* fallthrough */
dts_fh_0: dts_fh_0:
case GRPC_DTS_FH_0: case GRPC_DTS_FH_0:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_frame_size = (static_cast<uint32_t>(*cur)) << 16; t->incoming_frame_size = (static_cast<uint32_t>(*cur)) << 16;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_1; t->deframe_state = GRPC_DTS_FH_1;
@ -116,7 +116,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_1: case GRPC_DTS_FH_1:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_frame_size |= (static_cast<uint32_t>(*cur)) << 8; t->incoming_frame_size |= (static_cast<uint32_t>(*cur)) << 8;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_2; t->deframe_state = GRPC_DTS_FH_2;
@ -124,7 +124,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_2: case GRPC_DTS_FH_2:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_frame_size |= *cur; t->incoming_frame_size |= *cur;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_3; t->deframe_state = GRPC_DTS_FH_3;
@ -132,7 +132,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_3: case GRPC_DTS_FH_3:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_frame_type = *cur; t->incoming_frame_type = *cur;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_4; t->deframe_state = GRPC_DTS_FH_4;
@ -140,7 +140,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_4: case GRPC_DTS_FH_4:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_frame_flags = *cur; t->incoming_frame_flags = *cur;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_5; t->deframe_state = GRPC_DTS_FH_5;
@ -148,7 +148,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_5: case GRPC_DTS_FH_5:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_stream_id = ((static_cast<uint32_t>(*cur)) & 0x7f) << 24; t->incoming_stream_id = ((static_cast<uint32_t>(*cur)) & 0x7f) << 24;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_6; t->deframe_state = GRPC_DTS_FH_6;
@ -156,7 +156,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_6: case GRPC_DTS_FH_6:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_stream_id |= (static_cast<uint32_t>(*cur)) << 16; t->incoming_stream_id |= (static_cast<uint32_t>(*cur)) << 16;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_7; t->deframe_state = GRPC_DTS_FH_7;
@ -164,7 +164,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_7: case GRPC_DTS_FH_7:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_stream_id |= (static_cast<uint32_t>(*cur)) << 8; t->incoming_stream_id |= (static_cast<uint32_t>(*cur)) << 8;
if (++cur == end) { if (++cur == end) {
t->deframe_state = GRPC_DTS_FH_8; t->deframe_state = GRPC_DTS_FH_8;
@ -172,7 +172,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FH_8: case GRPC_DTS_FH_8:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
t->incoming_stream_id |= (static_cast<uint32_t>(*cur)); t->incoming_stream_id |= (static_cast<uint32_t>(*cur));
t->deframe_state = GRPC_DTS_FRAME; t->deframe_state = GRPC_DTS_FRAME;
err = init_frame_parser(t); err = init_frame_parser(t);
@ -208,7 +208,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
} }
/* fallthrough */ /* fallthrough */
case GRPC_DTS_FRAME: case GRPC_DTS_FRAME:
GPR_ASSERT(cur < end); GPR_DEBUG_ASSERT(cur < end);
if (static_cast<uint32_t>(end - cur) == t->incoming_frame_size) { if (static_cast<uint32_t>(end - cur) == t->incoming_frame_size) {
err = parse_frame_slice( err = parse_frame_slice(
t, t,
@ -425,7 +425,7 @@ static void on_initial_header(void* tp, grpc_mdelem md) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
grpc_chttp2_stream* s = t->incoming_stream; grpc_chttp2_stream* s = t->incoming_stream;
GPR_ASSERT(s != nullptr); GPR_DEBUG_ASSERT(s != nullptr);
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
char* key = grpc_slice_to_c_string(GRPC_MDKEY(md)); char* key = grpc_slice_to_c_string(GRPC_MDKEY(md));
@ -473,7 +473,7 @@ static void on_initial_header(void* tp, grpc_mdelem md) {
const size_t metadata_size_limit = const size_t metadata_size_limit =
t->settings[GRPC_ACKED_SETTINGS] t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
if (new_size > metadata_size_limit) { if (GPR_UNLIKELY(new_size > metadata_size_limit)) {
gpr_log(GPR_DEBUG, gpr_log(GPR_DEBUG,
"received initial metadata size exceeds limit (%" PRIuPTR "received initial metadata size exceeds limit (%" PRIuPTR
" vs. %" PRIuPTR ")", " vs. %" PRIuPTR ")",
@ -504,7 +504,7 @@ static void on_trailing_header(void* tp, grpc_mdelem md) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
grpc_chttp2_stream* s = t->incoming_stream; grpc_chttp2_stream* s = t->incoming_stream;
GPR_ASSERT(s != nullptr); GPR_DEBUG_ASSERT(s != nullptr);
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
char* key = grpc_slice_to_c_string(GRPC_MDKEY(md)); char* key = grpc_slice_to_c_string(GRPC_MDKEY(md));
@ -627,7 +627,7 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t,
} else { } else {
t->incoming_stream = s; t->incoming_stream = s;
} }
GPR_ASSERT(s != nullptr); GPR_DEBUG_ASSERT(s != nullptr);
s->stats.incoming.framing_bytes += 9; s->stats.incoming.framing_bytes += 9;
if (GPR_UNLIKELY(s->read_closed)) { if (GPR_UNLIKELY(s->read_closed)) {
GRPC_CHTTP2_IF_TRACING(gpr_log( GRPC_CHTTP2_IF_TRACING(gpr_log(

@ -174,6 +174,17 @@ struct grpc_slice_refcount {
namespace grpc_core { namespace grpc_core {
struct StaticSliceRefcount {
static grpc_slice_refcount kStaticSubRefcount;
StaticSliceRefcount(uint32_t index)
: base(&kStaticSubRefcount, grpc_slice_refcount::Type::STATIC),
index(index) {}
grpc_slice_refcount base;
uint32_t index;
};
extern grpc_slice_refcount kNoopRefcount; extern grpc_slice_refcount kNoopRefcount;
struct InternedSliceRefcount { struct InternedSliceRefcount {

@ -104,7 +104,7 @@ static grpc_error* maybe_link_callout(grpc_metadata_batch* batch,
if (idx == GRPC_BATCH_CALLOUTS_COUNT) { if (idx == GRPC_BATCH_CALLOUTS_COUNT) {
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
if (batch->idx.array[idx] == nullptr) { if (GPR_LIKELY(batch->idx.array[idx] == nullptr)) {
++batch->list.default_count; ++batch->list.default_count;
batch->idx.array[idx] = storage; batch->idx.array[idx] = storage;
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;

File diff suppressed because it is too large Load Diff

@ -260,15 +260,18 @@ extern const grpc_core::StaticMetadataSlice
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
(grpc_static_slice_table[105]) (grpc_static_slice_table[105])
extern grpc_slice_refcount namespace grpc_core {
struct StaticSliceRefcount;
}
extern grpc_core::StaticSliceRefcount
grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT];
#define GRPC_IS_STATIC_METADATA_STRING(slice) \ #define GRPC_IS_STATIC_METADATA_STRING(slice) \
((slice).refcount != NULL && \ ((slice).refcount != NULL && \
(slice).refcount->GetType() == grpc_slice_refcount::Type::STATIC) (slice).refcount->GetType() == grpc_slice_refcount::Type::STATIC)
#define GRPC_STATIC_METADATA_INDEX(static_slice) \ #define GRPC_STATIC_METADATA_INDEX(static_slice) \
(static_cast<intptr_t>( \ (reinterpret_cast<grpc_core::StaticSliceRefcount*>((static_slice).refcount) \
((static_slice).refcount - grpc_static_metadata_refcounts))) ->index)
#define GRPC_STATIC_MDELEM_COUNT 85 #define GRPC_STATIC_MDELEM_COUNT 85
extern grpc_core::StaticMetadata extern grpc_core::StaticMetadata
@ -519,11 +522,14 @@ typedef union {
} named; } named;
} grpc_metadata_batch_callouts; } grpc_metadata_batch_callouts;
#define GRPC_BATCH_INDEX_OF(slice) \ #define GRPC_BATCH_INDEX_OF(slice) \
(GRPC_IS_STATIC_METADATA_STRING((slice)) \ (GRPC_IS_STATIC_METADATA_STRING((slice)) && \
? static_cast<grpc_metadata_batch_callouts_index>( \ reinterpret_cast<grpc_core::StaticSliceRefcount*>((slice).refcount) \
GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, \ ->index <= static_cast<uint32_t>(GRPC_BATCH_CALLOUTS_COUNT) \
static_cast<intptr_t>(GRPC_BATCH_CALLOUTS_COUNT))) \ ? static_cast<grpc_metadata_batch_callouts_index>( \
reinterpret_cast<grpc_core::StaticSliceRefcount*>( \
(slice).refcount) \
->index) \
: GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT)
extern const uint8_t grpc_static_accept_encoding_metadata[8]; extern const uint8_t grpc_static_accept_encoding_metadata[8];

@ -393,7 +393,7 @@ for i, elem in enumerate(all_strs):
def slice_def(i): def slice_def(i):
return ( return (
'grpc_core::StaticMetadataSlice(&grpc_static_metadata_refcounts[%d], %d, g_bytes+%d)' 'grpc_core::StaticMetadataSlice(&grpc_static_metadata_refcounts[%d].base, %d, g_bytes+%d)'
) % (i, len(all_strs[i]), id2strofs[i]) ) % (i, len(all_strs[i]), id2strofs[i])
@ -416,14 +416,14 @@ print >> H
print >> C, 'static uint8_t g_bytes[] = {%s};' % (','.join( print >> C, 'static uint8_t g_bytes[] = {%s};' % (','.join(
'%d' % ord(c) for c in ''.join(all_strs))) '%d' % ord(c) for c in ''.join(all_strs)))
print >> C print >> C
print >> C, ('static grpc_slice_refcount static_sub_refcnt;') print >> H, ('namespace grpc_core { struct StaticSliceRefcount; }')
print >> H, ('extern grpc_slice_refcount ' print >> H, ('extern grpc_core::StaticSliceRefcount '
'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT];') 'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT];')
print >> C, ('grpc_slice_refcount ' print >> C, 'grpc_slice_refcount grpc_core::StaticSliceRefcount::kStaticSubRefcount;'
print >> C, ('grpc_core::StaticSliceRefcount '
'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {') 'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {')
for i, elem in enumerate(all_strs): for i, elem in enumerate(all_strs):
print >> C, (' grpc_slice_refcount(&static_sub_refcnt, ' print >> C, ' grpc_core::StaticSliceRefcount(%d), ' % i
'grpc_slice_refcount::Type::STATIC), ')
print >> C, '};' print >> C, '};'
print >> C print >> C
print >> H, '#define GRPC_IS_STATIC_METADATA_STRING(slice) \\' print >> H, '#define GRPC_IS_STATIC_METADATA_STRING(slice) \\'
@ -438,8 +438,7 @@ for i, elem in enumerate(all_strs):
print >> C, '};' print >> C, '};'
print >> C print >> C
print >> H, '#define GRPC_STATIC_METADATA_INDEX(static_slice) \\' print >> H, '#define GRPC_STATIC_METADATA_INDEX(static_slice) \\'
print >> H, (' (static_cast<intptr_t>(((static_slice).refcount - ' print >> H, '(reinterpret_cast<grpc_core::StaticSliceRefcount*>((static_slice).refcount)->index)'
'grpc_static_metadata_refcounts)))')
print >> H print >> H
print >> D, '# hpack fuzzing dictionary' print >> D, '# hpack fuzzing dictionary'
@ -598,8 +597,26 @@ for elem in METADATA_BATCH_CALLOUTS:
print >> H, ' } named;' print >> H, ' } named;'
print >> H, '} grpc_metadata_batch_callouts;' print >> H, '} grpc_metadata_batch_callouts;'
print >> H print >> H
print >> H, '#define GRPC_BATCH_INDEX_OF(slice) \\'
print >> H, ' (GRPC_IS_STATIC_METADATA_STRING((slice)) ? static_cast<grpc_metadata_batch_callouts_index>(GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, static_cast<intptr_t>(GRPC_BATCH_CALLOUTS_COUNT))) : GRPC_BATCH_CALLOUTS_COUNT)' batch_idx_of_hdr = '#define GRPC_BATCH_INDEX_OF(slice) \\'
static_slice = 'GRPC_IS_STATIC_METADATA_STRING((slice))'
slice_to_slice_ref = '(slice).refcount'
static_slice_ref_type = 'grpc_core::StaticSliceRefcount*'
slice_ref_as_static = ('reinterpret_cast<' + static_slice_ref_type + '>(' +
slice_to_slice_ref + ')')
slice_ref_idx = slice_ref_as_static + '->index'
batch_idx_type = 'grpc_metadata_batch_callouts_index'
slice_ref_idx_to_batch_idx = (
'static_cast<' + batch_idx_type + '>(' + slice_ref_idx + ')')
batch_invalid_idx = 'GRPC_BATCH_CALLOUTS_COUNT'
batch_invalid_u32 = 'static_cast<uint32_t>(' + batch_invalid_idx + ')'
# Assemble GRPC_BATCH_INDEX_OF(slice) macro as a join for ease of reading.
batch_idx_of_pieces = [
batch_idx_of_hdr, '\n', '(', static_slice, '&&', slice_ref_idx, '<=',
batch_invalid_u32, '?', slice_ref_idx_to_batch_idx, ':', batch_invalid_idx,
')'
]
print >> H, ''.join(batch_idx_of_pieces)
print >> H print >> H
print >> H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % ( print >> H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % (

Loading…
Cancel
Save