Merge github.com:grpc/grpc into slice_with_exec_ctx
diff --git a/BUILD b/BUILD
index fb81cf6..34bbbe8 100644
--- a/BUILD
+++ b/BUILD
@@ -231,6 +231,7 @@
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -558,6 +559,7 @@
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
@@ -670,6 +672,7 @@
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -955,6 +958,7 @@
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
@@ -1062,6 +1066,7 @@
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -1337,6 +1342,7 @@
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
@@ -1493,6 +1499,7 @@
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
@@ -1625,6 +1632,7 @@
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
@@ -1956,6 +1964,7 @@
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
@@ -2133,6 +2142,7 @@
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
@@ -2563,6 +2573,7 @@
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/exec_ctx_fwd.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
@@ -2654,6 +2665,7 @@
     "src/core/lib/json/json_reader.h",
     "src/core/lib/json/json_writer.h",
     "src/core/lib/slice/percent_encoding.h",
+    "src/core/lib/slice/slice_internal.h",
     "src/core/lib/slice/slice_string_helpers.h",
     "src/core/lib/surface/api_trace.h",
     "src/core/lib/surface/call.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 16e5d62..220a8dd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -531,6 +531,7 @@
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/compression_types.h
   include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
   include/grpc/impl/codegen/status.h
@@ -783,6 +784,7 @@
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/compression_types.h
   include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
   include/grpc/impl/codegen/status.h
@@ -1035,6 +1037,7 @@
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/compression_types.h
   include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
   include/grpc/impl/codegen/status.h
@@ -1199,6 +1202,7 @@
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/compression_types.h
   include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
   include/grpc/impl/codegen/status.h
@@ -1533,6 +1537,7 @@
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/compression_types.h
   include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
   include/grpc/impl/codegen/status.h
@@ -1740,6 +1745,7 @@
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/compression_types.h
   include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/exec_ctx_fwd.h
   include/grpc/impl/codegen/grpc_types.h
   include/grpc/impl/codegen/propagation_bits.h
   include/grpc/impl/codegen/status.h
diff --git a/Makefile b/Makefile
index 3a228b4..a7a1cab 100644
--- a/Makefile
+++ b/Makefile
@@ -2853,6 +2853,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
@@ -3124,6 +3125,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
@@ -3341,6 +3343,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
@@ -3632,6 +3635,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
@@ -3877,6 +3881,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
@@ -4240,6 +4245,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
@@ -4596,6 +4602,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
@@ -4775,6 +4782,7 @@
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/exec_ctx_fwd.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
diff --git a/build.yaml b/build.yaml
index 2555abc..289f2a8 100644
--- a/build.yaml
+++ b/build.yaml
@@ -238,6 +238,7 @@
   - src/core/lib/json/json_reader.h
   - src/core/lib/json/json_writer.h
   - src/core/lib/slice/percent_encoding.h
+  - src/core/lib/slice/slice_internal.h
   - src/core/lib/slice/slice_string_helpers.h
   - src/core/lib/surface/api_trace.h
   - src/core/lib/surface/call.h
@@ -422,6 +423,7 @@
   - include/grpc/impl/codegen/byte_buffer_reader.h
   - include/grpc/impl/codegen/compression_types.h
   - include/grpc/impl/codegen/connectivity_state.h
+  - include/grpc/impl/codegen/exec_ctx_fwd.h
   - include/grpc/impl/codegen/grpc_types.h
   - include/grpc/impl/codegen/propagation_bits.h
   - include/grpc/impl/codegen/status.h
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index f9e0164..ddcd34d 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -166,6 +166,7 @@
                       'include/grpc/impl/codegen/byte_buffer_reader.h',
                       'include/grpc/impl/codegen/compression_types.h',
                       'include/grpc/impl/codegen/connectivity_state.h',
+                      'include/grpc/impl/codegen/exec_ctx_fwd.h',
                       'include/grpc/impl/codegen/grpc_types.h',
                       'include/grpc/impl/codegen/propagation_bits.h',
                       'include/grpc/impl/codegen/status.h',
@@ -321,6 +322,7 @@
                       'src/core/lib/json/json_reader.h',
                       'src/core/lib/json/json_writer.h',
                       'src/core/lib/slice/percent_encoding.h',
+                      'src/core/lib/slice/slice_internal.h',
                       'src/core/lib/slice/slice_string_helpers.h',
                       'src/core/lib/surface/api_trace.h',
                       'src/core/lib/surface/call.h',
@@ -728,6 +730,7 @@
                               'src/core/lib/json/json_reader.h',
                               'src/core/lib/json/json_writer.h',
                               'src/core/lib/slice/percent_encoding.h',
+                              'src/core/lib/slice/slice_internal.h',
                               'src/core/lib/slice/slice_string_helpers.h',
                               'src/core/lib/surface/api_trace.h',
                               'src/core/lib/surface/call.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 9c9568c..317b6cc 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -149,6 +149,7 @@
   s.files += %w( include/grpc/impl/codegen/byte_buffer_reader.h )
   s.files += %w( include/grpc/impl/codegen/compression_types.h )
   s.files += %w( include/grpc/impl/codegen/connectivity_state.h )
+  s.files += %w( include/grpc/impl/codegen/exec_ctx_fwd.h )
   s.files += %w( include/grpc/impl/codegen/grpc_types.h )
   s.files += %w( include/grpc/impl/codegen/propagation_bits.h )
   s.files += %w( include/grpc/impl/codegen/status.h )
@@ -240,6 +241,7 @@
   s.files += %w( src/core/lib/json/json_reader.h )
   s.files += %w( src/core/lib/json/json_writer.h )
   s.files += %w( src/core/lib/slice/percent_encoding.h )
+  s.files += %w( src/core/lib/slice/slice_internal.h )
   s.files += %w( src/core/lib/slice/slice_string_helpers.h )
   s.files += %w( src/core/lib/surface/api_trace.h )
   s.files += %w( src/core/lib/surface/call.h )
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index 571ab5d..d43f7c6 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -127,7 +127,7 @@
   /// Default pointer argument operations.
   struct PointerVtableMembers {
     static void* Copy(void* in) { return in; }
-    static void Destroy(void* in) {}
+    static void Destroy(grpc_exec_ctx* exec_ctx, void* in) {}
     static int Compare(void* a, void* b) {
       if (a < b) return -1;
       if (a > b) return 1;
diff --git a/include/grpc/impl/codegen/exec_ctx_fwd.h b/include/grpc/impl/codegen/exec_ctx_fwd.h
new file mode 100644
index 0000000..32edced
--- /dev/null
+++ b/include/grpc/impl/codegen/exec_ctx_fwd.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2016, 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 GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
+#define GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
+
+/* forward declaration for exec_ctx.h */
+struct grpc_exec_ctx;
+typedef struct grpc_exec_ctx grpc_exec_ctx;
+
+#endif /* GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H */
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index da1bd9d..4307559 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -34,10 +34,10 @@
 #ifndef GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 #define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <grpc/impl/codegen/gpr_types.h>
 #include <grpc/impl/codegen/slice.h>
-
-#include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/status.h>
 
 #include <stddef.h>
@@ -96,7 +96,7 @@
 
 typedef struct grpc_arg_pointer_vtable {
   void *(*copy)(void *p);
-  void (*destroy)(void *p);
+  void (*destroy)(grpc_exec_ctx *exec_ctx, void *p);
   int (*cmp)(void *p, void *q);
 } grpc_arg_pointer_vtable;
 
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index 50b5426..00781bb 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -37,6 +37,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <grpc/impl/codegen/gpr_slice.h>
 
 /* Slice API
@@ -59,7 +60,7 @@
    grpc_slice_new, or grpc_slice_new_with_len instead. */
 typedef struct grpc_slice_refcount {
   void (*ref)(void *);
-  void (*unref)(void *);
+  void (*unref)(grpc_exec_ctx *exec_ctx, void *);
 } grpc_slice_refcount;
 
 #define GRPC_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
diff --git a/package.xml b/package.xml
index 2106b8f..c35cf40 100644
--- a/package.xml
+++ b/package.xml
@@ -157,6 +157,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer_reader.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/compression_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/connectivity_state.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/exec_ctx_fwd.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/grpc_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/propagation_bits.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/status.h" role="src" />
@@ -248,6 +249,7 @@
     <file baseinstalldir="/" name="src/core/lib/json/json_reader.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/json/json_writer.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" />
diff --git a/src/core/ext/census/grpc_plugin.c b/src/core/ext/census/grpc_plugin.c
index e43ceaf..c9fe453 100644
--- a/src/core/ext/census/grpc_plugin.c
+++ b/src/core/ext/census/grpc_plugin.c
@@ -51,7 +51,8 @@
   return census_enabled();
 }
 
-static bool maybe_add_census_filter(grpc_channel_stack_builder *builder,
+static bool maybe_add_census_filter(grpc_exec_ctx *exec_ctx,
+                                    grpc_channel_stack_builder *builder,
                                     void *arg) {
   const grpc_channel_args *args =
       grpc_channel_stack_builder_get_channel_arguments(builder);
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 4b3d895..f80d655 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -82,8 +82,12 @@
   return new_value;
 }
 
+static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *p) {
+  gpr_free(p);
+}
+
 static const grpc_mdstr_hash_table_vtable method_parameters_vtable = {
-    gpr_free, method_parameters_copy};
+    method_parameters_free, method_parameters_copy};
 
 static void *method_parameters_create_from_json(const grpc_json *json) {
   wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET;
@@ -326,7 +330,7 @@
           grpc_service_config_create(service_config_json);
       if (service_config != NULL) {
         method_params_table = grpc_service_config_create_method_config_table(
-            service_config, method_parameters_create_from_json,
+            exec_ctx, service_config, method_parameters_create_from_json,
             &method_parameters_vtable);
         grpc_service_config_destroy(service_config);
       }
@@ -335,7 +339,7 @@
     // be pointing to data inside chand->resolver_result.
     // The copy will be saved in chand->lb_policy_name below.
     lb_policy_name = gpr_strdup(lb_policy_name);
-    grpc_channel_args_destroy(chand->resolver_result);
+    grpc_channel_args_destroy(exec_ctx, chand->resolver_result);
     chand->resolver_result = NULL;
   }
 
@@ -356,7 +360,7 @@
     chand->service_config_json = service_config_json;
   }
   if (chand->method_params_table != NULL) {
-    grpc_mdstr_hash_table_unref(chand->method_params_table);
+    grpc_mdstr_hash_table_unref(exec_ctx, chand->method_params_table);
   }
   chand->method_params_table = method_params_table;
   if (lb_policy != NULL) {
@@ -540,7 +544,7 @@
   gpr_free(chand->lb_policy_name);
   gpr_free(chand->service_config_json);
   if (chand->method_params_table != NULL) {
-    grpc_mdstr_hash_table_unref(chand->method_params_table);
+    grpc_mdstr_hash_table_unref(exec_ctx, chand->method_params_table);
   }
   grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
   grpc_pollset_set_destroy(chand->interested_parties);
@@ -985,8 +989,8 @@
     gpr_mu_unlock(&chand->mu);
     // If the method config table was present, use it.
     if (method_params_table != NULL) {
-      const method_parameters *method_params =
-          grpc_method_config_table_get(method_params_table, calld->path);
+      const method_parameters *method_params = grpc_method_config_table_get(
+          exec_ctx, method_params_table, calld->path);
       if (method_params != NULL) {
         const bool have_method_timeout =
             gpr_time_cmp(method_params->timeout, gpr_time_0(GPR_TIMESPAN)) != 0;
@@ -1009,7 +1013,7 @@
           gpr_mu_unlock(&calld->mu);
         }
       }
-      grpc_mdstr_hash_table_unref(method_params_table);
+      grpc_mdstr_hash_table_unref(exec_ctx, method_params_table);
     }
   }
   GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config");
@@ -1050,8 +1054,8 @@
       grpc_mdstr_hash_table *method_params_table =
           grpc_mdstr_hash_table_ref(chand->method_params_table);
       gpr_mu_unlock(&chand->mu);
-      method_parameters *method_params =
-          grpc_method_config_table_get(method_params_table, args->path);
+      method_parameters *method_params = grpc_method_config_table_get(
+          exec_ctx, method_params_table, args->path);
       if (method_params != NULL) {
         if (gpr_time_cmp(method_params->timeout,
                          gpr_time_0(GPR_CLOCK_MONOTONIC)) != 0) {
@@ -1064,7 +1068,7 @@
               method_params->wait_for_ready;
         }
       }
-      grpc_mdstr_hash_table_unref(method_params_table);
+      grpc_mdstr_hash_table_unref(exec_ctx, method_params_table);
     } else {
       gpr_mu_unlock(&chand->mu);
     }
@@ -1092,7 +1096,7 @@
                                  void *and_free_memory) {
   call_data *calld = elem->call_data;
   grpc_deadline_state_destroy(exec_ctx, elem);
-  GRPC_MDSTR_UNREF(calld->path);
+  GRPC_MDSTR_UNREF(exec_ctx, calld->path);
   GRPC_ERROR_UNREF(calld->cancel_error);
   grpc_subchannel_call *call = GET_CALL(calld);
   if (call != NULL && call != CANCELLED_CALL) {
diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c
index a3e5079..988b7a1 100644
--- a/src/core/ext/client_channel/client_channel_plugin.c
+++ b/src/core/ext/client_channel/client_channel_plugin.c
@@ -43,12 +43,14 @@
 #include "src/core/ext/client_channel/subchannel_index.h"
 #include "src/core/lib/surface/channel_init.h"
 
-static bool append_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool append_filter(grpc_exec_ctx *exec_ctx,
+                          grpc_channel_stack_builder *builder, void *arg) {
   return grpc_channel_stack_builder_append_filter(
       builder, (const grpc_channel_filter *)arg, NULL, NULL);
 }
 
-static bool set_default_host_if_unset(grpc_channel_stack_builder *builder,
+static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
+                                      grpc_channel_stack_builder *builder,
                                       void *unused) {
   const grpc_channel_args *args =
       grpc_channel_stack_builder_get_channel_arguments(builder);
@@ -66,9 +68,10 @@
     arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
     arg.value.string = default_authority;
     grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
-    grpc_channel_stack_builder_set_channel_arguments(builder, new_args);
+    grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
+                                                     new_args);
     gpr_free(default_authority);
-    grpc_channel_args_destroy(new_args);
+    grpc_channel_args_destroy(exec_ctx, new_args);
   }
   return true;
 }
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 572af52..1e198cb 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/http/format_request.h"
 #include "src/core/lib/http/parser.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/env.h"
 
 typedef struct http_connect_handshaker {
@@ -82,12 +83,13 @@
       grpc_endpoint_destroy(exec_ctx, handshaker->endpoint_to_destroy);
     }
     if (handshaker->read_buffer_to_destroy != NULL) {
-      grpc_slice_buffer_destroy(handshaker->read_buffer_to_destroy);
+      grpc_slice_buffer_destroy_internal(exec_ctx,
+                                         handshaker->read_buffer_to_destroy);
       gpr_free(handshaker->read_buffer_to_destroy);
     }
     gpr_free(handshaker->proxy_server);
     gpr_free(handshaker->server_name);
-    grpc_slice_buffer_destroy(&handshaker->write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer);
     grpc_http_parser_destroy(&handshaker->http_parser);
     grpc_http_response_destroy(&handshaker->http_response);
     gpr_free(handshaker);
@@ -97,12 +99,12 @@
 // Set args fields to NULL, saving the endpoint and read buffer for
 // later destruction.
 static void cleanup_args_for_failure_locked(
-    http_connect_handshaker* handshaker) {
+    grpc_exec_ctx* exec_ctx, http_connect_handshaker* handshaker) {
   handshaker->endpoint_to_destroy = handshaker->args->endpoint;
   handshaker->args->endpoint = NULL;
   handshaker->read_buffer_to_destroy = handshaker->args->read_buffer;
   handshaker->args->read_buffer = NULL;
-  grpc_channel_args_destroy(handshaker->args->args);
+  grpc_channel_args_destroy(exec_ctx, handshaker->args->args);
   handshaker->args->args = NULL;
 }
 
@@ -125,7 +127,7 @@
     grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint);
     // Not shutting down, so the handshake failed.  Clean up before
     // invoking the callback.
-    cleanup_args_for_failure_locked(handshaker);
+    cleanup_args_for_failure_locked(exec_ctx, handshaker);
     // Set shutdown to true so that subsequent calls to
     // http_connect_handshaker_shutdown() do nothing.
     handshaker->shutdown = true;
@@ -193,7 +195,7 @@
                                &handshaker->args->read_buffer->slices[i + 1],
                                handshaker->args->read_buffer->count - i - 1);
         grpc_slice_buffer_swap(handshaker->args->read_buffer, &tmp_buffer);
-        grpc_slice_buffer_destroy(&tmp_buffer);
+        grpc_slice_buffer_destroy_internal(exec_ctx, &tmp_buffer);
         break;
       }
     }
@@ -210,7 +212,8 @@
   // complete (e.g., handling chunked transfer encoding or looking
   // at the Content-Length: header).
   if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
-    grpc_slice_buffer_reset_and_unref(handshaker->args->read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                               handshaker->args->read_buffer);
     grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
                        handshaker->args->read_buffer,
                        &handshaker->response_read_closure);
@@ -255,7 +258,7 @@
   if (!handshaker->shutdown) {
     handshaker->shutdown = true;
     grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint);
-    cleanup_args_for_failure_locked(handshaker);
+    cleanup_args_for_failure_locked(exec_ctx, handshaker);
   }
   gpr_mu_unlock(&handshaker->mu);
 }
diff --git a/src/core/ext/client_channel/lb_policy_factory.c b/src/core/ext/client_channel/lb_policy_factory.c
index 8a474c8..7af9bb0 100644
--- a/src/core/ext/client_channel/lb_policy_factory.c
+++ b/src/core/ext/client_channel/lb_policy_factory.c
@@ -112,11 +112,13 @@
   return 0;
 }
 
-void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) {
+void grpc_lb_addresses_destroy(grpc_exec_ctx* exec_ctx,
+                               grpc_lb_addresses* addresses) {
   for (size_t i = 0; i < addresses->num_addresses; ++i) {
     gpr_free(addresses->addresses[i].balancer_name);
     if (addresses->addresses[i].user_data != NULL) {
-      addresses->user_data_vtable->destroy(addresses->addresses[i].user_data);
+      addresses->user_data_vtable->destroy(exec_ctx,
+                                           addresses->addresses[i].user_data);
     }
   }
   gpr_free(addresses->addresses);
@@ -126,8 +128,8 @@
 static void* lb_addresses_copy(void* addresses) {
   return grpc_lb_addresses_copy(addresses);
 }
-static void lb_addresses_destroy(void* addresses) {
-  grpc_lb_addresses_destroy(addresses);
+static void lb_addresses_destroy(grpc_exec_ctx* exec_ctx, void* addresses) {
+  grpc_lb_addresses_destroy(exec_ctx, addresses);
 }
 static int lb_addresses_cmp(void* addresses1, void* addresses2) {
   return grpc_lb_addresses_cmp(addresses1, addresses2);
diff --git a/src/core/ext/client_channel/lb_policy_factory.h b/src/core/ext/client_channel/lb_policy_factory.h
index e2b8080..ceee3ef 100644
--- a/src/core/ext/client_channel/lb_policy_factory.h
+++ b/src/core/ext/client_channel/lb_policy_factory.h
@@ -61,7 +61,7 @@
 
 typedef struct grpc_lb_user_data_vtable {
   void *(*copy)(void *);
-  void (*destroy)(void *);
+  void (*destroy)(grpc_exec_ctx *exec_ctx, void *);
   int (*cmp)(void *, void *);
 } grpc_lb_user_data_vtable;
 
@@ -93,7 +93,8 @@
                           const grpc_lb_addresses *addresses2);
 
 /** Destroys \a addresses. */
-void grpc_lb_addresses_destroy(grpc_lb_addresses *addresses);
+void grpc_lb_addresses_destroy(grpc_exec_ctx *exec_ctx,
+                               grpc_lb_addresses *addresses);
 
 /** Returns a channel arg containing \a addresses. */
 grpc_arg grpc_lb_addresses_create_channel_arg(
diff --git a/src/core/ext/client_channel/resolver_factory.c b/src/core/ext/client_channel/resolver_factory.c
index 7c3d644..00bbb92 100644
--- a/src/core/ext/client_channel/resolver_factory.c
+++ b/src/core/ext/client_channel/resolver_factory.c
@@ -43,9 +43,10 @@
 
 /** Create a resolver instance for a name */
 grpc_resolver* grpc_resolver_factory_create_resolver(
-    grpc_resolver_factory* factory, grpc_resolver_args* args) {
+    grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
+    grpc_resolver_args* args) {
   if (factory == NULL) return NULL;
-  return factory->vtable->create_resolver(factory, args);
+  return factory->vtable->create_resolver(exec_ctx, factory, args);
 }
 
 char* grpc_resolver_factory_get_default_authority(
diff --git a/src/core/ext/client_channel/resolver_factory.h b/src/core/ext/client_channel/resolver_factory.h
index 4da42e8..76b1f45 100644
--- a/src/core/ext/client_channel/resolver_factory.h
+++ b/src/core/ext/client_channel/resolver_factory.h
@@ -55,7 +55,8 @@
   void (*unref)(grpc_resolver_factory *factory);
 
   /** Implementation of grpc_resolver_factory_create_resolver */
-  grpc_resolver *(*create_resolver)(grpc_resolver_factory *factory,
+  grpc_resolver *(*create_resolver)(grpc_exec_ctx *exec_ctx,
+                                    grpc_resolver_factory *factory,
                                     grpc_resolver_args *args);
 
   /** Implementation of grpc_resolver_factory_get_default_authority */
@@ -70,7 +71,8 @@
 
 /** Create a resolver instance for a name */
 grpc_resolver *grpc_resolver_factory_create_resolver(
-    grpc_resolver_factory *factory, grpc_resolver_args *args);
+    grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+    grpc_resolver_args *args);
 
 /** Return a (freshly allocated with gpr_malloc) string representing
     the default authority to use for this scheme. */
diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/client_channel/resolver_registry.c
index d0f0fc3..9feba14 100644
--- a/src/core/ext/client_channel/resolver_registry.c
+++ b/src/core/ext/client_channel/resolver_registry.c
@@ -131,7 +131,7 @@
   return factory;
 }
 
-grpc_resolver *grpc_resolver_create(const char *target,
+grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
                                     const grpc_channel_args *args) {
   grpc_uri *uri = NULL;
   grpc_resolver_factory *factory = resolve_factory(target, &uri);
@@ -140,7 +140,8 @@
   memset(&resolver_args, 0, sizeof(resolver_args));
   resolver_args.uri = uri;
   resolver_args.args = args;
-  resolver = grpc_resolver_factory_create_resolver(factory, &resolver_args);
+  resolver =
+      grpc_resolver_factory_create_resolver(exec_ctx, factory, &resolver_args);
   grpc_uri_destroy(uri);
   return resolver;
 }
diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h
index 2a95a66..4f6aba0 100644
--- a/src/core/ext/client_channel/resolver_registry.h
+++ b/src/core/ext/client_channel/resolver_registry.h
@@ -60,7 +60,7 @@
     If a resolver factory was not found, return NULL.
     \a args is a set of channel arguments to be included in the result
     (typically the set of arguments passed in from the client API). */
-grpc_resolver *grpc_resolver_create(const char *target,
+grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
                                     const grpc_channel_args *args);
 
 /** Find a resolver factory given a name and return an (owned-by-the-caller)
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index 0863207..05d2db8 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -46,6 +46,7 @@
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/backoff.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/channel_init.h"
@@ -206,9 +207,9 @@
                                grpc_error *error) {
   grpc_subchannel *c = arg;
   gpr_free((void *)c->filters);
-  grpc_channel_args_destroy(c->args);
+  grpc_channel_args_destroy(exec_ctx, c->args);
   gpr_free(c->addr);
-  grpc_slice_unref(c->initial_connect_string);
+  grpc_slice_unref_internal(exec_ctx, c->initial_connect_string);
   grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
   grpc_connector_unref(exec_ctx, c->connector);
   grpc_pollset_set_destroy(c->pollset_set);
@@ -600,7 +601,7 @@
   /* construct channel stack */
   grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
   grpc_channel_stack_builder_set_channel_arguments(
-      builder, c->connecting_result.channel_args);
+      exec_ctx, builder, c->connecting_result.channel_args);
   grpc_channel_stack_builder_set_transport(builder,
                                            c->connecting_result.transport);
 
@@ -609,7 +610,7 @@
     con = grpc_channel_stack_builder_finish(exec_ctx, builder, 0, 1,
                                             connection_destroy, NULL);
   } else {
-    grpc_channel_stack_builder_destroy(builder);
+    grpc_channel_stack_builder_destroy(exec_ctx, builder);
     abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
   }
   stk = CHANNEL_STACK_FROM_CONNECTION(con);
@@ -680,7 +681,7 @@
   }
   gpr_mu_unlock(&c->mu);
   GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connected");
-  grpc_channel_args_destroy(delete_channel_args);
+  grpc_channel_args_destroy(exec_ctx, delete_channel_args);
 }
 
 /*
diff --git a/src/core/ext/client_channel/subchannel_index.c b/src/core/ext/client_channel/subchannel_index.c
index 227013a..25fdfcf 100644
--- a/src/core/ext/client_channel/subchannel_index.c
+++ b/src/core/ext/client_channel/subchannel_index.c
@@ -131,7 +131,7 @@
                                  grpc_subchannel_key *k) {
   grpc_connector_unref(exec_ctx, k->connector);
   gpr_free((grpc_channel_args *)k->args.filters);
-  grpc_channel_args_destroy((grpc_channel_args *)k->args.args);
+  grpc_channel_args_destroy(exec_ctx, (grpc_channel_args *)k->args.args);
   gpr_free((void *)k->args.server_name);
   gpr_free(k->args.addr);
   gpr_free(k);
diff --git a/src/core/ext/client_channel/uri_parser.c b/src/core/ext/client_channel/uri_parser.c
index 0fbc542..f8c946b 100644
--- a/src/core/ext/client_channel/uri_parser.c
+++ b/src/core/ext/client_channel/uri_parser.c
@@ -42,7 +42,6 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
 /** a size_t default value... maps to all 1's */
@@ -138,7 +137,6 @@
   return 1;
 }
 
-static void do_nothing(void *ignored) {}
 static void parse_query_parts(grpc_uri *uri) {
   static const char *QUERY_PARTS_SEPARATOR = "&";
   static const char *QUERY_PARTS_VALUE_SEPARATOR = "=";
@@ -149,38 +147,32 @@
     uri->num_query_parts = 0;
     return;
   }
-  grpc_slice query_slice =
-      grpc_slice_new(uri->query, strlen(uri->query), do_nothing);
-  grpc_slice_buffer query_parts; /* the &-separated elements of the query */
-  grpc_slice_buffer query_param_parts; /* the =-separated subelements */
 
-  grpc_slice_buffer_init(&query_parts);
-  grpc_slice_buffer_init(&query_param_parts);
-
-  grpc_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts);
-  uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *));
-  uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *));
-  uri->num_query_parts = query_parts.count;
-  for (size_t i = 0; i < query_parts.count; i++) {
-    grpc_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR,
-                     &query_param_parts);
-    GPR_ASSERT(query_param_parts.count > 0);
-    uri->query_parts[i] =
-        grpc_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII);
-    if (query_param_parts.count > 1) {
+  gpr_string_split(uri->query, QUERY_PARTS_SEPARATOR, &uri->query_parts,
+                   &uri->num_query_parts);
+  uri->query_parts_values = gpr_malloc(uri->num_query_parts * sizeof(char **));
+  for (size_t i = 0; i < uri->num_query_parts; i++) {
+    char **query_param_parts;
+    size_t num_query_param_parts;
+    char *full = uri->query_parts[i];
+    gpr_string_split(full, QUERY_PARTS_VALUE_SEPARATOR, &query_param_parts,
+                     &num_query_param_parts);
+    GPR_ASSERT(num_query_param_parts > 0);
+    uri->query_parts[i] = query_param_parts[0];
+    if (num_query_param_parts > 1) {
       /* TODO(dgq): only the first value after the separator is considered.
        * Perhaps all chars after the first separator for the query part should
        * be included, even if they include the separator. */
-      uri->query_parts_values[i] =
-          grpc_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII);
+      uri->query_parts_values[i] = query_param_parts[1];
     } else {
       uri->query_parts_values[i] = NULL;
     }
-    grpc_slice_buffer_reset_and_unref(&query_param_parts);
+    for (size_t j = 2; j < num_query_param_parts; j++) {
+      gpr_free(query_param_parts[j]);
+    }
+    gpr_free(query_param_parts);
+    gpr_free(full);
   }
-  grpc_slice_buffer_destroy(&query_parts);
-  grpc_slice_buffer_destroy(&query_param_parts);
-  grpc_slice_unref(query_slice);
 }
 
 grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index df0db61..47a3ecd 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -116,6 +116,7 @@
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/backoff.h"
 #include "src/core/lib/support/string.h"
@@ -384,8 +385,8 @@
 static void *lb_token_copy(void *token) {
   return token == NULL ? NULL : GRPC_MDELEM_REF(token);
 }
-static void lb_token_destroy(void *token) {
-  if (token != NULL) GRPC_MDELEM_UNREF(token);
+static void lb_token_destroy(grpc_exec_ctx *exec_ctx, void *token) {
+  if (token != NULL) GRPC_MDELEM_UNREF(exec_ctx, token);
 }
 static int lb_token_cmp(void *token1, void *token2) {
   if (token1 > token2) return 1;
@@ -419,7 +420,7 @@
 
 /* Returns addresses extracted from \a serverlist. */
 static grpc_lb_addresses *process_serverlist_locked(
-    const grpc_grpclb_serverlist *serverlist) {
+    grpc_exec_ctx *exec_ctx, const grpc_grpclb_serverlist *serverlist) {
   size_t num_valid = 0;
   /* first pass: count how many are valid in order to allocate the necessary
    * memory in a single block */
@@ -455,8 +456,8 @@
           strnlen(server->load_balance_token, lb_token_max_length);
       grpc_mdstr *lb_token_mdstr = grpc_mdstr_from_buffer(
           (uint8_t *)server->load_balance_token, lb_token_length);
-      user_data = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_LB_TOKEN,
-                                                    lb_token_mdstr);
+      user_data = grpc_mdelem_from_metadata_strings(
+          exec_ctx, GRPC_MDSTR_LB_TOKEN, lb_token_mdstr);
     } else {
       char *uri = grpc_sockaddr_to_uri(&addr);
       gpr_log(GPR_INFO,
@@ -579,7 +580,8 @@
   grpc_lb_policy_args args;
   memset(&args, 0, sizeof(args));
   args.client_channel_factory = glb_policy->cc_factory;
-  grpc_lb_addresses *addresses = process_serverlist_locked(serverlist);
+  grpc_lb_addresses *addresses =
+      process_serverlist_locked(exec_ctx, serverlist);
 
   // Replace the LB addresses in the channel args that we pass down to
   // the subchannel.
@@ -591,8 +593,8 @@
 
   grpc_lb_policy *rr = grpc_lb_policy_create(exec_ctx, "round_robin", &args);
   GPR_ASSERT(rr != NULL);
-  grpc_lb_addresses_destroy(addresses);
-  grpc_channel_args_destroy(args.args);
+  grpc_lb_addresses_destroy(exec_ctx, addresses);
+  grpc_channel_args_destroy(exec_ctx, args.args);
   return rr;
 }
 
@@ -826,7 +828,7 @@
   glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
       exec_ctx, glb_policy->cc_factory, target_uri_str,
       GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
-  grpc_channel_args_destroy(new_args);
+  grpc_channel_args_destroy(exec_ctx, new_args);
 
   gpr_free(target_uri_str);
   for (size_t i = 0; i < num_grpclb_addrs; i++) {
@@ -852,7 +854,7 @@
   GPR_ASSERT(glb_policy->pending_picks == NULL);
   GPR_ASSERT(glb_policy->pending_pings == NULL);
   gpr_free((void *)glb_policy->server_name);
-  grpc_channel_args_destroy(glb_policy->args);
+  grpc_channel_args_destroy(exec_ctx, glb_policy->args);
   grpc_channel_destroy(glb_policy->lb_channel);
   glb_policy->lb_channel = NULL;
   grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker);
@@ -1075,7 +1077,8 @@
                                          grpc_error *error);
 static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
                                     grpc_error *error);
-static void lb_call_init_locked(glb_lb_policy *glb_policy) {
+static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
+                                glb_lb_policy *glb_policy) {
   GPR_ASSERT(glb_policy->server_name != NULL);
   GPR_ASSERT(glb_policy->server_name[0] != '\0');
   GPR_ASSERT(!glb_policy->shutting_down);
@@ -1084,7 +1087,7 @@
    * glb_policy->base.interested_parties, which is comprised of the polling
    * entities from \a client_channel. */
   glb_policy->lb_call = grpc_channel_create_pollset_set_call(
-      glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
+      exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
       glb_policy->base.interested_parties,
       "/grpc.lb.v1.LoadBalancer/BalanceLoad", glb_policy->server_name,
       glb_policy->deadline, NULL);
@@ -1097,7 +1100,7 @@
   grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
   glb_policy->lb_request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  grpc_slice_unref(request_payload_slice);
+  grpc_slice_unref_internal(exec_ctx, request_payload_slice);
   grpc_grpclb_request_destroy(request);
 
   glb_policy->lb_call_status_details = NULL;
@@ -1136,7 +1139,7 @@
   GPR_ASSERT(glb_policy->lb_channel != NULL);
   if (glb_policy->shutting_down) return;
 
-  lb_call_init_locked(glb_policy);
+  lb_call_init_locked(exec_ctx, glb_policy);
 
   if (grpc_lb_glb_trace) {
     gpr_log(GPR_INFO, "Query for backends (grpclb: %p, lb_call: %p)",
@@ -1221,7 +1224,7 @@
         grpc_grpclb_response_parse_serverlist(response_slice);
     if (serverlist != NULL) {
       GPR_ASSERT(glb_policy->lb_call != NULL);
-      grpc_slice_unref(response_slice);
+      grpc_slice_unref_internal(exec_ctx, response_slice);
       if (grpc_lb_glb_trace) {
         gpr_log(GPR_INFO, "Serverlist with %lu servers received",
                 (unsigned long)serverlist->num_servers);
@@ -1265,7 +1268,7 @@
     } else { /* serverlist == NULL */
       gpr_log(GPR_ERROR, "Invalid LB response received: '%s'. Ignoring.",
               grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
-      grpc_slice_unref(response_slice);
+      grpc_slice_unref_internal(exec_ctx, response_slice);
     }
 
     if (!glb_policy->shutting_down) {
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 59f8405..f93dd07 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -284,7 +284,7 @@
     GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "rr_destroy");
     if (sd->user_data != NULL) {
       GPR_ASSERT(sd->user_data_vtable != NULL);
-      sd->user_data_vtable->destroy(sd->user_data);
+      sd->user_data_vtable->destroy(exec_ctx, sd->user_data);
     }
     gpr_free(sd);
   }
diff --git a/src/core/ext/load_reporting/load_reporting.c b/src/core/ext/load_reporting/load_reporting.c
index df1ea0e..37b06a7 100644
--- a/src/core/ext/load_reporting/load_reporting.c
+++ b/src/core/ext/load_reporting/load_reporting.c
@@ -53,7 +53,8 @@
   return false;
 }
 
-static bool maybe_add_load_reporting_filter(grpc_channel_stack_builder *builder,
+static bool maybe_add_load_reporting_filter(grpc_exec_ctx *exec_ctx,
+                                            grpc_channel_stack_builder *builder,
                                             void *arg) {
   const grpc_channel_args *args =
       grpc_channel_stack_builder_get_channel_arguments(builder);
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index b810e20..f50e652 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -68,7 +68,8 @@
   grpc_exec_ctx *exec_ctx;
 } recv_md_filter_args;
 
-static grpc_mdelem *recv_md_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem *recv_md_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+                                   grpc_mdelem *md) {
   recv_md_filter_args *a = user_data;
   grpc_call_element *elem = a->elem;
   call_data *calld = elem->call_data;
@@ -92,8 +93,8 @@
     recv_md_filter_args a;
     a.elem = elem;
     a.exec_ctx = exec_ctx;
-    grpc_metadata_batch_filter(calld->recv_initial_metadata, recv_md_filter,
-                               &a);
+    grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+                               recv_md_filter, &a);
     if (calld->service_method == NULL) {
       err =
           grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header"));
@@ -189,7 +190,8 @@
   */
 }
 
-static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem *lr_trailing_md_filter(grpc_exec_ctx *exec_ctx,
+                                          void *user_data, grpc_mdelem *md) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
 
@@ -213,7 +215,7 @@
     calld->ops_recv_initial_metadata_ready = op->recv_initial_metadata_ready;
     op->recv_initial_metadata_ready = &calld->on_initial_md_ready;
   } else if (op->send_trailing_metadata) {
-    grpc_metadata_batch_filter(op->send_trailing_metadata,
+    grpc_metadata_batch_filter(exec_ctx, op->send_trailing_metadata,
                                lr_trailing_md_filter, elem);
   }
   grpc_call_next_op(exec_ctx, elem, op);
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 15476f5..9247f83 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -180,7 +180,7 @@
     grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
     result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
     grpc_resolved_addresses_destroy(r->addresses);
-    grpc_lb_addresses_destroy(addresses);
+    grpc_lb_addresses_destroy(exec_ctx, addresses);
   } else {
     gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
     gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
@@ -201,7 +201,7 @@
                     now);
   }
   if (r->resolved_result != NULL) {
-    grpc_channel_args_destroy(r->resolved_result);
+    grpc_channel_args_destroy(exec_ctx, r->resolved_result);
   }
   r->resolved_result = result;
   r->resolved_version++;
@@ -238,11 +238,11 @@
   dns_resolver *r = (dns_resolver *)gr;
   gpr_mu_destroy(&r->mu);
   if (r->resolved_result != NULL) {
-    grpc_channel_args_destroy(r->resolved_result);
+    grpc_channel_args_destroy(exec_ctx, r->resolved_result);
   }
   gpr_free(r->name_to_resolve);
   gpr_free(r->default_port);
-  grpc_channel_args_destroy(r->channel_args);
+  grpc_channel_args_destroy(exec_ctx, r->channel_args);
   gpr_free(r);
 }
 
@@ -287,7 +287,8 @@
 static void dns_factory_unref(grpc_resolver_factory *factory) {}
 
 static grpc_resolver *dns_factory_create_resolver(
-    grpc_resolver_factory *factory, grpc_resolver_args *args) {
+    grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+    grpc_resolver_args *args) {
   return dns_create(args, "https");
 }
 
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 26a650a..55f8c07 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -47,6 +47,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
@@ -131,8 +132,8 @@
 static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   sockaddr_resolver *r = (sockaddr_resolver *)gr;
   gpr_mu_destroy(&r->mu);
-  grpc_lb_addresses_destroy(r->addresses);
-  grpc_channel_args_destroy(r->channel_args);
+  grpc_lb_addresses_destroy(exec_ctx, r->addresses);
+  grpc_channel_args_destroy(exec_ctx, r->channel_args);
   gpr_free(r);
 }
 
@@ -161,7 +162,8 @@
 
 static void do_nothing(void *ignored) {}
 
-static grpc_resolver *sockaddr_create(grpc_resolver_args *args,
+static grpc_resolver *sockaddr_create(grpc_exec_ctx *exec_ctx,
+                                      grpc_resolver_args *args,
                                       int parse(grpc_uri *uri,
                                                 grpc_resolved_address *dst)) {
   if (0 != strcmp(args->uri->authority, "")) {
@@ -188,10 +190,10 @@
     gpr_free(part_str);
     if (errors_found) break;
   }
-  grpc_slice_buffer_destroy(&path_parts);
-  grpc_slice_unref(path_slice);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
+  grpc_slice_unref_internal(exec_ctx, path_slice);
   if (errors_found) {
-    grpc_lb_addresses_destroy(addresses);
+    grpc_lb_addresses_destroy(exec_ctx, addresses);
     return NULL;
   }
   /* Instantiate resolver. */
@@ -219,8 +221,9 @@
 
 #define DECL_FACTORY(name)                                                  \
   static grpc_resolver *name##_factory_create_resolver(                     \
-      grpc_resolver_factory *factory, grpc_resolver_args *args) {           \
-    return sockaddr_create(args, parse_##name);                             \
+      grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,              \
+      grpc_resolver_args *args) {                                           \
+    return sockaddr_create(exec_ctx, args, parse_##name);                   \
   }                                                                         \
   static const grpc_resolver_factory_vtable name##_factory_vtable = {       \
       sockaddr_factory_ref, sockaddr_factory_unref,                         \
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index 58a6877..d48ec7c 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -48,6 +48,7 @@
 #include "src/core/lib/channel/handshaker.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 typedef struct {
   grpc_connector base;
@@ -126,8 +127,8 @@
       // point this can be removed.
       grpc_endpoint_shutdown(exec_ctx, args->endpoint);
       grpc_endpoint_destroy(exec_ctx, args->endpoint);
-      grpc_channel_args_destroy(args->args);
-      grpc_slice_buffer_destroy(args->read_buffer);
+      grpc_channel_args_destroy(exec_ctx, args->args);
+      grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer);
       gpr_free(args->read_buffer);
     } else {
       error = GRPC_ERROR_REF(error);
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 89501c5..5c70034 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -67,7 +67,7 @@
     const grpc_channel_args *args) {
   grpc_channel *channel =
       grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
-  grpc_resolver *resolver = grpc_resolver_create(target, args);
+  grpc_resolver *resolver = grpc_resolver_create(exec_ctx, target, args);
   if (resolver == NULL) {
     GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
                                 "client_channel_factory_create_channel");
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
index 1e5b1c2..f1069e2 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
@@ -74,7 +74,7 @@
   GPR_ASSERT(transport);
   grpc_channel *channel = grpc_channel_create(
       &exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
-  grpc_channel_args_destroy(final_args);
+  grpc_channel_args_destroy(&exec_ctx, final_args);
   grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);
 
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 4bce3ba..dffa283 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -63,7 +63,7 @@
     grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
   client_channel_factory *f = (client_channel_factory *)cc_factory;
   if (gpr_unref(&f->refs)) {
-    GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
+    GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &f->security_connector->base,
                                   "client_channel_factory");
     gpr_free(f);
   }
@@ -93,7 +93,7 @@
   client_channel_factory *f = (client_channel_factory *)cc_factory;
   grpc_channel *channel =
       grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
-  grpc_resolver *resolver = grpc_resolver_create(target, args);
+  grpc_resolver *resolver = grpc_resolver_create(exec_ctx, target, args);
   if (resolver == NULL) {
     GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
                                 "client_channel_factory_create_channel");
@@ -136,8 +136,8 @@
   grpc_channel_security_connector *security_connector;
   grpc_channel_args *new_args_from_connector;
   if (grpc_channel_credentials_create_security_connector(
-          creds, target, args, &security_connector, &new_args_from_connector) !=
-      GRPC_SECURITY_OK) {
+          &exec_ctx, creds, target, args, &security_connector,
+          &new_args_from_connector) != GRPC_SECURITY_OK) {
     grpc_exec_ctx_finish(&exec_ctx);
     return grpc_lame_client_channel_create(
         target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
@@ -148,7 +148,7 @@
       new_args_from_connector != NULL ? new_args_from_connector : args,
       &connector_arg, 1);
   if (new_args_from_connector != NULL) {
-    grpc_channel_args_destroy(new_args_from_connector);
+    grpc_channel_args_destroy(&exec_ctx, new_args_from_connector);
   }
   // Create client channel factory.
   client_channel_factory *f = gpr_malloc(sizeof(*f));
@@ -162,9 +162,9 @@
   grpc_channel *channel = client_channel_factory_create_channel(
       &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
   // Clean up.
-  GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
+  GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &f->security_connector->base,
                                 "secure_client_channel_factory_create_channel");
-  grpc_channel_args_destroy(new_args);
+  grpc_channel_args_destroy(&exec_ctx, new_args);
   grpc_client_channel_factory_unref(&exec_ctx, &f->base);
   grpc_exec_ctx_finish(&exec_ctx);
   return channel; /* may be NULL */
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
index f085771..30bdcd8 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.c
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -50,6 +50,7 @@
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/tcp_server.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/server.h"
 
@@ -148,8 +149,8 @@
       // point this can be removed.
       grpc_endpoint_shutdown(exec_ctx, args->endpoint);
       grpc_endpoint_destroy(exec_ctx, args->endpoint);
-      grpc_channel_args_destroy(args->args);
-      grpc_slice_buffer_destroy(args->read_buffer);
+      grpc_channel_args_destroy(exec_ctx, args->args);
+      grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer);
       gpr_free(args->read_buffer);
     }
   } else {
@@ -238,7 +239,7 @@
     destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error));
     grpc_exec_ctx_flush(exec_ctx);
   }
-  grpc_channel_args_destroy(state->args);
+  grpc_channel_args_destroy(exec_ctx, state->args);
   gpr_mu_destroy(&state->mu);
   gpr_free(state);
 }
@@ -345,7 +346,7 @@
   if (tcp_server) {
     grpc_tcp_server_unref(exec_ctx, tcp_server);
   } else {
-    grpc_channel_args_destroy(args);
+    grpc_channel_args_destroy(exec_ctx, args);
     grpc_chttp2_server_handshaker_factory_destroy(exec_ctx, handshaker_factory);
     gpr_free(state);
   }
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
index aa2ecf5..f46e849 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
@@ -62,7 +62,7 @@
   grpc_endpoint *server_endpoint =
       grpc_tcp_create(grpc_fd_create(fd, name), resource_quota,
                       GRPC_TCP_DEFAULT_READ_SLICE_SIZE, name);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   gpr_free(name);
 
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index a33a7a3..b5e4996 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -67,8 +67,8 @@
     grpc_exec_ctx *exec_ctx, grpc_chttp2_server_handshaker_factory *hf) {
   server_security_handshaker_factory *handshaker_factory =
       (server_security_handshaker_factory *)hf;
-  GRPC_SECURITY_CONNECTOR_UNREF(&handshaker_factory->security_connector->base,
-                                "server");
+  GRPC_SECURITY_CONNECTOR_UNREF(
+      exec_ctx, &handshaker_factory->security_connector->base, "server");
   gpr_free(hf);
 }
 
@@ -94,7 +94,7 @@
     goto done;
   }
   grpc_security_status status =
-      grpc_server_credentials_create_security_connector(creds, &sc);
+      grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc);
   if (status != GRPC_SECURITY_OK) {
     char *msg;
     gpr_asprintf(&msg,
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.c b/src/core/ext/transport/chttp2/transport/bin_decoder.c
index 3eef80b..8db36e4 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.c
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.c
@@ -34,6 +34,7 @@
 #include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
@@ -143,7 +144,8 @@
   return true;
 }
 
-grpc_slice grpc_chttp2_base64_decode(grpc_slice input) {
+grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx,
+                                     grpc_slice input) {
   size_t input_length = GRPC_SLICE_LENGTH(input);
   size_t output_length = input_length / 4 * 3;
   struct grpc_base64_decode_context ctx;
@@ -179,7 +181,7 @@
     char *s = grpc_dump_slice(input, GPR_DUMP_ASCII);
     gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
     gpr_free(s);
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
   GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
@@ -187,7 +189,8 @@
   return output;
 }
 
-grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
+grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+                                                 grpc_slice input,
                                                  size_t output_length) {
   size_t input_length = GRPC_SLICE_LENGTH(input);
   grpc_slice output = grpc_slice_malloc(output_length);
@@ -200,7 +203,7 @@
             "grpc_chttp2_base64_decode_with_length has a length of %d, which "
             "has a tail of 1 byte.\n",
             (int)input_length);
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
 
@@ -210,7 +213,7 @@
             "than the max possible output length %d.\n",
             (int)output_length,
             (int)(input_length / 4 * 3 + tail_xtra[input_length % 4]));
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
 
@@ -224,7 +227,7 @@
     char *s = grpc_dump_slice(input, GPR_DUMP_ASCII);
     gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
     gpr_free(s);
-    grpc_slice_unref(output);
+    grpc_slice_unref_internal(exec_ctx, output);
     return gpr_empty_slice();
   }
   GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h
index 83a90be..48ffb2a 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h
@@ -55,12 +55,13 @@
 
 /* base64 decode a slice with pad chars. Returns a new slice, does not take
    ownership of the input. Returns an empty slice if decoding is failed. */
-grpc_slice grpc_chttp2_base64_decode(grpc_slice input);
+grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx, grpc_slice input);
 
 /* base64 decode a slice without pad chars, data length is needed. Returns a new
    slice, does not take ownership of the input. Returns an empty slice if
    decoding is failed. */
-grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
+grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+                                                 grpc_slice input,
                                                  size_t output_length);
 
 #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */
diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h
index 9e143b4..477559d 100644
--- a/src/core/ext/transport/chttp2/transport/bin_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h
@@ -47,7 +47,7 @@
 /* equivalent to:
    grpc_slice x = grpc_chttp2_base64_encode(input);
    grpc_slice y = grpc_chttp2_huffman_compress(x);
-   grpc_slice_unref(x);
+   grpc_slice_unref_internal(exec_ctx, x);
    return y; */
 grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl(
     grpc_slice input);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 6bc0548..5c1a1db 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -51,6 +51,7 @@
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/workqueue.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
@@ -141,13 +142,13 @@
 
   grpc_endpoint_destroy(exec_ctx, t->ep);
 
-  grpc_slice_buffer_destroy(&t->qbuf);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &t->qbuf);
 
-  grpc_slice_buffer_destroy(&t->outbuf);
-  grpc_chttp2_hpack_compressor_destroy(&t->hpack_compressor);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &t->outbuf);
+  grpc_chttp2_hpack_compressor_destroy(exec_ctx, &t->hpack_compressor);
 
-  grpc_slice_buffer_destroy(&t->read_buffer);
-  grpc_chttp2_hpack_parser_destroy(&t->hpack_parser);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &t->read_buffer);
+  grpc_chttp2_hpack_parser_destroy(exec_ctx, &t->hpack_parser);
   grpc_chttp2_goaway_parser_destroy(&t->goaway_parser);
 
   for (i = 0; i < STREAM_LIST_COUNT; i++) {
@@ -260,7 +261,7 @@
                     destructive_reclaimer_locked, t);
 
   grpc_chttp2_goaway_parser_init(&t->goaway_parser);
-  grpc_chttp2_hpack_parser_init(&t->hpack_parser);
+  grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser);
 
   grpc_slice_buffer_init(&t->read_buffer);
 
@@ -527,9 +528,11 @@
   GPR_ASSERT(s->recv_message_ready == NULL);
   GPR_ASSERT(s->recv_trailing_metadata_finished == NULL);
   grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser);
-  grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[0]);
-  grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[1]);
-  grpc_slice_buffer_destroy(&s->flow_controlled_buffer);
+  grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
+                                               &s->metadata_buffer[0]);
+  grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
+                                               &s->metadata_buffer[1]);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer);
   GRPC_ERROR_UNREF(s->read_closed_error);
   GRPC_ERROR_UNREF(s->write_closed_error);
 
@@ -760,7 +763,7 @@
   char *msg = grpc_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
   GRPC_CHTTP2_IF_TRACING(
       gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
-  grpc_slice_unref(goaway_text);
+  grpc_slice_unref_internal(exec_ctx, goaway_text);
   t->seen_goaway = 1;
   /* lie: use transient failure from the transport to indicate goaway has been
    * received */
@@ -1285,7 +1288,7 @@
   if (op->send_goaway) {
     send_goaway(exec_ctx, t,
                 grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
-                grpc_slice_ref(*op->goaway_message));
+                grpc_slice_ref_internal(*op->goaway_message));
   }
 
   if (op->set_accept_stream) {
@@ -1515,21 +1518,22 @@
     char status_string[GPR_LTOA_MIN_BUFSIZE];
     gpr_ltoa(status, status_string);
     grpc_chttp2_incoming_metadata_buffer_add(
-        &s->metadata_buffer[1],
-        grpc_mdelem_from_metadata_strings(
-            GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string)));
+        &s->metadata_buffer[1], grpc_mdelem_from_metadata_strings(
+                                    exec_ctx, GRPC_MDSTR_GRPC_STATUS,
+                                    grpc_mdstr_from_string(status_string)));
     if (slice) {
       grpc_chttp2_incoming_metadata_buffer_add(
           &s->metadata_buffer[1],
           grpc_mdelem_from_metadata_strings(
-              GRPC_MDSTR_GRPC_MESSAGE,
-              grpc_mdstr_from_slice(grpc_slice_ref(*slice))));
+              exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+              grpc_mdstr_from_slice(exec_ctx,
+                                    grpc_slice_ref_internal(*slice))));
     }
     s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
     grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
   }
   if (slice) {
-    grpc_slice_unref(*slice);
+    grpc_slice_unref_internal(exec_ctx, *slice);
   }
 }
 
@@ -1910,7 +1914,7 @@
     keep_reading = true;
     GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading");
   }
-  grpc_slice_buffer_reset_and_unref(&t->read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->read_buffer);
 
   if (keep_reading) {
     grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->read_action_begin);
@@ -1964,7 +1968,7 @@
                                        grpc_chttp2_incoming_byte_stream *bs) {
   if (gpr_unref(&bs->refs)) {
     GRPC_ERROR_UNREF(bs->error);
-    grpc_slice_buffer_destroy(&bs->slices);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices);
     gpr_mu_destroy(&bs->slice_mu);
     gpr_free(bs);
   }
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index eb68fe3..49a8326 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -48,6 +48,7 @@
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
 #include "src/core/ext/transport/chttp2/transport/hpack_table.h"
 #include "src/core/ext/transport/chttp2/transport/varint.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/transport/metadata.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/timeout_encoding.h"
@@ -183,7 +184,8 @@
 }
 
 /* add an element to the decoder table */
-static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
+static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
+                     grpc_mdelem *elem) {
   uint32_t key_hash = elem->key->hash;
   uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
   uint32_t new_index = c->tail_remote_index + c->table_elems + 1;
@@ -227,12 +229,12 @@
   } 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(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
+    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(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
+    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;
   }
@@ -251,11 +253,11 @@
     c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
   } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] <
              c->indices_keys[HASH_FRAGMENT_3(key_hash)]) {
-    GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
+    GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
     c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key);
     c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
   } else {
-    GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
+    GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
     c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key);
     c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
   }
@@ -294,7 +296,7 @@
                            add_tiny_header_data(st, len_pfx), len_pfx);
   GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c,
@@ -311,7 +313,7 @@
                            add_tiny_header_data(st, len_pfx), len_pfx);
   GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
@@ -327,10 +329,10 @@
   *add_tiny_header_data(st, 1) = 0x40;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
-  add_header_data(st, grpc_slice_ref(elem->key->slice));
+  add_header_data(st, grpc_slice_ref_internal(elem->key->slice));
   GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
@@ -346,10 +348,10 @@
   *add_tiny_header_data(st, 1) = 0x00;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
-  add_header_data(st, grpc_slice_ref(elem->key->slice));
+  add_header_data(st, grpc_slice_ref_internal(elem->key->slice));
   GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
                            add_tiny_header_data(st, len_val_len), len_val_len);
-  add_header_data(st, grpc_slice_ref(value_slice));
+  add_header_data(st, grpc_slice_ref_internal(value_slice));
 }
 
 static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c,
@@ -366,8 +368,8 @@
 }
 
 /* encode an mdelem */
-static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
-                      framer_state *st) {
+static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
+                      grpc_mdelem *elem, framer_state *st) {
   uint32_t key_hash = elem->key->hash;
   uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
   size_t decoder_space_usage;
@@ -417,7 +419,7 @@
     /* HIT: key (first cuckoo hash) */
     if (should_add_elem) {
       emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st);
-      add_elem(c, elem);
+      add_elem(exec_ctx, c, elem);
       return;
     } else {
       emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
@@ -432,7 +434,7 @@
     /* HIT: key (first cuckoo hash) */
     if (should_add_elem) {
       emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st);
-      add_elem(c, elem);
+      add_elem(exec_ctx, c, elem);
       return;
     } else {
       emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
@@ -445,7 +447,7 @@
 
   if (should_add_elem) {
     emit_lithdr_incidx_v(c, elem, st);
-    add_elem(c, elem);
+    add_elem(exec_ctx, c, elem);
     return;
   } else {
     emit_lithdr_noidx_v(c, elem, st);
@@ -457,16 +459,17 @@
 #define STRLEN_LIT(x) (sizeof(x) - 1)
 #define TIMEOUT_KEY "grpc-timeout"
 
-static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
+static void deadline_enc(grpc_exec_ctx *exec_ctx,
+                         grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
                          framer_state *st) {
   char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];
   grpc_mdelem *mdelem;
   grpc_http2_encode_timeout(
       gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
   mdelem = grpc_mdelem_from_metadata_strings(
-      GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str));
-  hpack_enc(c, mdelem, st);
-  GRPC_MDELEM_UNREF(mdelem);
+      exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str));
+  hpack_enc(exec_ctx, c, mdelem, st);
+  GRPC_MDELEM_UNREF(exec_ctx, mdelem);
 }
 
 static uint32_t elems_for_bytes(uint32_t bytes) { return (bytes + 31) / 32; }
@@ -483,11 +486,12 @@
          sizeof(*c->table_elem_size) * c->cap_table_elems);
 }
 
-void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
+void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx *exec_ctx,
+                                          grpc_chttp2_hpack_compressor *c) {
   int i;
   for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) {
-    if (c->entries_keys[i]) GRPC_MDSTR_UNREF(c->entries_keys[i]);
-    if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]);
+    if (c->entries_keys[i]) GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[i]);
+    if (c->entries_elems[i]) GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[i]);
   }
   gpr_free(c->table_elem_size);
 }
@@ -542,7 +546,8 @@
   }
 }
 
-void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
+void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
+                               grpc_chttp2_hpack_compressor *c,
                                uint32_t stream_id,
                                grpc_metadata_batch *metadata, int is_eof,
                                size_t max_frame_size,
@@ -571,11 +576,11 @@
   }
   grpc_metadata_batch_assert_ok(metadata);
   for (l = metadata->list.head; l; l = l->next) {
-    hpack_enc(c, l->md, &st);
+    hpack_enc(exec_ctx, c, l->md, &st);
   }
   deadline = metadata->deadline;
   if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) != 0) {
-    deadline_enc(c, deadline, &st);
+    deadline_enc(exec_ctx, c, deadline, &st);
   }
 
   finish_frame(&st, 1, is_eof);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index bcbd675..3a35496 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -83,13 +83,15 @@
 } grpc_chttp2_hpack_compressor;
 
 void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c);
-void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c);
+void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx *exec_ctx,
+                                          grpc_chttp2_hpack_compressor *c);
 void grpc_chttp2_hpack_compressor_set_max_table_size(
     grpc_chttp2_hpack_compressor *c, uint32_t max_table_size);
 void grpc_chttp2_hpack_compressor_set_max_usable_size(
     grpc_chttp2_hpack_compressor *c, uint32_t max_table_size);
 
-void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id,
+void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
+                               grpc_chttp2_hpack_compressor *c, uint32_t id,
                                grpc_metadata_batch *metadata, int is_eof,
                                size_t max_frame_size,
                                grpc_transport_one_way_stats *stats,
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 6a9200b..f4e69df 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -670,11 +670,11 @@
 static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p,
                           grpc_mdelem *md, int add_to_table) {
   if (add_to_table) {
-    grpc_error *err = grpc_chttp2_hptbl_add(&p->table, md);
+    grpc_error *err = grpc_chttp2_hptbl_add(exec_ctx, &p->table, md);
     if (err != GRPC_ERROR_NONE) return err;
   }
   if (p->on_header == NULL) {
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(exec_ctx, md);
     return GRPC_ERROR_CREATE("on_header callback not set");
   }
   p->on_header(exec_ctx, p->on_header_user_data, md);
@@ -815,10 +815,10 @@
                                         const uint8_t *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   GPR_ASSERT(md != NULL); /* handled in string parsing */
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
-                                                     take_string(p, &p->value)),
-      1);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, GRPC_MDSTR_REF(md->key),
+                                            take_string(p, &p->value)),
+                           1);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -828,10 +828,10 @@
                                           grpc_chttp2_hpack_parser *p,
                                           const uint8_t *cur,
                                           const uint8_t *end) {
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
-                                                     take_string(p, &p->value)),
-      1);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, take_string(p, &p->key),
+                                            take_string(p, &p->value)),
+                           1);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -883,10 +883,10 @@
                                         const uint8_t *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   GPR_ASSERT(md != NULL); /* handled in string parsing */
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, GRPC_MDSTR_REF(md->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -896,10 +896,10 @@
                                           grpc_chttp2_hpack_parser *p,
                                           const uint8_t *cur,
                                           const uint8_t *end) {
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, take_string(p, &p->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -951,10 +951,10 @@
                                         const uint8_t *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
   GPR_ASSERT(md != NULL); /* handled in string parsing */
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, GRPC_MDSTR_REF(md->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -964,10 +964,10 @@
                                           grpc_chttp2_hpack_parser *p,
                                           const uint8_t *cur,
                                           const uint8_t *end) {
-  grpc_error *err = on_hdr(
-      exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
-                                                     take_string(p, &p->value)),
-      0);
+  grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings(
+                                            exec_ctx, take_string(p, &p->key),
+                                            take_string(p, &p->value)),
+                           0);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -1020,7 +1020,7 @@
     gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index);
   }
   grpc_error *err =
-      grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index);
+      grpc_chttp2_hptbl_set_current_table_size(exec_ctx, &p->table, p->index);
   if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
   return parse_begin(exec_ctx, p, cur, end);
 }
@@ -1534,7 +1534,8 @@
 
 /* PUBLIC INTERFACE */
 
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
+void grpc_chttp2_hpack_parser_init(grpc_exec_ctx *exec_ctx,
+                                   grpc_chttp2_hpack_parser *p) {
   p->on_header = NULL;
   p->on_header_user_data = NULL;
   p->state = parse_begin;
@@ -1546,7 +1547,7 @@
   p->value.length = 0;
   p->dynamic_table_update_allowed = 2;
   p->last_error = GRPC_ERROR_NONE;
-  grpc_chttp2_hptbl_init(&p->table);
+  grpc_chttp2_hptbl_init(exec_ctx, &p->table);
 }
 
 void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
@@ -1554,8 +1555,9 @@
   p->state = parse_stream_dep0;
 }
 
-void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) {
-  grpc_chttp2_hptbl_destroy(&p->table);
+void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx *exec_ctx,
+                                      grpc_chttp2_hpack_parser *p) {
+  grpc_chttp2_hptbl_destroy(exec_ctx, &p->table);
   GRPC_ERROR_UNREF(p->last_error);
   gpr_free(p->key.str);
   gpr_free(p->value.str);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h
index a39bf46..52ccf1e 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h
@@ -99,8 +99,10 @@
   grpc_chttp2_hptbl table;
 };
 
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p);
-void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p);
+void grpc_chttp2_hpack_parser_init(grpc_exec_ctx *exec_ctx,
+                                   grpc_chttp2_hpack_parser *p);
+void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx *exec_ctx,
+                                      grpc_chttp2_hpack_parser *p);
 
 void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p);
 
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c
index 2dc793d..26d4036 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.c
@@ -179,7 +179,7 @@
          GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
 }
 
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) {
+void grpc_chttp2_hptbl_init(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) {
   size_t i;
 
   memset(tbl, 0, sizeof(*tbl));
@@ -190,18 +190,20 @@
   tbl->ents = gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries);
   memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries);
   for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
-    tbl->static_ents[i - 1] =
-        grpc_mdelem_from_strings(static_table[i].key, static_table[i].value);
+    tbl->static_ents[i - 1] = grpc_mdelem_from_strings(
+        exec_ctx, static_table[i].key, static_table[i].value);
   }
 }
 
-void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl) {
+void grpc_chttp2_hptbl_destroy(grpc_exec_ctx *exec_ctx,
+                               grpc_chttp2_hptbl *tbl) {
   size_t i;
   for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
-    GRPC_MDELEM_UNREF(tbl->static_ents[i]);
+    GRPC_MDELEM_UNREF(exec_ctx, tbl->static_ents[i]);
   }
   for (i = 0; i < tbl->num_ents; i++) {
-    GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
+    GRPC_MDELEM_UNREF(exec_ctx,
+                      tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
   }
   gpr_free(tbl->ents);
 }
@@ -224,7 +226,7 @@
 }
 
 /* Evict one element from the table */
-static void evict1(grpc_chttp2_hptbl *tbl) {
+static void evict1(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) {
   grpc_mdelem *first_ent = tbl->ents[tbl->first_ent];
   size_t elem_bytes = GRPC_SLICE_LENGTH(first_ent->key->slice) +
                       GRPC_SLICE_LENGTH(first_ent->value->slice) +
@@ -233,7 +235,7 @@
   tbl->mem_used -= (uint32_t)elem_bytes;
   tbl->first_ent = ((tbl->first_ent + 1) % tbl->cap_entries);
   tbl->num_ents--;
-  GRPC_MDELEM_UNREF(first_ent);
+  GRPC_MDELEM_UNREF(exec_ctx, first_ent);
 }
 
 static void rebuild_ents(grpc_chttp2_hptbl *tbl, uint32_t new_cap) {
@@ -249,7 +251,8 @@
   tbl->first_ent = 0;
 }
 
-void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx *exec_ctx,
+                                     grpc_chttp2_hptbl *tbl,
                                      uint32_t max_bytes) {
   if (tbl->max_bytes == max_bytes) {
     return;
@@ -258,12 +261,13 @@
     gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
   }
   while (tbl->mem_used > max_bytes) {
-    evict1(tbl);
+    evict1(exec_ctx, tbl);
   }
   tbl->max_bytes = max_bytes;
 }
 
-grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx,
+                                                     grpc_chttp2_hptbl *tbl,
                                                      uint32_t bytes) {
   if (tbl->current_table_bytes == bytes) {
     return GRPC_ERROR_NONE;
@@ -281,7 +285,7 @@
     gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes);
   }
   while (tbl->mem_used > bytes) {
-    evict1(tbl);
+    evict1(exec_ctx, tbl);
   }
   tbl->current_table_bytes = bytes;
   tbl->max_entries = entries_for_bytes(bytes);
@@ -296,7 +300,8 @@
   return GRPC_ERROR_NONE;
 }
 
-grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
+grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx,
+                                  grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
   /* determine how many bytes of buffer this entry represents */
   size_t elem_bytes = GRPC_SLICE_LENGTH(md->key->slice) +
                       GRPC_SLICE_LENGTH(md->value->slice) +
@@ -326,14 +331,14 @@
      * empty table.
      */
     while (tbl->num_ents) {
-      evict1(tbl);
+      evict1(exec_ctx, tbl);
     }
     return GRPC_ERROR_NONE;
   }
 
   /* evict entries to ensure no overflow */
   while (elem_bytes > (size_t)tbl->current_table_bytes - tbl->mem_used) {
-    evict1(tbl);
+    evict1(exec_ctx, tbl);
   }
 
   /* copy the finalized entry in */
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h
index 2ca130e..144574e 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.h
@@ -84,18 +84,21 @@
 } grpc_chttp2_hptbl;
 
 /* initialize a hpack table */
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl);
-void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl);
-void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+void grpc_chttp2_hptbl_init(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl);
+void grpc_chttp2_hptbl_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl);
+void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx *exec_ctx,
+                                     grpc_chttp2_hptbl *tbl,
                                      uint32_t max_bytes);
-grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx,
+                                                     grpc_chttp2_hptbl *tbl,
                                                      uint32_t bytes);
 
 /* lookup a table entry based on its hpack index */
 grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
                                       uint32_t index);
 /* add a table entry to the index */
-grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx,
+                                  grpc_chttp2_hptbl *tbl,
                                   grpc_mdelem *md) GRPC_MUST_USE_RESULT;
 /* Find a key/value pair in the table... returns the index in the table of the
    most similar entry, or 0 if the value was not found */
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.c b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
index 3e463a7..5d10949 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.c
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
@@ -46,11 +46,11 @@
 }
 
 void grpc_chttp2_incoming_metadata_buffer_destroy(
-    grpc_chttp2_incoming_metadata_buffer *buffer) {
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer) {
   size_t i;
   if (!buffer->published) {
     for (i = 0; i < buffer->count; i++) {
-      GRPC_MDELEM_UNREF(buffer->elems[i].md);
+      GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
     }
   }
   gpr_free(buffer->elems);
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
index df4343b..7a0c4da 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -49,7 +49,7 @@
 void grpc_chttp2_incoming_metadata_buffer_init(
     grpc_chttp2_incoming_metadata_buffer *buffer);
 void grpc_chttp2_incoming_metadata_buffer_destroy(
-    grpc_chttp2_incoming_metadata_buffer *buffer);
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer);
 void grpc_chttp2_incoming_metadata_buffer_publish(
     grpc_chttp2_incoming_metadata_buffer *buffer, grpc_metadata_batch *batch);
 
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 5efb497..4fb5dc7 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -336,7 +336,7 @@
 }
 
 static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) {
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(exec_ctx, md);
 }
 
 static grpc_error *init_skip_frame_parser(grpc_exec_ctx *exec_ctx,
@@ -477,7 +477,7 @@
     grpc_chttp2_incoming_metadata_buffer_set_deadline(
         &s->metadata_buffer[0],
         gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(exec_ctx, md);
   } else {
     const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
     const size_t metadata_size_limit =
@@ -495,7 +495,7 @@
               GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
       grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
       s->seen_error = true;
-      GRPC_MDELEM_UNREF(md);
+      GRPC_MDELEM_UNREF(exec_ctx, md);
     } else {
       grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
     }
@@ -538,7 +538,7 @@
             GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
     s->seen_error = true;
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(exec_ctx, md);
   } else {
     grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md);
   }
@@ -712,7 +712,7 @@
     memcpy(t->settings[GRPC_ACKED_SETTINGS], t->settings[GRPC_SENT_SETTINGS],
            GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t));
     grpc_chttp2_hptbl_set_max_bytes(
-        &t->hpack_parser.table,
+        exec_ctx, &t->hpack_parser.table,
         t->settings[GRPC_ACKED_SETTINGS]
                    [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
     t->sent_local_settings = 0;
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 139e738..ef2010a 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -39,6 +39,7 @@
 
 #include "src/core/ext/transport/chttp2/transport/http2_errors.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 static void add_to_write_list(grpc_chttp2_write_cb **list,
                               grpc_chttp2_write_cb *cb) {
@@ -119,7 +120,7 @@
     /* send initial metadata if it's available */
     if (!sent_initial_metadata && s->send_initial_metadata) {
       grpc_chttp2_encode_header(
-          &t->hpack_compressor, s->id, s->send_initial_metadata, 0,
+          exec_ctx, &t->hpack_compressor, s->id, s->send_initial_metadata, 0,
           t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
           &s->stats.outgoing, &t->outbuf);
       s->send_initial_metadata = NULL;
@@ -186,9 +187,9 @@
                                   &s->stats.outgoing, &t->outbuf);
         } else {
           grpc_chttp2_encode_header(
-              &t->hpack_compressor, s->id, s->send_trailing_metadata, true,
-              t->settings[GRPC_ACKED_SETTINGS]
-                         [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
+              exec_ctx, &t->hpack_compressor, s->id, s->send_trailing_metadata,
+              true, t->settings[GRPC_ACKED_SETTINGS]
+                               [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
               &s->stats.outgoing, &t->outbuf);
         }
         s->send_trailing_metadata = NULL;
@@ -254,7 +255,7 @@
     }
     GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:end");
   }
-  grpc_slice_buffer_reset_and_unref(&t->outbuf);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->outbuf);
   GRPC_ERROR_UNREF(error);
   GPR_TIMER_END("grpc_chttp2_end_write", 0);
 }
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index afc59f4..355cb7e 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -427,6 +427,7 @@
     cronet_bidirectional_stream *stream,
     const cronet_bidirectional_stream_header_array *headers,
     const char *negotiated_protocol) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream,
              headers, negotiated_protocol);
   stream_obj *s = (stream_obj *)stream->annotation;
@@ -438,7 +439,7 @@
     grpc_chttp2_incoming_metadata_buffer_add(
         &s->state.rs.initial_metadata,
         grpc_mdelem_from_metadata_strings(
-            grpc_mdstr_from_string(headers->headers[i].key),
+            &exec_ctx, grpc_mdstr_from_string(headers->headers[i].key),
             grpc_mdstr_from_string(headers->headers[i].value)));
   }
   s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
@@ -455,6 +456,7 @@
                                      s->state.rs.remaining_bytes);
   }
   gpr_mu_unlock(&s->mu);
+  grpc_exec_ctx_finish(&exec_ctx);
   execute_from_storage(s);
 }
 
@@ -520,6 +522,7 @@
 static void on_response_trailers_received(
     cronet_bidirectional_stream *stream,
     const cronet_bidirectional_stream_header_array *trailers) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream,
              trailers);
   stream_obj *s = (stream_obj *)stream->annotation;
@@ -534,7 +537,7 @@
     grpc_chttp2_incoming_metadata_buffer_add(
         &s->state.rs.trailing_metadata,
         grpc_mdelem_from_metadata_strings(
-            grpc_mdstr_from_string(trailers->headers[i].key),
+            &exec_ctx, grpc_mdstr_from_string(trailers->headers[i].key),
             grpc_mdstr_from_string(trailers->headers[i].value)));
     s->state.rs.trailing_metadata_valid = true;
     if (0 == strcmp(trailers->headers[i].key, "grpc-status") &&
@@ -554,8 +557,10 @@
     s->state.state_op_done[OP_SEND_TRAILING_METADATA] = true;
 
     gpr_mu_unlock(&s->mu);
+    grpc_exec_ctx_finish(&exec_ctx);
   } else {
     gpr_mu_unlock(&s->mu);
+    grpc_exec_ctx_finish(&exec_ctx);
     execute_from_storage(s);
   }
 }
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index 401a2ad..1a099ac 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -184,7 +184,7 @@
   return b;
 }
 
-void grpc_channel_args_destroy(grpc_channel_args *a) {
+void grpc_channel_args_destroy(grpc_exec_ctx *exec_ctx, grpc_channel_args *a) {
   size_t i;
   if (!a) return;
   for (i = 0; i < a->num_args; i++) {
@@ -195,7 +195,8 @@
       case GRPC_ARG_INTEGER:
         break;
       case GRPC_ARG_POINTER:
-        a->args[i].value.pointer.vtable->destroy(a->args[i].value.pointer.p);
+        a->args[i].value.pointer.vtable->destroy(exec_ctx,
+                                                 a->args[i].value.pointer.p);
         break;
     }
     gpr_free(a->args[i].key);
@@ -249,7 +250,8 @@
 }
 
 grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
-    grpc_channel_args **a, grpc_compression_algorithm algorithm, int state) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+    grpc_compression_algorithm algorithm, int state) {
   int *states_arg = NULL;
   grpc_channel_args *result = *a;
   const int states_arg_found =
@@ -282,7 +284,7 @@
       GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
     }
     result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
-    grpc_channel_args_destroy(*a);
+    grpc_channel_args_destroy(exec_ctx, *a);
     *a = result;
   }
   return result;
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 88fc0e3..5c7d31f 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -68,7 +68,7 @@
                                            const grpc_channel_args *b);
 
 /** Destroy arguments created by \a grpc_channel_args_copy */
-void grpc_channel_args_destroy(grpc_channel_args *a);
+void grpc_channel_args_destroy(grpc_exec_ctx *exec_ctx, grpc_channel_args *a);
 
 /** Returns the compression algorithm set in \a a. */
 grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
@@ -88,7 +88,8 @@
  * modified to point to the returned instance (which may be different from the
  * input value of \a a). */
 grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
-    grpc_channel_args **a, grpc_compression_algorithm algorithm, int enabled);
+    grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+    grpc_compression_algorithm algorithm, int enabled);
 
 /** Returns the bitset representing the support state (true for enabled, false
  * for disabled) for compression algorithms.
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 999ad5f..285ac17 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -300,7 +300,7 @@
   grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
   memset(op, 0, sizeof(*op));
   op->on_complete = grpc_closure_create(destroy_op, op);
-  grpc_transport_stream_op_add_cancellation_with_message(op, status,
+  grpc_transport_stream_op_add_cancellation_with_message(exec_ctx, op, status,
                                                          optional_message);
   elem->filter->start_transport_stream_op(exec_ctx, elem, op);
 }
@@ -312,6 +312,6 @@
   grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
   memset(op, 0, sizeof(*op));
   op->on_complete = grpc_closure_create(destroy_op, op);
-  grpc_transport_stream_op_add_close(op, status, optional_message);
+  grpc_transport_stream_op_add_close(exec_ctx, op, status, optional_message);
   elem->filter->start_transport_stream_op(exec_ctx, elem, op);
 }
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index eda4968..366bd0d 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -138,9 +138,10 @@
 }
 
 void grpc_channel_stack_builder_set_channel_arguments(
-    grpc_channel_stack_builder *builder, const grpc_channel_args *args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    const grpc_channel_args *args) {
   if (builder->args != NULL) {
-    grpc_channel_args_destroy(builder->args);
+    grpc_channel_args_destroy(exec_ctx, builder->args);
   }
   builder->args = grpc_channel_args_copy(args);
 }
@@ -213,7 +214,8 @@
   return true;
 }
 
-void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
+void grpc_channel_stack_builder_destroy(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_stack_builder *builder) {
   filter_node *p = builder->begin.next;
   while (p != &builder->end) {
     filter_node *next = p->next;
@@ -221,7 +223,7 @@
     p = next;
   }
   if (builder->args != NULL) {
-    grpc_channel_args_destroy(builder->args);
+    grpc_channel_args_destroy(exec_ctx, builder->args);
   }
   gpr_free(builder->target);
   gpr_free(builder);
@@ -270,7 +272,7 @@
     i++;
   }
 
-  grpc_channel_stack_builder_destroy(builder);
+  grpc_channel_stack_builder_destroy(exec_ctx, builder);
   gpr_free((grpc_channel_filter **)filters);
 
   return result;
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index 4a00f7b..3532819 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -73,7 +73,8 @@
 
 /// Set channel arguments: copies args
 void grpc_channel_stack_builder_set_channel_arguments(
-    grpc_channel_stack_builder *builder, const grpc_channel_args *args);
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+    const grpc_channel_args *args);
 
 /// Return a borrowed pointer to the channel arguments
 const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments(
@@ -158,7 +159,8 @@
                                         void *destroy_arg);
 
 /// Destroy the builder without creating a channel stack
-void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
+void grpc_channel_stack_builder_destroy(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_stack_builder *builder);
 
 extern int grpc_trace_channel_stack_builder;
 
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 2874d63..96188f0 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/compression/message_compress.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 
@@ -82,7 +83,8 @@
 /** For each \a md element from the incoming metadata, filter out the entry for
  * "grpc-encoding", using its value to populate the call data's
  * compression_algorithm field. */
-static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem *compression_md_filter(grpc_exec_ctx *exec_ctx,
+                                          void *user_data, grpc_mdelem *md) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
@@ -130,12 +132,14 @@
 
 /** Filter initial metadata */
 static void process_send_initial_metadata(
-    grpc_call_element *elem, grpc_metadata_batch *initial_metadata) {
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_metadata_batch *initial_metadata) {
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
   /* Parse incoming request for compression. If any, it'll be available
    * at calld->compression_algorithm */
-  grpc_metadata_batch_filter(initial_metadata, compression_md_filter, elem);
+  grpc_metadata_batch_filter(exec_ctx, initial_metadata, compression_md_filter,
+                             elem);
   if (!calld->has_compression_algorithm) {
     /* If no algorithm was found in the metadata and we aren't
      * exceptionally skipping compression, fall back to the channel
@@ -161,7 +165,7 @@
 static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
   grpc_call_element *elem = elemp;
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_reset_and_unref(&calld->slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices);
   calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
 }
 
@@ -171,8 +175,8 @@
   int did_compress;
   grpc_slice_buffer tmp;
   grpc_slice_buffer_init(&tmp);
-  did_compress =
-      grpc_msg_compress(calld->compression_algorithm, &calld->slices, &tmp);
+  did_compress = grpc_msg_compress(exec_ctx, calld->compression_algorithm,
+                                   &calld->slices, &tmp);
   if (did_compress) {
     if (grpc_compression_trace) {
       char *algo_name;
@@ -199,7 +203,7 @@
     }
   }
 
-  grpc_slice_buffer_destroy(&tmp);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &tmp);
 
   grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices,
                                 calld->send_flags);
@@ -243,7 +247,7 @@
   GPR_TIMER_BEGIN("compress_start_transport_stream_op", 0);
 
   if (op->send_initial_metadata) {
-    process_send_initial_metadata(elem, op->send_initial_metadata);
+    process_send_initial_metadata(exec_ctx, elem, op->send_initial_metadata);
   }
   if (op->send_message != NULL &&
       !skip_compression(elem, op->send_message->flags)) {
@@ -281,7 +285,7 @@
                               void *ignored) {
   /* grab pointers to our data from the call element */
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_destroy(&calld->slices);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
 }
 
 /* Constructor for channel_data */
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 038e819..ba2c7fc 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -170,7 +170,8 @@
   channel_stack->call_stack_size += grpc_transport_stream_size(t);
 }
 
-bool grpc_add_connected_filter(grpc_channel_stack_builder *builder,
+bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
+                               grpc_channel_stack_builder *builder,
                                void *arg_must_be_null) {
   GPR_ASSERT(arg_must_be_null == NULL);
   grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h
index 3142d64..3585c0e 100644
--- a/src/core/lib/channel/connected_channel.h
+++ b/src/core/lib/channel/connected_channel.h
@@ -36,7 +36,8 @@
 
 #include "src/core/lib/channel/channel_stack_builder.h"
 
-bool grpc_add_connected_filter(grpc_channel_stack_builder *builder,
+bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
+                               grpc_channel_stack_builder *builder,
                                void *arg_must_be_null);
 
 #endif /* GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H */
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 0e703d8..0293c34 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -41,6 +41,7 @@
 
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 //
 // grpc_deadline_state
@@ -58,7 +59,7 @@
     grpc_slice msg = grpc_slice_from_static_string("Deadline Exceeded");
     grpc_call_element_send_cancel_with_message(
         exec_ctx, elem, GRPC_STATUS_DEADLINE_EXCEEDED, &msg);
-    grpc_slice_unref(msg);
+    grpc_slice_unref_internal(exec_ctx, msg);
   }
   GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack, "deadline_timer");
 }
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index fd8b46a..8131074 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -37,6 +37,7 @@
 #include <string.h>
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/percent_encoding.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/transport_impl.h"
@@ -92,13 +93,9 @@
   size_t max_payload_size_for_get;
 } channel_data;
 
-typedef struct {
-  grpc_call_element *elem;
-  grpc_exec_ctx *exec_ctx;
-} client_recv_filter_args;
-
-static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
-  client_recv_filter_args *a = user_data;
+static grpc_mdelem *client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+                                       grpc_mdelem *md) {
+  grpc_call_element *elem = user_data;
   if (md == GRPC_MDELEM_STATUS_200) {
     return NULL;
   } else if (md->key == GRPC_MDSTR_STATUS) {
@@ -107,18 +104,19 @@
                  grpc_mdstr_as_c_string(md->value));
     grpc_slice message = grpc_slice_from_copied_string(message_string);
     gpr_free(message_string);
-    grpc_call_element_send_close_with_message(a->exec_ctx, a->elem,
+    grpc_call_element_send_close_with_message(exec_ctx, elem,
                                               GRPC_STATUS_CANCELLED, &message);
     return NULL;
   } else if (md->key == GRPC_MDSTR_GRPC_MESSAGE) {
     grpc_slice pct_decoded_msg =
         grpc_permissive_percent_decode_slice(md->value->slice);
     if (grpc_slice_is_equivalent(pct_decoded_msg, md->value->slice)) {
-      grpc_slice_unref(pct_decoded_msg);
+      grpc_slice_unref_internal(exec_ctx, pct_decoded_msg);
       return md;
     } else {
       return grpc_mdelem_from_metadata_strings(
-          GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(pct_decoded_msg));
+          exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+          grpc_mdstr_from_slice(exec_ctx, pct_decoded_msg));
     }
   } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
     return NULL;
@@ -147,11 +145,8 @@
                                         void *user_data, grpc_error *error) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
-  client_recv_filter_args a;
-  a.elem = elem;
-  a.exec_ctx = exec_ctx;
-  grpc_metadata_batch_filter(calld->recv_initial_metadata, client_recv_filter,
-                             &a);
+  grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+                             client_recv_filter, elem);
   grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata,
                    GRPC_ERROR_REF(error));
 }
@@ -160,11 +155,8 @@
                                          void *user_data, grpc_error *error) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
-  client_recv_filter_args a;
-  a.elem = elem;
-  a.exec_ctx = exec_ctx;
-  grpc_metadata_batch_filter(calld->recv_trailing_metadata, client_recv_filter,
-                             &a);
+  grpc_metadata_batch_filter(exec_ctx, calld->recv_trailing_metadata,
+                             client_recv_filter, elem);
   grpc_closure_run(exec_ctx, calld->on_done_recv_trailing_metadata,
                    GRPC_ERROR_REF(error));
 }
@@ -183,11 +175,12 @@
 static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
   grpc_call_element *elem = elemp;
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_reset_and_unref(&calld->slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices);
   calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
 }
 
-static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem *client_strip_filter(grpc_exec_ctx *exec_ctx,
+                                        void *user_data, grpc_mdelem *md) {
   /* eat the things we'd like to set ourselves */
   if (md->key == GRPC_MDSTR_METHOD) return NULL;
   if (md->key == GRPC_MDSTR_SCHEME) return NULL;
@@ -275,7 +268,7 @@
         /* when all the send_message data is available, then create a MDELEM and
         append to headers */
         grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings(
-            GRPC_MDSTR_GRPC_PAYLOAD_BIN,
+            exec_ctx, GRPC_MDSTR_GRPC_PAYLOAD_BIN,
             grpc_mdstr_from_buffer(calld->payload_bytes,
                                    op->send_message->length));
         grpc_metadata_batch_add_tail(op->send_initial_metadata,
@@ -292,8 +285,8 @@
       }
     }
 
-    grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter,
-                               elem);
+    grpc_metadata_batch_filter(exec_ctx, op->send_initial_metadata,
+                               client_strip_filter, elem);
     /* Send : prefixed headers, which have to be before any application
        layer headers. */
     grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
@@ -366,7 +359,7 @@
                               const grpc_call_final_info *final_info,
                               void *ignored) {
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_destroy(&calld->slices);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
 }
 
 static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
@@ -467,7 +460,7 @@
   chand->max_payload_size_for_get =
       max_payload_size_from_args(args->channel_args);
   chand->user_agent = grpc_mdelem_from_metadata_strings(
-      GRPC_MDSTR_USER_AGENT,
+      exec_ctx, GRPC_MDSTR_USER_AGENT,
       user_agent_from_args(args->channel_args,
                            args->optional_transport->vtable->name));
 }
@@ -476,7 +469,7 @@
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {
   channel_data *chand = elem->channel_data;
-  GRPC_MDELEM_UNREF(chand->user_agent);
+  GRPC_MDELEM_UNREF(exec_ctx, chand->user_agent);
 }
 
 const grpc_channel_filter grpc_http_client_filter = {
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index b42ff06..db39020 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -38,6 +38,7 @@
 #include <string.h>
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/percent_encoding.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 #define EXPECTED_CONTENT_TYPE "application/grpc"
@@ -82,31 +83,28 @@
 
 typedef struct channel_data { uint8_t unused; } channel_data;
 
-typedef struct {
-  grpc_call_element *elem;
-  grpc_exec_ctx *exec_ctx;
-} server_filter_args;
-
-static grpc_mdelem *server_filter_outgoing_metadata(void *user_data,
+static grpc_mdelem *server_filter_outgoing_metadata(grpc_exec_ctx *exec_ctx,
+                                                    void *user_data,
                                                     grpc_mdelem *md) {
   if (md->key == GRPC_MDSTR_GRPC_MESSAGE) {
     grpc_slice pct_encoded_msg = grpc_percent_encode_slice(
         md->value->slice, grpc_compatible_percent_encoding_unreserved_bytes);
     if (grpc_slice_is_equivalent(pct_encoded_msg, md->value->slice)) {
-      grpc_slice_unref(pct_encoded_msg);
+      grpc_slice_unref_internal(exec_ctx, pct_encoded_msg);
       return md;
     } else {
       return grpc_mdelem_from_metadata_strings(
-          GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(pct_encoded_msg));
+          exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+          grpc_mdstr_from_slice(exec_ctx, pct_encoded_msg));
     }
   } else {
     return md;
   }
 }
 
-static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
-  server_filter_args *a = user_data;
-  grpc_call_element *elem = a->elem;
+static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+                                  grpc_mdelem *md) {
+  grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
 
   /* Check if it is one of the headers we care about. */
@@ -157,7 +155,7 @@
     /* swallow it and error everything out. */
     /* TODO(klempner): We ought to generate more descriptive error messages
        on the wire here. */
-    grpc_call_element_send_cancel(a->exec_ctx, elem);
+    grpc_call_element_send_cancel(exec_ctx, elem);
     return NULL;
   } else if (md->key == GRPC_MDSTR_PATH) {
     if (calld->seen_path) {
@@ -173,7 +171,7 @@
     /* translate host to :authority since :authority may be
        omitted */
     grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
-        GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
+        exec_ctx, GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
     calld->seen_authority = 1;
     return authority;
   } else if (md->key == GRPC_MDSTR_GRPC_PAYLOAD_BIN) {
@@ -181,7 +179,7 @@
        header field */
     calld->seen_payload_bin = 1;
     grpc_slice_buffer_add(&calld->read_slice_buffer,
-                          grpc_slice_ref(md->value->slice));
+                          grpc_slice_ref_internal(md->value->slice));
     grpc_slice_buffer_stream_init(&calld->read_stream,
                                   &calld->read_slice_buffer, 0);
     return NULL;
@@ -195,10 +193,8 @@
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
   if (err == GRPC_ERROR_NONE) {
-    server_filter_args a;
-    a.elem = elem;
-    a.exec_ctx = exec_ctx;
-    grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, &a);
+    grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+                               server_filter, elem);
     /* Have we seen the required http2 transport headers?
        (:method, :scheme, content-type, with :path and :authority covered
        at the channel level right now) */
@@ -310,9 +306,8 @@
   }
 
   if (op->send_trailing_metadata) {
-    server_filter_args a = {elem, exec_ctx};
-    grpc_metadata_batch_filter(op->send_trailing_metadata,
-                               server_filter_outgoing_metadata, &a);
+    grpc_metadata_batch_filter(exec_ctx, op->send_trailing_metadata,
+                               server_filter_outgoing_metadata, elem);
   }
 }
 
@@ -346,7 +341,7 @@
                               const grpc_call_final_info *final_info,
                               void *ignored) {
   call_data *calld = elem->call_data;
-  grpc_slice_buffer_destroy(&calld->read_slice_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &calld->read_slice_buffer);
 }
 
 /* Constructor for channel_data */
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 1cf68d7..92be317 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -54,8 +54,12 @@
   return new_value;
 }
 
+static void message_size_limits_free(grpc_exec_ctx* exec_ctx, void* value) {
+  gpr_free(value);
+}
+
 static const grpc_mdstr_hash_table_vtable message_size_limits_vtable = {
-    gpr_free, message_size_limits_copy};
+    message_size_limits_free, message_size_limits_copy};
 
 static void* message_size_limits_create_from_json(const grpc_json* json) {
   int max_request_message_bytes = -1;
@@ -168,8 +172,8 @@
   calld->max_send_size = chand->max_send_size;
   calld->max_recv_size = chand->max_recv_size;
   if (chand->method_limit_table != NULL) {
-    message_size_limits* limits =
-        grpc_method_config_table_get(chand->method_limit_table, args->path);
+    message_size_limits* limits = grpc_method_config_table_get(
+        exec_ctx, chand->method_limit_table, args->path);
     if (limits != NULL) {
       if (limits->max_send_size >= 0 &&
           (limits->max_send_size < calld->max_send_size ||
@@ -226,7 +230,7 @@
     if (service_config != NULL) {
       chand->method_limit_table =
           grpc_service_config_create_method_config_table(
-              service_config, message_size_limits_create_from_json,
+              exec_ctx, service_config, message_size_limits_create_from_json,
               &message_size_limits_vtable);
       grpc_service_config_destroy(service_config);
     }
@@ -237,7 +241,7 @@
 static void destroy_channel_elem(grpc_exec_ctx* exec_ctx,
                                  grpc_channel_element* elem) {
   channel_data* chand = elem->channel_data;
-  grpc_mdstr_hash_table_unref(chand->method_limit_table);
+  grpc_mdstr_hash_table_unref(exec_ctx, chand->method_limit_table);
 }
 
 const grpc_channel_filter grpc_message_size_filter = {
diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c
index 6c245ac..49beb95 100644
--- a/src/core/lib/compression/message_compress.c
+++ b/src/core/lib/compression/message_compress.c
@@ -40,10 +40,12 @@
 
 #include <zlib.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 #define OUTPUT_BLOCK_SIZE 1024
 
-static int zlib_body(z_stream* zs, grpc_slice_buffer* input,
-                     grpc_slice_buffer* output,
+static int zlib_body(grpc_exec_ctx* exec_ctx, z_stream* zs,
+                     grpc_slice_buffer* input, grpc_slice_buffer* output,
                      int (*flate)(z_stream* zs, int flush)) {
   int r;
   int flush;
@@ -87,7 +89,7 @@
   return 1;
 
 error:
-  grpc_slice_unref(outbuf);
+  grpc_slice_unref_internal(exec_ctx, outbuf);
   return 0;
 }
 
@@ -97,8 +99,8 @@
 
 static void zfree_gpr(void* opaque, void* address) { gpr_free(address); }
 
-static int zlib_compress(grpc_slice_buffer* input, grpc_slice_buffer* output,
-                         int gzip) {
+static int zlib_compress(grpc_exec_ctx* exec_ctx, grpc_slice_buffer* input,
+                         grpc_slice_buffer* output, int gzip) {
   z_stream zs;
   int r;
   size_t i;
@@ -110,10 +112,11 @@
   r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0),
                    8, Z_DEFAULT_STRATEGY);
   GPR_ASSERT(r == Z_OK);
-  r = zlib_body(&zs, input, output, deflate) && output->length < input->length;
+  r = zlib_body(exec_ctx, &zs, input, output, deflate) &&
+      output->length < input->length;
   if (!r) {
     for (i = count_before; i < output->count; i++) {
-      grpc_slice_unref(output->slices[i]);
+      grpc_slice_unref_internal(exec_ctx, output->slices[i]);
     }
     output->count = count_before;
     output->length = length_before;
@@ -122,8 +125,8 @@
   return r;
 }
 
-static int zlib_decompress(grpc_slice_buffer* input, grpc_slice_buffer* output,
-                           int gzip) {
+static int zlib_decompress(grpc_exec_ctx* exec_ctx, grpc_slice_buffer* input,
+                           grpc_slice_buffer* output, int gzip) {
   z_stream zs;
   int r;
   size_t i;
@@ -134,10 +137,10 @@
   zs.zfree = zfree_gpr;
   r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
   GPR_ASSERT(r == Z_OK);
-  r = zlib_body(&zs, input, output, inflate);
+  r = zlib_body(exec_ctx, &zs, input, output, inflate);
   if (!r) {
     for (i = count_before; i < output->count; i++) {
-      grpc_slice_unref(output->slices[i]);
+      grpc_slice_unref_internal(exec_ctx, output->slices[i]);
     }
     output->count = count_before;
     output->length = length_before;
@@ -149,12 +152,13 @@
 static int copy(grpc_slice_buffer* input, grpc_slice_buffer* output) {
   size_t i;
   for (i = 0; i < input->count; i++) {
-    grpc_slice_buffer_add(output, grpc_slice_ref(input->slices[i]));
+    grpc_slice_buffer_add(output, grpc_slice_ref_internal(input->slices[i]));
   }
   return 1;
 }
 
-static int compress_inner(grpc_compression_algorithm algorithm,
+static int compress_inner(grpc_exec_ctx* exec_ctx,
+                          grpc_compression_algorithm algorithm,
                           grpc_slice_buffer* input, grpc_slice_buffer* output) {
   switch (algorithm) {
     case GRPC_COMPRESS_NONE:
@@ -162,9 +166,9 @@
          rely on that here */
       return 0;
     case GRPC_COMPRESS_DEFLATE:
-      return zlib_compress(input, output, 0);
+      return zlib_compress(exec_ctx, input, output, 0);
     case GRPC_COMPRESS_GZIP:
-      return zlib_compress(input, output, 1);
+      return zlib_compress(exec_ctx, input, output, 1);
     case GRPC_COMPRESS_ALGORITHMS_COUNT:
       break;
   }
@@ -172,24 +176,26 @@
   return 0;
 }
 
-int grpc_msg_compress(grpc_compression_algorithm algorithm,
+int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
+                      grpc_compression_algorithm algorithm,
                       grpc_slice_buffer* input, grpc_slice_buffer* output) {
-  if (!compress_inner(algorithm, input, output)) {
+  if (!compress_inner(exec_ctx, algorithm, input, output)) {
     copy(input, output);
     return 0;
   }
   return 1;
 }
 
-int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
+                        grpc_compression_algorithm algorithm,
                         grpc_slice_buffer* input, grpc_slice_buffer* output) {
   switch (algorithm) {
     case GRPC_COMPRESS_NONE:
       return copy(input, output);
     case GRPC_COMPRESS_DEFLATE:
-      return zlib_decompress(input, output, 0);
+      return zlib_decompress(exec_ctx, input, output, 0);
     case GRPC_COMPRESS_GZIP:
-      return zlib_decompress(input, output, 1);
+      return zlib_decompress(exec_ctx, input, output, 1);
     case GRPC_COMPRESS_ALGORITHMS_COUNT:
       break;
   }
diff --git a/src/core/lib/compression/message_compress.h b/src/core/lib/compression/message_compress.h
index 448d36a..7bd3d98 100644
--- a/src/core/lib/compression/message_compress.h
+++ b/src/core/lib/compression/message_compress.h
@@ -40,13 +40,15 @@
 /* compress 'input' to 'output' using 'algorithm'.
    On success, appends compressed slices to output and returns 1.
    On failure, appends uncompressed slices to output and returns 0. */
-int grpc_msg_compress(grpc_compression_algorithm algorithm,
+int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
+                      grpc_compression_algorithm algorithm,
                       grpc_slice_buffer* input, grpc_slice_buffer* output);
 
 /* decompress 'input' to 'output' using 'algorithm'.
    On success, appends slices to output and returns 1.
    On failure, output is unchanged, and returns 0. */
-int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
+                        grpc_compression_algorithm algorithm,
                         grpc_slice_buffer* input, grpc_slice_buffer* output);
 
 #endif /* GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H */
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index fdb8aba..6bab7ef 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -47,6 +47,7 @@
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/tcp_client.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 
 typedef struct {
@@ -111,14 +112,14 @@
   if (req->ep != NULL) {
     grpc_endpoint_destroy(exec_ctx, req->ep);
   }
-  grpc_slice_unref(req->request_text);
+  grpc_slice_unref_internal(exec_ctx, req->request_text);
   gpr_free(req->host);
   gpr_free(req->ssl_host_override);
   grpc_iomgr_unregister_object(&req->iomgr_obj);
-  grpc_slice_buffer_destroy(&req->incoming);
-  grpc_slice_buffer_destroy(&req->outgoing);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &req->incoming);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &req->outgoing);
   GRPC_ERROR_UNREF(req->overall_error);
-  grpc_resource_quota_internal_unref(exec_ctx, req->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, req->resource_quota);
   gpr_free(req);
 }
 
@@ -178,7 +179,7 @@
 }
 
 static void start_write(grpc_exec_ctx *exec_ctx, internal_request *req) {
-  grpc_slice_ref(req->request_text);
+  grpc_slice_ref_internal(req->request_text);
   grpc_slice_buffer_add(&req->outgoing, req->request_text);
   grpc_endpoint_write(exec_ctx, req->ep, &req->outgoing, &req->done_write);
 }
@@ -265,7 +266,7 @@
   req->context = context;
   req->pollent = pollent;
   req->overall_error = GRPC_ERROR_NONE;
-  req->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
+  req->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
   grpc_closure_init(&req->on_read, on_read, req);
   grpc_closure_init(&req->done_write, done_write, req);
   grpc_slice_buffer_init(&req->incoming);
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 14cdb1d..7dd50b7 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -41,6 +41,7 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/security/transport/security_handshaker.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/tsi/ssl_transport_security.h"
 
@@ -50,7 +51,8 @@
   char *secure_peer_name;
 } grpc_httpcli_ssl_channel_security_connector;
 
-static void httpcli_ssl_destroy(grpc_security_connector *sc) {
+static void httpcli_ssl_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
   grpc_httpcli_ssl_channel_security_connector *c =
       (grpc_httpcli_ssl_channel_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
@@ -104,8 +106,9 @@
     httpcli_ssl_destroy, httpcli_ssl_check_peer};
 
 static grpc_security_status httpcli_ssl_channel_security_connector_create(
-    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
-    const char *secure_peer_name, grpc_channel_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, const unsigned char *pem_root_certs,
+    size_t pem_root_certs_size, const char *secure_peer_name,
+    grpc_channel_security_connector **sc) {
   tsi_result result = TSI_OK;
   grpc_httpcli_ssl_channel_security_connector *c;
 
@@ -129,7 +132,7 @@
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
-    httpcli_ssl_destroy(&c->base.base);
+    httpcli_ssl_destroy(exec_ctx, &c->base.base);
     *sc = NULL;
     return GRPC_SECURITY_ERROR;
   }
@@ -156,8 +159,8 @@
     grpc_error_free_string(msg);
     c->func(exec_ctx, c->arg, NULL);
   } else {
-    grpc_channel_args_destroy(args->args);
-    grpc_slice_buffer_destroy(args->read_buffer);
+    grpc_channel_args_destroy(exec_ctx, args->args);
+    grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer);
     gpr_free(args->read_buffer);
     c->func(exec_ctx, c->arg, args->endpoint);
   }
@@ -184,14 +187,14 @@
   c->arg = arg;
   c->handshake_mgr = grpc_handshake_manager_create();
   GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
-                 pem_root_certs, pem_root_certs_size, host, &sc) ==
+                 exec_ctx, pem_root_certs, pem_root_certs_size, host, &sc) ==
              GRPC_SECURITY_OK);
   grpc_channel_security_connector_add_handshakers(exec_ctx, sc,
                                                   c->handshake_mgr);
   grpc_handshake_manager_do_handshake(
       exec_ctx, c->handshake_mgr, tcp, NULL /* channel_args */, deadline,
       NULL /* acceptor */, on_handshake_done, c /* user_data */);
-  GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
+  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "httpcli");
 }
 
 const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake};
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 2b4b271..ec0114a 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -35,6 +35,8 @@
 #define GRPC_CORE_LIB_IOMGR_CLOSURE_H
 
 #include <grpc/support/port_platform.h>
+
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <stdbool.h>
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/support/mpscq.h"
@@ -42,10 +44,6 @@
 struct grpc_closure;
 typedef struct grpc_closure grpc_closure;
 
-/* forward declaration for exec_ctx.h */
-struct grpc_exec_ctx;
-typedef struct grpc_exec_ctx grpc_exec_ctx;
-
 typedef struct grpc_closure_list {
   grpc_closure *head;
   grpc_closure *tail;
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 1b15e0e..59b1fe8 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -31,7 +31,6 @@
  *
  */
 
-#include <grpc/grpc_posix.h>
 #include "src/core/lib/iomgr/port.h"
 
 /* This polling engine is only relevant on linux kernels supporting epoll() */
diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index 8d7535d..4e78b61 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -121,9 +121,8 @@
   gpr_mu_unlock(&g_executor.mu);
 }
 
-void grpc_executor_shutdown() {
+void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
   int pending_join;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   gpr_mu_lock(&g_executor.mu);
   pending_join = g_executor.pending_join;
@@ -133,8 +132,7 @@
    * list below because we aren't accepting new work */
 
   /* Execute pending callbacks, some may be performing cleanups */
-  grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_exec_ctx_enqueue_list(exec_ctx, &g_executor.closures, NULL);
   GPR_ASSERT(grpc_closure_list_empty(g_executor.closures));
   if (pending_join) {
     gpr_thd_join(g_executor.tid);
diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h
index da9dcd0..7bf8f21 100644
--- a/src/core/lib/iomgr/executor.h
+++ b/src/core/lib/iomgr/executor.h
@@ -48,6 +48,6 @@
 void grpc_executor_push(grpc_closure *closure, grpc_error *error);
 
 /** Shutdown the executor, running all pending work as part of the call */
-void grpc_executor_shutdown();
+void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx);
 
 #endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */
diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c
index 3470b5a..001e528 100644
--- a/src/core/lib/iomgr/iomgr.c
+++ b/src/core/lib/iomgr/iomgr.c
@@ -83,11 +83,10 @@
   }
 }
 
-void grpc_iomgr_shutdown(void) {
+void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx) {
   gpr_timespec shutdown_deadline = gpr_time_add(
       gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN));
   gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   grpc_iomgr_platform_flush();
 
@@ -104,10 +103,9 @@
       }
       last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
     }
-    if (grpc_timer_check(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC),
-                         NULL)) {
+    if (grpc_timer_check(exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL)) {
       gpr_mu_unlock(&g_mu);
-      grpc_exec_ctx_flush(&exec_ctx);
+      grpc_exec_ctx_flush(exec_ctx);
       grpc_iomgr_platform_flush();
       gpr_mu_lock(&g_mu);
       continue;
@@ -139,8 +137,8 @@
   }
   gpr_mu_unlock(&g_mu);
 
-  grpc_timer_list_shutdown(&exec_ctx);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_timer_list_shutdown(exec_ctx);
+  grpc_exec_ctx_flush(exec_ctx);
 
   /* ensure all threads have left g_mu */
   gpr_mu_lock(&g_mu);
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index c1cfaf3..245a1e0 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -34,12 +34,14 @@
 #ifndef GRPC_CORE_LIB_IOMGR_IOMGR_H
 #define GRPC_CORE_LIB_IOMGR_IOMGR_H
 
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include "src/core/lib/iomgr/port.h"
 
 /** Initializes the iomgr. */
 void grpc_iomgr_init(void);
 
-/** Signals the intention to shutdown the iomgr. */
-void grpc_iomgr_shutdown(void);
+/** Signals the intention to shutdown the iomgr. Expects to be able to flush
+ * exec_ctx. */
+void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx);
 
 #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */
diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index 213d296..c5c536d 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -257,14 +257,14 @@
   }
 
 done:
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 }
 
 static void rq_step_sched(grpc_exec_ctx *exec_ctx,
                           grpc_resource_quota *resource_quota) {
   if (resource_quota->step_scheduled) return;
   resource_quota->step_scheduled = true;
-  grpc_resource_quota_internal_ref(resource_quota);
+  grpc_resource_quota_ref_internal(resource_quota);
   grpc_combiner_execute_finally(exec_ctx, resource_quota->combiner,
                                 &resource_quota->rq_step_closure,
                                 GRPC_ERROR_NONE, false);
@@ -345,7 +345,7 @@
             destructive ? "destructive" : "benign");
   }
   resource_quota->reclaiming = true;
-  grpc_resource_quota_internal_ref(resource_quota);
+  grpc_resource_quota_ref_internal(resource_quota);
   grpc_closure *c = resource_user->reclaimers[destructive];
   GPR_ASSERT(c);
   resource_quota->debug_only_last_reclaimer_resource_user = resource_user;
@@ -371,21 +371,10 @@
   gpr_ref(&rc->refs);
 }
 
-static void ru_slice_unref(void *p) {
+static void ru_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
   ru_slice_refcount *rc = p;
   if (gpr_unref(&rc->refs)) {
-    /* TODO(ctiller): this is dangerous, but I think safe for now:
-       we have no guarantee here that we're at a safe point for creating an
-       execution context, but we have no way of writing this code otherwise.
-       In the future: consider lifting grpc_slice to grpc, and offering an
-       internal_{ref,unref} pair that is execution context aware.
-       Alternatively,
-       make exec_ctx be thread local and 'do the right thing' (whatever that
-       is)
-       if NULL */
-    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_resource_user_free(&exec_ctx, rc->resource_user, rc->size);
-    grpc_exec_ctx_finish(&exec_ctx);
+    grpc_resource_user_free(exec_ctx, rc->resource_user, rc->size);
     gpr_free(rc);
   }
 }
@@ -504,7 +493,7 @@
     resource_user->resource_quota->free_pool += resource_user->free_pool;
     rq_step_sched(exec_ctx, resource_user->resource_quota);
   }
-  grpc_resource_quota_internal_unref(exec_ctx, resource_user->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_user->resource_quota);
   gpr_mu_destroy(&resource_user->mu);
   gpr_free(resource_user->name);
   gpr_free(resource_user);
@@ -540,7 +529,7 @@
   a->resource_quota->size += delta;
   a->resource_quota->free_pool += delta;
   rq_step_sched(exec_ctx, a->resource_quota);
-  grpc_resource_quota_internal_unref(exec_ctx, a->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, a->resource_quota);
   gpr_free(a);
 }
 
@@ -549,7 +538,7 @@
   grpc_resource_quota *resource_quota = rq;
   resource_quota->reclaiming = false;
   rq_step_sched(exec_ctx, resource_quota);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 }
 
 /*******************************************************************************
@@ -580,7 +569,7 @@
   return resource_quota;
 }
 
-void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
+void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
                                         grpc_resource_quota *resource_quota) {
   if (gpr_unref(&resource_quota->refs)) {
     grpc_combiner_destroy(exec_ctx, resource_quota->combiner);
@@ -592,11 +581,11 @@
 /* Public API */
 void grpc_resource_quota_unref(grpc_resource_quota *resource_quota) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-grpc_resource_quota *grpc_resource_quota_internal_ref(
+grpc_resource_quota *grpc_resource_quota_ref_internal(
     grpc_resource_quota *resource_quota) {
   gpr_ref(&resource_quota->refs);
   return resource_quota;
@@ -604,7 +593,7 @@
 
 /* Public API */
 void grpc_resource_quota_ref(grpc_resource_quota *resource_quota) {
-  grpc_resource_quota_internal_ref(resource_quota);
+  grpc_resource_quota_ref_internal(resource_quota);
 }
 
 /* Public API */
@@ -612,7 +601,7 @@
                                 size_t size) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   rq_resize_args *a = gpr_malloc(sizeof(*a));
-  a->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
+  a->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
   a->size = (int64_t)size;
   grpc_closure_init(&a->closure, rq_resize, a);
   grpc_combiner_execute(&exec_ctx, resource_quota->combiner, &a->closure,
@@ -629,7 +618,7 @@
   for (size_t i = 0; i < channel_args->num_args; i++) {
     if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
       if (channel_args->args[i].type == GRPC_ARG_POINTER) {
-        return grpc_resource_quota_internal_ref(
+        return grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       } else {
         gpr_log(GPR_DEBUG, GRPC_ARG_RESOURCE_QUOTA " should be a pointer");
@@ -644,7 +633,9 @@
   return rq;
 }
 
-static void rq_destroy(void *rq) { grpc_resource_quota_unref(rq); }
+static void rq_destroy(grpc_exec_ctx *exec_ctx, void *rq) {
+  grpc_resource_quota_unref_internal(exec_ctx, rq);
+}
 
 static int rq_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
 
@@ -661,7 +652,7 @@
     grpc_resource_quota *resource_quota, const char *name) {
   grpc_resource_user *resource_user = gpr_malloc(sizeof(*resource_user));
   resource_user->resource_quota =
-      grpc_resource_quota_internal_ref(resource_quota);
+      grpc_resource_quota_ref_internal(resource_quota);
   grpc_closure_init(&resource_user->allocate_closure, &ru_allocate,
                     resource_user);
   grpc_closure_init(&resource_user->add_to_free_pool_closure,
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index 0181fd9..ef286c2 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -77,9 +77,9 @@
 
 extern int grpc_resource_quota_trace;
 
-grpc_resource_quota *grpc_resource_quota_internal_ref(
+grpc_resource_quota *grpc_resource_quota_ref_internal(
     grpc_resource_quota *resource_quota);
-void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
+void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
                                         grpc_resource_quota *resource_quota);
 grpc_resource_quota *grpc_resource_quota_from_channel_args(
     const grpc_channel_args *channel_args);
diff --git a/src/core/lib/iomgr/socket_mutator.c b/src/core/lib/iomgr/socket_mutator.c
index 8b1efb6..34b61dc 100644
--- a/src/core/lib/iomgr/socket_mutator.c
+++ b/src/core/lib/iomgr/socket_mutator.c
@@ -76,7 +76,7 @@
   return grpc_socket_mutator_ref(p);
 }
 
-static void socket_mutator_arg_destroy(void *p) {
+static void socket_mutator_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
   grpc_socket_mutator_unref(p);
 }
 
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index a3a70a8..2db56b4 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -128,7 +128,7 @@
   if (done) {
     gpr_mu_destroy(&ac->mu);
     gpr_free(ac->addr_str);
-    grpc_channel_args_destroy(ac->channel_args);
+    grpc_channel_args_destroy(exec_ctx, ac->channel_args);
     gpr_free(ac);
   }
 }
@@ -148,8 +148,8 @@
             &channel_args->args[i], options);
       } else if (0 ==
                  strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_internal_ref(
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       }
     }
@@ -157,7 +157,7 @@
 
   grpc_endpoint *ep =
       grpc_tcp_create(fd, resource_quota, tcp_read_chunk_size, addr_str);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   return ep;
 }
 
@@ -262,7 +262,7 @@
   if (done) {
     gpr_mu_destroy(&ac->mu);
     gpr_free(ac->addr_str);
-    grpc_channel_args_destroy(ac->channel_args);
+    grpc_channel_args_destroy(exec_ctx, ac->channel_args);
     gpr_free(ac);
   }
   grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
diff --git a/src/core/lib/iomgr/tcp_client_uv.c b/src/core/lib/iomgr/tcp_client_uv.c
index b07f9ce..5f2ccfe 100644
--- a/src/core/lib/iomgr/tcp_client_uv.c
+++ b/src/core/lib/iomgr/tcp_client_uv.c
@@ -59,7 +59,7 @@
 
 static void uv_tcp_connect_cleanup(grpc_exec_ctx *exec_ctx,
                                    grpc_uv_tcp_connect *connect) {
-  grpc_resource_quota_internal_unref(exec_ctx, connect->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, connect->resource_quota);
   gpr_free(connect);
 }
 
@@ -128,8 +128,8 @@
   if (channel_args != NULL) {
     for (size_t i = 0; i < channel_args->num_args; i++) {
       if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_internal_ref(
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       }
     }
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index 1127588..cc10060 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -71,7 +71,7 @@
   int done = (--ac->refs == 0);
   gpr_mu_unlock(&ac->mu);
   if (done) {
-    grpc_resource_quota_internal_unref(exec_ctx, ac->resource_quota);
+    grpc_resource_quota_unref_internal(exec_ctx, ac->resource_quota);
     gpr_mu_destroy(&ac->mu);
     gpr_free(ac->addr_name);
     gpr_free(ac);
@@ -157,8 +157,8 @@
   if (channel_args != NULL) {
     for (size_t i = 0; i < channel_args->num_args; i++) {
       if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
-        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
-        resource_quota = grpc_resource_quota_internal_ref(
+        grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+        resource_quota = grpc_resource_quota_ref_internal(
             channel_args->args[i].value.pointer.p);
       }
     }
@@ -246,7 +246,7 @@
   } else if (sock != INVALID_SOCKET) {
     closesocket(sock);
   }
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   grpc_exec_ctx_sched(exec_ctx, on_done, final_error, NULL);
 }
 
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 540305e..2b46544 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -56,6 +56,7 @@
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
@@ -127,7 +128,7 @@
 static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
   grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd,
                  "tcp_unref_orphan");
-  grpc_slice_buffer_destroy(&tcp->last_read_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &tcp->last_read_buffer);
   grpc_resource_user_unref(exec_ctx, tcp->resource_user);
   gpr_free(tcp->peer_string);
   gpr_free(tcp);
@@ -168,7 +169,7 @@
 static void tcp_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
   grpc_network_status_unregister_endpoint(ep);
   grpc_tcp *tcp = (grpc_tcp *)ep;
-  grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &tcp->last_read_buffer);
   TCP_UNREF(exec_ctx, tcp, "destroy");
 }
 
@@ -235,14 +236,15 @@
       /* We've consumed the edge, request a new one */
       grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
     } else {
-      grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
+      grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                                 tcp->incoming_buffer);
       call_read_cb(exec_ctx, tcp,
                    tcp_annotate_error(GRPC_OS_ERROR(errno, "recvmsg"), tcp));
       TCP_UNREF(exec_ctx, tcp, "read");
     }
   } else if (read_bytes == 0) {
     /* 0 read size ==> end of stream */
-    grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
     call_read_cb(exec_ctx, tcp,
                  tcp_annotate_error(GRPC_ERROR_CREATE("Socket closed"), tcp));
     TCP_UNREF(exec_ctx, tcp, "read");
@@ -268,8 +270,9 @@
                                      grpc_error *error) {
   grpc_tcp *tcp = tcpp;
   if (error != GRPC_ERROR_NONE) {
-    grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
-    grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                               &tcp->last_read_buffer);
     call_read_cb(exec_ctx, tcp, GRPC_ERROR_REF(error));
     TCP_UNREF(exec_ctx, tcp, "read");
   } else {
@@ -294,8 +297,9 @@
   GPR_ASSERT(!tcp->finished_edge);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
-    grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+                                               &tcp->last_read_buffer);
     call_read_cb(exec_ctx, tcp, GRPC_ERROR_REF(error));
     TCP_UNREF(exec_ctx, tcp, "read");
   } else {
@@ -309,7 +313,7 @@
   GPR_ASSERT(tcp->read_cb == NULL);
   tcp->read_cb = cb;
   tcp->incoming_buffer = incoming_buffer;
-  grpc_slice_buffer_reset_and_unref(incoming_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, incoming_buffer);
   grpc_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer);
   TCP_REF(tcp, "read");
   if (tcp->finished_edge) {
@@ -579,7 +583,7 @@
   GPR_ASSERT(ep->vtable == &vtable);
   tcp->release_fd = fd;
   tcp->release_fd_cb = done;
-  grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &tcp->last_read_buffer);
   TCP_UNREF(exec_ctx, tcp, "destroy");
 }
 
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index 179f47e..1e63142 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -167,18 +167,18 @@
         s->so_reuseport =
             has_so_reuseport && (args->args[i].value.integer != 0);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_ALLOW_REUSEPORT
                                  " must be an integer");
       }
     } else if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         s->resource_quota =
-            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                  " must be a pointer to a buffer pool");
@@ -219,7 +219,7 @@
     gpr_free(sp);
   }
 
-  grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
 
   gpr_free(s);
 }
diff --git a/src/core/lib/iomgr/tcp_server_uv.c b/src/core/lib/iomgr/tcp_server_uv.c
index e1a174c..4ccc80c 100644
--- a/src/core/lib/iomgr/tcp_server_uv.c
+++ b/src/core/lib/iomgr/tcp_server_uv.c
@@ -89,11 +89,11 @@
   for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
     if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         s->resource_quota =
-            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                  " must be a pointer to a buffer pool");
@@ -136,7 +136,7 @@
     gpr_free(sp->handle);
     gpr_free(sp);
   }
-  grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
   gpr_free(s);
 }
 
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index b0c8586..053bb35 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -116,11 +116,11 @@
   for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
     if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_POINTER) {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         s->resource_quota =
-            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+            grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
       } else {
-        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
         gpr_free(s);
         return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                  " must be a pointer to a buffer pool");
@@ -155,7 +155,7 @@
     grpc_winsocket_destroy(sp->socket);
     gpr_free(sp);
   }
-  grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
   gpr_free(s);
 }
 
diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c
index 6e2ad1d..f3510bc 100644
--- a/src/core/lib/iomgr/tcp_uv.c
+++ b/src/core/lib/iomgr/tcp_uv.c
@@ -181,7 +181,7 @@
   GPR_ASSERT(tcp->read_cb == NULL);
   tcp->read_cb = cb;
   tcp->read_slices = read_slices;
-  grpc_slice_buffer_reset_and_unref(read_slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices);
   TCP_REF(tcp, "read");
   // TODO(murgatroid99): figure out what the return value here means
   status =
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index d4613b6..8b3b44a 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -53,6 +53,7 @@
 #include "src/core/lib/iomgr/socket_windows.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 #if defined(__MSYS__) && defined(GPR_ARCH_64)
 /* Nasty workaround for nasty bug when using the 64 bits msys compiler
@@ -174,13 +175,13 @@
       char *utf8_message = gpr_format_message(info->wsa_error);
       error = GRPC_ERROR_CREATE(utf8_message);
       gpr_free(utf8_message);
-      grpc_slice_unref(tcp->read_slice);
+      grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
     } else {
       if (info->bytes_transfered != 0 && !tcp->shutting_down) {
         sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered);
         grpc_slice_buffer_add(tcp->read_slices, sub);
       } else {
-        grpc_slice_unref(tcp->read_slice);
+        grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
         error = GRPC_ERROR_CREATE("End of TCP stream");
       }
     }
@@ -209,7 +210,7 @@
 
   tcp->read_cb = cb;
   tcp->read_slices = read_slices;
-  grpc_slice_buffer_reset_and_unref(read_slices);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices);
 
   tcp->read_slice = grpc_slice_malloc(8192);
 
diff --git a/src/core/lib/security/context/security_context.c b/src/core/lib/security/context/security_context.c
index 2204fad..fe82fab 100644
--- a/src/core/lib/security/context/security_context.c
+++ b/src/core/lib/security/context/security_context.c
@@ -47,6 +47,7 @@
 
 grpc_call_error grpc_call_set_credentials(grpc_call *call,
                                           grpc_call_credentials *creds) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_client_security_context *ctx = NULL;
   GRPC_API_TRACE("grpc_call_set_credentials(call=%p, creds=%p)", 2,
                  (call, creds));
@@ -62,9 +63,10 @@
     grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
                           grpc_client_security_context_destroy);
   } else {
-    grpc_call_credentials_unref(ctx->creds);
+    grpc_call_credentials_unref(&exec_ctx, ctx->creds);
     ctx->creds = grpc_call_credentials_ref(creds);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return GRPC_CALL_OK;
 }
 
@@ -96,13 +98,15 @@
 }
 
 void grpc_client_security_context_destroy(void *ctx) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_client_security_context *c = (grpc_client_security_context *)ctx;
-  grpc_call_credentials_unref(c->creds);
+  grpc_call_credentials_unref(&exec_ctx, c->creds);
   GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
   if (c->extension.instance != NULL && c->extension.destroy != NULL) {
     c->extension.destroy(c->extension.instance);
   }
   gpr_free(ctx);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 /* --- grpc_server_security_context --- */
@@ -307,7 +311,7 @@
   memset(property, 0, sizeof(grpc_auth_property));
 }
 
-static void auth_context_pointer_arg_destroy(void *p) {
+static void auth_context_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
   GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg");
 }
 
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.c b/src/core/lib/security/credentials/composite/composite_credentials.c
index d55d00b..be1588d 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.c
+++ b/src/core/lib/security/credentials/composite/composite_credentials.c
@@ -54,18 +54,20 @@
   grpc_credentials_metadata_cb cb;
 } grpc_composite_call_credentials_metadata_context;
 
-static void composite_call_destruct(grpc_call_credentials *creds) {
+static void composite_call_destruct(grpc_exec_ctx *exec_ctx,
+                                    grpc_call_credentials *creds) {
   grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
   size_t i;
   for (i = 0; i < c->inner.num_creds; i++) {
-    grpc_call_credentials_unref(c->inner.creds_array[i]);
+    grpc_call_credentials_unref(exec_ctx, c->inner.creds_array[i]);
   }
   gpr_free(c->inner.creds_array);
 }
 
 static void composite_call_md_context_destroy(
+    grpc_exec_ctx *exec_ctx,
     grpc_composite_call_credentials_metadata_context *ctx) {
-  grpc_credentials_md_store_unref(ctx->md_elems);
+  grpc_credentials_md_store_unref(exec_ctx, ctx->md_elems);
   gpr_free(ctx);
 }
 
@@ -103,7 +105,7 @@
   /* We're done!. */
   ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
           ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK, NULL);
-  composite_call_md_context_destroy(ctx);
+  composite_call_md_context_destroy(exec_ctx, ctx);
 }
 
 static void composite_call_get_request_metadata(
@@ -209,17 +211,19 @@
 
 /* -- Composite channel credentials. -- */
 
-static void composite_channel_destruct(grpc_channel_credentials *creds) {
+static void composite_channel_destruct(grpc_exec_ctx *exec_ctx,
+                                       grpc_channel_credentials *creds) {
   grpc_composite_channel_credentials *c =
       (grpc_composite_channel_credentials *)creds;
-  grpc_channel_credentials_unref(c->inner_creds);
-  grpc_call_credentials_unref(c->call_creds);
+  grpc_channel_credentials_unref(exec_ctx, c->inner_creds);
+  grpc_call_credentials_unref(exec_ctx, c->call_creds);
 }
 
 static grpc_security_status composite_channel_create_security_connector(
-    grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   grpc_composite_channel_credentials *c =
       (grpc_composite_channel_credentials *)creds;
   grpc_security_status status = GRPC_SECURITY_ERROR;
@@ -233,11 +237,12 @@
     grpc_call_credentials *composite_call_creds =
         grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL);
     status = c->inner_creds->vtable->create_security_connector(
-        c->inner_creds, composite_call_creds, target, args, sc, new_args);
-    grpc_call_credentials_unref(composite_call_creds);
+        exec_ctx, c->inner_creds, composite_call_creds, target, args, sc,
+        new_args);
+    grpc_call_credentials_unref(exec_ctx, composite_call_creds);
   } else {
     status = c->inner_creds->vtable->create_security_connector(
-        c->inner_creds, c->call_creds, target, args, sc, new_args);
+        exec_ctx, c->inner_creds, c->call_creds, target, args, sc, new_args);
   }
   return status;
 }
diff --git a/src/core/lib/security/credentials/credentials.c b/src/core/lib/security/credentials/credentials.c
index 1149e5c..9781a22 100644
--- a/src/core/lib/security/credentials/credentials.c
+++ b/src/core/lib/security/credentials/credentials.c
@@ -66,8 +66,8 @@
 }
 
 void grpc_credentials_metadata_request_destroy(
-    grpc_credentials_metadata_request *r) {
-  grpc_call_credentials_unref(r->creds);
+    grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *r) {
+  grpc_call_credentials_unref(exec_ctx, r->creds);
   grpc_http_response_destroy(&r->response);
   gpr_free(r);
 }
@@ -79,17 +79,22 @@
   return creds;
 }
 
-void grpc_channel_credentials_unref(grpc_channel_credentials *creds) {
+void grpc_channel_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                    grpc_channel_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) {
+      creds->vtable->destruct(exec_ctx, creds);
+    }
     gpr_free(creds);
   }
 }
 
 void grpc_channel_credentials_release(grpc_channel_credentials *creds) {
   GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds));
-  grpc_channel_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_channel_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
@@ -98,17 +103,22 @@
   return creds;
 }
 
-void grpc_call_credentials_unref(grpc_call_credentials *creds) {
+void grpc_call_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                 grpc_call_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) {
+      creds->vtable->destruct(exec_ctx, creds);
+    }
     gpr_free(creds);
   }
 }
 
 void grpc_call_credentials_release(grpc_call_credentials *creds) {
   GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
-  grpc_call_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 void grpc_call_credentials_get_request_metadata(
@@ -126,16 +136,16 @@
 }
 
 grpc_security_status grpc_channel_credentials_create_security_connector(
-    grpc_channel_credentials *channel_creds, const char *target,
-    const grpc_channel_args *args, grpc_channel_security_connector **sc,
-    grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *channel_creds,
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
   *new_args = NULL;
   if (channel_creds == NULL) {
     return GRPC_SECURITY_ERROR;
   }
   GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL);
   return channel_creds->vtable->create_security_connector(
-      channel_creds, NULL, target, args, sc, new_args);
+      exec_ctx, channel_creds, NULL, target, args, sc, new_args);
 }
 
 grpc_channel_credentials *
@@ -157,10 +167,13 @@
   return creds;
 }
 
-void grpc_server_credentials_unref(grpc_server_credentials *creds) {
+void grpc_server_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_server_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) {
+      creds->vtable->destruct(exec_ctx, creds);
+    }
     if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
       creds->processor.destroy(creds->processor.state);
     }
@@ -170,16 +183,19 @@
 
 void grpc_server_credentials_release(grpc_server_credentials *creds) {
   GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds));
-  grpc_server_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_server_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 grpc_security_status grpc_server_credentials_create_security_connector(
-    grpc_server_credentials *creds, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+    grpc_server_security_connector **sc) {
   if (creds == NULL || creds->vtable->create_security_connector == NULL) {
     gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
     return GRPC_SECURITY_ERROR;
   }
-  return creds->vtable->create_security_connector(creds, sc);
+  return creds->vtable->create_security_connector(exec_ctx, creds, sc);
 }
 
 void grpc_server_credentials_set_auth_metadata_processor(
@@ -196,8 +212,9 @@
   creds->processor = processor;
 }
 
-static void server_credentials_pointer_arg_destroy(void *p) {
-  grpc_server_credentials_unref(p);
+static void server_credentials_pointer_arg_destroy(grpc_exec_ctx *exec_ctx,
+                                                   void *p) {
+  grpc_server_credentials_unref(exec_ctx, p);
 }
 
 static void *server_credentials_pointer_arg_copy(void *p) {
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 85b3bc5..3011df6 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -101,12 +101,13 @@
 /* --- grpc_channel_credentials. --- */
 
 typedef struct {
-  void (*destruct)(grpc_channel_credentials *c);
+  void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c);
 
   grpc_security_status (*create_security_connector)(
-      grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-      const char *target, const grpc_channel_args *args,
-      grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+      grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+      grpc_call_credentials *call_creds, const char *target,
+      const grpc_channel_args *args, grpc_channel_security_connector **sc,
+      grpc_channel_args **new_args);
 
   grpc_channel_credentials *(*duplicate_without_call_credentials)(
       grpc_channel_credentials *c);
@@ -120,16 +121,17 @@
 
 grpc_channel_credentials *grpc_channel_credentials_ref(
     grpc_channel_credentials *creds);
-void grpc_channel_credentials_unref(grpc_channel_credentials *creds);
+void grpc_channel_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                    grpc_channel_credentials *creds);
 
 /* Creates a security connector for the channel. May also create new channel
    args for the channel to be used in place of the passed in const args if
    returned non NULL. In that case the caller is responsible for destroying
    new_args after channel creation. */
 grpc_security_status grpc_channel_credentials_create_security_connector(
-    grpc_channel_credentials *creds, const char *target,
-    const grpc_channel_args *args, grpc_channel_security_connector **sc,
-    grpc_channel_args **new_args);
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args);
 
 /* Creates a version of the channel credentials without any attached call
    credentials. This can be used in order to open a channel to a non-trusted
@@ -162,7 +164,8 @@
                                             const char *key, const char *value);
 grpc_credentials_md_store *grpc_credentials_md_store_ref(
     grpc_credentials_md_store *store);
-void grpc_credentials_md_store_unref(grpc_credentials_md_store *store);
+void grpc_credentials_md_store_unref(grpc_exec_ctx *exec_ctx,
+                                     grpc_credentials_md_store *store);
 
 /* --- grpc_call_credentials. --- */
 
@@ -172,7 +175,7 @@
     size_t num_md, grpc_credentials_status status, const char *error_details);
 
 typedef struct {
-  void (*destruct)(grpc_call_credentials *c);
+  void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_call_credentials *c);
   void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
                                grpc_call_credentials *c,
                                grpc_polling_entity *pollent,
@@ -188,7 +191,8 @@
 };
 
 grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds);
-void grpc_call_credentials_unref(grpc_call_credentials *creds);
+void grpc_call_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                 grpc_call_credentials *creds);
 void grpc_call_credentials_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_polling_entity *pollent, grpc_auth_metadata_context context,
@@ -202,9 +206,10 @@
 /* --- grpc_server_credentials. --- */
 
 typedef struct {
-  void (*destruct)(grpc_server_credentials *c);
+  void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_server_credentials *c);
   grpc_security_status (*create_security_connector)(
-      grpc_server_credentials *c, grpc_server_security_connector **sc);
+      grpc_exec_ctx *exec_ctx, grpc_server_credentials *c,
+      grpc_server_security_connector **sc);
 } grpc_server_credentials_vtable;
 
 struct grpc_server_credentials {
@@ -215,12 +220,14 @@
 };
 
 grpc_security_status grpc_server_credentials_create_security_connector(
-    grpc_server_credentials *creds, grpc_server_security_connector **sc);
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+    grpc_server_security_connector **sc);
 
 grpc_server_credentials *grpc_server_credentials_ref(
     grpc_server_credentials *creds);
 
-void grpc_server_credentials_unref(grpc_server_credentials *creds);
+void grpc_server_credentials_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_server_credentials *creds);
 
 #define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials"
 
@@ -243,6 +250,6 @@
     void *user_data);
 
 void grpc_credentials_metadata_request_destroy(
-    grpc_credentials_metadata_request *r);
+    grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *r);
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/credentials_metadata.c b/src/core/lib/security/credentials/credentials_metadata.c
index e6cb567..68da5fb 100644
--- a/src/core/lib/security/credentials/credentials_metadata.c
+++ b/src/core/lib/security/credentials/credentials_metadata.c
@@ -37,6 +37,8 @@
 
 #include <string.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 static void store_ensure_capacity(grpc_credentials_md_store *store) {
   if (store->num_entries == store->allocated) {
     store->allocated = (store->allocated == 0) ? 1 : store->allocated * 2;
@@ -62,8 +64,8 @@
                                    grpc_slice key, grpc_slice value) {
   if (store == NULL) return;
   store_ensure_capacity(store);
-  store->entries[store->num_entries].key = grpc_slice_ref(key);
-  store->entries[store->num_entries].value = grpc_slice_ref(value);
+  store->entries[store->num_entries].key = grpc_slice_ref_internal(key);
+  store->entries[store->num_entries].value = grpc_slice_ref_internal(value);
   store->num_entries++;
 }
 
@@ -85,14 +87,15 @@
   return store;
 }
 
-void grpc_credentials_md_store_unref(grpc_credentials_md_store *store) {
+void grpc_credentials_md_store_unref(grpc_exec_ctx *exec_ctx,
+                                     grpc_credentials_md_store *store) {
   if (store == NULL) return;
   if (gpr_unref(&store->refcount)) {
     if (store->entries != NULL) {
       size_t i;
       for (i = 0; i < store->num_entries; i++) {
-        grpc_slice_unref(store->entries[i].key);
-        grpc_slice_unref(store->entries[i].value);
+        grpc_slice_unref_internal(exec_ctx, store->entries[i].key);
+        grpc_slice_unref_internal(exec_ctx, store->entries[i].value);
       }
       gpr_free(store->entries);
     }
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.c
index ea4cb76..f41184f 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.c
@@ -45,16 +45,18 @@
 /* -- Fake transport security credentials. -- */
 
 static grpc_security_status fake_transport_security_create_security_connector(
-    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   *sc = grpc_fake_channel_security_connector_create(call_creds);
   return GRPC_SECURITY_OK;
 }
 
 static grpc_security_status
 fake_transport_security_server_create_security_connector(
-    grpc_server_credentials *c, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *c,
+    grpc_server_security_connector **sc) {
   *sc = grpc_fake_server_security_connector_create();
   return GRPC_SECURITY_OK;
 }
@@ -89,9 +91,10 @@
 
 /* -- Metadata-only test credentials. -- */
 
-static void md_only_test_destruct(grpc_call_credentials *creds) {
+static void md_only_test_destruct(grpc_exec_ctx *exec_ctx,
+                                  grpc_call_credentials *creds) {
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
-  grpc_credentials_md_store_unref(c->md_store);
+  grpc_credentials_md_store_unref(exec_ctx, c->md_store);
 }
 
 static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
@@ -101,7 +104,7 @@
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
   r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
         GRPC_CREDENTIALS_OK, NULL);
-  grpc_credentials_metadata_request_destroy(r);
+  grpc_credentials_metadata_request_destroy(exec_ctx, r);
 }
 
 static void md_only_test_get_request_metadata(
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index afe0e3d..4afeb4a 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -45,6 +45,7 @@
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
@@ -101,11 +102,10 @@
   grpc_pollset_destroy(p);
 }
 
-static int is_stack_running_on_compute_engine(void) {
+static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
   compute_engine_detector detector;
   grpc_httpcli_request request;
   grpc_httpcli_context context;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_closure destroy_closure;
 
   /* The http call is local. If it takes more than one sec, it is for sure not
@@ -128,13 +128,13 @@
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("google_default_credentials");
   grpc_httpcli_get(
-      &exec_ctx, &context, &detector.pollent, resource_quota, &request,
+      exec_ctx, &context, &detector.pollent, resource_quota, &request,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
       grpc_closure_create(on_compute_engine_detection_http_response, &detector),
       &detector.response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 
-  grpc_exec_ctx_flush(&exec_ctx);
+  grpc_exec_ctx_flush(exec_ctx);
 
   /* Block until we get the response. This is not ideal but this should only be
      called once for the lifetime of the process by the default credentials. */
@@ -143,7 +143,7 @@
     grpc_pollset_worker *worker = NULL;
     if (!GRPC_LOG_IF_ERROR(
             "pollset_work",
-            grpc_pollset_work(&exec_ctx,
+            grpc_pollset_work(exec_ctx,
                               grpc_polling_entity_pollset(&detector.pollent),
                               &worker, gpr_now(GPR_CLOCK_MONOTONIC),
                               gpr_inf_future(GPR_CLOCK_MONOTONIC)))) {
@@ -156,11 +156,11 @@
   grpc_httpcli_context_destroy(&context);
   grpc_closure_init(&destroy_closure, destroy_pollset,
                     grpc_polling_entity_pollset(&detector.pollent));
-  grpc_pollset_shutdown(&exec_ctx,
+  grpc_pollset_shutdown(exec_ctx,
                         grpc_polling_entity_pollset(&detector.pollent),
                         &destroy_closure);
-  grpc_exec_ctx_finish(&exec_ctx);
   g_polling_mu = NULL;
+  grpc_exec_ctx_flush(exec_ctx);
 
   gpr_free(grpc_polling_entity_pollset(&detector.pollent));
   grpc_http_response_destroy(&detector.response);
@@ -170,7 +170,7 @@
 
 /* Takes ownership of creds_path if not NULL. */
 static grpc_error *create_default_creds_from_path(
-    char *creds_path, grpc_call_credentials **creds) {
+    grpc_exec_ctx *exec_ctx, char *creds_path, grpc_call_credentials **creds) {
   grpc_json *json = NULL;
   grpc_auth_json_key key;
   grpc_auth_refresh_token token;
@@ -200,7 +200,7 @@
   if (grpc_auth_json_key_is_valid(&key)) {
     result =
         grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-            key, grpc_max_auth_token_lifetime());
+            exec_ctx, key, grpc_max_auth_token_lifetime());
     if (result == NULL) {
       error = GRPC_ERROR_CREATE(
           "grpc_service_account_jwt_access_credentials_create_from_auth_json_"
@@ -225,7 +225,7 @@
 end:
   GPR_ASSERT((result == NULL) + (error == GRPC_ERROR_NONE) == 1);
   if (creds_path != NULL) gpr_free(creds_path);
-  grpc_slice_unref(creds_data);
+  grpc_slice_unref_internal(exec_ctx, creds_data);
   if (json != NULL) grpc_json_destroy(json);
   *creds = result;
   return error;
@@ -236,6 +236,7 @@
   grpc_call_credentials *call_creds = NULL;
   grpc_error *error = GRPC_ERROR_CREATE("Failed to create Google credentials");
   grpc_error *err;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
 
@@ -250,20 +251,22 @@
 
   /* First, try the environment variable. */
   err = create_default_creds_from_path(
-      gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
+      &exec_ctx, gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
   if (err == GRPC_ERROR_NONE) goto end;
   error = grpc_error_add_child(error, err);
 
   /* Then the well-known file. */
   err = create_default_creds_from_path(
-      grpc_get_well_known_google_credentials_file_path(), &call_creds);
+      &exec_ctx, grpc_get_well_known_google_credentials_file_path(),
+      &call_creds);
   if (err == GRPC_ERROR_NONE) goto end;
   error = grpc_error_add_child(error, err);
 
   /* At last try to see if we're on compute engine (do the detection only once
      since it requires a network test). */
   if (!compute_engine_detection_done) {
-    int need_compute_engine_creds = is_stack_running_on_compute_engine();
+    int need_compute_engine_creds =
+        is_stack_running_on_compute_engine(&exec_ctx);
     compute_engine_detection_done = 1;
     if (need_compute_engine_creds) {
       call_creds = grpc_google_compute_engine_credentials_create(NULL);
@@ -286,8 +289,8 @@
           grpc_composite_channel_credentials_create(ssl_creds, call_creds,
                                                     NULL));
       GPR_ASSERT(default_credentials != NULL);
-      grpc_channel_credentials_unref(ssl_creds);
-      grpc_call_credentials_unref(call_creds);
+      grpc_channel_credentials_unref(&exec_ctx, ssl_creds);
+      grpc_call_credentials_unref(&exec_ctx, call_creds);
       result = default_credentials;
     } else {
       gpr_log(GPR_ERROR, "Could not create google default credentials.");
@@ -299,18 +302,21 @@
   } else {
     GRPC_ERROR_UNREF(error);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return result;
 }
 
 void grpc_flush_cached_google_default_credentials(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_once_init(&g_once, init_default_credentials);
   gpr_mu_lock(&g_state_mu);
   if (default_credentials != NULL) {
-    grpc_channel_credentials_unref(default_credentials);
+    grpc_channel_credentials_unref(&exec_ctx, default_credentials);
     default_credentials = NULL;
   }
   compute_engine_detection_done = 0;
   gpr_mu_unlock(&g_state_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 /* -- Well known credentials path. -- */
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.c b/src/core/lib/security/credentials/iam/iam_credentials.c
index 370a384..abd69a9 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.c
+++ b/src/core/lib/security/credentials/iam/iam_credentials.c
@@ -42,9 +42,10 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 
-static void iam_destruct(grpc_call_credentials *creds) {
+static void iam_destruct(grpc_exec_ctx *exec_ctx,
+                         grpc_call_credentials *creds) {
   grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
-  grpc_credentials_md_store_unref(c->iam_md);
+  grpc_credentials_md_store_unref(exec_ctx, c->iam_md);
 }
 
 static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.c b/src/core/lib/security/credentials/jwt/jwt_credentials.c
index 3daf0f4..616be64 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.c
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.c
@@ -42,9 +42,10 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 
-static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
+static void jwt_reset_cache(grpc_exec_ctx *exec_ctx,
+                            grpc_service_account_jwt_access_credentials *c) {
   if (c->cached.jwt_md != NULL) {
-    grpc_credentials_md_store_unref(c->cached.jwt_md);
+    grpc_credentials_md_store_unref(exec_ctx, c->cached.jwt_md);
     c->cached.jwt_md = NULL;
   }
   if (c->cached.service_url != NULL) {
@@ -54,11 +55,12 @@
   c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
 }
 
-static void jwt_destruct(grpc_call_credentials *creds) {
+static void jwt_destruct(grpc_exec_ctx *exec_ctx,
+                         grpc_call_credentials *creds) {
   grpc_service_account_jwt_access_credentials *c =
       (grpc_service_account_jwt_access_credentials *)creds;
   grpc_auth_json_key_destruct(&c->key);
-  jwt_reset_cache(c);
+  jwt_reset_cache(exec_ctx, c);
   gpr_mu_destroy(&c->cache_mu);
 }
 
@@ -92,7 +94,7 @@
     char *jwt = NULL;
     /* Generate a new jwt. */
     gpr_mu_lock(&c->cache_mu);
-    jwt_reset_cache(c);
+    jwt_reset_cache(exec_ctx, c);
     jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url,
                                    c->jwt_lifetime, NULL);
     if (jwt != NULL) {
@@ -114,7 +116,7 @@
   if (jwt_md != NULL) {
     cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries,
        GRPC_CREDENTIALS_OK, NULL);
-    grpc_credentials_md_store_unref(jwt_md);
+    grpc_credentials_md_store_unref(exec_ctx, jwt_md);
   } else {
     cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
        "Could not generate JWT.");
@@ -126,7 +128,8 @@
 
 grpc_call_credentials *
 grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-    grpc_auth_json_key key, gpr_timespec token_lifetime) {
+    grpc_exec_ctx *exec_ctx, grpc_auth_json_key key,
+    gpr_timespec token_lifetime) {
   grpc_service_account_jwt_access_credentials *c;
   if (!grpc_auth_json_key_is_valid(&key)) {
     gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
@@ -140,7 +143,7 @@
   c->key = key;
   c->jwt_lifetime = token_lifetime;
   gpr_mu_init(&c->cache_mu);
-  jwt_reset_cache(c);
+  jwt_reset_cache(exec_ctx, c);
   return &c->base;
 }
 
@@ -183,6 +186,11 @@
     gpr_free(clean_json);
   }
   GPR_ASSERT(reserved == NULL);
-  return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-      grpc_auth_json_key_create_from_string(json_key), token_lifetime);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call_credentials *creds =
+      grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
+          &exec_ctx, grpc_auth_json_key_create_from_string(json_key),
+          token_lifetime);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return creds;
 }
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h
index d572606..39b7aea 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.h
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h
@@ -57,6 +57,7 @@
 // Takes ownership of the key.
 grpc_call_credentials *
 grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
-    grpc_auth_json_key key, gpr_timespec token_lifetime);
+    grpc_exec_ctx *exec_ctx, grpc_auth_json_key key,
+    gpr_timespec token_lifetime);
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 42bd89d..71febc2 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -36,11 +36,6 @@
 #include <limits.h>
 #include <string.h>
 
-#include "src/core/lib/http/httpcli.h"
-#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/security/util/b64.h"
-#include "src/core/lib/tsi/ssl_types.h"
-
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
@@ -48,6 +43,12 @@
 #include <grpc/support/useful.h>
 #include <openssl/pem.h>
 
+#include "src/core/lib/http/httpcli.h"
+#include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/tsi/ssl_types.h"
+
 /* --- Utils. --- */
 
 const char *grpc_jwt_verifier_status_to_string(
@@ -84,11 +85,12 @@
   }
 }
 
-static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
+static grpc_json *parse_json_part_from_jwt(grpc_exec_ctx *exec_ctx,
+                                           const char *str, size_t len,
                                            grpc_slice *buffer) {
   grpc_json *json;
 
-  *buffer = grpc_base64_decode_with_len(str, len, 1);
+  *buffer = grpc_base64_decode_with_len(exec_ctx, str, len, 1);
   if (GRPC_SLICE_IS_EMPTY(*buffer)) {
     gpr_log(GPR_ERROR, "Invalid base64.");
     return NULL;
@@ -96,7 +98,7 @@
   json = grpc_json_parse_string_with_len((char *)GRPC_SLICE_START_PTR(*buffer),
                                          GRPC_SLICE_LENGTH(*buffer));
   if (json == NULL) {
-    grpc_slice_unref(*buffer);
+    grpc_slice_unref_internal(exec_ctx, *buffer);
     gpr_log(GPR_ERROR, "JSON parsing error.");
   }
   return json;
@@ -132,13 +134,14 @@
   grpc_slice buffer;
 } jose_header;
 
-static void jose_header_destroy(jose_header *h) {
-  grpc_slice_unref(h->buffer);
+static void jose_header_destroy(grpc_exec_ctx *exec_ctx, jose_header *h) {
+  grpc_slice_unref_internal(exec_ctx, h->buffer);
   gpr_free(h);
 }
 
 /* Takes ownership of json and buffer. */
-static jose_header *jose_header_from_json(grpc_json *json, grpc_slice buffer) {
+static jose_header *jose_header_from_json(grpc_exec_ctx *exec_ctx,
+                                          grpc_json *json, grpc_slice buffer) {
   grpc_json *cur;
   jose_header *h = gpr_malloc(sizeof(jose_header));
   memset(h, 0, sizeof(jose_header));
@@ -173,7 +176,7 @@
 
 error:
   grpc_json_destroy(json);
-  jose_header_destroy(h);
+  jose_header_destroy(exec_ctx, h);
   return NULL;
 }
 
@@ -193,9 +196,9 @@
   grpc_slice buffer;
 };
 
-void grpc_jwt_claims_destroy(grpc_jwt_claims *claims) {
+void grpc_jwt_claims_destroy(grpc_exec_ctx *exec_ctx, grpc_jwt_claims *claims) {
   grpc_json_destroy(claims->json);
-  grpc_slice_unref(claims->buffer);
+  grpc_slice_unref_internal(exec_ctx, claims->buffer);
   gpr_free(claims);
 }
 
@@ -240,7 +243,8 @@
 }
 
 /* Takes ownership of json and buffer even in case of failure. */
-grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer) {
+grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_exec_ctx *exec_ctx,
+                                           grpc_json *json, grpc_slice buffer) {
   grpc_json *cur;
   grpc_jwt_claims *claims = gpr_malloc(sizeof(grpc_jwt_claims));
   memset(claims, 0, sizeof(grpc_jwt_claims));
@@ -281,7 +285,7 @@
   return claims;
 
 error:
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(exec_ctx, claims);
   return NULL;
 }
 
@@ -362,12 +366,12 @@
   return ctx;
 }
 
-void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) {
+void verifier_cb_ctx_destroy(grpc_exec_ctx *exec_ctx, verifier_cb_ctx *ctx) {
   if (ctx->audience != NULL) gpr_free(ctx->audience);
-  if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims);
-  grpc_slice_unref(ctx->signature);
-  grpc_slice_unref(ctx->signed_data);
-  jose_header_destroy(ctx->header);
+  if (ctx->claims != NULL) grpc_jwt_claims_destroy(exec_ctx, ctx->claims);
+  grpc_slice_unref_internal(exec_ctx, ctx->signature);
+  grpc_slice_unref_internal(exec_ctx, ctx->signed_data);
+  jose_header_destroy(exec_ctx, ctx->header);
   for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) {
     grpc_http_response_destroy(&ctx->responses[i]);
   }
@@ -447,23 +451,24 @@
   return result;
 }
 
-static BIGNUM *bignum_from_base64(const char *b64) {
+static BIGNUM *bignum_from_base64(grpc_exec_ctx *exec_ctx, const char *b64) {
   BIGNUM *result = NULL;
   grpc_slice bin;
 
   if (b64 == NULL) return NULL;
-  bin = grpc_base64_decode(b64, 1);
+  bin = grpc_base64_decode(exec_ctx, b64, 1);
   if (GRPC_SLICE_IS_EMPTY(bin)) {
     gpr_log(GPR_ERROR, "Invalid base64 for big num.");
     return NULL;
   }
   result = BN_bin2bn(GRPC_SLICE_START_PTR(bin),
                      TSI_SIZE_AS_SIZE(GRPC_SLICE_LENGTH(bin)), NULL);
-  grpc_slice_unref(bin);
+  grpc_slice_unref_internal(exec_ctx, bin);
   return result;
 }
 
-static EVP_PKEY *pkey_from_jwk(const grpc_json *json, const char *kty) {
+static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
+                               const char *kty) {
   const grpc_json *key_prop;
   RSA *rsa = NULL;
   EVP_PKEY *result = NULL;
@@ -480,10 +485,12 @@
   }
   for (key_prop = json->child; key_prop != NULL; key_prop = key_prop->next) {
     if (strcmp(key_prop->key, "n") == 0) {
-      rsa->n = bignum_from_base64(validate_string_field(key_prop, "n"));
+      rsa->n =
+          bignum_from_base64(exec_ctx, validate_string_field(key_prop, "n"));
       if (rsa->n == NULL) goto end;
     } else if (strcmp(key_prop->key, "e") == 0) {
-      rsa->e = bignum_from_base64(validate_string_field(key_prop, "e"));
+      rsa->e =
+          bignum_from_base64(exec_ctx, validate_string_field(key_prop, "e"));
       if (rsa->e == NULL) goto end;
     }
   }
@@ -499,7 +506,8 @@
   return result;
 }
 
-static EVP_PKEY *find_verification_key(const grpc_json *json,
+static EVP_PKEY *find_verification_key(grpc_exec_ctx *exec_ctx,
+                                       const grpc_json *json,
                                        const char *header_alg,
                                        const char *header_kid) {
   const grpc_json *jkey;
@@ -543,7 +551,7 @@
     }
     if (alg != NULL && kid != NULL && kty != NULL &&
         strcmp(kid, header_kid) == 0 && strcmp(alg, header_alg) == 0) {
-      return pkey_from_jwk(jkey, kty);
+      return pkey_from_jwk(exec_ctx, jkey, kty);
     }
   }
   gpr_log(GPR_ERROR,
@@ -597,7 +605,7 @@
     goto end;
   }
   verification_key =
-      find_verification_key(json, ctx->header->alg, ctx->header->kid);
+      find_verification_key(exec_ctx, json, ctx->header->alg, ctx->header->kid);
   if (verification_key == NULL) {
     gpr_log(GPR_ERROR, "Could not find verification key with kid %s.",
             ctx->header->kid);
@@ -621,8 +629,8 @@
 end:
   if (json != NULL) grpc_json_destroy(json);
   if (verification_key != NULL) EVP_PKEY_free(verification_key);
-  ctx->user_cb(ctx->user_data, status, claims);
-  verifier_cb_ctx_destroy(ctx);
+  ctx->user_cb(exec_ctx, ctx->user_data, status, claims);
+  verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
 static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
@@ -667,15 +675,16 @@
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       grpc_closure_create(on_keys_retrieved, ctx),
       &ctx->responses[HTTP_RESPONSE_KEYS]);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   grpc_json_destroy(json);
   gpr_free(req.host);
   return;
 
 error:
   if (json != NULL) grpc_json_destroy(json);
-  ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
-  verifier_cb_ctx_destroy(ctx);
+  ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
+               NULL);
+  verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
 static email_key_mapping *verifier_get_mapping(grpc_jwt_verifier *v,
@@ -779,14 +788,15 @@
       exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       http_cb, &ctx->responses[rsp_idx]);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   gpr_free(req.host);
   gpr_free(req.http.path);
   return;
 
 error:
-  ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
-  verifier_cb_ctx_destroy(ctx);
+  ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
+               NULL);
+  verifier_cb_ctx_destroy(exec_ctx, ctx);
 }
 
 void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
@@ -808,22 +818,24 @@
   GPR_ASSERT(verifier != NULL && jwt != NULL && audience != NULL && cb != NULL);
   dot = strchr(cur, '.');
   if (dot == NULL) goto error;
-  json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &header_buffer);
+  json = parse_json_part_from_jwt(exec_ctx, cur, (size_t)(dot - cur),
+                                  &header_buffer);
   if (json == NULL) goto error;
-  header = jose_header_from_json(json, header_buffer);
+  header = jose_header_from_json(exec_ctx, json, header_buffer);
   if (header == NULL) goto error;
 
   cur = dot + 1;
   dot = strchr(cur, '.');
   if (dot == NULL) goto error;
-  json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &claims_buffer);
+  json = parse_json_part_from_jwt(exec_ctx, cur, (size_t)(dot - cur),
+                                  &claims_buffer);
   if (json == NULL) goto error;
-  claims = grpc_jwt_claims_from_json(json, claims_buffer);
+  claims = grpc_jwt_claims_from_json(exec_ctx, json, claims_buffer);
   if (claims == NULL) goto error;
 
   signed_jwt_len = (size_t)(dot - jwt);
   cur = dot + 1;
-  signature = grpc_base64_decode(cur, 1);
+  signature = grpc_base64_decode(exec_ctx, cur, 1);
   if (GRPC_SLICE_IS_EMPTY(signature)) goto error;
   retrieve_key_and_verify(
       exec_ctx,
@@ -832,9 +844,9 @@
   return;
 
 error:
-  if (header != NULL) jose_header_destroy(header);
-  if (claims != NULL) grpc_jwt_claims_destroy(claims);
-  cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
+  if (header != NULL) jose_header_destroy(exec_ctx, header);
+  if (claims != NULL) grpc_jwt_claims_destroy(exec_ctx, claims);
+  cb(exec_ctx, user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
 }
 
 grpc_jwt_verifier *grpc_jwt_verifier_create(
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index f09f9d5..b79f411 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -66,7 +66,7 @@
 
 typedef struct grpc_jwt_claims grpc_jwt_claims;
 
-void grpc_jwt_claims_destroy(grpc_jwt_claims *claims);
+void grpc_jwt_claims_destroy(grpc_exec_ctx *exec_ctx, grpc_jwt_claims *claims);
 
 /* Returns the whole JSON tree of the claims. */
 const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims);
@@ -115,7 +115,8 @@
    is done (maybe in another thread).
    It is the responsibility of the callee to call grpc_jwt_claims_destroy on
    the claims. */
-typedef void (*grpc_jwt_verification_done_cb)(void *user_data,
+typedef void (*grpc_jwt_verification_done_cb)(grpc_exec_ctx *exec_ctx,
+                                              void *user_data,
                                               grpc_jwt_verifier_status status,
                                               grpc_jwt_claims *claims);
 
@@ -129,7 +130,8 @@
 
 /* --- TESTING ONLY exposed functions. --- */
 
-grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer);
+grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_exec_ctx *exec_ctx,
+                                           grpc_json *json, grpc_slice buffer);
 grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
                                                const char *audience);
 
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index b3625b2..cbcd749 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -118,18 +118,19 @@
 // Oauth2 Token Fetcher credentials.
 //
 
-static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) {
+static void oauth2_token_fetcher_destruct(grpc_exec_ctx *exec_ctx,
+                                          grpc_call_credentials *creds) {
   grpc_oauth2_token_fetcher_credentials *c =
       (grpc_oauth2_token_fetcher_credentials *)creds;
-  grpc_credentials_md_store_unref(c->access_token_md);
+  grpc_credentials_md_store_unref(exec_ctx, c->access_token_md);
   gpr_mu_destroy(&c->mu);
   grpc_httpcli_context_destroy(&c->httpcli_context);
 }
 
 grpc_credentials_status
 grpc_oauth2_token_fetcher_credentials_parse_server_response(
-    const grpc_http_response *response, grpc_credentials_md_store **token_md,
-    gpr_timespec *token_lifetime) {
+    grpc_exec_ctx *exec_ctx, const grpc_http_response *response,
+    grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime) {
   char *null_terminated_body = NULL;
   char *new_access_token = NULL;
   grpc_credentials_status status = GRPC_CREDENTIALS_OK;
@@ -198,7 +199,7 @@
     token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10);
     token_lifetime->tv_nsec = 0;
     token_lifetime->clock_type = GPR_TIMESPAN;
-    if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md);
+    if (*token_md != NULL) grpc_credentials_md_store_unref(exec_ctx, *token_md);
     *token_md = grpc_credentials_md_store_create(1);
     grpc_credentials_md_store_add_cstrings(
         *token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token);
@@ -207,7 +208,7 @@
 
 end:
   if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) {
-    grpc_credentials_md_store_unref(*token_md);
+    grpc_credentials_md_store_unref(exec_ctx, *token_md);
     *token_md = NULL;
   }
   if (null_terminated_body != NULL) gpr_free(null_terminated_body);
@@ -230,7 +231,7 @@
 
   gpr_mu_lock(&c->mu);
   status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
-      &r->response, &c->access_token_md, &token_lifetime);
+      exec_ctx, &r->response, &c->access_token_md, &token_lifetime);
   if (status == GRPC_CREDENTIALS_OK) {
     c->token_expiration =
         gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
@@ -242,7 +243,7 @@
           "Error occured when fetching oauth2 token.");
   }
   gpr_mu_unlock(&c->mu);
-  grpc_credentials_metadata_request_destroy(r);
+  grpc_credentials_metadata_request_destroy(exec_ctx, r);
 }
 
 static void oauth2_token_fetcher_get_request_metadata(
@@ -268,7 +269,7 @@
   if (cached_access_token_md != NULL) {
     cb(exec_ctx, user_data, cached_access_token_md->entries,
        cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK, NULL);
-    grpc_credentials_md_store_unref(cached_access_token_md);
+    grpc_credentials_md_store_unref(exec_ctx, cached_access_token_md);
   } else {
     c->fetch_func(
         exec_ctx,
@@ -315,7 +316,7 @@
   grpc_httpcli_get(exec_ctx, httpcli_context, pollent, resource_quota, &request,
                    deadline, grpc_closure_create(response_cb, metadata_req),
                    &metadata_req->response);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
 }
 
 grpc_call_credentials *grpc_google_compute_engine_credentials_create(
@@ -334,11 +335,12 @@
 // Google Refresh Token credentials.
 //
 
-static void refresh_token_destruct(grpc_call_credentials *creds) {
+static void refresh_token_destruct(grpc_exec_ctx *exec_ctx,
+                                   grpc_call_credentials *creds) {
   grpc_google_refresh_token_credentials *c =
       (grpc_google_refresh_token_credentials *)creds;
   grpc_auth_refresh_token_destruct(&c->refresh_token);
-  oauth2_token_fetcher_destruct(&c->base.base);
+  oauth2_token_fetcher_destruct(exec_ctx, &c->base.base);
 }
 
 static grpc_call_credentials_vtable refresh_token_vtable = {
@@ -372,7 +374,7 @@
                     &request, body, strlen(body), deadline,
                     grpc_closure_create(response_cb, metadata_req),
                     &metadata_req->response);
-  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
   gpr_free(body);
 }
 
@@ -424,9 +426,10 @@
 // Oauth2 Access Token credentials.
 //
 
-static void access_token_destruct(grpc_call_credentials *creds) {
+static void access_token_destruct(grpc_exec_ctx *exec_ctx,
+                                  grpc_call_credentials *creds) {
   grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
-  grpc_credentials_md_store_unref(c->access_token_md);
+  grpc_credentials_md_store_unref(exec_ctx, c->access_token_md);
 }
 
 static void access_token_get_request_metadata(
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index 7f6f205..2d7c02c 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -103,7 +103,7 @@
 // Exposed for testing only.
 grpc_credentials_status
 grpc_oauth2_token_fetcher_credentials_parse_server_response(
-    const struct grpc_http_response *response,
+    grpc_exec_ctx *exec_ctx, const struct grpc_http_response *response,
     grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime);
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.c b/src/core/lib/security/credentials/plugin/plugin_credentials.c
index 5d95009..f90d7dc 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.c
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.c
@@ -35,20 +35,22 @@
 
 #include <string.h>
 
-#include "src/core/lib/surface/api_trace.h"
-
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/surface/api_trace.h"
+
 typedef struct {
   void *user_data;
   grpc_credentials_metadata_cb cb;
 } grpc_metadata_plugin_request;
 
-static void plugin_destruct(grpc_call_credentials *creds) {
+static void plugin_destruct(grpc_exec_ctx *exec_ctx,
+                            grpc_call_credentials *creds) {
   grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
   if (c->plugin.state != NULL && c->plugin.destroy != NULL) {
     c->plugin.destroy(c->plugin.state);
@@ -100,8 +102,8 @@
       r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK,
             NULL);
       for (i = 0; i < num_md; i++) {
-        grpc_slice_unref(md_array[i].key);
-        grpc_slice_unref(md_array[i].value);
+        grpc_slice_unref_internal(&exec_ctx, md_array[i].key);
+        grpc_slice_unref_internal(&exec_ctx, md_array[i].value);
       }
       gpr_free(md_array);
     } else if (num_md == 0) {
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.c b/src/core/lib/security/credentials/ssl/ssl_credentials.c
index 0dc1fcc..4eebb7d 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.c
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.c
@@ -57,7 +57,8 @@
 // SSL Channel Credentials.
 //
 
-static void ssl_destruct(grpc_channel_credentials *creds) {
+static void ssl_destruct(grpc_exec_ctx *exec_ctx,
+                         grpc_channel_credentials *creds) {
   grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
   if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
   if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
@@ -65,9 +66,10 @@
 }
 
 static grpc_security_status ssl_create_security_connector(
-    grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
   grpc_security_status status = GRPC_SECURITY_OK;
   size_t i = 0;
@@ -83,7 +85,7 @@
     }
   }
   status = grpc_ssl_channel_security_connector_create(
-      call_creds, &c->config, target, overridden_target_name, sc);
+      exec_ctx, call_creds, &c->config, target, overridden_target_name, sc);
   if (status != GRPC_SECURITY_OK) {
     return status;
   }
@@ -138,7 +140,8 @@
 // SSL Server Credentials.
 //
 
-static void ssl_server_destruct(grpc_server_credentials *creds) {
+static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
+                                grpc_server_credentials *creds) {
   grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
   size_t i;
   for (i = 0; i < c->config.num_key_cert_pairs; i++) {
@@ -161,9 +164,10 @@
 }
 
 static grpc_security_status ssl_server_create_security_connector(
-    grpc_server_credentials *creds, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+    grpc_server_security_connector **sc) {
   grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
-  return grpc_ssl_server_security_connector_create(&c->config, sc);
+  return grpc_ssl_server_security_connector_create(exec_ctx, &c->config, sc);
 }
 
 static grpc_server_credentials_vtable ssl_server_vtable = {
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index 053bf59..ae40bb4 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/transport/static_metadata.h"
@@ -93,7 +94,8 @@
   call_data *calld = elem->call_data;
   gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg);
   grpc_slice error_slice = grpc_slice_from_copied_string(error_msg);
-  grpc_transport_stream_op_add_close(&calld->op, status, &error_slice);
+  grpc_transport_stream_op_add_close(exec_ctx, &calld->op, status,
+                                     &error_slice);
   grpc_call_next_op(exec_ctx, elem, &calld->op);
 }
 
@@ -121,8 +123,9 @@
   for (i = 0; i < num_md; i++) {
     grpc_metadata_batch_add_tail(
         mdb, &calld->md_links[i],
-        grpc_mdelem_from_slices(grpc_slice_ref(md_elems[i].key),
-                                grpc_slice_ref(md_elems[i].value)));
+        grpc_mdelem_from_slices(exec_ctx,
+                                grpc_slice_ref_internal(md_elems[i].key),
+                                grpc_slice_ref_internal(md_elems[i].value)));
   }
   grpc_call_next_op(exec_ctx, elem, op);
 }
@@ -248,10 +251,10 @@
       /* Pointer comparison is OK for md_elems created from the same context.
        */
       if (md->key == GRPC_MDSTR_AUTHORITY) {
-        if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host);
+        if (calld->host != NULL) GRPC_MDSTR_UNREF(exec_ctx, calld->host);
         calld->host = GRPC_MDSTR_REF(md->value);
       } else if (md->key == GRPC_MDSTR_PATH) {
-        if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
+        if (calld->method != NULL) GRPC_MDSTR_UNREF(exec_ctx, calld->method);
         calld->method = GRPC_MDSTR_REF(md->value);
       }
     }
@@ -292,12 +295,12 @@
                               const grpc_call_final_info *final_info,
                               void *ignored) {
   call_data *calld = elem->call_data;
-  grpc_call_credentials_unref(calld->creds);
+  grpc_call_credentials_unref(exec_ctx, calld->creds);
   if (calld->host != NULL) {
-    GRPC_MDSTR_UNREF(calld->host);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->host);
   }
   if (calld->method != NULL) {
-    GRPC_MDSTR_UNREF(calld->method);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->method);
   }
   reset_auth_metadata_context(&calld->auth_md_context);
 }
@@ -336,7 +339,7 @@
   channel_data *chand = elem->channel_data;
   grpc_channel_security_connector *sc = chand->security_connector;
   if (sc != NULL) {
-    GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter");
+    GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "client_auth_filter");
   }
   GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
 }
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 1b27841..0e9a392 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -46,6 +46,7 @@
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/tsi_error.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/tsi/transport_security_interface.h"
@@ -80,11 +81,11 @@
   secure_endpoint *ep = secure_ep;
   grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep);
   tsi_frame_protector_destroy(ep->protector);
-  grpc_slice_buffer_destroy(&ep->leftover_bytes);
-  grpc_slice_unref(ep->read_staging_buffer);
-  grpc_slice_unref(ep->write_staging_buffer);
-  grpc_slice_buffer_destroy(&ep->output_buffer);
-  grpc_slice_buffer_destroy(&ep->source_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &ep->leftover_bytes);
+  grpc_slice_unref_internal(exec_ctx, ep->read_staging_buffer);
+  grpc_slice_unref_internal(exec_ctx, ep->write_staging_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &ep->output_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &ep->source_buffer);
   gpr_mu_destroy(&ep->protector_mu);
   gpr_free(ep);
 }
@@ -160,7 +161,7 @@
   uint8_t *end = GRPC_SLICE_END_PTR(ep->read_staging_buffer);
 
   if (error != GRPC_ERROR_NONE) {
-    grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
     call_read_cb(exec_ctx, ep, GRPC_ERROR_CREATE_REFERENCING(
                                    "Secure read failed", &error, 1));
     return;
@@ -215,10 +216,10 @@
 
   /* TODO(yangg) experiment with moving this block after read_cb to see if it
      helps latency */
-  grpc_slice_buffer_reset_and_unref(&ep->source_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->source_buffer);
 
   if (result != TSI_OK) {
-    grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
     call_read_cb(exec_ctx, ep, grpc_set_tsi_error_result(
                                    GRPC_ERROR_CREATE("Unwrap failed"), result));
     return;
@@ -232,7 +233,7 @@
   secure_endpoint *ep = (secure_endpoint *)secure_ep;
   ep->read_cb = cb;
   ep->read_buffer = slices;
-  grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
 
   SECURE_ENDPOINT_REF(ep, "read");
   if (ep->leftover_bytes.count) {
@@ -264,7 +265,7 @@
   uint8_t *cur = GRPC_SLICE_START_PTR(ep->write_staging_buffer);
   uint8_t *end = GRPC_SLICE_END_PTR(ep->write_staging_buffer);
 
-  grpc_slice_buffer_reset_and_unref(&ep->output_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
 
   if (grpc_trace_secure_endpoint) {
     for (i = 0; i < slices->count; i++) {
@@ -328,7 +329,7 @@
 
   if (result != TSI_OK) {
     /* TODO(yangg) do different things according to the error type? */
-    grpc_slice_buffer_reset_and_unref(&ep->output_buffer);
+    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
     grpc_exec_ctx_sched(
         exec_ctx, cb,
         grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Wrap failed"), result),
@@ -407,7 +408,7 @@
   grpc_slice_buffer_init(&ep->leftover_bytes);
   for (i = 0; i < leftover_nslices; i++) {
     grpc_slice_buffer_add(&ep->leftover_bytes,
-                          grpc_slice_ref(leftover_slices[i]));
+                          grpc_slice_ref_internal(leftover_slices[i]));
   }
   ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
   ep->read_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index 5b088aa..c0fdb6e 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -172,7 +172,8 @@
 }
 
 #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
-void grpc_security_connector_unref(grpc_security_connector *sc,
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *sc,
                                    const char *file, int line,
                                    const char *reason) {
   if (sc == NULL) return;
@@ -180,14 +181,15 @@
           "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc,
           (int)sc->refcount.count, (int)sc->refcount.count - 1, reason);
 #else
-void grpc_security_connector_unref(grpc_security_connector *sc) {
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *sc) {
   if (sc == NULL) return;
 #endif
-  if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
+  if (gpr_unref(&sc->refcount)) sc->vtable->destroy(exec_ctx, sc);
 }
 
-static void connector_pointer_arg_destroy(void *p) {
-  GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg_destroy");
+static void connector_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
+  GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, "connector_pointer_arg_destroy");
 }
 
 static void *connector_pointer_arg_copy(void *p) {
@@ -233,13 +235,17 @@
 
 /* -- Fake implementation. -- */
 
-static void fake_channel_destroy(grpc_security_connector *sc) {
+static void fake_channel_destroy(grpc_exec_ctx *exec_ctx,
+                                 grpc_security_connector *sc) {
   grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
-  grpc_call_credentials_unref(c->request_metadata_creds);
+  grpc_call_credentials_unref(exec_ctx, c->request_metadata_creds);
   gpr_free(sc);
 }
 
-static void fake_server_destroy(grpc_security_connector *sc) { gpr_free(sc); }
+static void fake_server_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
+  gpr_free(sc);
+}
 
 static void fake_check_peer(grpc_exec_ctx *exec_ctx,
                             grpc_security_connector *sc, tsi_peer peer,
@@ -351,10 +357,11 @@
   tsi_ssl_handshaker_factory *handshaker_factory;
 } grpc_ssl_server_security_connector;
 
-static void ssl_channel_destroy(grpc_security_connector *sc) {
+static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_security_connector *sc) {
   grpc_ssl_channel_security_connector *c =
       (grpc_ssl_channel_security_connector *)sc;
-  grpc_call_credentials_unref(c->base.request_metadata_creds);
+  grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
   }
@@ -363,7 +370,8 @@
   gpr_free(sc);
 }
 
-static void ssl_server_destroy(grpc_security_connector *sc) {
+static void ssl_server_destroy(grpc_exec_ctx *exec_ctx,
+                               grpc_security_connector *sc) {
   grpc_ssl_server_security_connector *c =
       (grpc_ssl_server_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
@@ -669,7 +677,7 @@
 }
 
 grpc_security_status grpc_ssl_channel_security_connector_create(
-    grpc_call_credentials *request_metadata_creds,
+    grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
     const grpc_ssl_config *config, const char *target_name,
     const char *overridden_target_name, grpc_channel_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
@@ -730,7 +738,7 @@
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
-    ssl_channel_destroy(&c->base.base);
+    ssl_channel_destroy(exec_ctx, &c->base.base);
     *sc = NULL;
     goto error;
   }
@@ -746,7 +754,8 @@
 }
 
 grpc_security_status grpc_ssl_server_security_connector_create(
-    const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
+    grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+    grpc_server_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@@ -786,7 +795,7 @@
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
-    ssl_server_destroy(&c->base.base);
+    ssl_server_destroy(exec_ctx, &c->base.base);
     *sc = NULL;
     goto error;
   }
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index a84b359..eba4e6d 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -60,7 +60,7 @@
 #define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector"
 
 typedef struct {
-  void (*destroy)(grpc_security_connector *sc);
+  void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc);
   void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
                      tsi_peer peer, grpc_auth_context **auth_context,
                      grpc_closure *on_peer_checked);
@@ -81,20 +81,23 @@
 #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
 #define GRPC_SECURITY_CONNECTOR_REF(p, r) \
   grpc_security_connector_ref((p), __FILE__, __LINE__, (r))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \
-  grpc_security_connector_unref((p), __FILE__, __LINE__, (r))
+#define GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, r) \
+  grpc_security_connector_unref((exec_ctx), (p), __FILE__, __LINE__, (r))
 grpc_security_connector *grpc_security_connector_ref(
     grpc_security_connector *policy, const char *file, int line,
     const char *reason);
-void grpc_security_connector_unref(grpc_security_connector *policy,
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *policy,
                                    const char *file, int line,
                                    const char *reason);
 #else
 #define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p))
+#define GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, r) \
+  grpc_security_connector_unref((exec_ctx), (p))
 grpc_security_connector *grpc_security_connector_ref(
     grpc_security_connector *policy);
-void grpc_security_connector_unref(grpc_security_connector *policy);
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+                                   grpc_security_connector *policy);
 #endif
 
 /* Check the peer. Callee takes ownership of the peer object.
@@ -203,7 +206,7 @@
   specific error code otherwise.
 */
 grpc_security_status grpc_ssl_channel_security_connector_create(
-    grpc_call_credentials *request_metadata_creds,
+    grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
     const grpc_ssl_config *config, const char *target_name,
     const char *overridden_target_name, grpc_channel_security_connector **sc);
 
@@ -232,7 +235,8 @@
   specific error code otherwise.
 */
 grpc_security_status grpc_ssl_server_security_connector_create(
-    const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
+    grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+    grpc_server_security_connector **sc);
 
 /* Util. */
 const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
index 41a775d..4f9f97e 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -45,6 +45,7 @@
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/tsi_error.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
 
@@ -86,26 +87,27 @@
       grpc_endpoint_destroy(exec_ctx, h->endpoint_to_destroy);
     }
     if (h->read_buffer_to_destroy != NULL) {
-      grpc_slice_buffer_destroy(h->read_buffer_to_destroy);
+      grpc_slice_buffer_destroy_internal(exec_ctx, h->read_buffer_to_destroy);
       gpr_free(h->read_buffer_to_destroy);
     }
     gpr_free(h->handshake_buffer);
-    grpc_slice_buffer_destroy(&h->left_overs);
-    grpc_slice_buffer_destroy(&h->outgoing);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &h->left_overs);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &h->outgoing);
     GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
-    GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
+    GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, h->connector, "handshake");
     gpr_free(h);
   }
 }
 
 // Set args fields to NULL, saving the endpoint and read buffer for
 // later destruction.
-static void cleanup_args_for_failure_locked(security_handshaker *h) {
+static void cleanup_args_for_failure_locked(grpc_exec_ctx *exec_ctx,
+                                            security_handshaker *h) {
   h->endpoint_to_destroy = h->args->endpoint;
   h->args->endpoint = NULL;
   h->read_buffer_to_destroy = h->args->read_buffer;
   h->args->read_buffer = NULL;
-  grpc_channel_args_destroy(h->args->args);
+  grpc_channel_args_destroy(exec_ctx, h->args->args);
   h->args->args = NULL;
 }
 
@@ -130,10 +132,14 @@
     grpc_endpoint_shutdown(exec_ctx, h->args->endpoint);
     // Not shutting down, so the write failed.  Clean up before
     // invoking the callback.
+<<<<<<< HEAD
+    cleanup_args_for_failure_locked(exec_ctx, h);
+=======
     cleanup_args_for_failure_locked(h);
     // Set shutdown to true so that subsequent calls to
     // security_handshaker_shutdown() do nothing.
     h->shutdown = true;
+>>>>>>> b62bffbea5eef106bfbe644e8af161889c927401
   }
   // Invoke callback.
   grpc_exec_ctx_sched(exec_ctx, h->on_handshake_done, error, NULL);
@@ -165,13 +171,13 @@
   h->left_overs.length = 0;
   // Clear out the read buffer before it gets passed to the transport,
   // since any excess bytes were already copied to h->left_overs.
-  grpc_slice_buffer_reset_and_unref(h->args->read_buffer);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, h->args->read_buffer);
   // Add auth context to channel args.
   grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context);
   grpc_channel_args *tmp_args = h->args->args;
   h->args->args =
       grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1);
-  grpc_channel_args_destroy(tmp_args);
+  grpc_channel_args_destroy(exec_ctx, tmp_args);
   // Invoke callback.
   grpc_exec_ctx_sched(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE, NULL);
   // Set shutdown to true so that subsequent calls to
@@ -218,7 +224,7 @@
   // Send data.
   grpc_slice to_send =
       grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
-  grpc_slice_buffer_reset_and_unref(&h->outgoing);
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing);
   grpc_slice_buffer_add(&h->outgoing, to_send);
   grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing,
                       &h->on_handshake_data_sent_to_peer);
@@ -287,7 +293,7 @@
           grpc_slice_split_tail(&h->args->read_buffer->slices[i],
                                 consumed_slice_size));
       /* split_tail above increments refcount. */
-      grpc_slice_unref(h->args->read_buffer->slices[i]);
+      grpc_slice_unref_internal(exec_ctx, h->args->read_buffer->slices[i]);
     }
     grpc_slice_buffer_addn(
         &h->left_overs, &h->args->read_buffer->slices[i + 1],
@@ -350,7 +356,7 @@
   if (!h->shutdown) {
     h->shutdown = true;
     grpc_endpoint_shutdown(exec_ctx, h->args->endpoint);
-    cleanup_args_for_failure_locked(h);
+    cleanup_args_for_failure_locked(exec_ctx, h);
   }
   gpr_mu_unlock(&h->mu);
 }
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index eaa1d07..7a00697 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -83,7 +83,8 @@
   return result;
 }
 
-static grpc_mdelem *remove_consumed_md(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem *remove_consumed_md(grpc_exec_ctx *exec_ctx, void *user_data,
+                                       grpc_mdelem *md) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
   size_t i;
@@ -129,8 +130,8 @@
   if (status == GRPC_STATUS_OK) {
     calld->consumed_md = consumed_md;
     calld->num_consumed_md = num_consumed_md;
-    grpc_metadata_batch_filter(calld->recv_initial_metadata, remove_consumed_md,
-                               elem);
+    grpc_metadata_batch_filter(&exec_ctx, calld->recv_initial_metadata,
+                               remove_consumed_md, elem);
     grpc_metadata_array_destroy(&calld->md);
     grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv, GRPC_ERROR_NONE, NULL);
   } else {
@@ -149,7 +150,7 @@
     }
     calld->transport_op->send_trailing_metadata = NULL;
     close_op->on_complete = grpc_closure_create(destroy_op, close_op);
-    grpc_transport_stream_op_add_close(close_op, status, &message);
+    grpc_transport_stream_op_add_close(&exec_ctx, close_op, status, &message);
     grpc_call_next_op(&exec_ctx, elem, close_op);
     grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv,
                         grpc_error_set_int(GRPC_ERROR_CREATE(error_details),
@@ -264,7 +265,7 @@
   /* grab pointers to our data from the channel element */
   channel_data *chand = elem->channel_data;
   GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter");
-  grpc_server_credentials_unref(chand->creds);
+  grpc_server_credentials_unref(exec_ctx, chand->creds);
 }
 
 const grpc_channel_filter grpc_server_auth_filter = {
diff --git a/src/core/lib/security/util/b64.c b/src/core/lib/security/util/b64.c
index 4892e8e..bbd7e33 100644
--- a/src/core/lib/security/util/b64.c
+++ b/src/core/lib/security/util/b64.c
@@ -40,6 +40,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 /* --- Constants. --- */
 
 static const int8_t base64_bytes[] = {
@@ -120,8 +122,9 @@
   return result;
 }
 
-grpc_slice grpc_base64_decode(const char *b64, int url_safe) {
-  return grpc_base64_decode_with_len(b64, strlen(b64), url_safe);
+grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
+                              int url_safe) {
+  return grpc_base64_decode_with_len(exec_ctx, b64, strlen(b64), url_safe);
 }
 
 static void decode_one_char(const unsigned char *codes, unsigned char *result,
@@ -182,8 +185,8 @@
   return 1;
 }
 
-grpc_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
-                                       int url_safe) {
+grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
+                                       size_t b64_len, int url_safe) {
   grpc_slice result = grpc_slice_malloc(b64_len);
   unsigned char *current = GRPC_SLICE_START_PTR(result);
   size_t result_size = 0;
@@ -228,6 +231,6 @@
   return result;
 
 fail:
-  grpc_slice_unref(result);
+  grpc_slice_unref_internal(exec_ctx, result);
   return gpr_empty_slice();
 }
diff --git a/src/core/lib/security/util/b64.h b/src/core/lib/security/util/b64.h
index 6ea0b53..d42a136 100644
--- a/src/core/lib/security/util/b64.h
+++ b/src/core/lib/security/util/b64.h
@@ -43,10 +43,11 @@
 
 /* Decodes data according to the base64 specification. Returns an empty
    slice in case of failure. */
-grpc_slice grpc_base64_decode(const char *b64, int url_safe);
+grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
+                              int url_safe);
 
 /* Same as above except that the length is provided by the caller. */
-grpc_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
-                                       int url_safe);
+grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
+                                       size_t b64_len, int url_safe);
 
 #endif /* GRPC_CORE_LIB_SECURITY_UTIL_B64_H */
diff --git a/src/core/lib/slice/percent_encoding.c b/src/core/lib/slice/percent_encoding.c
index b9e35f1..c76c58d 100644
--- a/src/core/lib/slice/percent_encoding.c
+++ b/src/core/lib/slice/percent_encoding.c
@@ -35,6 +35,8 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 const uint8_t grpc_url_percent_encoding_unreserved_bytes[256 / 8] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0xfe, 0xff, 0xff,
     0x87, 0xfe, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -66,7 +68,7 @@
   }
   // no unreserved bytes: return the string unmodified
   if (!any_reserved_bytes) {
-    return grpc_slice_ref(slice);
+    return grpc_slice_ref_internal(slice);
   }
   // second pass: actually encode
   grpc_slice out = grpc_slice_malloc(output_length);
@@ -119,7 +121,7 @@
     }
   }
   if (!any_percent_encoded_stuff) {
-    *slice_out = grpc_slice_ref(slice_in);
+    *slice_out = grpc_slice_ref_internal(slice_in);
     return true;
   }
   p = GRPC_SLICE_START_PTR(slice_in);
@@ -158,7 +160,7 @@
     }
   }
   if (!any_percent_encoded_stuff) {
-    return grpc_slice_ref(slice_in);
+    return grpc_slice_ref_internal(slice_in);
   }
   p = GRPC_SLICE_START_PTR(slice_in);
   grpc_slice out = grpc_slice_malloc(out_length);
diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c
index 52977e6..7611810 100644
--- a/src/core/lib/slice/slice.c
+++ b/src/core/lib/slice/slice.c
@@ -31,12 +31,16 @@
  *
  */
 
+#include "src/core/lib/slice/slice_internal.h"
+
 #include <grpc/slice.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
 #include <string.h>
 
+#include "src/core/lib/iomgr/exec_ctx.h"
+
 grpc_slice gpr_empty_slice(void) {
   grpc_slice out;
   out.refcount = 0;
@@ -44,25 +48,37 @@
   return out;
 }
 
-grpc_slice grpc_slice_ref(grpc_slice slice) {
+grpc_slice grpc_slice_ref_internal(grpc_slice slice) {
   if (slice.refcount) {
     slice.refcount->ref(slice.refcount);
   }
   return slice;
 }
 
-void grpc_slice_unref(grpc_slice slice) {
+void grpc_slice_unref_internal(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
   if (slice.refcount) {
-    slice.refcount->unref(slice.refcount);
+    slice.refcount->unref(exec_ctx, slice.refcount);
   }
 }
 
+/* Public API */
+grpc_slice grpc_slice_ref(grpc_slice slice) {
+  return grpc_slice_ref_internal(slice);
+}
+
+/* Public API */
+void grpc_slice_unref(grpc_slice slice) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_unref_internal(&exec_ctx, slice);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
 /* grpc_slice_from_static_string support structure - a refcount that does
    nothing */
-static void noop_ref_or_unref(void *unused) {}
+static void noop_ref(void *unused) {}
+static void noop_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
 
-static grpc_slice_refcount noop_refcount = {noop_ref_or_unref,
-                                            noop_ref_or_unref};
+static grpc_slice_refcount noop_refcount = {noop_ref, noop_unref};
 
 grpc_slice grpc_slice_from_static_string(const char *s) {
   grpc_slice slice;
@@ -86,7 +102,7 @@
   gpr_ref(&r->refs);
 }
 
-static void new_slice_unref(void *p) {
+static void new_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
   new_slice_refcount *r = p;
   if (gpr_unref(&r->refs)) {
     r->user_destroy(r->user_data);
@@ -131,7 +147,7 @@
   gpr_ref(&r->refs);
 }
 
-static void new_with_len_unref(void *p) {
+static void new_with_len_unref(grpc_exec_ctx *exec_ctx, void *p) {
   new_with_len_slice_refcount *r = p;
   if (gpr_unref(&r->refs)) {
     r->user_destroy(r->user_data, r->user_length);
@@ -177,7 +193,7 @@
   gpr_ref(&r->refs);
 }
 
-static void malloc_unref(void *p) {
+static void malloc_unref(grpc_exec_ctx *exec_ctx, void *p) {
   malloc_refcount *r = p;
   if (gpr_unref(&r->refs)) {
     gpr_free(r);
diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c
index 990ef12..08eaf49 100644
--- a/src/core/lib/slice/slice_buffer.c
+++ b/src/core/lib/slice/slice_buffer.c
@@ -40,6 +40,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 /* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */
 #define GROW(x) (3 * (x) / 2)
 
@@ -63,13 +65,20 @@
   sb->slices = sb->inlined;
 }
 
-void grpc_slice_buffer_destroy(grpc_slice_buffer *sb) {
-  grpc_slice_buffer_reset_and_unref(sb);
+void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
+                                        grpc_slice_buffer *sb) {
+  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, sb);
   if (sb->slices != sb->inlined) {
     gpr_free(sb->slices);
   }
 }
 
+void grpc_slice_buffer_destroy(grpc_slice_buffer *sb) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_buffer_destroy_internal(&exec_ctx, sb);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
 uint8_t *grpc_slice_buffer_tiny_add(grpc_slice_buffer *sb, size_t n) {
   grpc_slice *back;
   uint8_t *out;
@@ -154,17 +163,24 @@
   }
 }
 
-void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer *sb) {
+void grpc_slice_buffer_reset_and_unref_internal(grpc_exec_ctx *exec_ctx,
+                                                grpc_slice_buffer *sb) {
   size_t i;
 
   for (i = 0; i < sb->count; i++) {
-    grpc_slice_unref(sb->slices[i]);
+    grpc_slice_unref_internal(exec_ctx, sb->slices[i]);
   }
 
   sb->count = 0;
   sb->length = 0;
 }
 
+void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer *sb) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, sb);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
 void grpc_slice_buffer_swap(grpc_slice_buffer *a, grpc_slice_buffer *b) {
   GPR_SWAP(size_t, a->count, b->count);
   GPR_SWAP(size_t, a->capacity, b->capacity);
diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h
new file mode 100644
index 0000000..6185333
--- /dev/null
+++ b/src/core/lib/slice/slice_internal.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2016, 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 GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
+#define GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
+
+#include <grpc/slice.h>
+#include <grpc/slice_buffer.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+grpc_slice grpc_slice_ref_internal(grpc_slice slice);
+void grpc_slice_unref_internal(grpc_exec_ctx *exec_ctx, grpc_slice slice);
+void grpc_slice_buffer_reset_and_unref_internal(grpc_exec_ctx *exec_ctx,
+                                                grpc_slice_buffer *sb);
+void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
+                                        grpc_slice_buffer *sb);
+
+#endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */
diff --git a/src/core/lib/slice/slice_string_helpers.c b/src/core/lib/slice/slice_string_helpers.c
index 4731762..839c366 100644
--- a/src/core/lib/slice/slice_string_helpers.c
+++ b/src/core/lib/slice/slice_string_helpers.c
@@ -37,6 +37,7 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 
 char *grpc_dump_slice(grpc_slice s, uint32_t flags) {
@@ -84,6 +85,6 @@
     grpc_slice_buffer_add_indexed(
         dst, grpc_slice_sub(str, end + sep_len, GRPC_SLICE_LENGTH(str)));
   } else { /* no sep found, add whole input */
-    grpc_slice_buffer_add_indexed(dst, grpc_slice_ref(str));
+    grpc_slice_buffer_add_indexed(dst, grpc_slice_ref_internal(str));
   }
 }
diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index f10a30f..0dc55c2 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -275,3 +275,29 @@
   } while (ca == cb && ca && cb);
   return ca - cb;
 }
+
+static void add_string_to_split(const char *beg, const char *end, char ***strs,
+                                size_t *nstrs, size_t *capstrs) {
+  char *out = gpr_malloc((size_t)(end - beg) + 1);
+  memcpy(out, beg, (size_t)(end - beg));
+  out[end - beg] = 0;
+  if (*nstrs == *capstrs) {
+    *capstrs = GPR_MAX(8, 2 * *capstrs);
+    *strs = gpr_realloc(*strs, sizeof(*strs) * *capstrs);
+  }
+  (*strs)[*nstrs] = out;
+  ++*nstrs;
+}
+
+void gpr_string_split(const char *input, const char *sep, char ***strs,
+                      size_t *nstrs) {
+  char *next;
+  *strs = NULL;
+  *nstrs = 0;
+  size_t capstrs = 0;
+  while ((next = strstr(input, sep))) {
+    add_string_to_split(input, next, strs, nstrs, &capstrs);
+    input = next + strlen(sep);
+  }
+  add_string_to_split(input, input + strlen(input), strs, nstrs, &capstrs);
+}
diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h
index db59308..e81af68 100644
--- a/src/core/lib/support/string.h
+++ b/src/core/lib/support/string.h
@@ -96,6 +96,9 @@
 char *gpr_strjoin_sep(const char **strs, size_t nstrs, const char *sep,
                       size_t *total_length);
 
+void gpr_string_split(const char *input, const char *sep, char ***strs,
+                      size_t *nstrs);
+
 /* A vector of strings... for building up a final string one piece at a time */
 typedef struct {
   char **strs;
diff --git a/src/core/lib/surface/byte_buffer.c b/src/core/lib/surface/byte_buffer.c
index d646591..c8e2fdf 100644
--- a/src/core/lib/surface/byte_buffer.c
+++ b/src/core/lib/surface/byte_buffer.c
@@ -35,6 +35,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 grpc_byte_buffer *grpc_raw_byte_buffer_create(grpc_slice *slices,
                                               size_t nslices) {
   return grpc_raw_compressed_byte_buffer_create(slices, nslices,
@@ -50,7 +52,7 @@
   bb->data.raw.compression = compression;
   grpc_slice_buffer_init(&bb->data.raw.slice_buffer);
   for (i = 0; i < nslices; i++) {
-    grpc_slice_ref(slices[i]);
+    grpc_slice_ref_internal(slices[i]);
     grpc_slice_buffer_add(&bb->data.raw.slice_buffer, slices[i]);
   }
   return bb;
@@ -82,12 +84,14 @@
 
 void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) {
   if (!bb) return;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   switch (bb->type) {
     case GRPC_BB_RAW:
-      grpc_slice_buffer_destroy(&bb->data.raw.slice_buffer);
+      grpc_slice_buffer_destroy_internal(&exec_ctx, &bb->data.raw.slice_buffer);
       break;
   }
   gpr_free(bb);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) {
diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c
index 0089959..1a6ccda 100644
--- a/src/core/lib/surface/byte_buffer_reader.c
+++ b/src/core/lib/surface/byte_buffer_reader.c
@@ -42,6 +42,7 @@
 #include <grpc/support/log.h>
 
 #include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/slice/slice_internal.h"
 
 static int is_compressed(grpc_byte_buffer *buffer) {
   switch (buffer->type) {
@@ -56,13 +57,15 @@
 
 int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
                                  grpc_byte_buffer *buffer) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_slice_buffer decompressed_slices_buffer;
   reader->buffer_in = buffer;
   switch (reader->buffer_in->type) {
     case GRPC_BB_RAW:
       grpc_slice_buffer_init(&decompressed_slices_buffer);
       if (is_compressed(reader->buffer_in)) {
-        if (grpc_msg_decompress(reader->buffer_in->data.raw.compression,
+        if (grpc_msg_decompress(&exec_ctx,
+                                reader->buffer_in->data.raw.compression,
                                 &reader->buffer_in->data.raw.slice_buffer,
                                 &decompressed_slices_buffer) == 0) {
           gpr_log(GPR_ERROR,
@@ -76,13 +79,15 @@
               grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices,
                                           decompressed_slices_buffer.count);
         }
-        grpc_slice_buffer_destroy(&decompressed_slices_buffer);
+        grpc_slice_buffer_destroy_internal(&exec_ctx,
+                                           &decompressed_slices_buffer);
       } else { /* not compressed, use the input buffer as output */
         reader->buffer_out = reader->buffer_in;
       }
       reader->current.index = 0;
       break;
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return 1;
 }
 
@@ -104,7 +109,8 @@
       grpc_slice_buffer *slice_buffer;
       slice_buffer = &reader->buffer_out->data.raw.slice_buffer;
       if (reader->current.index < slice_buffer->count) {
-        *slice = grpc_slice_ref(slice_buffer->slices[reader->current.index]);
+        *slice = grpc_slice_ref_internal(
+            slice_buffer->slices[reader->current.index]);
         reader->current.index += 1;
         return 1;
       }
@@ -121,12 +127,14 @@
   grpc_slice out_slice = grpc_slice_malloc(input_size);
   uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) {
     const size_t slice_length = GRPC_SLICE_LENGTH(in_slice);
     memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length);
     bytes_read += slice_length;
-    grpc_slice_unref(in_slice);
+    grpc_slice_unref_internal(&exec_ctx, in_slice);
     GPR_ASSERT(bytes_read <= input_size);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   return out_slice;
 }
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 8ca3cab..5c98500 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -49,6 +49,7 @@
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
@@ -226,12 +227,12 @@
 static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
                                   grpc_error *error);
 
-grpc_error *grpc_call_create(const grpc_call_create_args *args,
+grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
+                             const grpc_call_create_args *args,
                              grpc_call **out_call) {
   size_t i, j;
   grpc_channel_stack *channel_stack =
       grpc_channel_get_channel_stack(args->channel);
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_call *call;
   GPR_TIMER_BEGIN("grpc_call_create", 0);
   call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
@@ -315,14 +316,14 @@
   GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
   /* initial refcount dropped by grpc_call_destroy */
   grpc_error *error = grpc_call_stack_init(
-      &exec_ctx, channel_stack, 1, destroy_call, call, call->context,
+      exec_ctx, channel_stack, 1, destroy_call, call, call->context,
       args->server_transport_data, path, call->start_time, send_deadline,
       CALL_STACK_FROM_CALL(call));
   if (error != GRPC_ERROR_NONE) {
     grpc_status_code status;
     const char *error_str;
     grpc_error_get_status(error, &status, &error_str);
-    close_with_status(&exec_ctx, call, status, error_str);
+    close_with_status(exec_ctx, call, status, error_str);
   }
   if (args->cq != NULL) {
     GPR_ASSERT(
@@ -338,12 +339,11 @@
   }
   if (!grpc_polling_entity_is_empty(&call->pollent)) {
     grpc_call_stack_set_pollset_or_pollset_set(
-        &exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
+        exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
   }
 
-  if (path != NULL) GRPC_MDSTR_UNREF(path);
+  if (path != NULL) GRPC_MDSTR_UNREF(exec_ctx, path);
 
-  grpc_exec_ctx_finish(&exec_ctx);
   GPR_TIMER_END("grpc_call_create", 0);
   return error;
 }
@@ -404,7 +404,7 @@
   GPR_TIMER_BEGIN("destroy_call", 0);
   for (i = 0; i < 2; i++) {
     grpc_metadata_batch_destroy(
-        &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
+        exec_ctx, &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
   }
   if (c->receiving_stream != NULL) {
     grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
@@ -412,11 +412,11 @@
   gpr_mu_destroy(&c->mu);
   for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
     if (c->status[i].details) {
-      GRPC_MDSTR_UNREF(c->status[i].details);
+      GRPC_MDSTR_UNREF(exec_ctx, c->status[i].details);
     }
   }
   for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
-    GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md);
+    GRPC_MDELEM_UNREF(exec_ctx, c->send_extra_metadata[ii].md);
   }
   for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
     if (c->context[i].destroy) {
@@ -446,22 +446,22 @@
   call->status[source].code = (grpc_status_code)status;
 }
 
-static void set_status_details(grpc_call *call, status_source source,
-                               grpc_mdstr *status) {
+static void set_status_details(grpc_exec_ctx *exec_ctx, grpc_call *call,
+                               status_source source, grpc_mdstr *status) {
   if (call->status[source].details != NULL) {
-    GRPC_MDSTR_UNREF(status);
+    GRPC_MDSTR_UNREF(exec_ctx, status);
   } else {
     call->status[source].details = status;
   }
 }
 
-static void set_status_from_error(grpc_call *call, status_source source,
-                                  grpc_error *error) {
+static void set_status_from_error(grpc_exec_ctx *exec_ctx, grpc_call *call,
+                                  status_source source, grpc_error *error) {
   grpc_status_code status;
   const char *msg;
   grpc_error_get_status(error, &status, &msg);
   set_status_code(call, source, (uint32_t)status);
-  set_status_details(call, source, grpc_mdstr_from_string(msg));
+  set_status_details(exec_ctx, call, source, grpc_mdstr_from_string(msg));
 }
 
 static void set_incoming_compression_algorithm(
@@ -495,7 +495,8 @@
 
 static void destroy_encodings_accepted_by_peer(void *p) { return; }
 
-static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
+static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
+                                           grpc_call *call, grpc_mdelem *mdel) {
   size_t i;
   grpc_compression_algorithm algorithm;
   grpc_slice_buffer accept_encoding_parts;
@@ -535,7 +536,7 @@
     }
   }
 
-  grpc_slice_buffer_destroy(&accept_encoding_parts);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &accept_encoding_parts);
 
   grpc_mdelem_set_user_data(
       mdel, destroy_encodings_accepted_by_peer,
@@ -593,12 +594,10 @@
   return res;
 }
 
-static int prepare_application_metadata(grpc_call *call, int count,
-                                        grpc_metadata *metadata,
-                                        int is_trailing,
-                                        int prepend_extra_metadata,
-                                        grpc_metadata *additional_metadata,
-                                        int additional_metadata_count) {
+static int prepare_application_metadata(
+    grpc_exec_ctx *exec_ctx, grpc_call *call, int count,
+    grpc_metadata *metadata, int is_trailing, int prepend_extra_metadata,
+    grpc_metadata *additional_metadata, int additional_metadata_count) {
   int total_count = count + additional_metadata_count;
   int i;
   grpc_metadata_batch *batch =
@@ -609,7 +608,7 @@
     grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
     GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
     l->md = grpc_mdelem_from_string_and_buffer(
-        md->key, (const uint8_t *)md->value, md->value_length);
+        exec_ctx, md->key, (const uint8_t *)md->value, md->value_length);
     if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key),
                                   GRPC_MDSTR_LENGTH(l->md->key))) {
       gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
@@ -629,7 +628,7 @@
       const grpc_metadata *md =
           get_md_elem(metadata, additional_metadata, j, count);
       grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
-      GRPC_MDELEM_UNREF(l->md);
+      GRPC_MDELEM_UNREF(exec_ctx, l->md);
     }
     return 0;
   }
@@ -811,7 +810,8 @@
 
 static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
                                              termination_closure *tc) {
-  set_status_from_error(tc->call, STATUS_FROM_API_OVERRIDE, tc->error);
+  set_status_from_error(exec_ctx, tc->call, STATUS_FROM_API_OVERRIDE,
+                        tc->error);
 
   if (tc->type == TC_CANCEL) {
     grpc_closure_init(&tc->closure, send_cancel, tc);
@@ -928,7 +928,8 @@
   return algorithm;
 }
 
-static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
+static grpc_mdelem *recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
+                                       grpc_mdelem *elem) {
   if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
     GPR_TIMER_BEGIN("status", 0);
     set_status_code(call, STATUS_FROM_WIRE, decode_status(elem));
@@ -936,7 +937,8 @@
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
     GPR_TIMER_BEGIN("status-details", 0);
-    set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value));
+    set_status_details(exec_ctx, call, STATUS_FROM_WIRE,
+                       GRPC_MDSTR_REF(elem->value));
     GPR_TIMER_END("status-details", 0);
     return NULL;
   }
@@ -962,9 +964,10 @@
   return elem;
 }
 
-static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) {
-  grpc_call *call = callp;
-  elem = recv_common_filter(call, elem);
+static grpc_mdelem *recv_initial_filter(grpc_exec_ctx *exec_ctx, void *args,
+                                        grpc_mdelem *elem) {
+  grpc_call *call = args;
+  elem = recv_common_filter(exec_ctx, call, elem);
   if (elem == NULL) {
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
@@ -974,7 +977,7 @@
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
     GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
-    set_encodings_accepted_by_peer(call, elem);
+    set_encodings_accepted_by_peer(exec_ctx, call, elem);
     GPR_TIMER_END("encodings_accepted_by_peer", 0);
     return NULL;
   } else {
@@ -982,9 +985,10 @@
   }
 }
 
-static grpc_mdelem *recv_trailing_filter(void *callp, grpc_mdelem *elem) {
-  grpc_call *call = callp;
-  elem = recv_common_filter(call, elem);
+static grpc_mdelem *recv_trailing_filter(grpc_exec_ctx *exec_ctx, void *args,
+                                         grpc_mdelem *elem) {
+  grpc_call *call = args;
+  elem = recv_common_filter(exec_ctx, call, elem);
   if (elem == NULL) {
     return NULL;
   } else {
@@ -1234,7 +1238,7 @@
   if (error == GRPC_ERROR_NONE) {
     grpc_metadata_batch *md =
         &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
-    grpc_metadata_batch_filter(md, recv_initial_filter, call);
+    grpc_metadata_batch_filter(exec_ctx, md, recv_initial_filter, call);
 
     GPR_TIMER_BEGIN("validate_filtered_metadata", 0);
     validate_filtered_metadata(exec_ctx, bctl);
@@ -1278,14 +1282,15 @@
   intptr_t status;
   if (error != GRPC_ERROR_NONE &&
       grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) {
-    set_status_from_error(call, STATUS_FROM_CORE, error);
+    set_status_from_error(exec_ctx, call, STATUS_FROM_CORE, error);
   }
 
   if (bctl->send_initial_metadata) {
     if (error != GRPC_ERROR_NONE) {
-      set_status_from_error(call, STATUS_FROM_CORE, error);
+      set_status_from_error(exec_ctx, call, STATUS_FROM_CORE, error);
     }
     grpc_metadata_batch_destroy(
+        exec_ctx,
         &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
   }
   if (bctl->send_message) {
@@ -1293,12 +1298,13 @@
   }
   if (bctl->send_final_op) {
     grpc_metadata_batch_destroy(
+        exec_ctx,
         &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]);
   }
   if (bctl->recv_final_op) {
     grpc_metadata_batch *md =
         &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
-    grpc_metadata_batch_filter(md, recv_trailing_filter, call);
+    grpc_metadata_batch_filter(exec_ctx, md, recv_trailing_filter, call);
 
     call->received_final_op = true;
     /* propagate cancellation to any interested children */
@@ -1435,7 +1441,7 @@
         bctl->send_initial_metadata = 1;
         call->sent_initial_metadata = 1;
         if (!prepare_application_metadata(
-                call, (int)op->data.send_initial_metadata.count,
+                exec_ctx, call, (int)op->data.send_initial_metadata.count,
                 op->data.send_initial_metadata.metadata, 0, call->is_client,
                 &compression_md, (int)additional_metadata_count)) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
@@ -1515,15 +1521,15 @@
         call->sent_final_op = 1;
         call->send_extra_metadata_count = 1;
         call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
-            call->channel, op->data.send_status_from_server.status);
+            exec_ctx, call->channel, op->data.send_status_from_server.status);
         if (op->data.send_status_from_server.status_details != NULL) {
           call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings(
-              GRPC_MDSTR_GRPC_MESSAGE,
+              exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
               grpc_mdstr_from_string(
                   op->data.send_status_from_server.status_details));
           call->send_extra_metadata_count++;
           set_status_details(
-              call, STATUS_FROM_API_OVERRIDE,
+              exec_ctx, call, STATUS_FROM_API_OVERRIDE,
               GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value));
         }
         if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
@@ -1531,7 +1537,7 @@
                           (uint32_t)op->data.send_status_from_server.status);
         }
         if (!prepare_application_metadata(
-                call,
+                exec_ctx, call,
                 (int)op->data.send_status_from_server.trailing_metadata_count,
                 op->data.send_status_from_server.trailing_metadata, 1, 1, NULL,
                 0)) {
@@ -1660,7 +1666,7 @@
   /* reverse any mutations that occured */
   if (bctl->send_initial_metadata) {
     call->sent_initial_metadata = 0;
-    grpc_metadata_batch_clear(&call->metadata_batch[0][0]);
+    grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][0]);
   }
   if (bctl->send_message) {
     call->sending_message = 0;
@@ -1668,7 +1674,7 @@
   }
   if (bctl->send_final_op) {
     call->sent_final_op = 0;
-    grpc_metadata_batch_clear(&call->metadata_batch[0][1]);
+    grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][1]);
   }
   if (bctl->recv_initial_metadata) {
     call->received_initial_metadata = 0;
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index 18af41b..233340c 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -70,7 +70,8 @@
 /* Create a new call based on \a args.
    Regardless of success or failure, always returns a valid new call into *call
    */
-grpc_error *grpc_call_create(const grpc_call_create_args *args,
+grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
+                             const grpc_call_create_args *args,
                              grpc_call **call);
 
 void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 1389df6..7e87f05 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -89,13 +89,14 @@
   bool is_client = grpc_channel_stack_type_is_client(channel_stack_type);
 
   grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
-  grpc_channel_stack_builder_set_channel_arguments(builder, input_args);
+  grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
+                                                   input_args);
   grpc_channel_stack_builder_set_target(builder, target);
   grpc_channel_stack_builder_set_transport(builder, optional_transport);
   grpc_channel *channel;
   grpc_channel_args *args;
   if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
-    grpc_channel_stack_builder_destroy(builder);
+    grpc_channel_stack_builder_destroy(exec_ctx, builder);
     return NULL;
   } else {
     args = grpc_channel_args_copy(
@@ -120,10 +121,10 @@
         } else {
           if (channel->default_authority) {
             /* setting this takes precedence over anything else */
-            GRPC_MDELEM_UNREF(channel->default_authority);
+            GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
           }
           channel->default_authority = grpc_mdelem_from_strings(
-              ":authority", args->args[i].value.string);
+              exec_ctx, ":authority", args->args[i].value.string);
         }
       } else if (0 ==
                  strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
@@ -138,7 +139,7 @@
                     GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
           } else {
             channel->default_authority = grpc_mdelem_from_strings(
-                ":authority", args->args[i].value.string);
+                exec_ctx, ":authority", args->args[i].value.string);
           }
         }
       } else if (0 == strcmp(args->args[i].key,
@@ -164,7 +165,7 @@
             0x1; /* always support no compression */
       }
     }
-    grpc_channel_args_destroy(args);
+    grpc_channel_args_destroy(exec_ctx, args);
   }
 
   return channel;
@@ -185,10 +186,10 @@
 }
 
 static grpc_call *grpc_channel_create_call_internal(
-    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
-    grpc_mdelem *path_mdelem, grpc_mdelem *authority_mdelem,
-    gpr_timespec deadline) {
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_completion_queue *cq,
+    grpc_pollset_set *pollset_set_alternative, grpc_mdelem *path_mdelem,
+    grpc_mdelem *authority_mdelem, gpr_timespec deadline) {
   grpc_mdelem *send_metadata[2];
   size_t num_metadata = 0;
 
@@ -215,7 +216,7 @@
   args.send_deadline = deadline;
 
   grpc_call *call;
-  GRPC_LOG_IF_ERROR("call_create", grpc_call_create(&args, &call));
+  GRPC_LOG_IF_ERROR("call_create", grpc_call_create(exec_ctx, &args, &call));
   return call;
 }
 
@@ -236,26 +237,30 @@
       (channel, parent_call, (unsigned)propagation_mask, cq, method, host,
        deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
-  return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, cq, NULL,
-      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call *call = grpc_channel_create_call_internal(
+      &exec_ctx, channel, parent_call, propagation_mask, cq, NULL,
+      grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
-      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+      host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
                                                grpc_mdstr_from_string(host))
            : NULL,
       deadline);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return call;
 }
 
 grpc_call *grpc_channel_create_pollset_set_call(
-    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_pollset_set *pollset_set, const char *method, const char *host,
-    gpr_timespec deadline, void *reserved) {
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_pollset_set *pollset_set,
+    const char *method, const char *host, gpr_timespec deadline,
+    void *reserved) {
   GPR_ASSERT(!reserved);
   return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, NULL, pollset_set,
-      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+      exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set,
+      grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
-      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+      host ? grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_AUTHORITY,
                                                grpc_mdstr_from_string(host))
            : NULL,
       deadline);
@@ -268,15 +273,18 @@
       "grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)",
       4, (channel, method, host, reserved));
   GPR_ASSERT(!reserved);
-  rc->path = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  rc->path = grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
                                                grpc_mdstr_from_string(method));
-  rc->authority = host ? grpc_mdelem_from_metadata_strings(
-                             GRPC_MDSTR_AUTHORITY, grpc_mdstr_from_string(host))
-                       : NULL;
+  rc->authority =
+      host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
+                                               grpc_mdstr_from_string(host))
+           : NULL;
   gpr_mu_lock(&channel->registered_call_mu);
   rc->next = channel->registered_calls;
   channel->registered_calls = rc;
   gpr_mu_unlock(&channel->registered_call_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
   return rc;
 }
 
@@ -296,10 +304,13 @@
           registered_call_handle, deadline.tv_sec, deadline.tv_nsec,
           (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
-  return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, completion_queue, NULL,
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_call *call = grpc_channel_create_call_internal(
+      &exec_ctx, channel, parent_call, propagation_mask, completion_queue, NULL,
       GRPC_MDELEM_REF(rc->path),
       rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return call;
 }
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -325,14 +336,14 @@
   while (channel->registered_calls) {
     registered_call *rc = channel->registered_calls;
     channel->registered_calls = rc->next;
-    GRPC_MDELEM_UNREF(rc->path);
+    GRPC_MDELEM_UNREF(exec_ctx, rc->path);
     if (rc->authority) {
-      GRPC_MDELEM_UNREF(rc->authority);
+      GRPC_MDELEM_UNREF(exec_ctx, rc->authority);
     }
     gpr_free(rc);
   }
   if (channel->default_authority != NULL) {
-    GRPC_MDELEM_UNREF(channel->default_authority);
+    GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
   }
   gpr_mu_destroy(&channel->registered_call_mu);
   gpr_free(channel->target);
@@ -362,7 +373,8 @@
   return channel->compression_options;
 }
 
-grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
+grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
+                                                 grpc_channel *channel, int i) {
   char tmp[GPR_LTOA_MIN_BUFSIZE];
   switch (i) {
     case 0:
@@ -373,6 +385,6 @@
       return GRPC_MDELEM_GRPC_STATUS_2;
   }
   gpr_ltoa(i, tmp);
-  return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS,
+  return grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
                                            grpc_mdstr_from_string(tmp));
 }
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 23cc865..2ebadb7 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -51,9 +51,10 @@
     properties from the server call to this new client call, depending on the
     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, const char *method, const char *host,
-    gpr_timespec deadline, void *reserved);
+    grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+    uint32_t propagation_mask, grpc_pollset_set *pollset_set,
+    const char *method, const char *host, gpr_timespec deadline,
+    void *reserved);
 
 /** Get a (borrowed) pointer to this channels underlying channel stack */
 grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
@@ -62,7 +63,8 @@
     status_code.
 
     The returned elem is owned by the caller. */
-grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel,
+grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
+                                                 grpc_channel *channel,
                                                  int status_code);
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
diff --git a/src/core/lib/surface/channel_init.c b/src/core/lib/surface/channel_init.c
index 0627b34..7acb444 100644
--- a/src/core/lib/surface/channel_init.c
+++ b/src/core/lib/surface/channel_init.c
@@ -131,7 +131,7 @@
 
   for (size_t i = 0; i < g_slots[type].num_slots; i++) {
     const stage_slot *slot = &g_slots[type].slots[i];
-    if (!slot->fn(builder, slot->arg)) {
+    if (!slot->fn(exec_ctx, builder, slot->arg)) {
       return false;
     }
   }
diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h
index b53f2ae..411f5ea 100644
--- a/src/core/lib/surface/channel_init.h
+++ b/src/core/lib/surface/channel_init.h
@@ -51,7 +51,8 @@
 
 /// One stage of mutation: call functions against \a builder to influence the
 /// finally constructed channel stack
-typedef bool (*grpc_channel_init_stage)(grpc_channel_stack_builder *builder,
+typedef bool (*grpc_channel_init_stage)(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_stack_builder *builder,
                                         void *arg);
 
 /// Global initialization of the system
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index 7903f57..e20e602 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -80,17 +80,20 @@
   g_initializations = 0;
 }
 
-static bool append_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool append_filter(grpc_exec_ctx *exec_ctx,
+                          grpc_channel_stack_builder *builder, void *arg) {
   return grpc_channel_stack_builder_append_filter(
       builder, (const grpc_channel_filter *)arg, NULL, NULL);
 }
 
-static bool prepend_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool prepend_filter(grpc_exec_ctx *exec_ctx,
+                           grpc_channel_stack_builder *builder, void *arg) {
   return grpc_channel_stack_builder_prepend_filter(
       builder, (const grpc_channel_filter *)arg, NULL, NULL);
 }
 
-static bool maybe_add_http_filter(grpc_channel_stack_builder *builder,
+static bool maybe_add_http_filter(grpc_exec_ctx *exec_ctx,
+                                  grpc_channel_stack_builder *builder,
                                   void *arg) {
   grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
   if (t && strstr(t->vtable->name, "http")) {
@@ -221,11 +224,12 @@
 void grpc_shutdown(void) {
   int i;
   GRPC_API_TRACE("grpc_shutdown(void)", 0, ());
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_mu_lock(&g_init_mu);
   if (--g_initializations == 0) {
-    grpc_executor_shutdown();
+    grpc_executor_shutdown(&exec_ctx);
     grpc_cq_global_shutdown();
-    grpc_iomgr_shutdown();
+    grpc_iomgr_shutdown(&exec_ctx);
     gpr_timers_global_destroy();
     grpc_tracer_shutdown();
     for (i = g_number_of_plugins; i >= 0; i--) {
@@ -233,9 +237,10 @@
         g_all_of_the_plugins[i].destroy();
       }
     }
-    grpc_mdctx_global_shutdown();
+    grpc_mdctx_global_shutdown(&exec_ctx);
   }
   gpr_mu_unlock(&g_init_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int grpc_is_initialized(void) {
diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c
index 7ee7b51..520a8aa 100644
--- a/src/core/lib/surface/init_secure.c
+++ b/src/core/lib/surface/init_secure.c
@@ -50,7 +50,7 @@
 }
 
 static bool maybe_prepend_client_auth_filter(
-    grpc_channel_stack_builder *builder, void *arg) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, void *arg) {
   const grpc_channel_args *args =
       grpc_channel_stack_builder_get_channel_arguments(builder);
   if (args) {
@@ -65,7 +65,7 @@
 }
 
 static bool maybe_prepend_server_auth_filter(
-    grpc_channel_stack_builder *builder, void *arg) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, void *arg) {
   const grpc_channel_args *args =
       grpc_channel_stack_builder_get_channel_arguments(builder);
   if (args) {
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index d0df8e7..d606f70 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -55,14 +55,15 @@
   const char *error_message;
 } channel_data;
 
-static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) {
+static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                          grpc_metadata_batch *mdb) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   char tmp[GPR_LTOA_MIN_BUFSIZE];
   gpr_ltoa(chand->error_code, tmp);
-  calld->status.md = grpc_mdelem_from_strings("grpc-status", tmp);
+  calld->status.md = grpc_mdelem_from_strings(exec_ctx, "grpc-status", tmp);
   calld->details.md =
-      grpc_mdelem_from_strings("grpc-message", chand->error_message);
+      grpc_mdelem_from_strings(exec_ctx, "grpc-message", chand->error_message);
   calld->status.prev = calld->details.next = NULL;
   calld->status.next = &calld->details;
   calld->details.prev = &calld->status;
@@ -76,9 +77,9 @@
                                            grpc_transport_stream_op *op) {
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
   if (op->recv_initial_metadata != NULL) {
-    fill_metadata(elem, op->recv_initial_metadata);
+    fill_metadata(exec_ctx, elem, op->recv_initial_metadata);
   } else if (op->recv_trailing_metadata != NULL) {
-    fill_metadata(elem, op->recv_trailing_metadata);
+    fill_metadata(exec_ctx, elem, op->recv_trailing_metadata);
   }
   grpc_transport_stream_op_finish_with_failure(
       exec_ctx, op, GRPC_ERROR_CREATE("lame client channel"));
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index fe73aa3..03e0913 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -45,6 +45,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/stack_lockfree.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
@@ -271,7 +272,7 @@
 static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
                              grpc_error *error) {
   struct shutdown_cleanup_args *a = arg;
-  grpc_slice_unref(a->slice);
+  grpc_slice_unref_internal(exec_ctx, a->slice);
   gpr_free(a);
 }
 
@@ -379,7 +380,7 @@
 static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
   registered_method *rm;
   size_t i;
-  grpc_channel_args_destroy(server->channel_args);
+  grpc_channel_args_destroy(exec_ctx, server->channel_args);
   gpr_mu_destroy(&server->mu_global);
   gpr_mu_destroy(&server->mu_call);
   while ((rm = server->registered_methods) != NULL) {
@@ -740,7 +741,8 @@
   }
 }
 
-static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+                                  grpc_mdelem *md) {
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
   if (md->key == GRPC_MDSTR_PATH) {
@@ -764,7 +766,8 @@
   gpr_timespec op_deadline;
 
   GRPC_ERROR_REF(error);
-  grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
+  grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+                             server_filter, elem);
   op_deadline = calld->recv_initial_metadata->deadline;
   if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
     calld->deadline = op_deadline;
@@ -838,7 +841,7 @@
   args.server_transport_data = transport_server_data;
   args.send_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   grpc_call *call;
-  grpc_error *error = grpc_call_create(&args, &call);
+  grpc_error *error = grpc_call_create(exec_ctx, &args, &call);
   grpc_call_element *elem =
       grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
   if (error != GRPC_ERROR_NONE) {
@@ -902,10 +905,10 @@
   GPR_ASSERT(calld->state != PENDING);
 
   if (calld->host) {
-    GRPC_MDSTR_UNREF(calld->host);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->host);
   }
   if (calld->path) {
-    GRPC_MDSTR_UNREF(calld->path);
+    GRPC_MDSTR_UNREF(exec_ctx, calld->path);
   }
   grpc_metadata_array_destroy(&calld->initial_metadata);
 
@@ -936,10 +939,10 @@
   if (chand->registered_methods) {
     for (i = 0; i < chand->registered_method_slots; i++) {
       if (chand->registered_methods[i].method) {
-        GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
+        GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].method);
       }
       if (chand->registered_methods[i].host) {
-        GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
+        GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].host);
       }
     }
     gpr_free(chand->registered_methods);
diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c
index 2f1d7b7..4d42061 100644
--- a/src/core/lib/transport/byte_stream.c
+++ b/src/core/lib/transport/byte_stream.c
@@ -37,6 +37,8 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
+
 int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx,
                           grpc_byte_stream *byte_stream, grpc_slice *slice,
                           size_t max_size_hint, grpc_closure *on_complete) {
@@ -57,7 +59,8 @@
                                     grpc_closure *on_complete) {
   grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream;
   GPR_ASSERT(stream->cursor < stream->backing_buffer->count);
-  *slice = grpc_slice_ref(stream->backing_buffer->slices[stream->cursor]);
+  *slice =
+      grpc_slice_ref_internal(stream->backing_buffer->slices[stream->cursor]);
   stream->cursor++;
   return 1;
 }
diff --git a/src/core/lib/transport/mdstr_hash_table.c b/src/core/lib/transport/mdstr_hash_table.c
index 3d01e56..2791bf6 100644
--- a/src/core/lib/transport/mdstr_hash_table.c
+++ b/src/core/lib/transport/mdstr_hash_table.c
@@ -94,13 +94,14 @@
   return table;
 }
 
-void grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table) {
+void grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
+                                 grpc_mdstr_hash_table* table) {
   if (table != NULL && gpr_unref(&table->refs)) {
     for (size_t i = 0; i < table->size; ++i) {
       grpc_mdstr_hash_table_entry* entry = &table->entries[i];
       if (entry->key != NULL) {
-        GRPC_MDSTR_UNREF(entry->key);
-        entry->vtable->destroy_value(entry->value);
+        GRPC_MDSTR_UNREF(exec_ctx, entry->key);
+        entry->vtable->destroy_value(exec_ctx, entry->value);
       }
     }
     gpr_free(table->entries);
diff --git a/src/core/lib/transport/mdstr_hash_table.h b/src/core/lib/transport/mdstr_hash_table.h
index 8982ec3..57f497e 100644
--- a/src/core/lib/transport/mdstr_hash_table.h
+++ b/src/core/lib/transport/mdstr_hash_table.h
@@ -49,7 +49,7 @@
 typedef struct grpc_mdstr_hash_table grpc_mdstr_hash_table;
 
 typedef struct grpc_mdstr_hash_table_vtable {
-  void (*destroy_value)(void* value);
+  void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value);
   void* (*copy_value)(void* value);
 } grpc_mdstr_hash_table_vtable;
 
@@ -66,7 +66,8 @@
     size_t num_entries, grpc_mdstr_hash_table_entry* entries);
 
 grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table);
-void grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table);
+void grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
+                                 grpc_mdstr_hash_table* table);
 
 /** Returns the value from \a table associated with \a key.
     Returns NULL if \a key is not found. */
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index fac19b9..54c39df 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -47,6 +47,7 @@
 
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/murmur_hash.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
@@ -153,7 +154,7 @@
 static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT];
 static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT];
 
-static void gc_mdtab(mdtab_shard *shard);
+static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard);
 
 void grpc_test_only_set_metadata_hash_seed(uint32_t seed) {
   g_hash_seed = seed;
@@ -227,12 +228,12 @@
   }
 }
 
-void grpc_mdctx_global_shutdown(void) {
+void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) {
   size_t i;
   for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
     mdtab_shard *shard = &g_mdtab_shard[i];
     gpr_mu_destroy(&shard->mu);
-    gc_mdtab(shard);
+    gc_mdtab(exec_ctx, shard);
     /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
     if (shard->count != 0) {
       gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata elements were leaked",
@@ -316,12 +317,13 @@
   GPR_TIMER_END("grow_strtab", 0);
 }
 
-static void internal_destroy_string(strtab_shard *shard, internal_string *is) {
+static void internal_destroy_string(grpc_exec_ctx *exec_ctx,
+                                    strtab_shard *shard, internal_string *is) {
   internal_string **prev_next;
   internal_string *cur;
   GPR_TIMER_BEGIN("internal_destroy_string", 0);
   if (is->has_base64_and_huffman_encoded) {
-    grpc_slice_unref(is->base64_and_huffman);
+    grpc_slice_unref_internal(exec_ctx, is->base64_and_huffman);
   }
   for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT,
                                           shard->capacity)],
@@ -340,20 +342,20 @@
   GRPC_MDSTR_REF((grpc_mdstr *)(is));
 }
 
-static void slice_unref(void *p) {
+static void slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
   internal_string *is =
       (internal_string *)((char *)p - offsetof(internal_string, refcount));
-  GRPC_MDSTR_UNREF((grpc_mdstr *)(is));
+  GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)(is));
 }
 
 grpc_mdstr *grpc_mdstr_from_string(const char *str) {
   return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str));
 }
 
-grpc_mdstr *grpc_mdstr_from_slice(grpc_slice slice) {
+grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
   grpc_mdstr *result = grpc_mdstr_from_buffer(GRPC_SLICE_START_PTR(slice),
                                               GRPC_SLICE_LENGTH(slice));
-  grpc_slice_unref(slice);
+  grpc_slice_unref_internal(exec_ctx, slice);
   return result;
 }
 
@@ -444,7 +446,7 @@
   return (grpc_mdstr *)s;
 }
 
-static void gc_mdtab(mdtab_shard *shard) {
+static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
   size_t i;
   internal_metadata **prev_next;
   internal_metadata *md, *next;
@@ -457,8 +459,8 @@
       void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data);
       next = md->bucket_next;
       if (gpr_atm_acq_load(&md->refcnt) == 0) {
-        GRPC_MDSTR_UNREF((grpc_mdstr *)md->key);
-        GRPC_MDSTR_UNREF((grpc_mdstr *)md->value);
+        GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->key);
+        GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->value);
         if (md->user_data) {
           ((destroy_user_data_func)gpr_atm_no_barrier_load(
               &md->destroy_user_data))(user_data);
@@ -506,16 +508,17 @@
   GPR_TIMER_END("grow_mdtab", 0);
 }
 
-static void rehash_mdtab(mdtab_shard *shard) {
+static void rehash_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
   if (gpr_atm_no_barrier_load(&shard->free_estimate) >
       (gpr_atm)(shard->capacity / 4)) {
-    gc_mdtab(shard);
+    gc_mdtab(exec_ctx, shard);
   } else {
     grow_mdtab(shard);
   }
 }
 
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
+grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
+                                               grpc_mdstr *mkey,
                                                grpc_mdstr *mvalue) {
   internal_string *key = (internal_string *)mkey;
   internal_string *value = (internal_string *)mvalue;
@@ -547,8 +550,8 @@
   for (md = shard->elems[idx]; md; md = md->bucket_next) {
     if (md->key == key && md->value == value) {
       REF_MD_LOCKED(shard, md);
-      GRPC_MDSTR_UNREF((grpc_mdstr *)key);
-      GRPC_MDSTR_UNREF((grpc_mdstr *)value);
+      GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)key);
+      GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)value);
       gpr_mu_unlock(&shard->mu);
       GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
       return (grpc_mdelem *)md;
@@ -574,7 +577,7 @@
   shard->count++;
 
   if (shard->count > shard->capacity * 2) {
-    rehash_mdtab(shard);
+    rehash_mdtab(exec_ctx, shard);
   }
 
   gpr_mu_unlock(&shard->mu);
@@ -584,21 +587,26 @@
   return (grpc_mdelem *)md;
 }
 
-grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value) {
-  return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_string(key),
-                                           grpc_mdstr_from_string(value));
+grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key,
+                                      const char *value) {
+  return grpc_mdelem_from_metadata_strings(
+      exec_ctx, grpc_mdstr_from_string(key), grpc_mdstr_from_string(value));
 }
 
-grpc_mdelem *grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) {
-  return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_slice(key),
-                                           grpc_mdstr_from_slice(value));
+grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
+                                     grpc_slice value) {
+  return grpc_mdelem_from_metadata_strings(
+      exec_ctx, grpc_mdstr_from_slice(exec_ctx, key),
+      grpc_mdstr_from_slice(exec_ctx, value));
 }
 
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx,
+                                                const char *key,
                                                 const uint8_t *value,
                                                 size_t value_length) {
   return grpc_mdelem_from_metadata_strings(
-      grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length));
+      exec_ctx, grpc_mdstr_from_string(key),
+      grpc_mdstr_from_buffer(value, value_length));
 }
 
 static size_t get_base64_encoded_size(size_t raw_length) {
@@ -654,7 +662,7 @@
   return gmd;
 }
 
-void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) {
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *gmd DEBUG_ARGS) {
   internal_metadata *md = (internal_metadata *)gmd;
   if (!md) return;
   if (is_mdelem_static(gmd)) return;
@@ -696,7 +704,7 @@
   return gs;
 }
 
-void grpc_mdstr_unref(grpc_mdstr *gs DEBUG_ARGS) {
+void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *gs DEBUG_ARGS) {
   internal_string *s = (internal_string *)gs;
   if (is_mdstr_static(gs)) return;
 #ifdef GRPC_METADATA_REFCOUNT_DEBUG
@@ -709,7 +717,7 @@
         &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)];
     gpr_mu_lock(&shard->mu);
     GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
-    internal_destroy_string(shard, s);
+    internal_destroy_string(exec_ctx, shard, s);
     gpr_mu_unlock(&shard->mu);
   }
 }
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index a4955a1..991eee9 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -37,6 +37,8 @@
 #include <grpc/slice.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/iomgr/exec_ctx.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -96,7 +98,7 @@
    clients may have handy */
 grpc_mdstr *grpc_mdstr_from_string(const char *str);
 /* Unrefs the slice. */
-grpc_mdstr *grpc_mdstr_from_slice(grpc_slice slice);
+grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice);
 grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *str, size_t length);
 
 /* Returns a borrowed slice from the mdstr with its contents base64 encoded
@@ -105,12 +107,16 @@
 
 /* Constructors for grpc_mdelem instances; take a variety of data types that
    clients may have handy */
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *key,
+grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
+                                               grpc_mdstr *key,
                                                grpc_mdstr *value);
-grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value);
+grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key,
+                                      const char *value);
 /* Unrefs the slices. */
-grpc_mdelem *grpc_mdelem_from_slices(grpc_slice key, grpc_slice value);
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
+grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
+                                     grpc_slice value);
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx,
+                                                const char *key,
                                                 const uint8_t *value,
                                                 size_t value_length);
 
@@ -127,22 +133,26 @@
 //#define GRPC_METADATA_REFCOUNT_DEBUG
 #ifdef GRPC_METADATA_REFCOUNT_DEBUG
 #define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__)
-#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s), __FILE__, __LINE__)
+#define GRPC_MDSTR_UNREF(exec_ctx, s) \
+  grpc_mdstr_unref((exec_ctx), (s), __FILE__, __LINE__)
 #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__)
-#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__)
+#define GRPC_MDELEM_UNREF(exec_ctx, s) \
+  grpc_mdelem_unref((exec_ctx), (s), __FILE__, __LINE__)
 grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s, const char *file, int line);
-void grpc_mdstr_unref(grpc_mdstr *s, const char *file, int line);
+void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s, const char *file,
+                      int line);
 grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md, const char *file, int line);
-void grpc_mdelem_unref(grpc_mdelem *md, const char *file, int line);
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md,
+                       const char *file, int line);
 #else
 #define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s))
-#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s))
+#define GRPC_MDSTR_UNREF(exec_ctx, s) grpc_mdstr_unref((exec_ctx), (s))
 #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s))
-#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s))
+#define GRPC_MDELEM_UNREF(exec_ctx, s) grpc_mdelem_unref((exec_ctx), (s))
 grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s);
-void grpc_mdstr_unref(grpc_mdstr *s);
+void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s);
 grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md);
-void grpc_mdelem_unref(grpc_mdelem *md);
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md);
 #endif
 
 /* Recover a char* from a grpc_mdstr. The returned string is null terminated.
@@ -162,7 +172,7 @@
 #define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
 
 void grpc_mdctx_global_init(void);
-void grpc_mdctx_global_shutdown(void);
+void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx);
 
 /* Implementation provided by chttp2_transport */
 extern grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(
diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c
index 84b5a74..b62ecc3 100644
--- a/src/core/lib/transport/metadata_batch.c
+++ b/src/core/lib/transport/metadata_batch.c
@@ -72,10 +72,11 @@
   batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
 }
 
-void grpc_metadata_batch_destroy(grpc_metadata_batch *batch) {
+void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
+                                 grpc_metadata_batch *batch) {
   grpc_linked_mdelem *l;
   for (l = batch->list.head; l; l = l->next) {
-    GRPC_MDELEM_UNREF(l->md);
+    GRPC_MDELEM_UNREF(exec_ctx, l->md);
   }
 }
 
@@ -140,8 +141,10 @@
   memset(src, 0, sizeof(grpc_metadata_batch));
 }
 
-void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
-                                grpc_mdelem *(*filter)(void *user_data,
+void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
+                                grpc_metadata_batch *batch,
+                                grpc_mdelem *(*filter)(grpc_exec_ctx *exec_ctx,
+                                                       void *user_data,
                                                        grpc_mdelem *elem),
                                 void *user_data) {
   grpc_linked_mdelem *l;
@@ -152,7 +155,7 @@
   assert_valid_list(&batch->list);
   for (l = batch->list.head; l; l = next) {
     grpc_mdelem *orig = l->md;
-    grpc_mdelem *filt = filter(user_data, orig);
+    grpc_mdelem *filt = filter(exec_ctx, user_data, orig);
     next = l->next;
     if (filt == NULL) {
       if (l->prev) {
@@ -168,9 +171,9 @@
         batch->list.tail = l->prev;
       }
       assert_valid_list(&batch->list);
-      GRPC_MDELEM_UNREF(l->md);
+      GRPC_MDELEM_UNREF(exec_ctx, l->md);
     } else if (filt != orig) {
-      GRPC_MDELEM_UNREF(orig);
+      GRPC_MDELEM_UNREF(exec_ctx, orig);
       l->md = filt;
     }
   }
@@ -179,13 +182,15 @@
   GPR_TIMER_END("grpc_metadata_batch_filter", 0);
 }
 
-static grpc_mdelem *no_metadata_for_you(void *user_data, grpc_mdelem *elem) {
+static grpc_mdelem *no_metadata_for_you(grpc_exec_ctx *exec_ctx,
+                                        void *user_data, grpc_mdelem *elem) {
   return NULL;
 }
 
-void grpc_metadata_batch_clear(grpc_metadata_batch *batch) {
+void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
+                               grpc_metadata_batch *batch) {
   batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
-  grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL);
+  grpc_metadata_batch_filter(exec_ctx, batch, no_metadata_for_you, NULL);
 }
 
 bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h
index 7a9ccb4..c0bd517 100644
--- a/src/core/lib/transport/metadata_batch.h
+++ b/src/core/lib/transport/metadata_batch.h
@@ -68,8 +68,10 @@
 } grpc_metadata_batch;
 
 void grpc_metadata_batch_init(grpc_metadata_batch *batch);
-void grpc_metadata_batch_destroy(grpc_metadata_batch *batch);
-void grpc_metadata_batch_clear(grpc_metadata_batch *batch);
+void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
+                                 grpc_metadata_batch *batch);
+void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
+                               grpc_metadata_batch *batch);
 bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch);
 
 /* Returns the transport size of the batch. */
@@ -118,8 +120,10 @@
     The return value from \a filter will be substituted for the
     grpc_mdelem passed to \a filter. If \a filter returns NULL,
     the element will be moved to the garbage list. */
-void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
-                                grpc_mdelem *(*filter)(void *user_data,
+void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
+                                grpc_metadata_batch *batch,
+                                grpc_mdelem *(*filter)(grpc_exec_ctx *exec_ctx,
+                                                       void *user_data,
                                                        grpc_mdelem *elem),
                                 void *user_data);
 
diff --git a/src/core/lib/transport/method_config.c b/src/core/lib/transport/method_config.c
new file mode 100644
index 0000000..25fb54b
--- /dev/null
+++ b/src/core/lib/transport/method_config.c
@@ -0,0 +1,347 @@
+//
+// 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.
+//
+
+#include "src/core/lib/transport/method_config.h"
+
+#include <string.h>
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/transport/mdstr_hash_table.h"
+#include "src/core/lib/transport/metadata.h"
+
+//
+// grpc_method_config
+//
+
+// bool vtable
+
+static void* bool_copy(void* valuep) {
+  bool value = *(bool*)valuep;
+  bool* new_value = gpr_malloc(sizeof(bool));
+  *new_value = value;
+  return new_value;
+}
+
+static int bool_cmp(void* v1, void* v2) {
+  bool b1 = *(bool*)v1;
+  bool b2 = *(bool*)v2;
+  if (!b1 && b2) return -1;
+  if (b1 && !b2) return 1;
+  return 0;
+}
+
+static void free_mem(grpc_exec_ctx* exec_ctx, void* p) { gpr_free(p); }
+
+static grpc_mdstr_hash_table_vtable bool_vtable = {free_mem, bool_copy,
+                                                   bool_cmp};
+
+// timespec vtable
+
+static void* timespec_copy(void* valuep) {
+  gpr_timespec value = *(gpr_timespec*)valuep;
+  gpr_timespec* new_value = gpr_malloc(sizeof(gpr_timespec));
+  *new_value = value;
+  return new_value;
+}
+
+static int timespec_cmp(void* v1, void* v2) {
+  return gpr_time_cmp(*(gpr_timespec*)v1, *(gpr_timespec*)v2);
+}
+
+static grpc_mdstr_hash_table_vtable timespec_vtable = {free_mem, timespec_copy,
+                                                       timespec_cmp};
+
+// int32 vtable
+
+static void* int32_copy(void* valuep) {
+  int32_t value = *(int32_t*)valuep;
+  int32_t* new_value = gpr_malloc(sizeof(int32_t));
+  *new_value = value;
+  return new_value;
+}
+
+static int int32_cmp(void* v1, void* v2) {
+  int32_t i1 = *(int32_t*)v1;
+  int32_t i2 = *(int32_t*)v2;
+  if (i1 < i2) return -1;
+  if (i1 > i2) return 1;
+  return 0;
+}
+
+static grpc_mdstr_hash_table_vtable int32_vtable = {free_mem, int32_copy,
+                                                    int32_cmp};
+
+// Hash table keys.
+#define GRPC_METHOD_CONFIG_WAIT_FOR_READY "grpc.wait_for_ready"  // bool
+#define GRPC_METHOD_CONFIG_TIMEOUT "grpc.timeout"                // gpr_timespec
+#define GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES \
+  "grpc.max_request_message_bytes"  // int32
+#define GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES \
+  "grpc.max_response_message_bytes"  // int32
+
+struct grpc_method_config {
+  grpc_mdstr_hash_table* table;
+  grpc_mdstr* wait_for_ready_key;
+  grpc_mdstr* timeout_key;
+  grpc_mdstr* max_request_message_bytes_key;
+  grpc_mdstr* max_response_message_bytes_key;
+};
+
+grpc_method_config* grpc_method_config_create(
+    bool* wait_for_ready, gpr_timespec* timeout,
+    int32_t* max_request_message_bytes, int32_t* max_response_message_bytes) {
+  grpc_method_config* method_config = gpr_malloc(sizeof(grpc_method_config));
+  memset(method_config, 0, sizeof(grpc_method_config));
+  method_config->wait_for_ready_key =
+      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_WAIT_FOR_READY);
+  method_config->timeout_key =
+      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_TIMEOUT);
+  method_config->max_request_message_bytes_key =
+      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES);
+  method_config->max_response_message_bytes_key =
+      grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES);
+  grpc_mdstr_hash_table_entry entries[4];
+  size_t num_entries = 0;
+  if (wait_for_ready != NULL) {
+    entries[num_entries].key = method_config->wait_for_ready_key;
+    entries[num_entries].value = wait_for_ready;
+    entries[num_entries].vtable = &bool_vtable;
+    ++num_entries;
+  }
+  if (timeout != NULL) {
+    entries[num_entries].key = method_config->timeout_key;
+    entries[num_entries].value = timeout;
+    entries[num_entries].vtable = &timespec_vtable;
+    ++num_entries;
+  }
+  if (max_request_message_bytes != NULL) {
+    entries[num_entries].key = method_config->max_request_message_bytes_key;
+    entries[num_entries].value = max_request_message_bytes;
+    entries[num_entries].vtable = &int32_vtable;
+    ++num_entries;
+  }
+  if (max_response_message_bytes != NULL) {
+    entries[num_entries].key = method_config->max_response_message_bytes_key;
+    entries[num_entries].value = max_response_message_bytes;
+    entries[num_entries].vtable = &int32_vtable;
+    ++num_entries;
+  }
+  method_config->table = grpc_mdstr_hash_table_create(num_entries, entries);
+  return method_config;
+}
+
+grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config) {
+  grpc_mdstr_hash_table_ref(method_config->table);
+  return method_config;
+}
+
+void grpc_method_config_unref(grpc_exec_ctx* exec_ctx,
+                              grpc_method_config* method_config) {
+  if (grpc_mdstr_hash_table_unref(exec_ctx, method_config->table)) {
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->wait_for_ready_key);
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->timeout_key);
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->max_request_message_bytes_key);
+    GRPC_MDSTR_UNREF(exec_ctx, method_config->max_response_message_bytes_key);
+    gpr_free(method_config);
+  }
+}
+
+int grpc_method_config_cmp(const grpc_method_config* method_config1,
+                           const grpc_method_config* method_config2) {
+  return grpc_mdstr_hash_table_cmp(method_config1->table,
+                                   method_config2->table);
+}
+
+const bool* grpc_method_config_get_wait_for_ready(
+    const grpc_method_config* method_config) {
+  return grpc_mdstr_hash_table_get(method_config->table,
+                                   method_config->wait_for_ready_key);
+}
+
+const gpr_timespec* grpc_method_config_get_timeout(
+    const grpc_method_config* method_config) {
+  return grpc_mdstr_hash_table_get(method_config->table,
+                                   method_config->timeout_key);
+}
+
+const int32_t* grpc_method_config_get_max_request_message_bytes(
+    const grpc_method_config* method_config) {
+  return grpc_mdstr_hash_table_get(
+      method_config->table, method_config->max_request_message_bytes_key);
+}
+
+const int32_t* grpc_method_config_get_max_response_message_bytes(
+    const grpc_method_config* method_config) {
+  return grpc_mdstr_hash_table_get(
+      method_config->table, method_config->max_response_message_bytes_key);
+}
+
+//
+// grpc_method_config_table
+//
+
+static void method_config_unref(grpc_exec_ctx* exec_ctx, void* valuep) {
+  grpc_method_config_unref(exec_ctx, valuep);
+}
+
+static void* method_config_ref(void* valuep) {
+  return grpc_method_config_ref(valuep);
+}
+
+static int method_config_cmp(void* valuep1, void* valuep2) {
+  return grpc_method_config_cmp(valuep1, valuep2);
+}
+
+static const grpc_mdstr_hash_table_vtable method_config_table_vtable = {
+    method_config_unref, method_config_ref, method_config_cmp};
+
+grpc_method_config_table* grpc_method_config_table_create(
+    size_t num_entries, grpc_method_config_table_entry* entries) {
+  grpc_mdstr_hash_table_entry* hash_table_entries =
+      gpr_malloc(sizeof(grpc_mdstr_hash_table_entry) * num_entries);
+  for (size_t i = 0; i < num_entries; ++i) {
+    hash_table_entries[i].key = entries[i].method_name;
+    hash_table_entries[i].value = entries[i].method_config;
+    hash_table_entries[i].vtable = &method_config_table_vtable;
+  }
+  grpc_method_config_table* method_config_table =
+      grpc_mdstr_hash_table_create(num_entries, hash_table_entries);
+  gpr_free(hash_table_entries);
+  return method_config_table;
+}
+
+grpc_method_config_table* grpc_method_config_table_ref(
+    grpc_method_config_table* table) {
+  return grpc_mdstr_hash_table_ref(table);
+}
+
+void grpc_method_config_table_unref(grpc_exec_ctx* exec_ctx,
+                                    grpc_method_config_table* table) {
+  grpc_mdstr_hash_table_unref(exec_ctx, table);
+}
+
+int grpc_method_config_table_cmp(const grpc_method_config_table* table1,
+                                 const grpc_method_config_table* table2) {
+  return grpc_mdstr_hash_table_cmp(table1, table2);
+}
+
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+                                   const grpc_mdstr_hash_table* table,
+                                   const grpc_mdstr* path) {
+  void* value = grpc_mdstr_hash_table_get(table, path);
+  // If we didn't find a match for the path, try looking for a wildcard
+  // entry (i.e., change "/service/method" to "/service/*").
+  if (value == NULL) {
+    const char* path_str = grpc_mdstr_as_c_string(path);
+    const char* sep = strrchr(path_str, '/') + 1;
+    const size_t len = (size_t)(sep - path_str);
+    char* buf = gpr_malloc(len + 2);  // '*' and NUL
+    memcpy(buf, path_str, len);
+    buf[len] = '*';
+    buf[len + 1] = '\0';
+    grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf);
+    gpr_free(buf);
+    value = grpc_mdstr_hash_table_get(table, wildcard_path);
+    GRPC_MDSTR_UNREF(exec_ctx, wildcard_path);
+  }
+  return value;
+}
+
+static void* copy_arg(void* p) { return grpc_method_config_table_ref(p); }
+
+static void destroy_arg(grpc_exec_ctx* exec_ctx, void* p) {
+  grpc_method_config_table_unref(exec_ctx, p);
+}
+
+static int cmp_arg(void* p1, void* p2) {
+  return grpc_method_config_table_cmp(p1, p2);
+}
+
+static grpc_arg_pointer_vtable arg_vtable = {copy_arg, destroy_arg, cmp_arg};
+
+grpc_arg grpc_method_config_table_create_channel_arg(
+    grpc_method_config_table* table) {
+  grpc_arg arg;
+  arg.type = GRPC_ARG_POINTER;
+  arg.key = GRPC_ARG_SERVICE_CONFIG;
+  arg.value.pointer.p = table;
+  arg.value.pointer.vtable = &arg_vtable;
+  return arg;
+}
+
+// State used by convert_entry() below.
+typedef struct conversion_state {
+  void* (*convert_value)(const grpc_method_config* method_config);
+  const grpc_mdstr_hash_table_vtable* vtable;
+  size_t num_entries;
+  grpc_mdstr_hash_table_entry* entries;
+} conversion_state;
+
+// A function to be passed to grpc_mdstr_hash_table_iterate() to create
+// a copy of the entries.
+static void convert_entry(const grpc_mdstr_hash_table_entry* entry,
+                          void* user_data) {
+  conversion_state* state = user_data;
+  state->entries[state->num_entries].key = GRPC_MDSTR_REF(entry->key);
+  state->entries[state->num_entries].value = state->convert_value(entry->value);
+  state->entries[state->num_entries].vtable = state->vtable;
+  ++state->num_entries;
+}
+
+grpc_mdstr_hash_table* grpc_method_config_table_convert(
+    grpc_exec_ctx* exec_ctx, const grpc_method_config_table* table,
+    void* (*convert_value)(const grpc_method_config* method_config),
+    const grpc_mdstr_hash_table_vtable* vtable) {
+  // Create an array of the entries in the table with converted values.
+  conversion_state state;
+  state.convert_value = convert_value;
+  state.vtable = vtable;
+  state.num_entries = 0;
+  state.entries = gpr_malloc(sizeof(grpc_mdstr_hash_table_entry) *
+                             grpc_mdstr_hash_table_num_entries(table));
+  grpc_mdstr_hash_table_iterate(table, convert_entry, &state);
+  // Create a new table based on the array we just constructed.
+  grpc_mdstr_hash_table* new_table =
+      grpc_mdstr_hash_table_create(state.num_entries, state.entries);
+  // Clean up the array.
+  for (size_t i = 0; i < state.num_entries; ++i) {
+    GRPC_MDSTR_UNREF(exec_ctx, state.entries[i].key);
+    vtable->destroy_value(exec_ctx, state.entries[i].value);
+  }
+  gpr_free(state.entries);
+  // Return the new table.
+  return new_table;
+}
diff --git a/src/core/lib/transport/method_config.h b/src/core/lib/transport/method_config.h
new file mode 100644
index 0000000..d17a493
--- /dev/null
+++ b/src/core/lib/transport/method_config.h
@@ -0,0 +1,139 @@
+//
+// Copyright 2016, 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 GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H
+#define GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H
+
+#include <stdbool.h>
+
+#include <grpc/impl/codegen/gpr_types.h>
+#include <grpc/impl/codegen/grpc_types.h>
+
+#include "src/core/lib/transport/mdstr_hash_table.h"
+#include "src/core/lib/transport/metadata.h"
+
+/// Per-method configuration.
+typedef struct grpc_method_config grpc_method_config;
+
+/// Creates a grpc_method_config with the specified parameters.
+/// Any parameter may be NULL to indicate that the value is unset.
+///
+/// \a wait_for_ready indicates whether the client should wait until the
+/// request deadline for the channel to become ready, even if there is a
+/// temporary failure before the deadline while attempting to connect.
+///
+/// \a timeout indicates the timeout for calls.
+///
+/// \a max_request_message_bytes and \a max_response_message_bytes
+/// indicate the maximum sizes of the request (checked when sending) and
+/// response (checked when receiving) messages.
+grpc_method_config* grpc_method_config_create(
+    bool* wait_for_ready, gpr_timespec* timeout,
+    int32_t* max_request_message_bytes, int32_t* max_response_message_bytes);
+
+grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config);
+void grpc_method_config_unref(grpc_exec_ctx* exec_ctx,
+                              grpc_method_config* method_config);
+
+/// Compares two grpc_method_configs.
+/// The sort order is stable but undefined.
+int grpc_method_config_cmp(const grpc_method_config* method_config1,
+                           const grpc_method_config* method_config2);
+
+/// These methods return NULL if the requested field is unset.
+/// The caller does NOT take ownership of the result.
+const bool* grpc_method_config_get_wait_for_ready(
+    const grpc_method_config* method_config);
+const gpr_timespec* grpc_method_config_get_timeout(
+    const grpc_method_config* method_config);
+const int32_t* grpc_method_config_get_max_request_message_bytes(
+    const grpc_method_config* method_config);
+const int32_t* grpc_method_config_get_max_response_message_bytes(
+    const grpc_method_config* method_config);
+
+/// A table of method configs.
+typedef grpc_mdstr_hash_table grpc_method_config_table;
+
+typedef struct grpc_method_config_table_entry {
+  /// The name is of one of the following forms:
+  ///   service/method -- specifies exact service and method name
+  ///   service/*      -- matches all methods for the specified service
+  grpc_mdstr* method_name;
+  grpc_method_config* method_config;
+} grpc_method_config_table_entry;
+
+/// Takes new references to all keys and values in \a entries.
+grpc_method_config_table* grpc_method_config_table_create(
+    size_t num_entries, grpc_method_config_table_entry* entries);
+
+grpc_method_config_table* grpc_method_config_table_ref(
+    grpc_method_config_table* table);
+void grpc_method_config_table_unref(grpc_exec_ctx* exec_ctx,
+                                    grpc_method_config_table* table);
+
+/// Compares two grpc_method_config_tables.
+/// The sort order is stable but undefined.
+int grpc_method_config_table_cmp(const grpc_method_config_table* table1,
+                                 const grpc_method_config_table* table2);
+
+/// Gets the method config for the specified \a path, which should be of
+/// the form "/service/method".
+/// Returns NULL if the method has no config.
+/// Caller does NOT own a reference to the result.
+///
+/// Note: This returns a void* instead of a grpc_method_config* so that
+/// it can also be used for tables constructed via
+/// grpc_method_config_table_convert().
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+                                   const grpc_mdstr_hash_table* table,
+                                   const grpc_mdstr* path);
+
+/// Returns a channel arg containing \a table.
+grpc_arg grpc_method_config_table_create_channel_arg(
+    grpc_method_config_table* table);
+
+/// Generates a new table from \a table whose values are converted to a
+/// new form via the \a convert_value function.  The new table will use
+/// \a vtable for its values.
+///
+/// This is generally used to convert the table's value type from
+/// grpc_method_config to a simple struct containing only the parameters
+/// relevant to a particular filter, thus avoiding the need for a hash
+/// table lookup on the fast path.  In that scenario, \a convert_value
+/// will return a new instance of the struct containing the values from
+/// the grpc_method_config, and \a vtable provides the methods for
+/// operating on the struct type.
+grpc_mdstr_hash_table* grpc_method_config_table_convert(
+    grpc_exec_ctx* exec_ctx, const grpc_method_config_table* table,
+    void* (*convert_value)(const grpc_method_config* method_config),
+    const grpc_mdstr_hash_table_vtable* vtable);
+
+#endif /* GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H */
diff --git a/src/core/lib/transport/pid_controller.h b/src/core/lib/transport/pid_controller.h
index 059b5b0..83c82d6 100644
--- a/src/core/lib/transport/pid_controller.h
+++ b/src/core/lib/transport/pid_controller.h
@@ -61,4 +61,4 @@
 double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
                                   double error, double dt);
 
-#endif
+#endif /* GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H */
diff --git a/src/core/lib/transport/service_config.c b/src/core/lib/transport/service_config.c
index 2e2b59e..552d3ec 100644
--- a/src/core/lib/transport/service_config.c
+++ b/src/core/lib/transport/service_config.c
@@ -146,7 +146,8 @@
 // each name found, incrementing \a idx for each entry added.
 // Returns false on error.
 static bool parse_json_method_config(
-    grpc_json* json, void* (*create_value)(const grpc_json* method_config_json),
+    grpc_exec_ctx* exec_ctx, grpc_json* json,
+    void* (*create_value)(const grpc_json* method_config_json),
     const grpc_mdstr_hash_table_vtable* vtable,
     grpc_mdstr_hash_table_entry* entries, size_t* idx) {
   // Construct value.
@@ -176,13 +177,13 @@
   }
   success = true;
 done:
-  vtable->destroy_value(method_config);
+  vtable->destroy_value(exec_ctx, method_config);
   gpr_strvec_destroy(&paths);
   return success;
 }
 
 grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
-    const grpc_service_config* service_config,
+    grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
     void* (*create_value)(const grpc_json* method_config_json),
     const grpc_mdstr_hash_table_vtable* vtable) {
   const grpc_json* json = service_config->json_tree;
@@ -205,8 +206,8 @@
       size_t idx = 0;
       for (grpc_json* method = field->child; method != NULL;
            method = method->next) {
-        if (!parse_json_method_config(method, create_value, vtable, entries,
-                                      &idx)) {
+        if (!parse_json_method_config(exec_ctx, method, create_value, vtable,
+                                      entries, &idx)) {
           return NULL;
         }
       }
@@ -219,15 +220,16 @@
     method_config_table = grpc_mdstr_hash_table_create(num_entries, entries);
     // Clean up.
     for (size_t i = 0; i < num_entries; ++i) {
-      GRPC_MDSTR_UNREF(entries[i].key);
-      vtable->destroy_value(entries[i].value);
+      GRPC_MDSTR_UNREF(exec_ctx, entries[i].key);
+      vtable->destroy_value(exec_ctx, entries[i].value);
     }
     gpr_free(entries);
   }
   return method_config_table;
 }
 
-void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+                                   const grpc_mdstr_hash_table* table,
                                    const grpc_mdstr* path) {
   void* value = grpc_mdstr_hash_table_get(table, path);
   // If we didn't find a match for the path, try looking for a wildcard
@@ -243,7 +245,7 @@
     grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf);
     gpr_free(buf);
     value = grpc_mdstr_hash_table_get(table, wildcard_path);
-    GRPC_MDSTR_UNREF(wildcard_path);
+    GRPC_MDSTR_UNREF(exec_ctx, wildcard_path);
   }
   return value;
 }
diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h
index 2ffe475..f089717 100644
--- a/src/core/lib/transport/service_config.h
+++ b/src/core/lib/transport/service_config.h
@@ -54,7 +54,7 @@
 /// \a vtable provides methods used to manage the values.
 /// Returns NULL on error.
 grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
-    const grpc_service_config* service_config,
+    grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
     void* (*create_value)(const grpc_json* method_config_json),
     const grpc_mdstr_hash_table_vtable* vtable);
 
@@ -64,7 +64,8 @@
 /// the form "/service/method".
 /// Returns NULL if the method has no config.
 /// Caller does NOT own a reference to the result.
-void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+                                   const grpc_mdstr_hash_table* table,
                                    const grpc_mdstr* path);
 
 #endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index b448126..9bc278c 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -40,6 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/transport_impl.h"
@@ -212,12 +213,12 @@
 }
 
 void grpc_transport_stream_op_add_cancellation_with_message(
-    grpc_transport_stream_op *op, grpc_status_code status,
-    grpc_slice *optional_message) {
+    grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op,
+    grpc_status_code status, grpc_slice *optional_message) {
   GPR_ASSERT(status != GRPC_STATUS_OK);
   if (op->cancel_error != GRPC_ERROR_NONE) {
     if (optional_message) {
-      grpc_slice_unref(*optional_message);
+      grpc_slice_unref_internal(exec_ctx, *optional_message);
     }
     return;
   }
@@ -227,7 +228,7 @@
     error = grpc_error_set_str(GRPC_ERROR_CREATE(msg),
                                GRPC_ERROR_STR_GRPC_MESSAGE, msg);
     gpr_free(msg);
-    grpc_slice_unref(*optional_message);
+    grpc_slice_unref_internal(exec_ctx, *optional_message);
   } else {
     error = GRPC_ERROR_CREATE("Call cancelled");
   }
@@ -235,14 +236,15 @@
   add_error(op, &op->cancel_error, error);
 }
 
-void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
+void grpc_transport_stream_op_add_close(grpc_exec_ctx *exec_ctx,
+                                        grpc_transport_stream_op *op,
                                         grpc_status_code status,
                                         grpc_slice *optional_message) {
   GPR_ASSERT(status != GRPC_STATUS_OK);
   if (op->cancel_error != GRPC_ERROR_NONE ||
       op->close_error != GRPC_ERROR_NONE) {
     if (optional_message) {
-      grpc_slice_unref(*optional_message);
+      grpc_slice_unref_internal(exec_ctx, *optional_message);
     }
     return;
   }
@@ -252,7 +254,7 @@
     error = grpc_error_set_str(GRPC_ERROR_CREATE(msg),
                                GRPC_ERROR_STR_GRPC_MESSAGE, msg);
     gpr_free(msg);
-    grpc_slice_unref(*optional_message);
+    grpc_slice_unref_internal(exec_ctx, *optional_message);
   } else {
     error = GRPC_ERROR_CREATE("Call force closed");
   }
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 96c2674..d128183 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -249,10 +249,11 @@
                                                grpc_status_code status);
 
 void grpc_transport_stream_op_add_cancellation_with_message(
-    grpc_transport_stream_op *op, grpc_status_code status,
-    grpc_slice *optional_message);
+    grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op,
+    grpc_status_code status, grpc_slice *optional_message);
 
-void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
+void grpc_transport_stream_op_add_close(grpc_exec_ctx *exec_ctx,
+                                        grpc_transport_stream_op *op,
                                         grpc_status_code status,
                                         grpc_slice *optional_message);
 
diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc
index 0301b5b..1fdd106 100644
--- a/src/cpp/common/channel_arguments.cc
+++ b/src/cpp/common/channel_arguments.cc
@@ -38,8 +38,11 @@
 #include <grpc++/resource_quota.h>
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/support/log.h>
+extern "C" {
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/socket_mutator.h"
+}
 namespace grpc {
 
 ChannelArguments::ChannelArguments() {
@@ -94,13 +97,15 @@
   }
   grpc_arg mutator_arg = grpc_socket_mutator_to_arg(mutator);
   bool replaced = false;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   for (auto it = args_.begin(); it != args_.end(); ++it) {
     if (it->type == mutator_arg.type &&
         grpc::string(it->key) == grpc::string(mutator_arg.key)) {
-      it->value.pointer.vtable->destroy(it->value.pointer.p);
+      it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p);
       it->value.pointer = mutator_arg.value.pointer;
     }
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   if (!replaced) {
     args_.push_back(mutator_arg);
   }
diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc
index ad2c0f2..c0dc9dd 100644
--- a/src/cpp/common/channel_filter.cc
+++ b/src/cpp/common/channel_filter.cc
@@ -40,11 +40,12 @@
 
 // MetadataBatch
 
-grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key,
+grpc_linked_mdelem *MetadataBatch::AddMetadata(grpc_exec_ctx *exec_ctx,
+                                               const string &key,
                                                const string &value) {
   grpc_linked_mdelem *storage = new grpc_linked_mdelem;
   memset(storage, 0, sizeof(grpc_linked_mdelem));
-  storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str());
+  storage->md = grpc_mdelem_from_strings(exec_ctx, key.c_str(), value.c_str());
   grpc_metadata_batch_link_head(batch_, storage);
   return storage;
 }
@@ -89,7 +90,8 @@
 
 namespace {
 
-bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) {
+bool MaybeAddFilter(grpc_exec_ctx *exec_ctx,
+                    grpc_channel_stack_builder *builder, void *arg) {
   const FilterRecord &filter = *(FilterRecord *)arg;
   if (filter.include_filter) {
     const grpc_channel_args *args =
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index e420efc..65f4466 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -70,7 +70,8 @@
   /// Adds metadata and returns the newly allocated storage.
   /// The caller takes ownership of the result, which must exist for the
   /// lifetime of the gRPC call.
-  grpc_linked_mdelem *AddMetadata(const string &key, const string &value);
+  grpc_linked_mdelem *AddMetadata(grpc_exec_ctx *exec_ctx, const string &key,
+                                  const string &value);
 
   class const_iterator : public std::iterator<std::bidirectional_iterator_tag,
                                               const grpc_mdelem> {
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index 07fcd99..1ce3a49 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -33,15 +33,18 @@
 
 #include "test/core/bad_client/bad_client.h"
 
+#include <stdio.h>
+
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
-#include <stdio.h>
+
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/http_server_filter.h"
 #include "src/core/lib/iomgr/endpoint_pair.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/murmur_hash.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/completion_queue.h"
@@ -117,7 +120,7 @@
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("bad_client_test");
   sfd = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, 65536);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   /* Create server, completion events */
   a.server = grpc_server_create(NULL, NULL);
@@ -181,7 +184,7 @@
       grpc_exec_ctx_finish(&exec_ctx);
       GPR_ASSERT(
           gpr_event_wait(&args.read_done, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
-      grpc_slice_buffer_destroy(&args.incoming);
+      grpc_slice_buffer_destroy_internal(&exec_ctx, &args.incoming);
     }
     // Shutdown.
     grpc_endpoint_shutdown(&exec_ctx, sfd.client);
@@ -194,7 +197,7 @@
                  .type == GRPC_OP_COMPLETE);
   grpc_server_destroy(a.server);
   grpc_completion_queue_destroy(a.cq);
-  grpc_slice_buffer_destroy(&outgoing);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &outgoing);
 
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c
index d3eb969..b2c4165 100644
--- a/test/core/channel/channel_args_test.c
+++ b/test/core/channel/channel_args_test.c
@@ -37,10 +37,12 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/channel/channel_args.h"
-
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "test/core/util/test_config.h"
 
 static void test_create(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   grpc_arg arg_int;
   grpc_arg arg_string;
   grpc_arg to_add[2];
@@ -68,10 +70,12 @@
   GPR_ASSERT(strcmp(ch_args->args[1].value.string, arg_string.value.string) ==
              0);
 
-  grpc_channel_args_destroy(ch_args);
+  grpc_channel_args_destroy(&exec_ctx, ch_args);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_set_compression_algorithm(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *ch_args;
 
   ch_args =
@@ -81,10 +85,12 @@
                     GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0);
   GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER);
 
-  grpc_channel_args_destroy(ch_args);
+  grpc_channel_args_destroy(&exec_ctx, ch_args);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_compression_algorithm_states(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate;
   unsigned states_bitset;
   size_t i;
@@ -100,10 +106,10 @@
 
   /* disable gzip and deflate */
   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
-      &ch_args, GRPC_COMPRESS_GZIP, 0);
+      &exec_ctx, &ch_args, GRPC_COMPRESS_GZIP, 0);
   GPR_ASSERT(ch_args == ch_args_wo_gzip);
   ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state(
-      &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
+      &exec_ctx, &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
   GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
 
   states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
@@ -118,7 +124,7 @@
 
   /* re-enabled gzip only */
   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
-      &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1);
+      &exec_ctx, &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1);
   GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
 
   states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
@@ -131,7 +137,8 @@
     }
   }
 
-  grpc_channel_args_destroy(ch_args);
+  grpc_channel_args_destroy(&exec_ctx, ch_args);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_set_socket_mutator(void) {
@@ -144,7 +151,11 @@
   GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_ARG_SOCKET_MUTATOR) == 0);
   GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_POINTER);
 
-  grpc_channel_args_destroy(ch_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, ch_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 0840820..54575ae 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -156,8 +156,8 @@
 
   GRPC_CHANNEL_STACK_UNREF(&exec_ctx, channel_stack, "done");
 
+  GRPC_MDSTR_UNREF(&exec_ctx, path);
   grpc_exec_ctx_finish(&exec_ctx);
-  GRPC_MDSTR_UNREF(path);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index 6e4058f..e3550d7 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -643,7 +643,11 @@
   arg.value.string = "{\"loadBalancingPolicy\": \"ROUND_ROBIN\"}";
   grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
   channel = grpc_insecure_channel_create("ipv4:127.0.0.1:1234", args, NULL);
-  grpc_channel_args_destroy(args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   // Ensures that resolver returns.
   grpc_channel_check_connectivity_state(channel, true /* try_to_connect */);
   // Now request the service config again.
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index ffa167a..5ba8ef8 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -64,6 +64,7 @@
 }
 
 static grpc_resolver *create_resolver(const char *name) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns");
   grpc_uri *uri = grpc_uri_parse(name, 0);
   GPR_ASSERT(uri);
@@ -71,9 +72,10 @@
   memset(&args, 0, sizeof(args));
   args.uri = uri;
   grpc_resolver *resolver =
-      grpc_resolver_factory_create_resolver(factory, &args);
+      grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   grpc_resolver_factory_unref(factory);
   grpc_uri_destroy(uri);
+  grpc_exec_ctx_finish(&exec_ctx);
   return resolver;
 }
 
@@ -123,7 +125,7 @@
   GPR_ASSERT(wait_loop(30, &ev2));
   GPR_ASSERT(result != NULL);
 
-  grpc_channel_args_destroy(result);
+  grpc_channel_args_destroy(&exec_ctx, result);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test");
   grpc_exec_ctx_finish(&exec_ctx);
 
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c
index 41a9125..5603a57 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_test.c
@@ -48,7 +48,7 @@
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver != NULL);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
   grpc_uri_destroy(uri);
@@ -65,7 +65,7 @@
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver == NULL);
   grpc_uri_destroy(uri);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index ebf311a..bf49fb1 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -54,7 +54,7 @@
   GPR_ASSERT(channel_arg != NULL);
   GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
   GPR_ASSERT(strcmp(res->expected_server_name, channel_arg->value.string) == 0);
-  grpc_channel_args_destroy(res->resolver_result);
+  grpc_channel_args_destroy(exec_ctx, res->resolver_result);
 }
 
 static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
@@ -67,7 +67,7 @@
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver != NULL);
 
   on_resolution_arg on_res_arg;
@@ -93,7 +93,7 @@
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  resolver = grpc_resolver_factory_create_resolver(factory, &args);
+  resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
   GPR_ASSERT(resolver == NULL);
   grpc_uri_destroy(uri);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/set_initial_connect_string_test.c b/test/core/client_channel/set_initial_connect_string_test.c
index 11e5743..b922348 100644
--- a/test/core/client_channel/set_initial_connect_string_test.c
+++ b/test/core/client_channel/set_initial_connect_string_test.c
@@ -158,7 +158,7 @@
   grpc_event ev;
   grpc_slice_buffer_destroy(&state.incoming_buffer);
   grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
-  grpc_channel_credentials_unref(state.creds);
+  grpc_channel_credentials_release(state.creds);
   grpc_call_destroy(state.call);
   grpc_completion_queue_shutdown(state.cq);
   do {
diff --git a/test/core/compression/algorithm_test.c b/test/core/compression/algorithm_test.c
index bdee748..ff17667 100644
--- a/test/core/compression/algorithm_test.c
+++ b/test/core/compression/algorithm_test.c
@@ -53,6 +53,7 @@
     grpc_compression_algorithm parsed;
     grpc_mdstr *mdstr;
     grpc_mdelem *mdelem;
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     GPR_ASSERT(
         grpc_compression_algorithm_name((grpc_compression_algorithm)i, &name));
     GPR_ASSERT(grpc_compression_algorithm_parse(name, strlen(name), &parsed));
@@ -63,8 +64,9 @@
     mdelem = grpc_compression_encoding_mdelem(parsed);
     GPR_ASSERT(mdelem->value == mdstr);
     GPR_ASSERT(mdelem->key == GRPC_MDSTR_GRPC_ENCODING);
-    GRPC_MDSTR_UNREF(mdstr);
-    GRPC_MDELEM_UNREF(mdelem);
+    GRPC_MDSTR_UNREF(&exec_ctx, mdstr);
+    GRPC_MDELEM_UNREF(&exec_ctx, mdelem);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
 
   /* test failure */
@@ -73,6 +75,7 @@
 }
 
 static void test_algorithm_failure(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_mdstr *mdstr;
 
   gpr_log(GPR_DEBUG, "test_algorithm_failure");
@@ -88,7 +91,8 @@
              NULL);
   GPR_ASSERT(grpc_compression_algorithm_mdstr(GRPC_COMPRESS_ALGORITHMS_COUNT +
                                               1) == NULL);
-  GRPC_MDSTR_UNREF(mdstr);
+  GRPC_MDSTR_UNREF(&exec_ctx, mdstr);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index fc53cd9..2432ca7 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -40,6 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/support/murmur_hash.h"
 #include "test/core/util/slice_splitter.h"
 #include "test/core/util/test_config.h"
@@ -82,7 +83,12 @@
 
   grpc_split_slices_to_buffer(uncompressed_split_mode, &value, 1, &input);
 
-  was_compressed = grpc_msg_compress(algorithm, &input, &compressed_raw);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    was_compressed =
+        grpc_msg_compress(&exec_ctx, algorithm, &input, &compressed_raw);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   GPR_ASSERT(input.count > 0);
 
   switch (compress_result_check) {
@@ -99,8 +105,13 @@
 
   grpc_split_slice_buffer(compressed_split_mode, &compressed_raw, &compressed);
 
-  GPR_ASSERT(grpc_msg_decompress(
-      was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed, &output));
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    GPR_ASSERT(grpc_msg_decompress(
+        &exec_ctx, was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed,
+        &output));
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   final = grpc_slice_merge(output.slices, output.count);
   GPR_ASSERT(0 == grpc_slice_cmp(value, final));
@@ -160,7 +171,9 @@
 
   for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
     if (i == GRPC_COMPRESS_NONE) continue;
-    GPR_ASSERT(0 == grpc_msg_compress(i, &input, &output));
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    GPR_ASSERT(0 == grpc_msg_compress(&exec_ctx, i, &input, &output));
+    grpc_exec_ctx_finish(&exec_ctx);
     GPR_ASSERT(1 == output.count);
   }
 
@@ -180,8 +193,9 @@
   grpc_slice_buffer_init(&output);
   grpc_slice_buffer_add(&input, create_test_value(ONE_MB_A));
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   /* compress it */
-  grpc_msg_compress(GRPC_COMPRESS_GZIP, &input, &corrupted);
+  grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_GZIP, &input, &corrupted);
   /* corrupt the output by smashing the CRC */
   GPR_ASSERT(corrupted.count > 1);
   GPR_ASSERT(GRPC_SLICE_LENGTH(corrupted.slices[1]) > 8);
@@ -189,7 +203,9 @@
   memcpy(GRPC_SLICE_START_PTR(corrupted.slices[1]) + idx, &bad, 4);
 
   /* try (and fail) to decompress the corrupted compresed buffer */
-  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_GZIP, &corrupted, &output));
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_GZIP, &corrupted,
+                                      &output));
+  grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
   grpc_slice_buffer_destroy(&corrupted);
@@ -208,7 +224,10 @@
                   "\x78\xda\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01\x99", 13));
 
   /* try (and fail) to decompress the invalid compresed buffer */
-  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
+                                      &output));
+  grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
   grpc_slice_buffer_destroy(&output);
@@ -224,7 +243,10 @@
                         grpc_slice_from_copied_buffer("\x78\xda\xff\xff", 4));
 
   /* try (and fail) to decompress the invalid compresed buffer */
-  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
+                                      &output));
+  grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
   grpc_slice_buffer_destroy(&output);
@@ -239,13 +261,16 @@
   grpc_slice_buffer_init(&output);
   grpc_slice_buffer_add(
       &input, grpc_slice_from_copied_string("Never gonna give you up"));
-  was_compressed =
-      grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  was_compressed = grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT,
+                                     &input, &output);
   GPR_ASSERT(0 == was_compressed);
 
-  was_compressed =
-      grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
+  was_compressed = grpc_msg_compress(
+      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
   GPR_ASSERT(0 == was_compressed);
+  grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
   grpc_slice_buffer_destroy(&output);
@@ -261,13 +286,15 @@
   grpc_slice_buffer_add(&input,
                         grpc_slice_from_copied_string(
                             "I'm not really compressed but it doesn't matter"));
-  was_decompressed =
-      grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  was_decompressed = grpc_msg_decompress(
+      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
   GPR_ASSERT(0 == was_decompressed);
 
-  was_decompressed = grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123,
-                                         &input, &output);
+  was_decompressed = grpc_msg_decompress(
+      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
   GPR_ASSERT(0 == was_decompressed);
+  grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
   grpc_slice_buffer_destroy(&output);
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 3046855..a483645 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -47,6 +47,7 @@
 #include <grpc/support/thd.h>
 
 #include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "test/core/end2end/cq_verifier.h"
@@ -227,10 +228,10 @@
   cq_verifier_destroy(cqv);
 }
 
-static void cleanup_rpc(void) {
+static void cleanup_rpc(grpc_exec_ctx *exec_ctx) {
   grpc_event ev;
-  grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
-  grpc_slice_buffer_destroy(&state.outgoing_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.temp_incoming_buffer);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &state.outgoing_buffer);
   grpc_call_destroy(state.call);
   grpc_completion_queue_shutdown(state.cq);
   do {
@@ -299,8 +300,8 @@
   /* clean up */
   grpc_endpoint_shutdown(&exec_ctx, state.tcp);
   grpc_endpoint_destroy(&exec_ctx, state.tcp);
+  cleanup_rpc(&exec_ctx);
   grpc_exec_ctx_finish(&exec_ctx);
-  cleanup_rpc();
   test_tcp_server_destroy(&test_server);
 
   grpc_shutdown();
diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c
index 728d6dc..4430804 100644
--- a/test/core/end2end/connection_refused_test.c
+++ b/test/core/end2end/connection_refused_test.c
@@ -145,7 +145,11 @@
   gpr_free(details);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
 
-  if (args != NULL) grpc_channel_args_destroy(args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    if (args != NULL) grpc_channel_args_destroy(&exec_ctx, args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   grpc_shutdown();
 }
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 865b55d..55a42b8 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -48,6 +48,7 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
@@ -76,8 +77,8 @@
 static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
   fake_resolver* r = (fake_resolver*)gr;
   gpr_mu_destroy(&r->mu);
-  grpc_channel_args_destroy(r->channel_args);
-  grpc_lb_addresses_destroy(r->addresses);
+  grpc_channel_args_destroy(exec_ctx, r->channel_args);
+  grpc_lb_addresses_destroy(exec_ctx, r->addresses);
   gpr_free(r);
 }
 
@@ -140,7 +141,8 @@
 
 static void do_nothing(void* ignored) {}
 
-static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
+static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx,
+                                           grpc_resolver_factory* factory,
                                            grpc_resolver_args* args) {
   if (0 != strcmp(args->uri->authority, "")) {
     gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
@@ -172,10 +174,10 @@
     addresses->addresses[i].is_balancer = lb_enabled;
     if (errors_found) break;
   }
-  grpc_slice_buffer_destroy(&path_parts);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
   grpc_slice_unref(path_slice);
   if (errors_found) {
-    grpc_lb_addresses_destroy(addresses);
+    grpc_lb_addresses_destroy(exec_ctx, addresses);
     return NULL;
   }
   // Instantiate resolver.
diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c
index c52d766..8e60123 100644
--- a/test/core/end2end/fixtures/h2_census.c
+++ b/test/core/end2end/fixtures/h2_census.c
@@ -85,7 +85,11 @@
   client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1);
   f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client);
-  grpc_channel_args_destroy(client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
@@ -97,7 +101,11 @@
   }
   server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
   f->server = grpc_server_create(server_args, NULL);
-  grpc_channel_args_destroy(server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_server_register_completion_queue(f->server, f->cq, NULL);
   GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
   grpc_server_start(f->server);
diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c
index fedd2eb..c01e456 100644
--- a/test/core/end2end/fixtures/h2_compress.c
+++ b/test/core/end2end/fixtures/h2_compress.c
@@ -78,7 +78,9 @@
                                               grpc_channel_args *client_args) {
   fullstack_compression_fixture_data *ffd = f->fixture_data;
   if (ffd->client_args_compression != NULL) {
-    grpc_channel_args_destroy(ffd->client_args_compression);
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, ffd->client_args_compression);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
   ffd->client_args_compression = grpc_channel_args_set_compression_algorithm(
       client_args, GRPC_COMPRESS_GZIP);
@@ -90,7 +92,9 @@
                                               grpc_channel_args *server_args) {
   fullstack_compression_fixture_data *ffd = f->fixture_data;
   if (ffd->server_args_compression != NULL) {
-    grpc_channel_args_destroy(ffd->server_args_compression);
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, ffd->server_args_compression);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
   ffd->server_args_compression = grpc_channel_args_set_compression_algorithm(
       server_args, GRPC_COMPRESS_GZIP);
@@ -104,11 +108,13 @@
 }
 
 void chttp2_tear_down_fullstack_compression(grpc_end2end_test_fixture *f) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   fullstack_compression_fixture_data *ffd = f->fixture_data;
-  grpc_channel_args_destroy(ffd->client_args_compression);
-  grpc_channel_args_destroy(ffd->server_args_compression);
+  grpc_channel_args_destroy(&exec_ctx, ffd->client_args_compression);
+  grpc_channel_args_destroy(&exec_ctx, ffd->server_args_compression);
   gpr_free(ffd->localaddr);
   gpr_free(ffd);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 /* All test configurations */
diff --git a/test/core/end2end/fixtures/h2_load_reporting.c b/test/core/end2end/fixtures/h2_load_reporting.c
index 7a76489..38321f3 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.c
+++ b/test/core/end2end/fixtures/h2_load_reporting.c
@@ -88,7 +88,11 @@
   }
   server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
   f->server = grpc_server_create(server_args, NULL);
-  grpc_channel_args_destroy(server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_server_register_completion_queue(f->server, f->cq, NULL);
   GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
   grpc_server_start(f->server);
diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c
index 6122f4f..83f759c 100644
--- a/test/core/end2end/fixtures/h2_oauth2.c
+++ b/test/core/end2end/fixtures/h2_oauth2.c
@@ -163,7 +163,11 @@
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_oauth2_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_channel_credentials_release(ssl_creds);
   grpc_call_credentials_release(oauth2_creds);
 }
diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c
index bbd522c..cf44cd0 100644
--- a/test/core/end2end/fixtures/h2_ssl.c
+++ b/test/core/end2end/fixtures/h2_ssl.c
@@ -118,7 +118,11 @@
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 static int fail_server_auth_check(grpc_channel_args *server_args) {
diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c
index e39cb49..ae49cc8 100644
--- a/test/core/end2end/fixtures/h2_ssl_cert.c
+++ b/test/core/end2end/fixtures/h2_ssl_cert.c
@@ -186,7 +186,11 @@
     grpc_channel_args *new_client_args =                                     \
         grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);  \
     chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);      \
-    grpc_channel_args_destroy(new_client_args);                              \
+    {                                                                        \
+      grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;                           \
+      grpc_channel_args_destroy(&exec_ctx, new_client_args);                 \
+      grpc_exec_ctx_finish(&exec_ctx);                                       \
+    }                                                                        \
   }
 
 CLIENT_INIT(NONE)
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c
index 27cf3eb..740b075 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.c
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.c
@@ -79,7 +79,11 @@
   channel =
       grpc_secure_channel_create(ssl_creds, target, new_client_args, NULL);
   grpc_channel_credentials_release(ssl_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   return channel;
 }
 
@@ -151,7 +155,11 @@
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 static int fail_server_auth_check(grpc_channel_args *server_args) {
diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy.c
index 80865fc..ef1e929 100644
--- a/test/core/end2end/fixtures/http_proxy.c
+++ b/test/core/end2end/fixtures/http_proxy.c
@@ -59,6 +59,7 @@
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/iomgr/tcp_server.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/port.h"
 
 struct grpc_end2end_http_proxy {
@@ -110,12 +111,14 @@
     if (conn->server_endpoint != NULL)
       grpc_endpoint_destroy(exec_ctx, conn->server_endpoint);
     grpc_pollset_set_destroy(conn->pollset_set);
-    grpc_slice_buffer_destroy(&conn->client_read_buffer);
-    grpc_slice_buffer_destroy(&conn->client_deferred_write_buffer);
-    grpc_slice_buffer_destroy(&conn->client_write_buffer);
-    grpc_slice_buffer_destroy(&conn->server_read_buffer);
-    grpc_slice_buffer_destroy(&conn->server_deferred_write_buffer);
-    grpc_slice_buffer_destroy(&conn->server_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx,
+                                       &conn->client_deferred_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx,
+                                       &conn->server_deferred_write_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_write_buffer);
     grpc_http_parser_destroy(&conn->http_parser);
     grpc_http_request_destroy(&conn->http_request);
     gpr_free(conn);
@@ -469,7 +472,7 @@
   grpc_tcp_server_shutdown_listeners(&exec_ctx, proxy->server);
   grpc_tcp_server_unref(&exec_ctx, proxy->server);
   gpr_free(proxy->proxy_name);
-  grpc_channel_args_destroy(proxy->channel_args);
+  grpc_channel_args_destroy(&exec_ctx, proxy->channel_args);
   grpc_closure destroyed;
   grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset);
   grpc_pollset_shutdown(&exec_ctx, proxy->pollset, &destroyed);
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 19ac6ce..90ad065 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -744,7 +744,11 @@
           grpc_channel_args *args = read_args(&inp);
           g_channel = grpc_insecure_channel_create(target_uri, args, NULL);
           GPR_ASSERT(g_channel != NULL);
-          grpc_channel_args_destroy(args);
+          {
+            grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+            grpc_channel_args_destroy(&exec_ctx, args);
+            grpc_exec_ctx_finish(&exec_ctx);
+          }
           gpr_free(target_uri);
           gpr_free(target);
         } else {
@@ -768,7 +772,11 @@
           grpc_channel_args *args = read_args(&inp);
           g_server = grpc_server_create(args, NULL);
           GPR_ASSERT(g_server != NULL);
-          grpc_channel_args_destroy(args);
+          {
+            grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+            grpc_channel_args_destroy(&exec_ctx, args);
+            grpc_exec_ctx_finish(&exec_ctx);
+          }
           grpc_server_register_completion_queue(g_server, cq, NULL);
           grpc_server_start(g_server);
           server_shutdown = false;
@@ -1104,7 +1112,11 @@
           grpc_channel_credentials *creds = read_channel_creds(&inp);
           g_channel = grpc_secure_channel_create(creds, target_uri, args, NULL);
           GPR_ASSERT(g_channel != NULL);
-          grpc_channel_args_destroy(args);
+          {
+            grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+            grpc_channel_args_destroy(&exec_ctx, args);
+            grpc_exec_ctx_finish(&exec_ctx);
+          }
           gpr_free(target_uri);
           gpr_free(target);
           grpc_channel_credentials_release(creds);
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index c5260cd..26b5208 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -62,7 +62,7 @@
       grpc_resource_quota_create("client_fuzzer");
   grpc_endpoint *mock_endpoint =
       grpc_mock_endpoint_create(discard_write, resource_quota);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
   grpc_transport *transport =
diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c
index 164022e..115fb06 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.c
+++ b/test/core/end2end/fuzzers/server_fuzzer.c
@@ -60,7 +60,7 @@
       grpc_resource_quota_create("server_fuzzer");
   grpc_endpoint *mock_endpoint =
       grpc_mock_endpoint_create(discard_write, resource_quota);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_mock_endpoint_put_read(
       &exec_ctx, mock_endpoint,
       grpc_slice_from_copied_buffer((const char *)data, size));
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index e582c59..a8e310c 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -251,7 +251,11 @@
   grpc_call_destroy(c);
   grpc_call_destroy(s);
 
-  if (args != NULL) grpc_channel_args_destroy(args);
+  if (args != NULL) {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   cq_verifier_destroy(cqv);
   end_test(&f);
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index 81fc709..d7efe77 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -140,8 +140,12 @@
       NULL, requested_client_compression_algorithm);
   server_args =
       grpc_channel_args_set_compression_algorithm(NULL, GRPC_COMPRESS_NONE);
-  server_args = grpc_channel_args_compression_algorithm_set_state(
-      &server_args, algorithm_to_disable, false);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    server_args = grpc_channel_args_compression_algorithm_set_state(
+        &exec_ctx, &server_args, algorithm_to_disable, false);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   f = begin_test(config, test_name, client_args, server_args);
   cqv = cq_verifier_create(f.cq);
@@ -262,8 +266,12 @@
   grpc_byte_buffer_destroy(request_payload);
   grpc_byte_buffer_destroy(request_payload_recv);
 
-  grpc_channel_args_destroy(client_args);
-  grpc_channel_args_destroy(server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, client_args);
+    grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   end_test(&f);
   config.tear_down_data(&f);
@@ -512,8 +520,12 @@
 
   cq_verifier_destroy(cqv);
 
-  grpc_channel_args_destroy(client_args);
-  grpc_channel_args_destroy(server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, client_args);
+    grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   end_test(&f);
   config.tear_down_data(&f);
diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c
index 41ae575..01b6c32 100644
--- a/test/core/end2end/tests/filter_call_init_fails.c
+++ b/test/core/end2end/tests/filter_call_init_fails.c
@@ -241,7 +241,8 @@
  * Registration
  */
 
-static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
+                             grpc_channel_stack_builder *builder, void *arg) {
   if (g_enable_filter) {
     // Want to add the filter as close to the end as possible, to make
     // sure that all of the filters work well together.  However, we
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index bf9fd90..def21be 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -213,8 +213,8 @@
     grpc_slice message =
         grpc_slice_from_copied_string("Failure that's not preventable.");
     grpc_transport_stream_op *op = grpc_make_transport_stream_op(NULL);
-    grpc_transport_stream_op_add_close(op, GRPC_STATUS_PERMISSION_DENIED,
-                                       &message);
+    grpc_transport_stream_op_add_close(exec_ctx, op,
+                                       GRPC_STATUS_PERMISSION_DENIED, &message);
     grpc_call_next_op(exec_ctx, elem, op);
   }
   grpc_exec_ctx_sched(
@@ -268,7 +268,8 @@
  * Registration
  */
 
-static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
+                             grpc_channel_stack_builder *builder, void *arg) {
   if (g_enable_filter) {
     return grpc_channel_stack_builder_prepend_filter(builder, &test_filter,
                                                      NULL, NULL);
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index ea63d45..e698e38 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -320,7 +320,8 @@
  * Registration
  */
 
-static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
+                             grpc_channel_stack_builder *builder, void *arg) {
   grpc_channel_filter *filter = arg;
   if (g_enable_filter) {
     // Want to add the filter as close to the end as possible, to make
diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c
index 5b75f26..ae5c270 100644
--- a/test/core/end2end/tests/load_reporting_hook.c
+++ b/test/core/end2end/tests/load_reporting_hook.c
@@ -311,7 +311,11 @@
                                 response_msg, &initial_lr_metadata,
                                 &trailing_lr_metadata);
   end_test(&f);
-  grpc_channel_args_destroy(lr_server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, lr_server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   config.tear_down_data(&f);
 }
 
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index c222d9d..4a6ef44 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -168,8 +168,12 @@
 
   f = begin_test(config, "test_max_request_message_length", client_args,
                  server_args);
-  if (client_args != NULL) grpc_channel_args_destroy(client_args);
-  if (server_args != NULL) grpc_channel_args_destroy(server_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    if (client_args != NULL) grpc_channel_args_destroy(&exec_ctx, client_args);
+    if (server_args != NULL) grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   cqv = cq_verifier_create(f.cq);
 
@@ -342,9 +346,12 @@
 
   f = begin_test(config, "test_max_response_message_length", client_args,
                  server_args);
-  if (client_args != NULL) grpc_channel_args_destroy(client_args);
-  if (server_args != NULL) grpc_channel_args_destroy(server_args);
-
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    if (client_args != NULL) grpc_channel_args_destroy(&exec_ctx, client_args);
+    if (server_args != NULL) grpc_channel_args_destroy(&exec_ctx, server_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   cqv = cq_verifier_create(f.cq);
 
   c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index 3e312c1..57b779c 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -93,7 +93,7 @@
   grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                    n_seconds_time(15),
                    grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
@@ -133,7 +133,7 @@
   grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                     "hello", 5, n_seconds_time(15),
                     grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index d060351..765ae10 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -94,7 +94,7 @@
   grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                    n_seconds_time(15),
                    grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
@@ -135,7 +135,7 @@
   grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
                     "hello", 5, n_seconds_time(15),
                     grpc_closure_create(on_finish, &response), &response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
diff --git a/test/core/internal_api_canaries/iomgr.c b/test/core/internal_api_canaries/iomgr.c
index de03c47..82eeb0e 100644
--- a/test/core/internal_api_canaries/iomgr.c
+++ b/test/core/internal_api_canaries/iomgr.c
@@ -48,7 +48,7 @@
 static void test_code(void) {
   /* iomgr.h */
   grpc_iomgr_init();
-  grpc_iomgr_shutdown();
+  grpc_iomgr_shutdown(NULL);
 
   /* closure.h */
   grpc_closure closure;
@@ -100,7 +100,7 @@
   /* executor.h */
   grpc_executor_init();
   grpc_executor_push(&closure, GRPC_ERROR_CREATE("Phi"));
-  grpc_executor_shutdown();
+  grpc_executor_shutdown(NULL);
 
   /* pollset.h */
   grpc_pollset_size();
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 8186ea7..14991c9 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -41,6 +41,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
 
 /*
@@ -249,8 +251,8 @@
   grpc_exec_ctx_flush(&exec_ctx);
 
   end_test(config);
-  grpc_slice_buffer_destroy(&state.outgoing);
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.outgoing);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, state.read_ep);
   grpc_endpoint_destroy(&exec_ctx, state.write_ep);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -304,7 +306,7 @@
   grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
   wait_for_fail_count(&exec_ctx, &fail_count, 3);
 
-  grpc_slice_buffer_destroy(&slice_buffer);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &slice_buffer);
 
   grpc_endpoint_destroy(&exec_ctx, f.client_ep);
   grpc_endpoint_destroy(&exec_ctx, f.server_ep);
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index 564b05d..8553bc3 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -236,7 +236,11 @@
             "strategy. and the current strategy is: '%s'",
             poll_strategy);
   }
-  grpc_iomgr_shutdown();
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_iomgr_shutdown(&exec_ctx);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   return 0;
 }
 #else /* defined(GRPC_LINUX_EPOLL) */
diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c
index 652b37e..3dffa02 100644
--- a/test/core/iomgr/fd_conservation_posix_test.c
+++ b/test/core/iomgr/fd_conservation_posix_test.c
@@ -65,6 +65,10 @@
 
   grpc_resource_quota_unref(resource_quota);
 
-  grpc_iomgr_shutdown();
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_iomgr_shutdown(&exec_ctx);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   return 0;
 }
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 6166699..951a247 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -548,9 +548,10 @@
   test_grpc_fd_change();
   grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
-  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_exec_ctx_flush(&exec_ctx);
   gpr_free(g_pollset);
-  grpc_iomgr_shutdown();
+  grpc_iomgr_shutdown(&exec_ctx);
+  grpc_exec_ctx_finish(&exec_ctx);
   return 0;
 }
 
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 2dd0d88..36ee0db 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -172,7 +172,11 @@
   test_ipv6_without_port();
   test_invalid_ip_addresses();
   test_unparseable_hostports();
-  grpc_iomgr_shutdown();
-  grpc_executor_shutdown();
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_executor_shutdown(&exec_ctx);
+    grpc_iomgr_shutdown(&exec_ctx);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   return 0;
 }
diff --git a/test/core/iomgr/resource_quota_test.c b/test/core/iomgr/resource_quota_test.c
index a82d44f..43fb838 100644
--- a/test/core/iomgr/resource_quota_test.c
+++ b/test/core/iomgr/resource_quota_test.c
@@ -36,6 +36,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
 
 static void inc_int_cb(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
@@ -631,7 +632,11 @@
     GPR_ASSERT(num_allocs == start_allocs + 1);
   }
 
-  grpc_slice_buffer_destroy(&buffer);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_slice_buffer_destroy_internal(&exec_ctx, &buffer);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   destroy_user(usr);
   grpc_resource_quota_unref(q);
 }
@@ -667,7 +672,11 @@
   }
 
   grpc_resource_quota_unref(q);
-  grpc_slice_buffer_destroy(&buffer);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_slice_buffer_destroy_internal(&exec_ctx, &buffer);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 5eafa57..065064f 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -50,6 +50,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/iomgr/endpoint_tests.h"
 #include "test/core/util/test_config.h"
 
@@ -184,7 +186,7 @@
   grpc_resource_quota *resource_quota = grpc_resource_quota_create("read_test");
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
                        slice_size, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -212,7 +214,7 @@
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -235,7 +237,7 @@
       grpc_resource_quota_create("large_read_test");
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), resource_quota,
                        slice_size, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket(sv[0]);
@@ -263,7 +265,7 @@
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -374,7 +376,7 @@
       grpc_resource_quota_create("write_test");
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"), resource_quota,
                        GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   state.ep = ep;
@@ -404,7 +406,7 @@
   }
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&outgoing);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &outgoing);
   grpc_endpoint_destroy(&exec_ctx, ep);
   gpr_free(slices);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -442,7 +444,7 @@
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
                        slice_size, "test");
   GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -472,7 +474,7 @@
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
   gpr_mu_unlock(g_mu);
 
-  grpc_slice_buffer_destroy(&state.incoming);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
   grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
   grpc_exec_ctx_flush(&exec_ctx);
   gpr_mu_lock(g_mu);
@@ -534,7 +536,7 @@
                                 resource_quota, slice_size, "test");
   f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server"),
                                 resource_quota, slice_size, "test");
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
   grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
 
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 9bea229..6bd6d60 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -238,7 +238,7 @@
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(g_pollset);
-  grpc_iomgr_shutdown();
+  grpc_shutdown();
   return 0;
 }
 
diff --git a/test/core/security/b64_test.c b/test/core/security/b64_test.c
index af883f5..28af480 100644
--- a/test/core/security/b64_test.c
+++ b/test/core/security/b64_test.c
@@ -38,6 +38,8 @@
 #include <grpc/slice.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
 
 static int buffers_are_equal(const unsigned char *buf1,
@@ -57,12 +59,14 @@
   const char *hello = "hello";
   char *hello_b64 =
       grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
-  grpc_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_slice hello_slice = grpc_base64_decode(&exec_ctx, hello_b64, url_safe);
   GPR_ASSERT(GRPC_SLICE_LENGTH(hello_slice) == strlen(hello));
   GPR_ASSERT(strncmp((const char *)GRPC_SLICE_START_PTR(hello_slice), hello,
                      GRPC_SLICE_LENGTH(hello_slice)) == 0);
 
-  grpc_slice_unref(hello_slice);
+  grpc_slice_unref_internal(&exec_ctx, hello_slice);
+  grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(hello_b64);
 }
 
@@ -75,13 +79,15 @@
 
   /* Try all the different paddings. */
   for (i = 0; i < 3; i++) {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     b64 = grpc_base64_encode(orig, sizeof(orig) - i, url_safe, multiline);
-    orig_decoded = grpc_base64_decode(b64, url_safe);
+    orig_decoded = grpc_base64_decode(&exec_ctx, b64, url_safe);
     GPR_ASSERT(GRPC_SLICE_LENGTH(orig_decoded) == (sizeof(orig) - i));
     GPR_ASSERT(buffers_are_equal(orig, GRPC_SLICE_START_PTR(orig_decoded),
                                  sizeof(orig) - i));
-    grpc_slice_unref(orig_decoded);
+    grpc_slice_unref_internal(&exec_ctx, orig_decoded);
     gpr_free(b64);
+    grpc_exec_ctx_finish(&exec_ctx);
   }
 }
 
@@ -117,7 +123,7 @@
   test_full_range_encode_decode_b64(1, 1);
 }
 
-static void test_url_safe_unsafe_mismtach_failure(void) {
+static void test_url_safe_unsafe_mismatch_failure(void) {
   unsigned char orig[256];
   size_t i;
   char *b64;
@@ -125,17 +131,19 @@
   int url_safe = 1;
   for (i = 0; i < sizeof(orig); i++) orig[i] = (uint8_t)i;
 
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0);
-  orig_decoded = grpc_base64_decode(b64, !url_safe);
+  orig_decoded = grpc_base64_decode(&exec_ctx, b64, !url_safe);
   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
   gpr_free(b64);
-  grpc_slice_unref(orig_decoded);
+  grpc_slice_unref_internal(&exec_ctx, orig_decoded);
 
   b64 = grpc_base64_encode(orig, sizeof(orig), !url_safe, 0);
-  orig_decoded = grpc_base64_decode(b64, url_safe);
+  orig_decoded = grpc_base64_decode(&exec_ctx, b64, url_safe);
   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
   gpr_free(b64);
-  grpc_slice_unref(orig_decoded);
+  grpc_slice_unref_internal(&exec_ctx, orig_decoded);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_rfc4648_test_vectors(void) {
@@ -173,38 +181,40 @@
 static void test_unpadded_decode(void) {
   grpc_slice decoded;
 
-  decoded = grpc_base64_decode("Zm9vYmFy", 0);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9vYmFy", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foobar") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm9vYmE", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9vYmE", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "fooba") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm9vYg", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9vYg", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foob") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm9v", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm9v", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foo") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zm8", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zm8", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "fo") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("Zg", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "Zg", 0);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
   GPR_ASSERT(grpc_slice_str_cmp(decoded, "f") == 0);
   grpc_slice_unref(decoded);
 
-  decoded = grpc_base64_decode("", 0);
+  decoded = grpc_base64_decode(&exec_ctx, "", 0);
   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(decoded));
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
@@ -217,7 +227,7 @@
   test_full_range_encode_decode_b64_multiline();
   test_full_range_encode_decode_b64_urlsafe_no_multiline();
   test_full_range_encode_decode_b64_urlsafe_multiline();
-  test_url_safe_unsafe_mismtach_failure();
+  test_url_safe_unsafe_mismatch_failure();
   test_rfc4648_test_vectors();
   test_unpadded_decode();
   return 0;
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index d4c7550..8fd4737 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -166,24 +166,29 @@
 /* -- Tests. -- */
 
 static void test_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   GPR_ASSERT(store->num_entries == 0);
   GPR_ASSERT(store->allocated == 0);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_ref_unref_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   grpc_credentials_md_store_ref(store);
   grpc_credentials_md_store_ref(store);
   GPR_ASSERT(store->num_entries == 0);
   GPR_ASSERT(store->allocated == 0);
-  grpc_credentials_md_store_unref(store);
-  grpc_credentials_md_store_unref(store);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_add_to_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   const char *key_str = "hello";
   const char *value_str = "there blah blah blah blah blah blah blah";
@@ -195,10 +200,12 @@
   GPR_ASSERT(grpc_slice_cmp(value, store->entries[0].value) == 0);
   grpc_slice_unref(key);
   grpc_slice_unref(value);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_add_cstrings_to_empty_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   const char *key_str = "hello";
   const char *value_str = "there blah blah blah blah blah blah blah";
@@ -206,18 +213,22 @@
   GPR_ASSERT(store->num_entries == 1);
   GPR_ASSERT(grpc_slice_str_cmp(store->entries[0].key, key_str) == 0);
   GPR_ASSERT(grpc_slice_str_cmp(store->entries[0].value, value_str) == 0);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_empty_preallocated_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
   GPR_ASSERT(store->num_entries == 0);
   GPR_ASSERT(store->allocated == 4);
   GPR_ASSERT(store->entries != NULL);
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_add_abunch_to_md_store(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
   size_t num_entries = 1000;
   const char *key_str = "hello";
@@ -230,16 +241,19 @@
     GPR_ASSERT(grpc_slice_str_cmp(store->entries[i].key, key_str) == 0);
     GPR_ASSERT(grpc_slice_str_cmp(store->entries[i].value, value_str) == 0);
   }
-  grpc_credentials_md_store_unref(store);
+  grpc_credentials_md_store_unref(&exec_ctx, store);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
       http_response(200, valid_oauth2_json_response);
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK);
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
+             GRPC_CREDENTIALS_OK);
   GPR_ASSERT(token_lifetime.tv_sec == 3599);
   GPR_ASSERT(token_lifetime.tv_nsec == 0);
   GPR_ASSERT(token_md->num_entries == 1);
@@ -248,32 +262,38 @@
   GPR_ASSERT(grpc_slice_str_cmp(token_md->entries[0].value,
                                 "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
              0);
-  grpc_credentials_md_store_unref(token_md);
+  grpc_credentials_md_store_unref(&exec_ctx, token_md);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
       http_response(401, valid_oauth2_json_response);
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response = http_response(200, "");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
@@ -282,12 +302,14 @@
                     " \"expires_in\":3599, "
                     " \"token_type\":\"Bearer\"");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response = http_response(200,
@@ -295,12 +317,14 @@
                                                  " \"expires_in\":3599, "
                                                  " \"token_type\":\"Bearer\"}");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
@@ -309,13 +333,15 @@
                     " \"expires_in\":3599, "
                     "}");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
     void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_credentials_md_store *token_md = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
@@ -323,9 +349,10 @@
                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
                     " \"token_type\":\"Bearer\"}");
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
-                 &response, &token_md, &token_lifetime) ==
+                 &exec_ctx, &response, &token_md, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_http_response_destroy(&response);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void check_metadata(expected_md *expected, grpc_credentials_md *md_elems,
@@ -361,7 +388,7 @@
   GPR_ASSERT(error_details == NULL);
   GPR_ASSERT(num_md == 2);
   check_metadata(emd, md_elems, num_md);
-  grpc_call_credentials_unref(c);
+  grpc_call_credentials_unref(exec_ctx, c);
 }
 
 static void test_google_iam_creds(void) {
@@ -385,7 +412,7 @@
   GPR_ASSERT(error_details == NULL);
   GPR_ASSERT(num_md == 1);
   check_metadata(emd, md_elems, num_md);
-  grpc_call_credentials_unref(c);
+  grpc_call_credentials_unref(exec_ctx, c);
 }
 
 static void test_access_token_creds(void) {
@@ -401,9 +428,10 @@
 }
 
 static grpc_security_status check_channel_oauth2_create_security_connector(
-    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   GPR_ASSERT(strcmp(c->type, "mock") == 0);
   GPR_ASSERT(call_creds != NULL);
   GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
@@ -411,6 +439,7 @@
 }
 
 static void test_channel_oauth2_composite_creds(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *new_args;
   grpc_channel_credentials_vtable vtable = {
       NULL, check_channel_oauth2_create_security_connector, NULL};
@@ -424,9 +453,10 @@
   grpc_channel_credentials_release(channel_creds);
   grpc_call_credentials_release(oauth2_creds);
   GPR_ASSERT(grpc_channel_credentials_create_security_connector(
-                 channel_oauth2_creds, NULL, NULL, NULL, &new_args) ==
-             GRPC_SECURITY_OK);
+                 &exec_ctx, channel_oauth2_creds, NULL, NULL, NULL,
+                 &new_args) == GRPC_SECURITY_OK);
   grpc_channel_credentials_release(channel_oauth2_creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void check_oauth2_google_iam_composite_metadata(
@@ -443,7 +473,7 @@
   GPR_ASSERT(error_details == NULL);
   GPR_ASSERT(num_md == 3);
   check_metadata(emd, md_elems, num_md);
-  grpc_call_credentials_unref(c);
+  grpc_call_credentials_unref(exec_ctx, c);
 }
 
 static void test_oauth2_google_iam_composite_creds(void) {
@@ -459,8 +489,8 @@
   grpc_call_credentials *composite_creds =
       grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds,
                                              NULL);
-  grpc_call_credentials_unref(oauth2_creds);
-  grpc_call_credentials_unref(google_iam_creds);
+  grpc_call_credentials_unref(&exec_ctx, oauth2_creds);
+  grpc_call_credentials_unref(&exec_ctx, google_iam_creds);
   GPR_ASSERT(
       strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
   creds_array =
@@ -478,9 +508,10 @@
 
 static grpc_security_status
 check_channel_oauth2_google_iam_create_security_connector(
-    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+    grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+    grpc_call_credentials *call_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   const grpc_call_credentials_array *creds_array;
   GPR_ASSERT(strcmp(c->type, "mock") == 0);
   GPR_ASSERT(call_creds != NULL);
@@ -495,6 +526,7 @@
 }
 
 static void test_channel_oauth2_google_iam_composite_creds(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *new_args;
   grpc_channel_credentials_vtable vtable = {
       NULL, check_channel_oauth2_google_iam_create_security_connector, NULL};
@@ -517,10 +549,11 @@
   grpc_call_credentials_release(google_iam_creds);
 
   GPR_ASSERT(grpc_channel_credentials_create_security_connector(
-                 channel_oauth2_iam_creds, NULL, NULL, NULL, &new_args) ==
-             GRPC_SECURITY_OK);
+                 &exec_ctx, channel_oauth2_iam_creds, NULL, NULL, NULL,
+                 &new_args) == GRPC_SECURITY_OK);
 
   grpc_channel_credentials_release(channel_oauth2_iam_creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void on_oauth2_creds_get_metadata_success(
@@ -619,7 +652,7 @@
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_call_credentials_unref(compute_engine_creds);
+  grpc_call_credentials_unref(&exec_ctx, compute_engine_creds);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -634,7 +667,7 @@
   grpc_call_credentials_get_request_metadata(
       &exec_ctx, compute_engine_creds, NULL, auth_md_ctx,
       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
-  grpc_call_credentials_unref(compute_engine_creds);
+  grpc_call_credentials_unref(&exec_ctx, compute_engine_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -706,7 +739,7 @@
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
 
-  grpc_call_credentials_unref(refresh_token_creds);
+  grpc_call_credentials_unref(&exec_ctx, refresh_token_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -723,7 +756,7 @@
   grpc_call_credentials_get_request_metadata(
       &exec_ctx, refresh_token_creds, NULL, auth_md_ctx,
       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
-  grpc_call_credentials_unref(refresh_token_creds);
+  grpc_call_credentials_unref(&exec_ctx, refresh_token_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -832,7 +865,7 @@
   grpc_exec_ctx_flush(&exec_ctx);
 
   gpr_free(json_key_string);
-  grpc_call_credentials_unref(jwt_creds);
+  grpc_call_credentials_unref(&exec_ctx, jwt_creds);
   grpc_jwt_encode_and_sign_set_override(NULL);
 }
 
@@ -851,7 +884,7 @@
       on_jwt_creds_get_metadata_failure, (void *)test_user_data);
 
   gpr_free(json_key_string);
-  grpc_call_credentials_unref(jwt_creds);
+  grpc_call_credentials_unref(&exec_ctx, jwt_creds);
   grpc_jwt_encode_and_sign_set_override(NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -870,6 +903,7 @@
 }
 
 static void test_google_default_creds_auth_key(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_service_account_jwt_access_credentials *jwt;
   grpc_composite_channel_credentials *creds;
   char *json_key = test_json_key_str();
@@ -885,11 +919,13 @@
       strcmp(jwt->key.client_id,
              "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
       0);
-  grpc_channel_credentials_unref(&creds->base);
+  grpc_channel_credentials_unref(&exec_ctx, &creds->base);
   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_google_default_creds_refresh_token(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_google_refresh_token_credentials *refresh;
   grpc_composite_channel_credentials *creds;
   grpc_flush_cached_google_default_credentials();
@@ -901,8 +937,9 @@
   refresh = (grpc_google_refresh_token_credentials *)creds->call_creds;
   GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
                     "32555999999.apps.googleusercontent.com") == 0);
-  grpc_channel_credentials_unref(&creds->base);
+  grpc_channel_credentials_unref(&exec_ctx, &creds->base);
   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static int default_creds_gce_detection_httpcli_get_success_override(
@@ -1142,6 +1179,8 @@
 }
 
 static void test_channel_creds_duplicate_without_call_creds(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   grpc_channel_credentials *channel_creds =
       grpc_fake_transport_security_credentials_create();
 
@@ -1149,21 +1188,23 @@
       grpc_channel_credentials_duplicate_without_call_credentials(
           channel_creds);
   GPR_ASSERT(dup == channel_creds);
-  grpc_channel_credentials_unref(dup);
+  grpc_channel_credentials_unref(&exec_ctx, dup);
 
   grpc_call_credentials *call_creds =
       grpc_access_token_credentials_create("blah", NULL);
   grpc_channel_credentials *composite_creds =
       grpc_composite_channel_credentials_create(channel_creds, call_creds,
                                                 NULL);
-  grpc_call_credentials_unref(call_creds);
+  grpc_call_credentials_unref(&exec_ctx, call_creds);
   dup = grpc_channel_credentials_duplicate_without_call_credentials(
       composite_creds);
   GPR_ASSERT(dup == channel_creds);
-  grpc_channel_credentials_unref(dup);
+  grpc_channel_credentials_unref(&exec_ctx, dup);
 
-  grpc_channel_credentials_unref(channel_creds);
-  grpc_channel_credentials_unref(composite_creds);
+  grpc_channel_credentials_unref(&exec_ctx, channel_creds);
+  grpc_channel_credentials_unref(&exec_ctx, composite_creds);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index 2016558..5cebb09 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -44,6 +44,7 @@
 #include "src/core/lib/json/json.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
 #include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
 
 /* This JSON key was generated with the GCE console and revoked immediately.
@@ -220,6 +221,7 @@
 
 static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
                                            char **scratchpad) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   char *b64;
   char *decoded;
   grpc_json *json;
@@ -227,7 +229,7 @@
   b64 = gpr_malloc(len + 1);
   strncpy(b64, str, len);
   b64[len] = '\0';
-  slice = grpc_base64_decode(b64, 1);
+  slice = grpc_base64_decode(&exec_ctx, b64, 1);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(slice));
   decoded = gpr_malloc(GRPC_SLICE_LENGTH(slice) + 1);
   strncpy(decoded, (const char *)GRPC_SLICE_START_PTR(slice),
@@ -237,6 +239,7 @@
   gpr_free(b64);
   *scratchpad = decoded;
   grpc_slice_unref(slice);
+  grpc_exec_ctx_finish(&exec_ctx);
   return json;
 }
 
@@ -338,10 +341,12 @@
 static void check_jwt_signature(const char *b64_signature, RSA *rsa_key,
                                 const char *signed_data,
                                 size_t signed_data_size) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
   EVP_PKEY *key = EVP_PKEY_new();
 
-  grpc_slice sig = grpc_base64_decode(b64_signature, 1);
+  grpc_slice sig = grpc_base64_decode(&exec_ctx, b64_signature, 1);
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(sig));
   GPR_ASSERT(GRPC_SLICE_LENGTH(sig) == 128);
 
@@ -355,9 +360,11 @@
   GPR_ASSERT(EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(sig),
                                    GRPC_SLICE_LENGTH(sig)) == 1);
 
-  grpc_slice_unref(sig);
+  grpc_slice_unref_internal(&exec_ctx, sig);
   if (key != NULL) EVP_PKEY_free(key);
   if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static char *service_account_creds_jwt_encode_and_sign(
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index f8afba8..71da935 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -185,7 +185,8 @@
   grpc_json *json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
   GPR_ASSERT(json != NULL);
-  claims = grpc_jwt_claims_from_json(json, s);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
@@ -194,7 +195,8 @@
   GPR_ASSERT(strcmp(grpc_jwt_claims_id(claims), "jwtuniqueid") == 0);
   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
              GRPC_JWT_VERIFIER_OK);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_expired_claims_failure(void) {
@@ -206,7 +208,8 @@
   gpr_timespec exp_exp = {120, 0, GPR_CLOCK_REALTIME};
   gpr_timespec exp_nbf = {60, 0, GPR_CLOCK_REALTIME};
   GPR_ASSERT(json != NULL);
-  claims = grpc_jwt_claims_from_json(json, s);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
@@ -219,14 +222,17 @@
 
   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
              GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_invalid_claims_failure(void) {
   grpc_slice s = grpc_slice_from_copied_string(invalid_claims);
   grpc_json *json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
-  GPR_ASSERT(grpc_jwt_claims_from_json(json, s) == NULL);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GPR_ASSERT(grpc_jwt_claims_from_json(&exec_ctx, json, s) == NULL);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_bad_audience_claims_failure(void) {
@@ -235,11 +241,13 @@
   grpc_json *json = grpc_json_parse_string_with_len(
       (char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
   GPR_ASSERT(json != NULL);
-  claims = grpc_jwt_claims_from_json(json, s);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(grpc_jwt_claims_check(claims, "https://bar.com") ==
              GRPC_JWT_VERIFIER_BAD_AUDIENCE);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(&exec_ctx, claims);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static char *json_key_str(const char *last_part) {
@@ -298,14 +306,14 @@
   return 1;
 }
 
-static void on_verification_success(void *user_data,
+static void on_verification_success(grpc_exec_ctx *exec_ctx, void *user_data,
                                     grpc_jwt_verifier_status status,
                                     grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_OK);
   GPR_ASSERT(claims != NULL);
   GPR_ASSERT(user_data == (void *)expected_user_data);
   GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), expected_audience) == 0);
-  grpc_jwt_claims_destroy(claims);
+  grpc_jwt_claims_destroy(exec_ctx, claims);
 }
 
 static void test_jwt_verifier_google_email_issuer_success(void) {
@@ -413,7 +421,8 @@
   grpc_httpcli_set_override(NULL, NULL);
 }
 
-static void on_verification_key_retrieval_error(void *user_data,
+static void on_verification_key_retrieval_error(grpc_exec_ctx *exec_ctx,
+                                                void *user_data,
                                                 grpc_jwt_verifier_status status,
                                                 grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR);
@@ -483,7 +492,11 @@
   uint8_t *sig_bytes;
   char *last_dot = strrchr(jwt, '.');
   GPR_ASSERT(last_dot != NULL);
-  sig = grpc_base64_decode(last_dot + 1, 1);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    sig = grpc_base64_decode(&exec_ctx, last_dot + 1, 1);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(sig));
   sig_bytes = GRPC_SLICE_START_PTR(sig);
   (*sig_bytes)++; /* Corrupt first byte. */
@@ -494,7 +507,8 @@
   grpc_slice_unref(sig);
 }
 
-static void on_verification_bad_signature(void *user_data,
+static void on_verification_bad_signature(grpc_exec_ctx *exec_ctx,
+                                          void *user_data,
                                           grpc_jwt_verifier_status status,
                                           grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_SIGNATURE);
@@ -535,7 +549,7 @@
   return 1;
 }
 
-static void on_verification_bad_format(void *user_data,
+static void on_verification_bad_format(grpc_exec_ctx *exec_ctx, void *user_data,
                                        grpc_jwt_verifier_status status,
                                        grpc_jwt_claims *claims) {
   GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_FORMAT);
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index b5d9500..3a0c2bb 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -42,6 +42,7 @@
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/tsi/fake_transport_security.h"
 #include "test/core/util/test_config.h"
 
@@ -59,7 +60,7 @@
   grpc_resource_quota *resource_quota =
       grpc_resource_quota_create("secure_endpoint_test");
   tcp = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, slice_size);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset);
   grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset);
 
@@ -170,8 +171,8 @@
   grpc_endpoint_destroy(&exec_ctx, f.client_ep);
   grpc_endpoint_destroy(&exec_ctx, f.server_ep);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_slice_unref(s);
-  grpc_slice_buffer_destroy(&incoming);
+  grpc_slice_unref_internal(&exec_ctx, s);
+  grpc_slice_buffer_destroy_internal(&exec_ctx, &incoming);
 
   clean_up();
 }
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
index 8673225..55e8f5e 100644
--- a/test/core/security/ssl_server_fuzzer.c
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -79,7 +79,7 @@
       grpc_resource_quota_create("ssl_server_fuzzer");
   grpc_endpoint *mock_endpoint =
       grpc_mock_endpoint_create(discard_write, resource_quota);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
 
   grpc_mock_endpoint_put_read(
       &exec_ctx, mock_endpoint,
@@ -103,7 +103,7 @@
   // Create security connector
   grpc_server_security_connector *sc = NULL;
   grpc_security_status status =
-      grpc_server_credentials_create_security_connector(creds, &sc);
+      grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc);
   GPR_ASSERT(status == GRPC_SECURITY_OK);
   gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
                                        gpr_time_from_seconds(1, GPR_TIMESPAN));
@@ -128,7 +128,7 @@
   GPR_ASSERT(state.done_callback_called);
 
   grpc_handshake_manager_destroy(&exec_ctx, handshake_mgr);
-  GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test");
+  GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "test");
   grpc_server_credentials_release(creds);
   grpc_slice_unref(cert_slice);
   grpc_slice_unref(key_slice);
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index 043d29e..32169bb 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -59,7 +59,7 @@
   exit(1);
 }
 
-static void on_jwt_verification_done(void *user_data,
+static void on_jwt_verification_done(grpc_exec_ctx *exec_ctx, void *user_data,
                                      grpc_jwt_verifier_status status,
                                      grpc_jwt_claims *claims) {
   synchronizer *sync = user_data;
@@ -72,7 +72,7 @@
         grpc_json_dump_to_string((grpc_json *)grpc_jwt_claims_json(claims), 2);
     printf("Claims: \n\n%s\n", claims_str);
     gpr_free(claims_str);
-    grpc_jwt_claims_destroy(claims);
+    grpc_jwt_claims_destroy(exec_ctx, claims);
   } else {
     GPR_ASSERT(claims == NULL);
     fprintf(stderr, "Verification failed with error %s\n",
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index d8d7a52..2f1f72f 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -40,9 +40,10 @@
 #include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
-#include "test/core/util/test_config.h"
 
 #include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "test/core/util/test_config.h"
 
 #include <string.h>
 
@@ -145,7 +146,12 @@
   input_slice = grpc_slice_malloc(input_size);
   memset(GRPC_SLICE_START_PTR(input_slice), 'a', input_size);
   grpc_slice_buffer_add(&sliceb_in, input_slice); /* takes ownership */
-  GPR_ASSERT(grpc_msg_compress(algorithm, &sliceb_in, &sliceb_out));
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    GPR_ASSERT(
+        grpc_msg_compress(&exec_ctx, algorithm, &sliceb_in, &sliceb_out));
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 
   buffer = grpc_raw_compressed_byte_buffer_create(sliceb_out.slices,
                                                   sliceb_out.count, algorithm);
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index df6b733..e0a2c94 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -42,6 +42,7 @@
 #include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/connectivity_state.h>
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
 #include <grpc/impl/codegen/gpr_slice.h>
 #include <grpc/impl/codegen/gpr_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c
index 444ebdc..ab4067d 100644
--- a/test/core/surface/secure_channel_create_test.c
+++ b/test/core/surface/secure_channel_create_test.c
@@ -51,7 +51,9 @@
   creds = grpc_fake_transport_security_credentials_create();
   chan = grpc_secure_channel_create(creds, "blah://blah", NULL, NULL);
   GPR_ASSERT(chan == NULL);
-  grpc_channel_credentials_unref(creds);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_channel_credentials_unref(&exec_ctx, creds);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 void test_security_connector_already_in_arg(void) {
diff --git a/test/core/surface/sequential_connectivity_test.c b/test/core/surface/sequential_connectivity_test.c
index fe87f11..3292718 100644
--- a/test/core/surface/sequential_connectivity_test.c
+++ b/test/core/surface/sequential_connectivity_test.c
@@ -39,6 +39,7 @@
 #include <grpc/support/thd.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
@@ -162,7 +163,11 @@
       grpc_channel_args_copy_and_add(NULL, &ssl_name_override, 1);
   grpc_channel *channel =
       grpc_secure_channel_create(ssl_creds, addr, new_client_args, NULL);
-  grpc_channel_args_destroy(new_client_args);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_channel_args_destroy(&exec_ctx, new_client_args);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
   grpc_channel_credentials_release(ssl_creds);
   return channel;
 }
diff --git a/test/core/transport/chttp2/bin_decoder_test.c b/test/core/transport/chttp2/bin_decoder_test.c
index 7ddc302..221112a 100644
--- a/test/core/transport/chttp2/bin_decoder_test.c
+++ b/test/core/transport/chttp2/bin_decoder_test.c
@@ -38,13 +38,14 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 
 static int all_ok = 1;
 
-static void expect_slice_eq(grpc_slice expected, grpc_slice slice, char *debug,
-                            int line) {
+static void expect_slice_eq(grpc_exec_ctx *exec_ctx, grpc_slice expected,
+                            grpc_slice slice, char *debug, int line) {
   if (0 != grpc_slice_cmp(slice, expected)) {
     char *hs = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
     char *he = grpc_dump_slice(expected, GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -54,92 +55,104 @@
     gpr_free(he);
     all_ok = 0;
   }
-  grpc_slice_unref(expected);
-  grpc_slice_unref(slice);
+  grpc_slice_unref_internal(exec_ctx, expected);
+  grpc_slice_unref_internal(exec_ctx, slice);
 }
 
-static grpc_slice base64_encode(const char *s) {
+static grpc_slice base64_encode(grpc_exec_ctx *exec_ctx, const char *s) {
   grpc_slice ss = grpc_slice_from_copied_string(s);
   grpc_slice out = grpc_chttp2_base64_encode(ss);
-  grpc_slice_unref(ss);
+  grpc_slice_unref_internal(exec_ctx, ss);
   return out;
 }
 
-static grpc_slice base64_decode(const char *s) {
+static grpc_slice base64_decode(grpc_exec_ctx *exec_ctx, const char *s) {
   grpc_slice ss = grpc_slice_from_copied_string(s);
-  grpc_slice out = grpc_chttp2_base64_decode(ss);
-  grpc_slice_unref(ss);
+  grpc_slice out = grpc_chttp2_base64_decode(exec_ctx, ss);
+  grpc_slice_unref_internal(exec_ctx, ss);
   return out;
 }
 
-static grpc_slice base64_decode_with_length(const char *s,
+static grpc_slice base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+                                            const char *s,
                                             size_t output_length) {
   grpc_slice ss = grpc_slice_from_copied_string(s);
-  grpc_slice out = grpc_chttp2_base64_decode_with_length(ss, output_length);
-  grpc_slice_unref(ss);
+  grpc_slice out =
+      grpc_chttp2_base64_decode_with_length(exec_ctx, ss, output_length);
+  grpc_slice_unref_internal(exec_ctx, ss);
   return out;
 }
 
-#define EXPECT_SLICE_EQ(expected, slice)                                    \
-  expect_slice_eq(                                                          \
-      grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), slice, \
-      #slice, __LINE__);
+#define EXPECT_SLICE_EQ(exec_ctx, expected, slice)                             \
+  expect_slice_eq(                                                             \
+      exec_ctx, grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), \
+      slice, #slice, __LINE__);
 
-#define ENCODE_AND_DECODE(s) \
-  EXPECT_SLICE_EQ(           \
-      s, grpc_chttp2_base64_decode_with_length(base64_encode(s), strlen(s)));
+#define ENCODE_AND_DECODE(exec_ctx, s)                   \
+  EXPECT_SLICE_EQ(exec_ctx, s,                           \
+                  grpc_chttp2_base64_decode_with_length( \
+                      exec_ctx, base64_encode(exec_ctx, s), strlen(s)));
 
 int main(int argc, char **argv) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
   /* ENCODE_AND_DECODE tests grpc_chttp2_base64_decode_with_length(), which
      takes encoded base64 strings without pad chars, but output length is
      required. */
   /* Base64 test vectors from RFC 4648 */
-  ENCODE_AND_DECODE("");
-  ENCODE_AND_DECODE("f");
-  ENCODE_AND_DECODE("foo");
-  ENCODE_AND_DECODE("fo");
-  ENCODE_AND_DECODE("foob");
-  ENCODE_AND_DECODE("fooba");
-  ENCODE_AND_DECODE("foobar");
+  ENCODE_AND_DECODE(&exec_ctx, "");
+  ENCODE_AND_DECODE(&exec_ctx, "f");
+  ENCODE_AND_DECODE(&exec_ctx, "foo");
+  ENCODE_AND_DECODE(&exec_ctx, "fo");
+  ENCODE_AND_DECODE(&exec_ctx, "foob");
+  ENCODE_AND_DECODE(&exec_ctx, "fooba");
+  ENCODE_AND_DECODE(&exec_ctx, "foobar");
 
-  ENCODE_AND_DECODE("\xc0\xc1\xc2\xc3\xc4\xc5");
+  ENCODE_AND_DECODE(&exec_ctx, "\xc0\xc1\xc2\xc3\xc4\xc5");
 
   /* Base64 test vectors from RFC 4648, with pad chars */
   /* BASE64("") = "" */
-  EXPECT_SLICE_EQ("", base64_decode(""));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, ""));
   /* BASE64("f") = "Zg==" */
-  EXPECT_SLICE_EQ("f", base64_decode("Zg=="));
+  EXPECT_SLICE_EQ(&exec_ctx, "f", base64_decode(&exec_ctx, "Zg=="));
   /* BASE64("fo") = "Zm8=" */
-  EXPECT_SLICE_EQ("fo", base64_decode("Zm8="));
+  EXPECT_SLICE_EQ(&exec_ctx, "fo", base64_decode(&exec_ctx, "Zm8="));
   /* BASE64("foo") = "Zm9v" */
-  EXPECT_SLICE_EQ("foo", base64_decode("Zm9v"));
+  EXPECT_SLICE_EQ(&exec_ctx, "foo", base64_decode(&exec_ctx, "Zm9v"));
   /* BASE64("foob") = "Zm9vYg==" */
-  EXPECT_SLICE_EQ("foob", base64_decode("Zm9vYg=="));
+  EXPECT_SLICE_EQ(&exec_ctx, "foob", base64_decode(&exec_ctx, "Zm9vYg=="));
   /* BASE64("fooba") = "Zm9vYmE=" */
-  EXPECT_SLICE_EQ("fooba", base64_decode("Zm9vYmE="));
+  EXPECT_SLICE_EQ(&exec_ctx, "fooba", base64_decode(&exec_ctx, "Zm9vYmE="));
   /* BASE64("foobar") = "Zm9vYmFy" */
-  EXPECT_SLICE_EQ("foobar", base64_decode("Zm9vYmFy"));
+  EXPECT_SLICE_EQ(&exec_ctx, "foobar", base64_decode(&exec_ctx, "Zm9vYmFy"));
 
-  EXPECT_SLICE_EQ("\xc0\xc1\xc2\xc3\xc4\xc5", base64_decode("wMHCw8TF"));
+  EXPECT_SLICE_EQ(&exec_ctx, "\xc0\xc1\xc2\xc3\xc4\xc5",
+                  base64_decode(&exec_ctx, "wMHCw8TF"));
 
   // Test illegal input length in grpc_chttp2_base64_decode
-  EXPECT_SLICE_EQ("", base64_decode("a"));
-  EXPECT_SLICE_EQ("", base64_decode("ab"));
-  EXPECT_SLICE_EQ("", base64_decode("abc"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "a"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "ab"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "abc"));
 
   // Test illegal charactors in grpc_chttp2_base64_decode
-  EXPECT_SLICE_EQ("", base64_decode("Zm:v"));
-  EXPECT_SLICE_EQ("", base64_decode("Zm=v"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "Zm:v"));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "Zm=v"));
 
   // Test output_length longer than max possible output length in
   // grpc_chttp2_base64_decode_with_length
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zg", 2));
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm8", 3));
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm9v", 4));
+  EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode_with_length(&exec_ctx, "Zg", 2));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm8", 3));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm9v", 4));
 
   // Test illegal charactors in grpc_chttp2_base64_decode_with_length
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm:v", 3));
-  EXPECT_SLICE_EQ("", base64_decode_with_length("Zm=v", 3));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm:v", 3));
+  EXPECT_SLICE_EQ(&exec_ctx, "",
+                  base64_decode_with_length(&exec_ctx, "Zm=v", 3));
+
+  grpc_exec_ctx_finish(&exec_ctx);
 
   return all_ok ? 0 : 1;
 }
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 91421e1..1fd2540 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -41,6 +41,7 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/metadata.h"
@@ -59,8 +60,9 @@
 
 /* verify that the output generated by encoding the stream matches the
    hexstring passed in */
-static void verify(size_t window_available, int eof, size_t expect_window_used,
-                   const char *expected, size_t nheaders, ...) {
+static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof,
+                   size_t expect_window_used, const char *expected,
+                   size_t nheaders, ...) {
   grpc_slice_buffer output;
   grpc_slice merged;
   grpc_slice expect = parse_hexstring(expected);
@@ -79,7 +81,7 @@
       e[i - 1].next = &e[i];
       e[i].prev = &e[i - 1];
     }
-    e[i].md = grpc_mdelem_from_strings(key, value);
+    e[i].md = grpc_mdelem_from_strings(exec_ctx, key, value);
   }
   e[0].prev = NULL;
   e[nheaders - 1].next = NULL;
@@ -98,11 +100,11 @@
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats,
-                            &output);
+  grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, eof, 16384,
+                            &stats, &output);
   merged = grpc_slice_merge(output.slices, output.count);
-  grpc_slice_buffer_destroy(&output);
-  grpc_metadata_batch_destroy(&b);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_metadata_batch_destroy(exec_ctx, &b);
 
   if (0 != grpc_slice_cmp(merged, expect)) {
     char *expect_str = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -115,31 +117,32 @@
     g_failure = 1;
   }
 
-  grpc_slice_unref(merged);
-  grpc_slice_unref(expect);
+  grpc_slice_unref_internal(exec_ctx, merged);
+  grpc_slice_unref_internal(exec_ctx, expect);
 }
 
-static void test_basic_headers(void) {
+static void test_basic_headers(grpc_exec_ctx *exec_ctx) {
   int i;
 
-  verify(0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
-  verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
-  verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
-  verify(0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a", "b",
+  verify(exec_ctx, 0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
+  verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
+  verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
+  verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a",
+         "b", "c");
+  verify(exec_ctx, 0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b",
          "c");
-  verify(0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b", "c");
-  verify(0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
+  verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
 
   /* flush out what's there to make a few values look very popular */
   for (i = 0; i < 350; i++) {
-    verify(0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b", "c", "a",
-           "d");
+    verify(exec_ctx, 0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b",
+           "c", "a", "d");
   }
 
-  verify(0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a", "k",
-         "v");
+  verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a",
+         "k", "v");
   /* this could be 000004 0104 deadbeef 0f 30 0176 also */
-  verify(0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
+  verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
 }
 
 static void encode_int_to_str(int i, char *p) {
@@ -150,7 +153,7 @@
   p[2] = 0;
 }
 
-static void test_decode_table_overflow(void) {
+static void test_decode_table_overflow(grpc_exec_ctx *exec_ctx) {
   int i;
   char key[3], value[3];
   char *expect;
@@ -173,22 +176,24 @@
     }
 
     if (i > 0) {
-      verify(0, 0, 0, expect, 2, "aa", "ba", key, value);
+      verify(exec_ctx, 0, 0, 0, expect, 2, "aa", "ba", key, value);
     } else {
-      verify(0, 0, 0, expect, 1, key, value);
+      verify(exec_ctx, 0, 0, 0, expect, 1, key, value);
     }
     gpr_free(expect);
   }
 
   /* if the above passes, then we must have just knocked this pair out of the
      decoder stack, and so we'll be forced to re-encode it */
-  verify(0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa", "ba");
+  verify(exec_ctx, 0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa",
+         "ba");
 }
 
-static void verify_table_size_change_match_elem_size(const char *key,
+static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
+                                                     const char *key,
                                                      const char *value) {
   grpc_slice_buffer output;
-  grpc_mdelem *elem = grpc_mdelem_from_strings(key, value);
+  grpc_mdelem *elem = grpc_mdelem_from_strings(exec_ctx, key, value);
   size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
   size_t initial_table_size = g_compressor.table_size;
   grpc_linked_mdelem *e = gpr_malloc(sizeof(*e));
@@ -203,25 +208,27 @@
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, 16384, &stats,
-                            &output);
-  grpc_slice_buffer_destroy(&output);
-  grpc_metadata_batch_destroy(&b);
+  grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, 0, 16384,
+                            &stats, &output);
+  grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+  grpc_metadata_batch_destroy(exec_ctx, &b);
 
   GPR_ASSERT(g_compressor.table_size == elem_size + initial_table_size);
   gpr_free(e);
 }
 
-static void test_encode_header_size(void) {
-  verify_table_size_change_match_elem_size("hello", "world");
-  verify_table_size_change_match_elem_size("hello-bin", "world");
+static void test_encode_header_size(grpc_exec_ctx *exec_ctx) {
+  verify_table_size_change_match_elem_size(exec_ctx, "hello", "world");
+  verify_table_size_change_match_elem_size(exec_ctx, "hello-bin", "world");
 }
 
-static void run_test(void (*test)(), const char *name) {
+static void run_test(void (*test)(grpc_exec_ctx *exec_ctx), const char *name) {
   gpr_log(GPR_INFO, "RUN TEST: %s", name);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hpack_compressor_init(&g_compressor);
-  test();
-  grpc_chttp2_hpack_compressor_destroy(&g_compressor);
+  test(&exec_ctx);
+  grpc_chttp2_hpack_compressor_destroy(&exec_ctx, &g_compressor);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
index 95acbf1..4e00f49 100644
--- a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
+++ b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
@@ -44,7 +44,7 @@
 bool leak_check = true;
 
 static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem *md) {
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(exec_ctx, md);
 }
 static void dont_log(gpr_log_func_args *args) {}
 
@@ -53,13 +53,13 @@
   if (squelch) gpr_set_log_function(dont_log);
   grpc_init();
   grpc_chttp2_hpack_parser parser;
-  grpc_chttp2_hpack_parser_init(&parser);
-  parser.on_header = onhdr;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+  parser.on_header = onhdr;
   GRPC_ERROR_UNREF(
       grpc_chttp2_hpack_parser_parse(&exec_ctx, &parser, data, data + size));
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_chttp2_hpack_parser_destroy(&parser);
   grpc_shutdown();
   return 0;
 }
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index e2813df..8f48849 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -54,7 +54,7 @@
   GPR_ASSERT(evalue);
   GPR_ASSERT(grpc_slice_str_cmp(md->key->slice, ekey) == 0);
   GPR_ASSERT(grpc_slice_str_cmp(md->value->slice, evalue) == 0);
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(exec_ctx, md);
 }
 
 static void test_vector(grpc_chttp2_hpack_parser *parser,
@@ -94,8 +94,9 @@
 
 static void test_vectors(grpc_slice_split_mode mode) {
   grpc_chttp2_hpack_parser parser;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
-  grpc_chttp2_hpack_parser_init(&parser);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
   /* D.2.1 */
   test_vector(&parser, mode,
               "400a 6375 7374 6f6d 2d6b 6579 0d63 7573"
@@ -111,9 +112,9 @@
               "password", "secret", NULL);
   /* D.2.4 */
   test_vector(&parser, mode, "82", ":method", "GET", NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
   /* D.3.1 */
   test_vector(&parser, mode,
               "8286 8441 0f77 7777 2e65 7861 6d70 6c65"
@@ -131,9 +132,9 @@
               ":method", "GET", ":scheme", "https", ":path", "/index.html",
               ":authority", "www.example.com", "custom-key", "custom-value",
               NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
   /* D.4.1 */
   test_vector(&parser, mode,
               "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4"
@@ -151,11 +152,11 @@
               ":method", "GET", ":scheme", "https", ":path", "/index.html",
               ":authority", "www.example.com", "custom-key", "custom-value",
               NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
-  grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
-  grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+  grpc_chttp2_hptbl_set_max_bytes(&exec_ctx, &parser.table, 256);
+  grpc_chttp2_hptbl_set_current_table_size(&exec_ctx, &parser.table, 256);
   /* D.5.1 */
   test_vector(&parser, mode,
               "4803 3330 3258 0770 7269 7661 7465 611d"
@@ -185,11 +186,11 @@
               "https://www.example.com", "content-encoding", "gzip",
               "set-cookie",
               "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
 
-  grpc_chttp2_hpack_parser_init(&parser);
-  grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
-  grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
+  grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+  grpc_chttp2_hptbl_set_max_bytes(&exec_ctx, &parser.table, 256);
+  grpc_chttp2_hptbl_set_current_table_size(&exec_ctx, &parser.table, 256);
   /* D.6.1 */
   test_vector(&parser, mode,
               "4882 6402 5885 aec3 771a 4b61 96d0 7abe"
@@ -216,7 +217,9 @@
               "https://www.example.com", "content-encoding", "gzip",
               "set-cookie",
               "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
-  grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index 1a7e244..ef2ad66 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -59,9 +59,10 @@
 }
 
 static void test_static_lookup(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hptbl tbl;
 
-  grpc_chttp2_hptbl_init(&tbl);
+  grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
 
   LOG_TEST("test_static_lookup");
   assert_index(&tbl, 1, ":authority", "");
@@ -126,7 +127,8 @@
   assert_index(&tbl, 60, "via", "");
   assert_index(&tbl, 61, "www-authenticate", "");
 
-  grpc_chttp2_hptbl_destroy(&tbl);
+  grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_many_additions(void) {
@@ -137,15 +139,16 @@
 
   LOG_TEST("test_many_additions");
 
-  grpc_chttp2_hptbl_init(&tbl);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
 
   for (i = 0; i < 100000; i++) {
     grpc_mdelem *elem;
     gpr_asprintf(&key, "K:%d", i);
     gpr_asprintf(&value, "VALUE:%d", i);
-    elem = grpc_mdelem_from_strings(key, value);
-    GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-    GRPC_MDELEM_UNREF(elem);
+    elem = grpc_mdelem_from_strings(&exec_ctx, key, value);
+    GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+    GRPC_MDELEM_UNREF(&exec_ctx, elem);
     assert_index(&tbl, 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
     gpr_free(key);
     gpr_free(value);
@@ -158,19 +161,23 @@
     }
   }
 
-  grpc_chttp2_hptbl_destroy(&tbl);
+  grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static grpc_chttp2_hptbl_find_result find_simple(grpc_chttp2_hptbl *tbl,
                                                  const char *key,
                                                  const char *value) {
-  grpc_mdelem *md = grpc_mdelem_from_strings(key, value);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_mdelem *md = grpc_mdelem_from_strings(&exec_ctx, key, value);
   grpc_chttp2_hptbl_find_result r = grpc_chttp2_hptbl_find(tbl, md);
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(&exec_ctx, md);
+  grpc_exec_ctx_finish(&exec_ctx);
   return r;
 }
 
 static void test_find(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_chttp2_hptbl tbl;
   uint32_t i;
   char buffer[32];
@@ -179,16 +186,16 @@
 
   LOG_TEST("test_find");
 
-  grpc_chttp2_hptbl_init(&tbl);
-  elem = grpc_mdelem_from_strings("abc", "xyz");
-  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-  GRPC_MDELEM_UNREF(elem);
-  elem = grpc_mdelem_from_strings("abc", "123");
-  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-  GRPC_MDELEM_UNREF(elem);
-  elem = grpc_mdelem_from_strings("x", "1");
-  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-  GRPC_MDELEM_UNREF(elem);
+  grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
+  elem = grpc_mdelem_from_strings(&exec_ctx, "abc", "xyz");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+  GRPC_MDELEM_UNREF(&exec_ctx, elem);
+  elem = grpc_mdelem_from_strings(&exec_ctx, "abc", "123");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+  GRPC_MDELEM_UNREF(&exec_ctx, elem);
+  elem = grpc_mdelem_from_strings(&exec_ctx, "x", "1");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+  GRPC_MDELEM_UNREF(&exec_ctx, elem);
 
   r = find_simple(&tbl, "abc", "123");
   GPR_ASSERT(r.index == 2 + GRPC_CHTTP2_LAST_STATIC_ENTRY);
@@ -237,9 +244,9 @@
   /* overflow the string buffer, check find still works */
   for (i = 0; i < 10000; i++) {
     int64_ttoa(i, buffer);
-    elem = grpc_mdelem_from_strings("test", buffer);
-    GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
-    GRPC_MDELEM_UNREF(elem);
+    elem = grpc_mdelem_from_strings(&exec_ctx, "test", buffer);
+    GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+    GRPC_MDELEM_UNREF(&exec_ctx, elem);
   }
 
   r = find_simple(&tbl, "abc", "123");
@@ -267,7 +274,8 @@
   GPR_ASSERT(r.index != 0);
   GPR_ASSERT(r.has_value == 0);
 
-  grpc_chttp2_hptbl_destroy(&tbl);
+  grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index 5c89d85..3625043 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -42,6 +42,7 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "test/core/util/test_config.h"
@@ -63,6 +64,7 @@
   LOG_TEST("test_create_string");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   s1 = grpc_mdstr_from_string("hello");
   s2 = grpc_mdstr_from_string("hello");
   s3 = grpc_mdstr_from_string("very much not hello");
@@ -70,9 +72,10 @@
   GPR_ASSERT(s3 != s1);
   GPR_ASSERT(grpc_slice_str_cmp(s1->slice, "hello") == 0);
   GPR_ASSERT(grpc_slice_str_cmp(s3->slice, "very much not hello") == 0);
-  GRPC_MDSTR_UNREF(s1);
-  GRPC_MDSTR_UNREF(s2);
-  GRPC_MDSTR_UNREF(s3);
+  GRPC_MDSTR_UNREF(&exec_ctx, s1);
+  GRPC_MDSTR_UNREF(&exec_ctx, s2);
+  GRPC_MDSTR_UNREF(&exec_ctx, s3);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -82,9 +85,10 @@
   LOG_TEST("test_create_metadata");
 
   grpc_init();
-  m1 = grpc_mdelem_from_strings("a", "b");
-  m2 = grpc_mdelem_from_strings("a", "b");
-  m3 = grpc_mdelem_from_strings("a", "c");
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  m1 = grpc_mdelem_from_strings(&exec_ctx, "a", "b");
+  m2 = grpc_mdelem_from_strings(&exec_ctx, "a", "b");
+  m3 = grpc_mdelem_from_strings(&exec_ctx, "a", "c");
   GPR_ASSERT(m1 == m2);
   GPR_ASSERT(m3 != m1);
   GPR_ASSERT(m3->key == m1->key);
@@ -92,9 +96,10 @@
   GPR_ASSERT(grpc_slice_str_cmp(m1->key->slice, "a") == 0);
   GPR_ASSERT(grpc_slice_str_cmp(m1->value->slice, "b") == 0);
   GPR_ASSERT(grpc_slice_str_cmp(m3->value->slice, "c") == 0);
-  GRPC_MDELEM_UNREF(m1);
-  GRPC_MDELEM_UNREF(m2);
-  GRPC_MDELEM_UNREF(m3);
+  GRPC_MDELEM_UNREF(&exec_ctx, m1);
+  GRPC_MDELEM_UNREF(&exec_ctx, m2);
+  GRPC_MDELEM_UNREF(&exec_ctx, m3);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -105,11 +110,14 @@
   LOG_TEST("test_create_many_ephemeral_metadata");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   /* add, and immediately delete a bunch of different elements */
   for (i = 0; i < MANY; i++) {
     gpr_ltoa(i, buffer);
-    GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", buffer));
+    GRPC_MDELEM_UNREF(&exec_ctx,
+                      grpc_mdelem_from_strings(&exec_ctx, "a", buffer));
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -122,22 +130,24 @@
   LOG_TEST("test_create_many_persistant_metadata");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   /* add phase */
   for (i = 0; i < MANY; i++) {
     gpr_ltoa(i, buffer);
-    created[i] = grpc_mdelem_from_strings("a", buffer);
+    created[i] = grpc_mdelem_from_strings(&exec_ctx, "a", buffer);
   }
   /* verify phase */
   for (i = 0; i < MANY; i++) {
     gpr_ltoa(i, buffer);
-    md = grpc_mdelem_from_strings("a", buffer);
+    md = grpc_mdelem_from_strings(&exec_ctx, "a", buffer);
     GPR_ASSERT(md == created[i]);
-    GRPC_MDELEM_UNREF(md);
+    GRPC_MDELEM_UNREF(&exec_ctx, md);
   }
   /* cleanup phase */
   for (i = 0; i < MANY; i++) {
-    GRPC_MDELEM_UNREF(created[i]);
+    GRPC_MDELEM_UNREF(&exec_ctx, created[i]);
   }
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 
   gpr_free(created);
@@ -147,9 +157,11 @@
   LOG_TEST("test_spin_creating_the_same_thing");
 
   grpc_init();
-  GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
-  GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
-  GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_from_strings(&exec_ctx, "a", "b"));
+  GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_from_strings(&exec_ctx, "a", "b"));
+  GRPC_MDELEM_UNREF(&exec_ctx, grpc_mdelem_from_strings(&exec_ctx, "a", "b"));
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -164,6 +176,7 @@
   LOG_TEST("test_things_stick_around");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   for (i = 0; i < nstrs; i++) {
     gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x", i);
@@ -174,7 +187,7 @@
 
   for (i = 0; i < nstrs; i++) {
     GRPC_MDSTR_REF(strs[i]);
-    GRPC_MDSTR_UNREF(strs[i]);
+    GRPC_MDSTR_UNREF(&exec_ctx, strs[i]);
   }
 
   for (i = 0; i < nstrs; i++) {
@@ -186,17 +199,18 @@
   }
 
   for (i = 0; i < nstrs; i++) {
-    GRPC_MDSTR_UNREF(strs[shuf[i]]);
+    GRPC_MDSTR_UNREF(&exec_ctx, strs[shuf[i]]);
     for (j = i + 1; j < nstrs; j++) {
       gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x",
                    shuf[j]);
       test = grpc_mdstr_from_string(buffer);
       GPR_ASSERT(test == strs[shuf[j]]);
-      GRPC_MDSTR_UNREF(test);
+      GRPC_MDSTR_UNREF(&exec_ctx, test);
       gpr_free(buffer);
     }
   }
 
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
   gpr_free(strs);
   gpr_free(shuf);
@@ -210,19 +224,21 @@
   LOG_TEST("test_slices_work");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   str = grpc_mdstr_from_string(
       "123456789012345678901234567890123456789012345678901234567890");
   slice = grpc_slice_ref(str->slice);
-  GRPC_MDSTR_UNREF(str);
-  grpc_slice_unref(slice);
+  GRPC_MDSTR_UNREF(&exec_ctx, str);
+  grpc_slice_unref_internal(&exec_ctx, slice);
 
   str = grpc_mdstr_from_string(
       "123456789012345678901234567890123456789012345678901234567890");
   slice = grpc_slice_ref(str->slice);
-  grpc_slice_unref(slice);
-  GRPC_MDSTR_UNREF(str);
+  grpc_slice_unref_internal(&exec_ctx, slice);
+  GRPC_MDSTR_UNREF(&exec_ctx, str);
 
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -234,13 +250,15 @@
   LOG_TEST("test_base64_and_huffman_works");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   str = grpc_mdstr_from_string("abcdefg");
   slice1 = grpc_mdstr_as_base64_encoded_and_huffman_compressed(str);
   slice2 = grpc_chttp2_base64_encode_and_huffman_compress(str->slice);
   GPR_ASSERT(0 == grpc_slice_cmp(slice1, slice2));
 
-  grpc_slice_unref(slice2);
-  GRPC_MDSTR_UNREF(str);
+  grpc_slice_unref_internal(&exec_ctx, slice2);
+  GRPC_MDSTR_UNREF(&exec_ctx, str);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
@@ -251,29 +269,33 @@
   LOG_TEST("test_user_data_works");
 
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   ud1 = gpr_malloc(sizeof(int));
   *ud1 = 1;
   ud2 = gpr_malloc(sizeof(int));
   *ud2 = 2;
-  md = grpc_mdelem_from_strings("abc", "123");
+  md = grpc_mdelem_from_strings(&exec_ctx, "abc", "123");
   grpc_mdelem_set_user_data(md, gpr_free, ud1);
   grpc_mdelem_set_user_data(md, gpr_free, ud2);
   GPR_ASSERT(grpc_mdelem_get_user_data(md, gpr_free) == ud1);
-  GRPC_MDELEM_UNREF(md);
+  GRPC_MDELEM_UNREF(&exec_ctx, md);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
-static void verify_ascii_header_size(const char *key, const char *value) {
-  grpc_mdelem *elem = grpc_mdelem_from_strings(key, value);
+static void verify_ascii_header_size(grpc_exec_ctx *exec_ctx, const char *key,
+                                     const char *value) {
+  grpc_mdelem *elem = grpc_mdelem_from_strings(exec_ctx, key, value);
   size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
   size_t expected_size = 32 + strlen(key) + strlen(value);
   GPR_ASSERT(expected_size == elem_size);
-  GRPC_MDELEM_UNREF(elem);
+  GRPC_MDELEM_UNREF(exec_ctx, elem);
 }
 
-static void verify_binary_header_size(const char *key, const uint8_t *value,
-                                      size_t value_len) {
-  grpc_mdelem *elem = grpc_mdelem_from_string_and_buffer(key, value, value_len);
+static void verify_binary_header_size(grpc_exec_ctx *exec_ctx, const char *key,
+                                      const uint8_t *value, size_t value_len) {
+  grpc_mdelem *elem =
+      grpc_mdelem_from_string_and_buffer(exec_ctx, key, value, value_len);
   GPR_ASSERT(grpc_is_binary_header(key, strlen(key)));
   size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
   grpc_slice value_slice =
@@ -281,33 +303,37 @@
   grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice);
   size_t expected_size = 32 + strlen(key) + GRPC_SLICE_LENGTH(base64_encoded);
   GPR_ASSERT(expected_size == elem_size);
-  grpc_slice_unref(value_slice);
-  grpc_slice_unref(base64_encoded);
-  GRPC_MDELEM_UNREF(elem);
+  grpc_slice_unref_internal(exec_ctx, value_slice);
+  grpc_slice_unref_internal(exec_ctx, base64_encoded);
+  GRPC_MDELEM_UNREF(exec_ctx, elem);
 }
 
 #define BUFFER_SIZE 64
 static void test_mdelem_sizes_in_hpack(void) {
   LOG_TEST("test_mdelem_size");
   grpc_init();
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   uint8_t binary_value[BUFFER_SIZE] = {0};
   for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
     binary_value[i] = i;
   }
 
-  verify_ascii_header_size("hello", "world");
-  verify_ascii_header_size("hello", "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-  verify_ascii_header_size(":scheme", "http");
+  verify_ascii_header_size(&exec_ctx, "hello", "world");
+  verify_ascii_header_size(&exec_ctx, "hello",
+                           "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+  verify_ascii_header_size(&exec_ctx, ":scheme", "http");
 
   for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
-    verify_binary_header_size("hello-bin", binary_value, i);
+    verify_binary_header_size(&exec_ctx, "hello-bin", binary_value, i);
   }
 
   const char *static_metadata = grpc_static_metadata_strings[0];
   memcpy(binary_value, static_metadata, strlen(static_metadata));
-  verify_binary_header_size("hello-bin", binary_value, strlen(static_metadata));
+  verify_binary_header_size(&exec_ctx, "hello-bin", binary_value,
+                            strlen(static_metadata));
 
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 }
 
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index b3405f02..ecffe35 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -39,6 +39,8 @@
 #include <grpc/support/string_util.h>
 #include "src/core/lib/iomgr/sockaddr.h"
 
+#include "src/core/lib/slice/slice_internal.h"
+
 typedef struct passthru_endpoint passthru_endpoint;
 
 typedef struct {
@@ -133,8 +135,8 @@
   if (0 == --p->halves) {
     gpr_mu_unlock(&p->mu);
     gpr_mu_destroy(&p->mu);
-    grpc_slice_buffer_destroy(&p->client.read_buffer);
-    grpc_slice_buffer_destroy(&p->server.read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &p->client.read_buffer);
+    grpc_slice_buffer_destroy_internal(exec_ctx, &p->server.read_buffer);
     grpc_resource_user_unref(exec_ctx, p->client.resource_user);
     grpc_resource_user_unref(exec_ctx, p->server.resource_user);
     gpr_free(p);
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index b2342fe..384a158 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -104,7 +104,7 @@
   grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
                    grpc_closure_create(freed_port_from_server, &pr), &rsp);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   gpr_mu_lock(pr.mu);
   while (!pr.done) {
     grpc_pollset_worker *worker = NULL;
@@ -176,7 +176,7 @@
                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
                      grpc_closure_create(got_port_from_server, pr),
                      &pr->response);
-    grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+    grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
     return;
   }
   GPR_ASSERT(response);
@@ -223,7 +223,7 @@
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
                    grpc_closure_create(got_port_from_server, &pr),
                    &pr.response);
-  grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_mu_lock(pr.mu);
   while (pr.port == -1) {
diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc
index 60d3215..190d32c 100644
--- a/test/cpp/common/channel_arguments_test.cc
+++ b/test/cpp/common/channel_arguments_test.cc
@@ -37,7 +37,11 @@
 #include <grpc/grpc.h>
 #include <grpc/support/useful.h>
 #include <gtest/gtest.h>
+
+extern "C" {
+#include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/socket_mutator.h"
+}
 
 namespace grpc {
 namespace testing {
@@ -228,7 +232,11 @@
   EXPECT_FALSE(HasArg(arg0));
 
   // arg0 is destroyed by grpc_socket_mutator_to_arg(mutator1)
-  arg1.value.pointer.vtable->destroy(arg1.value.pointer.p);
+  {
+    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+    arg1.value.pointer.vtable->destroy(&exec_ctx, arg1.value.pointer.p);
+    grpc_exec_ctx_finish(&exec_ctx);
+  }
 }
 
 TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 9e3fc62..bf4cb57 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -833,6 +833,7 @@
 include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/status.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 074ba50..1ab5f49 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -833,6 +833,7 @@
 include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/status.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index b83e710..af9c00a 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -772,6 +772,7 @@
 include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/status.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 533999b..1391924 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -772,6 +772,7 @@
 include/grpc/impl/codegen/byte_buffer_reader.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/status.h \
@@ -863,6 +864,7 @@
 src/core/lib/json/json_reader.h \
 src/core/lib/json/json_writer.h \
 src/core/lib/slice/percent_encoding.h \
+src/core/lib/slice/slice_internal.h \
 src/core/lib/slice/slice_string_helpers.h \
 src/core/lib/surface/api_trace.h \
 src/core/lib/surface/call.h \
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
new file mode 100755
index 0000000..afac10b
--- /dev/null
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python2.7
+
+# Copyright 2016, 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.
+
+import os
+import sys
+
+os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+
+# map of banned function signature to whitelist
+BANNED_EXCEPT = {
+    'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.c'],
+    'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.c'],
+    'grpc_slice_buffer_destroy(': ['src/core/lib/slice/slice_buffer.c'],
+    'grpc_slice_buffer_reset_and_unref(': ['src/core/lib/slice/slice_buffer.c'],
+    'grpc_slice_ref(': ['src/core/lib/slice/slice.c'],
+    'grpc_slice_unref(': ['src/core/lib/slice/slice.c'],
+}
+
+errors = 0
+for root, dirs, files in os.walk('src/core'):
+  for filename in files:
+    path = os.path.join(root, filename)
+    if os.path.splitext(path)[1] != '.c': continue
+    with open(path) as f:
+      text = f.read()
+    for banned, exceptions in BANNED_EXCEPT.items():
+      if path in exceptions: continue
+      if banned in text:
+        print 'Illegal use of "%s" in %s' % (banned, path)
+        errors += 1
+
+assert errors == 0
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 32e62dd..3781916 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -3,6 +3,7 @@
 - script: tools/run_tests/sanity/check_sources_and_headers.py
 - script: tools/run_tests/sanity/check_submodules.sh
 - script: tools/run_tests/sanity/check_test_filtering.py
+- script: tools/run_tests/sanity/core_banned_functions.py
 - script: tools/buildgen/generate_projects.sh -j 3
   cpu_cost: 3
 - script: tools/distrib/check_copyright.py
@@ -12,3 +13,4 @@
 - script: tools/distrib/check_nanopb_output.sh
 - script: tools/distrib/check_include_guards.py
 - script: tools/distrib/python/check_grpcio_tools.py
+
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 9dd5a1c..93cd028 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -6751,6 +6751,7 @@
       "src/core/lib/json/json_reader.h", 
       "src/core/lib/json/json_writer.h", 
       "src/core/lib/slice/percent_encoding.h", 
+      "src/core/lib/slice/slice_internal.h", 
       "src/core/lib/slice/slice_string_helpers.h", 
       "src/core/lib/surface/api_trace.h", 
       "src/core/lib/surface/call.h", 
@@ -6944,6 +6945,7 @@
       "src/core/lib/slice/percent_encoding.h", 
       "src/core/lib/slice/slice.c", 
       "src/core/lib/slice/slice_buffer.c", 
+      "src/core/lib/slice/slice_internal.h", 
       "src/core/lib/slice/slice_string_helpers.c", 
       "src/core/lib/slice/slice_string_helpers.h", 
       "src/core/lib/surface/alarm.c", 
@@ -7072,6 +7074,7 @@
       "include/grpc/impl/codegen/byte_buffer_reader.h", 
       "include/grpc/impl/codegen/compression_types.h", 
       "include/grpc/impl/codegen/connectivity_state.h", 
+      "include/grpc/impl/codegen/exec_ctx_fwd.h", 
       "include/grpc/impl/codegen/grpc_types.h", 
       "include/grpc/impl/codegen/propagation_bits.h", 
       "include/grpc/impl/codegen/status.h"
@@ -7083,6 +7086,7 @@
       "include/grpc/impl/codegen/byte_buffer_reader.h", 
       "include/grpc/impl/codegen/compression_types.h", 
       "include/grpc/impl/codegen/connectivity_state.h", 
+      "include/grpc/impl/codegen/exec_ctx_fwd.h", 
       "include/grpc/impl/codegen/grpc_types.h", 
       "include/grpc/impl/codegen/propagation_bits.h", 
       "include/grpc/impl/codegen/status.h"
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 14b3453..bd9c546 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -331,6 +331,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 5360819..93d8274 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -333,6 +333,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index 6a928e1..7eba5c5 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -178,6 +178,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
index bf8fab0..9a10e07 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -126,6 +126,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 39b01e6..7f2e815 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -331,6 +331,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 9cafa16..df62384 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -318,6 +318,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 40f0f14..eeb1691 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -279,6 +279,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
@@ -372,6 +373,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index c0de285..14f79ca 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -684,6 +684,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -959,6 +962,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 01b73ce..c73584a 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -159,6 +159,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
@@ -265,6 +266,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 40ff676..b317c14 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -435,6 +435,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -749,6 +752,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 49c2d2d..0f57f38 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -270,6 +270,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
@@ -362,6 +363,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 5bca4fb..9327bff 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -600,6 +600,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -872,6 +875,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_internal.h">
+      <Filter>src\core\lib\slice</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
       <Filter>src\core\lib\slice</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
index 377d86f..ad6865a 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -191,6 +191,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
index e9ba002..1b367b1 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
@@ -114,6 +114,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
index 3254ad8..9df6702 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -191,6 +191,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
index 6f32f65..c8f62ff 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
@@ -117,6 +117,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
index 7fad922..88e4bf6 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
@@ -192,6 +192,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
index 19cb113..fece7f3 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
@@ -108,6 +108,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>