[vm/ffi] Refactor callback id exponential growth

Also lower the initial array size to save a tiny bit of memory and
let the existing tests exercise exponential growth

TEST=tests/{ffi,ffi_2}/function_callbacks_many_test.dart

Change-Id: I7b490878035cf2e2264ce7443dfdc2b342bedcc3
Cq-Include-Trybots: luci.dart.try:vm-precomp-ffi-qemu-linux-release-arm-try,vm-ffi-android-debug-arm64-try,vm-ffi-android-debug-arm-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170438
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 9dc2ac5..68448fc 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -1056,9 +1056,9 @@
   }
 }
 
-const intptr_t kInitialCallbackIdsReserved = 1024;
+const intptr_t kInitialCallbackIdsReserved = 16;
 int32_t Thread::AllocateFfiCallbackId() {
-  Zone* Z = isolate()->current_zone();
+  Zone* Z = Thread::Current()->zone();
   if (ffi_callback_code_ == GrowableObjectArray::null()) {
     ffi_callback_code_ = GrowableObjectArray::New(kInitialCallbackIdsReserved);
   }
@@ -1079,7 +1079,7 @@
 }
 
 void Thread::SetFfiCallbackCode(int32_t callback_id, const Code& code) {
-  Zone* Z = isolate()->current_zone();
+  Zone* Z = Thread::Current()->zone();
 
   /// In AOT the callback ID might have been allocated during compilation but
   /// 'ffi_callback_code_' is initialized to empty again when the program
@@ -1093,8 +1093,12 @@
   const auto& array = GrowableObjectArray::Handle(Z, ffi_callback_code_);
 
   if (callback_id >= array.Length()) {
-    if (callback_id >= array.Capacity()) {
-      array.Grow(callback_id + 1);
+    const int32_t capacity = array.Capacity();
+    if (callback_id >= capacity) {
+      // Ensure both that we grow enough and an exponential growth strategy.
+      const int32_t new_capacity =
+          Utils::Maximum(callback_id + 1, capacity * 2);
+      array.Grow(new_capacity);
     }
     array.SetLength(callback_id + 1);
   }