Merge "<bits/glibc-syscalls.h>: only regenerate when we have new uapi headers."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 98bede5..c9dcd8f 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,4 +1,3 @@
[Hook Scripts]
notice = tools/update_notice.sh
-seccomp = tools/update_seccomp.sh
syscalls = tools/update_syscalls.sh
diff --git a/benchmarks/malloc_benchmark.cpp b/benchmarks/malloc_benchmark.cpp
index 2fa1c87..ca54f11 100644
--- a/benchmarks/malloc_benchmark.cpp
+++ b/benchmarks/malloc_benchmark.cpp
@@ -102,22 +102,27 @@
// bionic/libc/malloc_debug/tools/gen_malloc.pl -i <THREAD_ID> g_sql_entries kMaxSqlAllocSlots < <ALLOC_FILE> > malloc_sql.h
#include "malloc_sql.h"
-static void BM_malloc_sql_trace_decay_time_0(benchmark::State& state) {
+static void BM_malloc_sql_trace_default(benchmark::State& state) {
+ // The default is expected to be a zero decay time.
mallopt(M_DECAY_TIME, 0);
- for (auto _ : state) {
- BenchmarkMalloc(g_sql_entries, sizeof(g_sql_entries) / sizeof(MallocEntry),
- kMaxSqlAllocSlots);
- }
-}
-BIONIC_BENCHMARK(BM_malloc_sql_trace_decay_time_0);
-static void BM_malloc_sql_trace_decay_time_1(benchmark::State& state) {
- mallopt(M_DECAY_TIME, 1);
for (auto _ : state) {
BenchmarkMalloc(g_sql_entries, sizeof(g_sql_entries) / sizeof(MallocEntry),
kMaxSqlAllocSlots);
}
}
-BIONIC_BENCHMARK(BM_malloc_sql_trace_decay_time_1);
+BIONIC_BENCHMARK(BM_malloc_sql_trace_default);
+
+static void BM_malloc_sql_trace_decay1(benchmark::State& state) {
+ mallopt(M_DECAY_TIME, 1);
+
+ for (auto _ : state) {
+ BenchmarkMalloc(g_sql_entries, sizeof(g_sql_entries) / sizeof(MallocEntry),
+ kMaxSqlAllocSlots);
+ }
+
+ mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK(BM_malloc_sql_trace_decay1);
#endif
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index 7330dc4..6afe7aa 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -17,30 +17,120 @@
#include <err.h>
#include <langinfo.h>
#include <locale.h>
+#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
#include <benchmark/benchmark.h>
#include "util.h"
-static void BM_stdlib_malloc_free(benchmark::State& state) {
+#if defined(__BIONIC__)
+
+#else
+#endif
+
+static __always_inline void MakeAllocationResident(void* ptr, size_t nbytes, int pagesize) {
+ uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
+ for (size_t i = 0; i < nbytes; i += pagesize) {
+ data[i] = 1;
+ }
+}
+
+static void MallocFree(benchmark::State& state) {
const size_t nbytes = state.range(0);
int pagesize = getpagesize();
- void* ptr;
for (auto _ : state) {
- ptr = malloc(nbytes);
- // Make the entire allocation resident.
- uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
- for (size_t i = 0; i < nbytes; i += pagesize) {
- data[i] = 1;
- }
+ void* ptr;
+ benchmark::DoNotOptimize(ptr = malloc(nbytes));
+ MakeAllocationResident(ptr, nbytes, pagesize);
free(ptr);
}
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free, "AT_COMMON_SIZES");
+
+static void BM_stdlib_malloc_free_default(benchmark::State& state) {
+#if defined(__BIONIC__)
+ // The default is expected to be a zero decay time.
+ mallopt(M_DECAY_TIME, 0);
+#endif
+
+ MallocFree(state);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free_default, "AT_COMMON_SIZES");
+
+#if defined(__BIONIC__)
+static void BM_stdlib_malloc_free_decay1(benchmark::State& state) {
+ mallopt(M_DECAY_TIME, 1);
+
+ MallocFree(state);
+
+ mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free_decay1, "AT_COMMON_SIZES");
+#endif
+
+static void MallocMultiple(benchmark::State& state, size_t nbytes, size_t numAllocs) {
+ int pagesize = getpagesize();
+ void* ptrs[numAllocs];
+ for (auto _ : state) {
+ for (size_t i = 0; i < numAllocs; i++) {
+ benchmark::DoNotOptimize(ptrs[i] = reinterpret_cast<uint8_t*>(malloc(nbytes)));
+ MakeAllocationResident(ptrs[i], nbytes, pagesize);
+ }
+ state.PauseTiming(); // Stop timers while freeing pointers.
+ for (size_t i = 0; i < numAllocs; i++) {
+ free(ptrs[i]);
+ }
+ state.ResumeTiming();
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes) * numAllocs);
+}
+
+void BM_stdlib_malloc_forty_default(benchmark::State& state) {
+
+#if defined(__BIONIC__)
+ // The default is expected to be a zero decay time.
+ mallopt(M_DECAY_TIME, 0);
+#endif
+
+ MallocMultiple(state, state.range(0), 40);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_forty_default, "AT_COMMON_SIZES");
+
+#if defined(__BIONIC__)
+void BM_stdlib_malloc_forty_decay1(benchmark::State& state) {
+ mallopt(M_DECAY_TIME, 1);
+
+ MallocMultiple(state, state.range(0), 40);
+
+ mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_forty_decay1, "AT_COMMON_SIZES");
+#endif
+
+void BM_stdlib_malloc_multiple_8192_allocs_default(benchmark::State& state) {
+#if defined(__BIONIC__)
+ // The default is expected to be a zero decay time.
+ mallopt(M_DECAY_TIME, 0);
+#endif
+
+ MallocMultiple(state, 8192, state.range(0));
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_default, "AT_SMALL_SIZES");
+
+#if defined(__BIONIC__)
+void BM_stdlib_malloc_multiple_8192_allocs_decay1(benchmark::State& state) {
+ mallopt(M_DECAY_TIME, 1);
+
+ MallocMultiple(state, 8192, state.range(0));
+
+ mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_decay1, "AT_SMALL_SIZES");
+#endif
static void BM_stdlib_mbstowcs(benchmark::State& state) {
const size_t buf_alignment = state.range(0);
@@ -167,3 +257,4 @@
}
}
BIONIC_BENCHMARK(BM_stdlib_strtoull);
+
diff --git a/libc/Android.bp b/libc/Android.bp
index 0950662..23ccbe3 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1578,6 +1578,9 @@
"ld-android",
"libdl",
],
+ static_libs: [
+ "libdl_android",
+ ],
whole_static_libs: [
"libjemalloc5",
],
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 3ccaed6..e7147a0 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -54,6 +54,8 @@
#include <stdlib.h>
#include <unistd.h>
+#include <android/dlext.h>
+
#include <private/bionic_config.h>
#include <private/bionic_defs.h>
#include <private/bionic_malloc_dispatch.h>
@@ -277,8 +279,41 @@
return true;
}
+// Note about USE_SCUDO. This file is compiled into libc.so and libc_scudo.so.
+// When compiled into libc_scudo.so, the libc_malloc_* libraries don't need
+// to be loaded from the runtime namespace since libc_scudo.so is not from
+// the runtime APEX, but is copied to any APEX that needs it.
+#ifndef USE_SCUDO
+extern "C" struct android_namespace_t* android_get_exported_namespace(const char* name);
+#endif
+
void* LoadSharedLibrary(const char* shared_lib, const char* prefix, MallocDispatch* dispatch_table) {
- void* impl_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
+ void* impl_handle = nullptr;
+#ifndef USE_SCUDO
+ // Try to load the libc_malloc_* libs from the "runtime" namespace and then
+ // fall back to dlopen() to load them from the default namespace.
+ //
+ // The libraries are packaged in the runtime APEX together with libc.so.
+ // However, since the libc.so is searched via the symlink in the system
+ // partition (/system/lib/libc.so -> /apex/com.android.runtime/bionic.libc.so)
+ // libc.so is loaded into the default namespace. If we just dlopen() here, the
+ // linker will load the libs found in /system/lib which might be incompatible
+ // with libc.so in the runtime APEX. Use android_dlopen_ext to explicitly load
+ // the ones in the runtime APEX.
+ struct android_namespace_t* runtime_ns = android_get_exported_namespace("runtime");
+ if (runtime_ns != nullptr) {
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = runtime_ns,
+ };
+ impl_handle = android_dlopen_ext(shared_lib, RTLD_NOW | RTLD_LOCAL, &dlextinfo);
+ }
+#endif
+
+ if (impl_handle == nullptr) {
+ impl_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
+ }
+
if (impl_handle == nullptr) {
error_log("%s: Unable to open shared library %s: %s", getprogname(), shared_lib, dlerror());
return nullptr;
diff --git a/libdl/Android.bp b/libdl/Android.bp
index a41aa2d..b1ee5ab 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -114,6 +114,7 @@
name: "libdl_android",
defaults: ["linux_bionic_supported"],
+ recovery_available: true,
// NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
// libgcc.a are made static to libdl.so. This in turn ensures that libraries that
diff --git a/tools/update_seccomp.sh b/tools/update_seccomp.sh
deleted file mode 100755
index b9e53aa..0000000
--- a/tools/update_seccomp.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-cd $DIR/..
-./libc/tools/genseccomp.py
-
-git diff --exit-code HEAD libc/seccomp/
-exit $?