Add method to use allocator app defaults.

Currently, apps turn off zeroing of memory and enable the decay
timer. For shell commands, set these values when the environment
variable MALLOC_USE_APP_DEFAULTS is set. This fixes performance
differences found between shell spawned command-line tools and
native code running in an app.

Add a unit test to verify setting after exec.

Bug: 302212507

Test: Set the variable to 1 and verified the decay time is enabled.
Test: Set the variable to "" and also unset it and verified the decay
Test: time is not enabled.
Test: Verified that with the variable set, the memory is not zero'd
Test: by default.
Test: Unit tests pass.
Change-Id: I22a47f70f1ce1205c16195532c54b2bf9403e9cd
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 441d884..1e0ef14 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -41,6 +41,7 @@
 #include <platform/bionic/malloc.h>
 #include <private/ScopedPthreadMutexLocker.h>
 #include <private/bionic_config.h>
+#include <private/bionic_defs.h>
 
 #include "gwp_asan_wrappers.h"
 #include "heap_tagging.h"
@@ -358,3 +359,37 @@
 const MallocDispatch* NativeAllocatorDispatch() {
   return &__libc_malloc_default_dispatch;
 }
+
+#if !defined(LIBC_STATIC)
+void MallocInitImpl(libc_globals* globals);
+#endif
+
+// Initializes memory allocation framework.
+// This routine is called from __libc_init routines in libc_init_dynamic.cpp
+// and libc_init_static.cpp.
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+__LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals) {
+#if !defined(LIBC_STATIC)
+  MallocInitImpl(globals);
+#endif
+  const char* value = getenv("MALLOC_USE_APP_DEFAULTS");
+  if (value == nullptr || value[0] == '\0') {
+    return;
+  }
+
+  // Normal apps currently turn off zero init for performance reasons.
+  SetHeapZeroInitialize(false);
+
+  // Do not call mallopt directly since that will try and lock the globals
+  // data structure.
+  int retval;
+  auto dispatch_table = GetDispatchTable();
+  if (__predict_false(dispatch_table != nullptr)) {
+    retval = dispatch_table->mallopt(M_DECAY_TIME, 1);
+  } else {
+    retval = Malloc(mallopt)(M_DECAY_TIME, 1);
+  }
+  if (retval == 1) {
+    globals->decay_time_enabled = true;
+  }
+}