aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Soheil Hassas Yeganeh <soheil@google.com>2018-10-07 18:41:31 -0400
committerGravatar Soheil Hassas Yeganeh <soheil@google.com>2018-10-07 18:41:31 -0400
commit5faf1b72edba62a06dd6b4273c2a36f570b7c949 (patch)
treeed84b65e507ab6eb9883ef39f8b349692e0eb800
parent3b26fe7262a9db90dfb69f84ad582d9f71871a5c (diff)
Avoid unnecessary ref/unref calls to get mdelem from slices.
grpc_mdelem_from_slices() unref's the key and value. As a result, in quite a few cases on the hot path, we first ref slice, so that grpc_mdelem_from_slices() can unref them. Add grpc_mdelem_from_slices_no_unref() which does not unref() the input slices. This cuts 0.5% - 1.0% across app benchmarks.
-rw-r--r--include/grpc/grpc.h2
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc2
-rw-r--r--src/core/ext/filters/http/client_authority_filter.cc5
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc5
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.cc3
-rw-r--r--src/core/lib/surface/channel.cc30
-rw-r--r--src/core/lib/surface/channel.h4
-rw-r--r--src/core/lib/transport/metadata.cc10
-rw-r--r--src/core/lib/transport/metadata.h8
9 files changed, 37 insertions, 32 deletions
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index a9beee1c9e..416958ed96 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -211,7 +211,7 @@ GRPCAPI int grpc_channel_support_connectivity_watcher(grpc_channel* channel);
possible values). */
GRPCAPI grpc_call* grpc_channel_create_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
- grpc_completion_queue* completion_queue, grpc_slice method,
+ grpc_completion_queue* completion_queue, const grpc_slice& method,
const grpc_slice* host, gpr_timespec deadline, void* reserved);
/** Ping the channels peer (load balanced channels will select one sub-channel
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 388736b60a..3df5f6f2a0 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -2211,7 +2211,7 @@ static void add_retriable_send_initial_metadata_op(
.grpc_previous_rpc_attempts);
}
if (GPR_UNLIKELY(calld->num_attempts_completed > 0)) {
- grpc_mdelem retry_md = grpc_mdelem_from_slices(
+ grpc_mdelem retry_md = grpc_mdelem_from_slices_no_unref(
GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS,
*retry_count_strings[calld->num_attempts_completed - 1]);
grpc_error* error = grpc_metadata_batch_add_tail(
diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc
index 1ca20ebb26..40b3ea22fd 100644
--- a/src/core/ext/filters/http/client_authority_filter.cc
+++ b/src/core/ext/filters/http/client_authority_filter.cc
@@ -59,9 +59,8 @@ void authority_start_transport_stream_op_batch(
initial_metadata->idx.named.authority == nullptr) {
grpc_error* error = grpc_metadata_batch_add_head(
initial_metadata, &calld->authority_storage,
- grpc_mdelem_from_slices(
- GRPC_MDSTR_AUTHORITY,
- grpc_slice_ref_internal(chand->default_authority)));
+ grpc_mdelem_from_slices_no_unref(GRPC_MDSTR_AUTHORITY,
+ chand->default_authority));
if (error != GRPC_ERROR_NONE) {
grpc_transport_stream_op_batch_finish_with_failure(batch, error,
calld->call_combiner);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index 2d4b4da4c6..77a0a69393 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -2127,9 +2127,8 @@ void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
GRPC_LOG_IF_ERROR(
"add_status_message",
grpc_chttp2_incoming_metadata_buffer_replace_or_add(
- &s->metadata_buffer[1],
- grpc_mdelem_from_slices(GRPC_MDSTR_GRPC_MESSAGE,
- grpc_slice_ref_internal(slice))));
+ &s->metadata_buffer[1], grpc_mdelem_from_slices_no_unref(
+ GRPC_MDSTR_GRPC_MESSAGE, slice)));
}
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s);
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
index 73946ce039..d97963d891 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
@@ -102,8 +102,7 @@ static grpc_error* process_plugin_result(
} else {
for (size_t i = 0; i < num_md; ++i) {
grpc_mdelem mdelem =
- grpc_mdelem_from_slices(grpc_slice_ref_internal(md[i].key),
- grpc_slice_ref_internal(md[i].value));
+ grpc_mdelem_from_slices_no_unref(md[i].key, md[i].value);
grpc_credentials_mdelem_array_add(r->md_array, mdelem);
GRPC_MDELEM_UNREF(mdelem);
}
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index 4294434504..cd0b3cb458 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -326,20 +326,18 @@ static grpc_call* grpc_channel_create_call_internal(
return call;
}
-grpc_call* grpc_channel_create_call(grpc_channel* channel,
- grpc_call* parent_call,
- uint32_t propagation_mask,
- grpc_completion_queue* cq,
- grpc_slice method, const grpc_slice* host,
- gpr_timespec deadline, void* reserved) {
+grpc_call* grpc_channel_create_call(
+ grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
+ grpc_completion_queue* cq, const grpc_slice& method, const grpc_slice* host,
+ gpr_timespec deadline, void* reserved) {
GPR_ASSERT(!reserved);
grpc_core::ExecCtx exec_ctx;
grpc_call* call = grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, cq, nullptr,
- grpc_mdelem_from_slices(GRPC_MDSTR_PATH, grpc_slice_ref_internal(method)),
- host != nullptr ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
- grpc_slice_ref_internal(*host))
- : GRPC_MDNULL,
+ grpc_mdelem_from_slices_no_unref(GRPC_MDSTR_PATH, method),
+ host != nullptr
+ ? grpc_mdelem_from_slices_no_unref(GRPC_MDSTR_AUTHORITY, *host)
+ : GRPC_MDNULL,
grpc_timespec_to_millis_round_up(deadline));
return call;
@@ -347,15 +345,15 @@ grpc_call* grpc_channel_create_call(grpc_channel* channel,
grpc_call* grpc_channel_create_pollset_set_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
- grpc_pollset_set* pollset_set, grpc_slice method, const grpc_slice* host,
- grpc_millis deadline, void* reserved) {
+ grpc_pollset_set* pollset_set, const grpc_slice& method,
+ const grpc_slice* host, grpc_millis deadline, void* reserved) {
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, nullptr, pollset_set,
- grpc_mdelem_from_slices(GRPC_MDSTR_PATH, grpc_slice_ref_internal(method)),
- host != nullptr ? grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
- grpc_slice_ref_internal(*host))
- : GRPC_MDNULL,
+ grpc_mdelem_from_slices_no_unref(GRPC_MDSTR_PATH, method),
+ host != nullptr
+ ? grpc_mdelem_from_slices_no_unref(GRPC_MDSTR_AUTHORITY, *host)
+ : GRPC_MDNULL,
deadline);
}
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index e5ff2c3596..4ac76b8a29 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -45,8 +45,8 @@ grpc_channel* grpc_channel_create_with_builder(
value of \a propagation_mask (see propagation_bits.h for possible values) */
grpc_call* grpc_channel_create_pollset_set_call(
grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
- grpc_pollset_set* pollset_set, grpc_slice method, const grpc_slice* host,
- grpc_millis deadline, void* reserved);
+ grpc_pollset_set* pollset_set, const grpc_slice& method,
+ const grpc_slice* host, grpc_millis deadline, void* reserved);
/** Get a (borrowed) pointer to this channels underlying channel stack */
grpc_channel_stack* grpc_channel_get_channel_stack(grpc_channel* channel);
diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc
index d164502280..8f84e06fae 100644
--- a/src/core/lib/transport/metadata.cc
+++ b/src/core/lib/transport/metadata.cc
@@ -237,7 +237,7 @@ static void rehash_mdtab(mdtab_shard* shard) {
}
grpc_mdelem grpc_mdelem_create(
- grpc_slice key, grpc_slice value,
+ const grpc_slice& key, const grpc_slice& value,
grpc_mdelem_data* compatible_external_backing_store) {
if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) {
if (compatible_external_backing_store != nullptr) {
@@ -324,13 +324,19 @@ grpc_mdelem grpc_mdelem_create(
return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
}
-grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) {
+grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
+ const grpc_slice& value) {
grpc_mdelem out = grpc_mdelem_create(key, value, nullptr);
grpc_slice_unref_internal(key);
grpc_slice_unref_internal(value);
return out;
}
+grpc_mdelem grpc_mdelem_from_slices_no_unref(const grpc_slice& key,
+ const grpc_slice& value) {
+ return grpc_mdelem_create(key, value, nullptr);
+}
+
grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) {
bool changed = false;
grpc_slice key_slice =
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 338082276c..22481d6824 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -109,7 +109,11 @@ struct grpc_mdelem {
(uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
/* Unrefs the slices. */
-grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value);
+grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
+ const grpc_slice& value);
+/* Does not unref the slices. */
+grpc_mdelem grpc_mdelem_from_slices_no_unref(const grpc_slice& key,
+ const grpc_slice& value);
/* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
object as backing storage (so lifetimes should align) */
@@ -120,7 +124,7 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata);
compatible_external_backing_store if it is non-NULL (in which case it's the
users responsibility to ensure that it outlives usage) */
grpc_mdelem grpc_mdelem_create(
- grpc_slice key, grpc_slice value,
+ const grpc_slice& key, const grpc_slice& value,
grpc_mdelem_data* compatible_external_backing_store);
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);