diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index 6ab00612f6e660b82d56039650f6fc80af2a84de..1d5117925709bf762182113cf3c74262b4eb7925 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -45,6 +45,7 @@
 #include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/serialization_traits.h>
+#include <grpc++/impl/codegen/slice.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/status_helper.h>
 #include <grpc++/impl/codegen/string_ref.h>
@@ -68,8 +69,8 @@ inline void FillMetadataMap(
   for (size_t i = 0; i < arr->count; i++) {
     // TODO(yangg) handle duplicates?
     metadata->insert(std::pair<grpc::string_ref, grpc::string_ref>(
-        arr->metadata[i].key, grpc::string_ref(arr->metadata[i].value,
-                                               arr->metadata[i].value_length)));
+        StringRefFromSlice(arr->metadata[i].key),
+        StringRefFromSlice(arr->metadata[i].value)));
   }
   g_core_codegen_interface->grpc_metadata_array_destroy(arr);
   g_core_codegen_interface->grpc_metadata_array_init(arr);
@@ -87,9 +88,8 @@ inline grpc_metadata* FillMetadataArray(
           metadata.size() * sizeof(grpc_metadata)));
   size_t i = 0;
   for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
-    metadata_array[i].key = iter->first.c_str();
-    metadata_array[i].value = iter->second.c_str();
-    metadata_array[i].value_length = iter->second.size();
+    metadata_array[i].key = SliceReferencingString(iter->first);
+    metadata_array[i].value = SliceReferencingString(iter->second);
   }
   return metadata_array;
 }
@@ -451,8 +451,9 @@ class CallOpServerSendStatus {
         trailing_metadata_count_;
     op->data.send_status_from_server.trailing_metadata = trailing_metadata_;
     op->data.send_status_from_server.status = send_status_code_;
+    grpc_slice status_details = SliceReferencingString(send_status_details_);
     op->data.send_status_from_server.status_details =
-        send_status_details_.empty() ? nullptr : send_status_details_.c_str();
+        send_status_details_.empty() ? nullptr : &status_details;
     op->flags = 0;
     op->reserved = NULL;
   }
@@ -515,16 +516,12 @@ class CallOpClientRecvStatus {
     if (recv_status_ == nullptr) return;
     memset(&recv_trailing_metadata_arr_, 0,
            sizeof(recv_trailing_metadata_arr_));
-    status_details_ = nullptr;
-    status_details_capacity_ = 0;
     grpc_op* op = &ops[(*nops)++];
     op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
     op->data.recv_status_on_client.trailing_metadata =
         &recv_trailing_metadata_arr_;
     op->data.recv_status_on_client.status = &status_code_;
     op->data.recv_status_on_client.status_details = &status_details_;
-    op->data.recv_status_on_client.status_details_capacity =
-        &status_details_capacity_;
     op->flags = 0;
     op->reserved = NULL;
   }
@@ -532,10 +529,10 @@ class CallOpClientRecvStatus {
   void FinishOp(bool* status, int max_receive_message_size) {
     if (recv_status_ == nullptr) return;
     FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_);
-    *recv_status_ = Status(
-        static_cast<StatusCode>(status_code_),
-        status_details_ ? grpc::string(status_details_) : grpc::string());
-    g_core_codegen_interface->gpr_free(status_details_);
+    *recv_status_ = Status(static_cast<StatusCode>(status_code_),
+                           grpc::string(GRPC_SLICE_START_PTR(status_details_),
+                                        GRPC_SLICE_END_PTR(status_details_)));
+    g_core_codegen_interface->grpc_slice_unref(status_details_);
     recv_status_ = nullptr;
   }
 
@@ -544,8 +541,7 @@ class CallOpClientRecvStatus {
   Status* recv_status_;
   grpc_metadata_array recv_trailing_metadata_arr_;
   grpc_status_code status_code_;
-  char* status_details_;
-  size_t status_details_capacity_;
+  grpc_slice status_details_;
 };
 
 /// An abstract collection of CallOpSet's, to be used whenever
diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
index 6b5e637e4e2ce7bd7ba6d2689483fac36908ce73..b5ab26154e2f7af684539a3b941391ce081125ea 100644
--- a/include/grpc++/impl/codegen/core_codegen.h
+++ b/include/grpc++/impl/codegen/core_codegen.h
@@ -81,7 +81,10 @@ class CoreCodegen : public CoreCodegenInterface {
   grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) override;
   void grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice) override;
   void grpc_slice_buffer_pop(grpc_slice_buffer* sb) override;
-
+  grpc_slice grpc_slice_from_static_buffer(const void* buffer,
+                                           size_t length) override;
+  grpc_slice grpc_slice_from_copied_buffer(const void* buffer,
+                                           size_t length) override;
   void grpc_metadata_array_init(grpc_metadata_array* array) override;
   void grpc_metadata_array_destroy(grpc_metadata_array* array) override;
 
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index 4783a43454fe64f1ce84f87e795e2aa70d6c88e4..9c1af972b3c399922154747edfd618dca2f8f58f 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -99,6 +99,10 @@ class CoreCodegenInterface {
   virtual void grpc_slice_buffer_add(grpc_slice_buffer* sb,
                                      grpc_slice slice) = 0;
   virtual void grpc_slice_buffer_pop(grpc_slice_buffer* sb) = 0;
+  virtual grpc_slice grpc_slice_from_static_buffer(const void* buffer,
+                                                   size_t length) = 0;
+  virtual grpc_slice grpc_slice_from_copied_buffer(const void* buffer,
+                                                   size_t length) = 0;
 
   virtual void grpc_metadata_array_init(grpc_metadata_array* array) = 0;
   virtual void grpc_metadata_array_destroy(grpc_metadata_array* array) = 0;
diff --git a/include/grpc++/impl/codegen/slice.h b/include/grpc++/impl/codegen/slice.h
new file mode 100644
index 0000000000000000000000000000000000000000..7280698978898560b03fcb9a74da4819f30fe9a5
--- /dev/null
+++ b/include/grpc++/impl/codegen/slice.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_SLICE_H
+#define GRPCXX_IMPL_CODEGEN_SLICE_H
+
+#include <grpc++/impl/codegen/core_codegen_interface.h>
+#include <grpc++/impl/codegen/string_ref.h>
+
+namespace grpc {
+
+inline grpc::string_ref StringRefFromSlice(grpc_slice slice) {
+  return grpc::string_ref(reinterpret_cast<char*>(GRPC_SLICE_START_PTR(slice)),
+                          GRPC_SLICE_LENGTH(slice));
+}
+
+inline grpc_slice SliceReferencingString(const grpc::string& str) {
+  return g_core_codegen_interface->grpc_slice_from_static_buffer(str.data(),
+                                                                 str.length());
+}
+
+inline grpc_slice SliceFromCopiedString(const grpc::string& str) {
+  return g_core_codegen_interface->grpc_slice_from_copied_buffer(str.data(),
+                                                                 str.length());
+}
+
+}  // namespace grpc
+
+#endif
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index 357d8317adfc8eed1744d7e9221396f918778c9f..c985183ae7600022d36bef593547202772ff76d8 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -107,10 +107,20 @@ Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
     } else if (!host_.empty()) {
       host_str = host_.c_str();
     }
