[vm] Move disabling of OS thread creation after last Thread::EnterIsolate (which can create a thread)

With our current C++ unit test framework (run_vm_tests) we cannot write
a regression test for this.

See b/155605399

Change-Id: I86453db2b74dbf6d57a205abff6e9cdcac18b9df
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/146260
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 180a7e0..08ae076 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -566,6 +566,22 @@
   delete predefined_handles_;
   predefined_handles_ = NULL;
 
+  // Set the VM isolate as current isolate.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
+                 UptimeMillis());
+  }
+
+  // If Dart_Cleanup() is called on a thread which hasn't invoked any Dart API
+  // functions before, entering the "vm-isolate" will cause lazy creation of a
+  // OSThread (which is attached to the current thread via TLS).
+  //
+  // If we run in PRODUCT mode this lazy creation of OSThread can happen here,
+  // which is why disabling the OSThread creation has to come after entering the
+  // "vm-isolate".
+  const bool result = Thread::EnterIsolate(vm_isolate_);
+  ASSERT(result);
+
   // Disable creation of any new OSThread structures which means no more new
   // threads can do an EnterIsolate. This must come after isolate shutdown
   // because new threads may need to be spawned to shutdown the isolates.
@@ -578,14 +594,6 @@
   }
   OSThread::DisableOSThreadCreation();
 
-  // Set the VM isolate as current isolate.
-  if (FLAG_trace_shutdown) {
-    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
-                 UptimeMillis());
-  }
-  bool result = Thread::EnterIsolate(vm_isolate_);
-  ASSERT(result);
-
   ShutdownIsolate();
   vm_isolate_ = NULL;
   ASSERT(Isolate::IsolateListLength() == 0);