Introduce `art::FastExit` to replace all uses of `quick_exit` in ART.

No longer use `quick_exit(3)` in ART, as it does not play well with
Clang's code coverage instrumentation (see b/187935521 and
b/186576313). Replace all its uses with a new routine,
`art::FastExit`, calling either `exit(3)` when ART is built with
Clang's code coverage instrumentation (in order to dump coverage
profiles when the program terminates) or `_exit(2)` otherwise (to exit
quickly).

Function `art::FastExit` is implemented as part of the
`art_libartbase_headers` header library, so that it can be used easily
in `dalvikvm`.

(cherry picked from commit bdf1737bd17132525bcfdc778663123b61e97fa3)

Test: mmma art
Test: ART tests
Bug: 186576313
Bug: 187935521
Change-Id: I7b4f86f6f0e7b12814684ecea73a2ed0ef994395
Merged-In: I7b4f86f6f0e7b12814684ecea73a2ed0ef994395
diff --git a/dalvikvm/Android.bp b/dalvikvm/Android.bp
index a1f57ca..6e06eba 100644
--- a/dalvikvm/Android.bp
+++ b/dalvikvm/Android.bp
@@ -34,6 +34,9 @@
         "liblog",
         "libnativehelper",
     ],
+    header_libs: [
+        "art_libartbase_headers", // For base/fast_exit.h
+    ],
     target: {
         android: {
             shared_libs: [
diff --git a/dalvikvm/dalvikvm.cc b/dalvikvm/dalvikvm.cc
index f2cc225..27709fd 100644
--- a/dalvikvm/dalvikvm.cc
+++ b/dalvikvm/dalvikvm.cc
@@ -21,6 +21,7 @@
 #include <algorithm>
 #include <memory>
 
+#include "base/fast_exit.h"
 #include "jni.h"
 #include "nativehelper/JniInvocation.h"
 #include "nativehelper/ScopedLocalRef.h"
@@ -215,8 +216,6 @@
 
 int main(int argc, char** argv) {
   // Do not allow static destructors to be called, since it's conceivable that
-  // daemons may still awaken (literally); but still have functions registered
-  // with `at_quick_exit` (for instance LLVM's code coverage profile dumping
-  // routine) be called before exiting.
-  quick_exit(art::dalvikvm(argc, argv));
+  // daemons may still awaken (literally).
+  art::FastExit(art::dalvikvm(argc, argv));
 }
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index c613e33..fa1a10e 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -53,6 +53,7 @@
 #include "base/macros.h"
 #include "base/mutex.h"
 #include "base/os.h"
+#include "base/fast_exit.h"
 #include "base/scoped_flock.h"
 #include "base/stl_util.h"
 #include "base/time_utils.h"
@@ -3142,11 +3143,9 @@
   int result = static_cast<int>(art::Dex2oat(argc, argv));
   // Everything was done, do an explicit exit here to avoid running Runtime destructors that take
   // time (bug 10645725) unless we're a debug or instrumented build or running on a memory tool.
-  // Also have functions registered with `at_quick_exit` (for instance LLVM's code coverage
-  // profile dumping routine) be called before exiting.
   // Note: The Dex2Oat class should not destruct the runtime in this case.
   if (!art::kIsDebugBuild && !art::kIsPGOInstrumentation && !art::kRunningOnMemoryTool) {
-    quick_exit(result);
+    art::FastExit(result);
   }
   return result;
 }
diff --git a/libartbase/base/fast_exit.h b/libartbase/base/fast_exit.h
new file mode 100644
index 0000000..35dd85e
--- /dev/null
+++ b/libartbase/base/fast_exit.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_LIBARTBASE_BASE_FAST_EXIT_H_
+#define ART_LIBARTBASE_BASE_FAST_EXIT_H_
+
+// Header-only definition of `art::FastExit`.
+//
+// Ideally, this routine should be declared in `base/os.h` and defined in
+// `base/os_linux.cc`, but as `libartbase` is not linked (directly) with
+// `dalvikvm`, we would not be able to easily use `art::FastExit` in
+// `dex2oat`. Use a header-only approach and define `art::FastExit` in its own
+// file for clarity.
+
+#include <base/macros.h>
+
+namespace art {
+
+#ifdef __ANDROID_CLANG_COVERAGE__
+static constexpr bool kAndroidClangCoverage = true;
+#else
+static constexpr bool kAndroidClangCoverage = false;
+#endif
+
+// Terminate program without completely cleaning the resources (e.g. without
+// calling destructors), unless ART is built with Clang (native) code coverage
+// instrumentation; in that case, exit normally to allow LLVM's code coverage
+// profile dumping routine (`__llvm_profile_write_file`), registered via
+// `atexit` in Android when Clang instrumentation is enabled, to be called
+// before terminating the program.
+NO_RETURN inline void FastExit(int exit_code) {
+  if (kAndroidClangCoverage) {
+    exit(exit_code);
+  } else {
+    _exit(exit_code);
+  }
+}
+
+}  // namespace art
+
+#endif  // ART_LIBARTBASE_BASE_FAST_EXIT_H_
diff --git a/openjdkjvm/OpenjdkJvm.cc b/openjdkjvm/OpenjdkJvm.cc
index 18078ab..d64086d 100644
--- a/openjdkjvm/OpenjdkJvm.cc
+++ b/openjdkjvm/OpenjdkJvm.cc
@@ -35,7 +35,6 @@
 #include <dlfcn.h>
 #include <limits.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/time.h>
@@ -46,6 +45,7 @@
 #include "../../libcore/ojluni/src/main/native/jvm.h"  // TODO(narayan): fix it
 
 #include "base/macros.h"
+#include "base/fast_exit.h"
 #include "common_throws.h"
 #include "gc/heap.h"
 #include "handle_scope-inl.h"
@@ -315,10 +315,8 @@
   LOG(INFO) << "System.exit called, status: " << status;
   art::Runtime::Current()->CallExitHook(status);
   // Unsafe to call exit() while threads may still be running. They would race
-  // with static destructors. However, have functions registered with
-  // `at_quick_exit` (for instance LLVM's code coverage profile dumping routine)
-  // be called before exiting.
-  quick_exit(status);
+  // with static destructors.
+  art::FastExit(status);
 }
 
 JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env,
diff --git a/perfetto_hprof/perfetto_hprof.cc b/perfetto_hprof/perfetto_hprof.cc
index 0a7f380..3affe8d 100644
--- a/perfetto_hprof/perfetto_hprof.cc
+++ b/perfetto_hprof/perfetto_hprof.cc
@@ -19,11 +19,11 @@
 #include "perfetto_hprof.h"
 
 #include <android-base/logging.h>
+#include <base/fast_exit.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <sched.h>
 #include <signal.h>
-#include <stdlib.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -847,11 +847,9 @@
           });
 
   LOG(INFO) << "finished dumping heap for " << parent_pid;