-    c_call = grpc_channel_create_call(c_channel_, context->propagate_from_call_,
-                                      context->propagation_options_.c_bitmask(),
-                                      cq->cq(), method.name(), host_str,
-                                      context->raw_deadline(), nullptr);
+    grpc_slice method_slice = SliceFromCopiedString(method.name());
+    grpc_slice host_slice;
+    if (host_str != nullptr) {
+      host_slice = SliceFromCopiedString(host_str);
+    }
+    c_call = grpc_channel_create_call(
+        c_channel_, context->propagate_from_call_,
+        context->propagation_options_.c_bitmask(), cq->cq(), method_slice,
+        host_str == nullptr ? nullptr : &host_slice, context->raw_deadline(),
+        nullptr);
+    grpc_slice_unref(method_slice);
+    if (host_str != nullptr) {
+      grpc_slice_unref(host_slice);
+    }
   }
   grpc_census_call_set_context(c_call, context->census_context());
   context->set_call(c_call, shared_from_this());
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 269c523bba12304ae20c82b1a790eec2cf3846b2..21445c91fd86348a629f2aeab155e6548050b477 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -206,9 +206,8 @@ void MetadataCredentialsPluginWrapper::InvokePlugin(
   std::vector<grpc_metadata> md;
   for (auto it = metadata.begin(); it != metadata.end(); ++it) {
     grpc_metadata md_entry;
-    md_entry.key = it->first.c_str();
-    md_entry.value = it->second.data();
-    md_entry.value_length = it->second.size();
+    md_entry.key = SliceReferencingString(it->first);
+    md_entry.value = SliceReferencingString(it->second);
     md_entry.flags = 0;
     md.push_back(md_entry);
   }
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index a07ad54376956573a64cff0048cbb566989ae337..36c8938c95bff912c2134391a623cf039b6b299a 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -123,6 +123,16 @@ grpc_slice CoreCodegen::grpc_slice_split_tail(grpc_slice* s, size_t split) {
   return ::grpc_slice_split_tail(s, split);
 }
 
+grpc_slice CoreCodegen::grpc_slice_from_static_buffer(const void* buffer,
+                                                      size_t length) {
+  return ::grpc_slice_from_static_buffer(buffer, length);
+}
+
+grpc_slice CoreCodegen::grpc_slice_from_copied_buffer(const void* buffer,
+                                                      size_t length) {
+  return ::grpc_slice_from_copied_buffer(buffer, length);
+}
+
 void CoreCodegen::grpc_slice_buffer_add(grpc_slice_buffer* sb,
                                         grpc_slice slice) {
   ::grpc_slice_buffer_add(sb, slice);
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index 33bdc2a1f4f1ca6f8a74e803c43cbecb55b8b14a..3c90986cd055b4eb7ec1b85751089a278ac50474 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -35,11 +35,12 @@
 #include <map>
 #include <memory>
 
+#include <grpc++/impl/codegen/slice.h>
+#include <grpc++/security/auth_metadata_processor.h>
+
 #include "src/cpp/common/secure_auth_context.h"
 #include "src/cpp/server/secure_server_credentials.h"
 
-#include <grpc++/security/auth_metadata_processor.h>
-
 namespace grpc {
 
 void AuthMetadataProcessorAyncWrapper::Destroy(void* wrapper) {
@@ -71,8 +72,8 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor(
     grpc_process_auth_metadata_done_cb cb, void* user_data) {
   AuthMetadataProcessor::InputMetadata metadata;
   for (size_t i = 0; i < num_md; i++) {
-    metadata.insert(std::make_pair(
-        md[i].key, grpc::string_ref(md[i].value, md[i].value_length)));
+    metadata.insert(std::make_pair(StringRefFromSlice(md[i].key),
+                                   StringRefFromSlice(md[i].value)));
   }
   SecureAuthContext context(ctx, false);
   AuthMetadataProcessor::OutputMetadata consumed_metadata;
@@ -85,9 +86,8 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor(
   for (auto it = consumed_metadata.begin(); it != consumed_metadata.end();
        ++it) {
     grpc_metadata md_entry;
-    md_entry.key = it->first.c_str();
-    md_entry.value = it->second.data();
-    md_entry.value_length = it->second.size();
+    md_entry.key = SliceReferencingString(it->first);
+    md_entry.value = SliceReferencingString(it->second);
     md_entry.flags = 0;
     consumed_md.push_back(md_entry);
   }
@@ -95,9 +95,8 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor(
   for (auto it = response_metadata.begin(); it != response_metadata.end();
        ++it) {
     grpc_metadata md_entry;
-    md_entry.key = it->first.c_str();
-    md_entry.value = it->second.data();
-    md_entry.value_length = it->second.size();
+    md_entry.key = SliceReferencingString(it->first);
+    md_entry.value = SliceReferencingString(it->second);
     md_entry.flags = 0;
     response_md.push_back(md_entry);
   }