[vm, io] Restore global destructors for normal shutdown path.

Cf. ef4984566b7534bb128325fe7f8b099208833e12.

TEST=samples/hello_world
Bug: https://github.com/dart-lang/samples/issues/195
Change-Id: I05cac92500a912c5d3e0771f626878decac18a9b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324267
Reviewed-by: Brian Quinlan <bquinlan@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 2b840e0..74acf31 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -99,6 +99,7 @@
   static void SetProcessName(const char* name);
 
   DART_NORETURN static void Exit(int exit_code);
+  DART_NORETURN static void _Exit(int exit_code);
 
   static void SetCoreDumpResourceLimit(int value);
 
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index f9c4d20..fd2fc6a 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -162,9 +162,12 @@
 void Platform::Exit(int exit_code) {
   Console::RestoreConfig();
   Dart_PrepareToAbort();
-  // We're not doing a full VM shutdown with Dart_Cleanup, which might block,
-  // and other VM threads may be accessing state with global destructors, so
-  // we skip global destructors by using _exit instead of exit.
+  exit(exit_code);
+}
+
+void Platform::_Exit(int exit_code) {
+  Console::RestoreConfig();
+  Dart_PrepareToAbort();
   _exit(exit_code);
 }
 
diff --git a/runtime/bin/platform_fuchsia.cc b/runtime/bin/platform_fuchsia.cc
index 1a47f95..5cf6d52 100644
--- a/runtime/bin/platform_fuchsia.cc
+++ b/runtime/bin/platform_fuchsia.cc
@@ -157,9 +157,12 @@
 void Platform::Exit(int exit_code) {
   Console::RestoreConfig();
   Dart_PrepareToAbort();
-  // We're not doing a full VM shutdown with Dart_Cleanup, which might block,
-  // and other VM threads may be accessing state with global destructors, so
-  // we skip global destructors by using _exit instead of exit.
+  exit(exit_code);
+}
+
+void Platform::_Exit(int exit_code) {
+  Console::RestoreConfig();
+  Dart_PrepareToAbort();
   _exit(exit_code);
 }
 
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 0050d79..66f5e92 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -169,9 +169,12 @@
 void Platform::Exit(int exit_code) {
   Console::RestoreConfig();
   Dart_PrepareToAbort();
-  // We're not doing a full VM shutdown with Dart_Cleanup, which might block,
-  // and other VM threads may be accessing state with global destructors, so
-  // we skip global destructors by using _exit instead of exit.
+  exit(exit_code);
+}
+
+void Platform::_Exit(int exit_code) {
+  Console::RestoreConfig();
+  Dart_PrepareToAbort();
   _exit(exit_code);
 }
 
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index cc20fbf..7afc201 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -342,9 +342,12 @@
 void Platform::Exit(int exit_code) {
   Console::RestoreConfig();
   Dart_PrepareToAbort();
-  // We're not doing a full VM shutdown with Dart_Cleanup, which might block,
-  // and other VM threads may be accessing state with global destructors, so
-  // we skip global destructors by using _exit instead of exit.
+  exit(exit_code);
+}
+
+void Platform::_Exit(int exit_code) {
+  Console::RestoreConfig();
+  Dart_PrepareToAbort();
   _exit(exit_code);
 }
 
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 65f2b12..b083506 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -307,6 +307,15 @@
   ::ExitProcess(exit_code);
 }
 
+void Platform::_Exit(int exit_code) {
+  // Restore the console's output code page
+  Console::RestoreConfig();
+  // On Windows we use ExitProcess so that threads can't clobber the exit_code.
+  // See: https://code.google.com/p/nativeclient/issues/detail?id=2870
+  Dart_PrepareToAbort();
+  ::ExitProcess(exit_code);
+}
+
 void Platform::SetCoreDumpResourceLimit(int value) {
   // Not supported.
 }
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index 3a9d9cb..309f690 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -263,7 +263,10 @@
   DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
   Process::RunExitHook(status);
   Dart_ExitIsolate();
-  Platform::Exit(static_cast<int>(status));
+  // We're not doing a full VM shutdown with Dart_Cleanup, which might block,
+  // and other VM threads may be accessing state with global destructors, so
+  // we skip global destructors by using _exit instead of exit.
+  Platform::_Exit(static_cast<int>(status));
 }
 
 void FUNCTION_NAME(Process_SetExitCode)(Dart_NativeArguments args) {