-  // Prevent the atexit handlers to run. We do not want to call cleanup
-  // functions the parent process has registered. However, have functions
-  // registered with `at_quick_exit` (for instance LLVM's code coverage profile
-  // dumping routine) be called before exiting.
-  quick_exit(0);
+  // Prevent the `atexit` handlers from running. We do not want to call cleanup
+  // functions the parent process has registered.
+  art::FastExit(0);
 }
 
 // The plugin initialization function.
diff --git a/runtime/runtime_options.cc b/runtime/runtime_options.cc
index 12dab15..e21587a 100644
--- a/runtime/runtime_options.cc
+++ b/runtime/runtime_options.cc
@@ -18,6 +18,7 @@
 
 #include <memory>
 
+#include "base/fast_exit.h"
 #include "base/sdk_version.h"
 #include "base/utils.h"
 #include "debugger.h"
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index 3f0e3cc..3743670 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -156,12 +156,10 @@
 RUNTIME_OPTIONS_KEY (bool (*)(),          HookIsSensitiveThread)
 RUNTIME_OPTIONS_KEY (int32_t (*)(FILE* stream, const char* format, va_list ap), \
                                           HookVfprintf,                   vfprintf)
-// Use `quick_exit` instead of `exit` so that we won't get DCHECK failures
-// in global data destructors (see b/28106055); but still have functions
-// registered with `at_quick_exit` (for instance LLVM's code coverage profile
-// dumping routine) be called before exiting.
+// Use `art::FastExit` instead of `exit` so that we won't get DCHECK failures
+// in global data destructors (see b/28106055).
 RUNTIME_OPTIONS_KEY (void (*)(int32_t status), \
-                                          HookExit,                       quick_exit)
+                                          HookExit,                       art::FastExit)
                                                                           // We don't call abort(3) by default; see
                                                                           // Runtime::Abort.
 RUNTIME_OPTIONS_KEY (void (*)(),          HookAbort,                      nullptr)