Merge branch 'master' into fix-dns-job
diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc
index 31d66e8..023ede5 100644
--- a/src/core/lib/channel/channelz_registry.cc
+++ b/src/core/lib/channel/channelz_registry.cc
@@ -26,27 +26,14 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include <cstring>
+
 namespace grpc_core {
 namespace {
 
 // singleton instance of the registry.
 ChannelzRegistry* g_channelz_registry = nullptr;
 
-// avl vtable for uuid (intptr_t) -> channelz_obj (void*)
-// this table is only looking, it does not own anything.
-void destroy_intptr(void* not_used, void* user_data) {}
-void* copy_intptr(void* key, void* user_data) { return key; }
-long compare_intptr(void* key1, void* key2, void* user_data) {
-  return GPR_ICMP(key1, key2);
-}
-
-void destroy_channelz_obj(void* channelz_obj, void* user_data) {}
-void* copy_channelz_obj(void* channelz_obj, void* user_data) {
-  return channelz_obj;
-}
-const grpc_avl_vtable avl_vtable = {destroy_intptr, copy_intptr, compare_intptr,
-                                    destroy_channelz_obj, copy_channelz_obj};
-
 }  // anonymous namespace
 
 void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); }
@@ -58,19 +45,15 @@
   return g_channelz_registry;
 }
 
-ChannelzRegistry::ChannelzRegistry() : uuid_(1) {
-  gpr_mu_init(&mu_);
-  avl_ = grpc_avl_create(&avl_vtable);
-}
+ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }
 
-ChannelzRegistry::~ChannelzRegistry() {
-  grpc_avl_unref(avl_, nullptr);
-  gpr_mu_destroy(&mu_);
-}
+ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }
 
 void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
+  GPR_ASSERT(uuid >= 1);
   gpr_mu_lock(&mu_);
-  avl_ = grpc_avl_remove(avl_, (void*)uuid, nullptr);
+  GPR_ASSERT(static_cast<size_t>(uuid) <= entities_.size());
+  entities_[uuid - 1] = nullptr;
   gpr_mu_unlock(&mu_);
 }
 
diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h
index 4de7d47..a5a187a 100644
--- a/src/core/lib/channel/channelz_registry.h
+++ b/src/core/lib/channel/channelz_registry.h
@@ -21,8 +21,8 @@
 
 #include <grpc/impl/codegen/port_platform.h>
 
-#include "src/core/lib/avl/avl.h"
 #include "src/core/lib/channel/channel_trace.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
 
 #include <stdint.h>
 
@@ -67,11 +67,11 @@
   // globally registers a channelz Object. Returns its unique uuid
   template <typename Object>
   intptr_t InternalRegister(Object* object) {
-    intptr_t prior = gpr_atm_no_barrier_fetch_add(&uuid_, 1);
     gpr_mu_lock(&mu_);
-    avl_ = grpc_avl_add(avl_, (void*)prior, object, nullptr);
+    entities_.push_back(static_cast<void*>(object));
+    intptr_t uuid = entities_.size();
     gpr_mu_unlock(&mu_);
-    return prior;
+    return uuid;
   }
 
   // globally unregisters the object that is associated to uuid.
@@ -82,16 +82,20 @@
   template <typename Object>
   Object* InternalGet(intptr_t uuid) {
     gpr_mu_lock(&mu_);
-    Object* ret =
-        static_cast<Object*>(grpc_avl_get(avl_, (void*)uuid, nullptr));
+    if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
+      gpr_mu_unlock(&mu_);
+      return nullptr;
+    }
+    Object* ret = static_cast<Object*>(entities_[uuid - 1]);
     gpr_mu_unlock(&mu_);
     return ret;
   }
 
   // private members
+
+  // protects entities_ and uuid_
   gpr_mu mu_;
-  grpc_avl avl_;
-  gpr_atm uuid_;
+  InlinedVector<void*, 20> entities_;
 };
 
 }  // namespace grpc_core
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index 3e4e434..8f3ad6c 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -148,6 +148,8 @@
       channel_tracer_max_nodes =
           (size_t)grpc_channel_arg_get_integer(&args->args[i], options);
     } else if (0 == strcmp(args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) {
+      // channelz will not be enabled by default until all concerns in
+      // https://github.com/grpc/grpc/issues/15986 are addressed.
       channelz_enabled = grpc_channel_arg_get_bool(&args->args[i], false);
     } else if (0 == strcmp(args->args[i].key,
                            GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC)) {
diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc
index eb6305e..24e5093 100644
--- a/test/core/channel/channelz_registry_test.cc
+++ b/test/core/channel/channelz_registry_test.cc
@@ -82,6 +82,15 @@
   EXPECT_EQ(&str_to_register, retrieved_str);
 }
 
+TEST(ChannelzRegistryTest, RegisterManyItems) {
+  int object_to_register = 42;
+  for (int i = 0; i < 100; i++) {
+    intptr_t uuid = ChannelzRegistry::Register(&object_to_register);
+    int* retrieved = ChannelzRegistry::Get<int>(uuid);
+    EXPECT_EQ(&object_to_register, retrieved);
+  }
+}
+
 namespace {
 class Foo {
  public: