Merge "Revert "Revert "Add benchmarks that run simple programs"""
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index f2ab32a..70f7bab 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -28,6 +28,7 @@
     srcs: [
         "bionic_benchmarks.cpp",
         "atomic_benchmark.cpp",
+        "ctype_benchmark.cpp",
         "get_heap_size_benchmark.cpp",
         "inttypes_benchmark.cpp",
         "malloc_benchmark.cpp",
diff --git a/benchmarks/ctype_benchmark.cpp b/benchmarks/ctype_benchmark.cpp
new file mode 100644
index 0000000..3c7f48d
--- /dev/null
+++ b/benchmarks/ctype_benchmark.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <ctype.h>
+
+#include <benchmark/benchmark.h>
+#include "util.h"
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_tolower_y, tolower('X'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_tolower_n, tolower('x'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_toupper_y, toupper('x'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_toupper_n, toupper('X'));
diff --git a/benchmarks/inttypes_benchmark.cpp b/benchmarks/inttypes_benchmark.cpp
index f123eb8..b96384e 100644
--- a/benchmarks/inttypes_benchmark.cpp
+++ b/benchmarks/inttypes_benchmark.cpp
@@ -19,16 +19,5 @@
 #include <benchmark/benchmark.h>
 #include "util.h"
 
-void BM_inttypes_strtoimax(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    strtoimax(" -123", nullptr, 0);
-  }
-}
-BIONIC_BENCHMARK(BM_inttypes_strtoimax);
-
-void BM_inttypes_strtoumax(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    strtoumax(" -123", nullptr, 0);
-  }
-}
-BIONIC_BENCHMARK(BM_inttypes_strtoumax);
+BIONIC_TRIVIAL_BENCHMARK(BM_inttypes_strtoimax, strtoimax(" -123", nullptr, 0));
+BIONIC_TRIVIAL_BENCHMARK(BM_inttypes_strtoumax, strtoumax(" -123", nullptr, 0));
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index 6afe7aa..ec3f6f2 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -216,45 +216,9 @@
 }
 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc, "0");
 
-void BM_stdlib_atoi(benchmark::State& state) {
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(atoi(" -123"));
-  }
-}
-BIONIC_BENCHMARK(BM_stdlib_atoi);
-
-void BM_stdlib_atol(benchmark::State& state) {
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(atol(" -123"));
-  }
-}
-BIONIC_BENCHMARK(BM_stdlib_atol);
-
-void BM_stdlib_strtol(benchmark::State& state) {
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(strtol(" -123", nullptr, 0));
-  }
-}
-BIONIC_BENCHMARK(BM_stdlib_strtol);
-
-void BM_stdlib_strtoll(benchmark::State& state) {
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(strtoll(" -123", nullptr, 0));
-  }
-}
-BIONIC_BENCHMARK(BM_stdlib_strtoll);
-
-void BM_stdlib_strtoul(benchmark::State& state) {
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(strtoul(" -123", nullptr, 0));
-  }
-}
-BIONIC_BENCHMARK(BM_stdlib_strtoul);
-
-void BM_stdlib_strtoull(benchmark::State& state) {
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(strtoull(" -123", nullptr, 0));
-  }
-}
-BIONIC_BENCHMARK(BM_stdlib_strtoull);
-
+BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_atoi, atoi(" -123"));
+BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_atol, atol(" -123"));
+BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_strtol, strtol(" -123", nullptr, 0));
+BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_strtoll, strtoll(" -123", nullptr, 0));
+BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_strtoul, strtoul(" -123", nullptr, 0));
+BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_strtoull, strtoull(" -123", nullptr, 0));
diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp
index 98e8858..d697dfd 100644
--- a/benchmarks/unistd_benchmark.cpp
+++ b/benchmarks/unistd_benchmark.cpp
@@ -20,37 +20,11 @@
 #include <benchmark/benchmark.h>
 #include "util.h"
 
-static void BM_unistd_getpid(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    getpid();
-  }
-}
-BIONIC_BENCHMARK(BM_unistd_getpid);
+BIONIC_TRIVIAL_BENCHMARK(BM_unistd_getpid, getpid());
+BIONIC_TRIVIAL_BENCHMARK(BM_unistd_getpid_syscall, syscall(__NR_getpid));
 
-static void BM_unistd_getpid_syscall(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    syscall(__NR_getpid);
-  }
-}
-BIONIC_BENCHMARK(BM_unistd_getpid_syscall);
-
+// TODO: glibc 2.30 added gettid() too.
 #if defined(__BIONIC__)
-
-// Stop GCC optimizing out our pure function.
-/* Must not be static! */ pid_t (*gettid_fp)() = gettid;
-
-static void BM_unistd_gettid(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    gettid_fp();
-  }
-}
-BIONIC_BENCHMARK(BM_unistd_gettid);
-
+BIONIC_TRIVIAL_BENCHMARK(BM_unistd_gettid, gettid());
 #endif
-
-void BM_unistd_gettid_syscall(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    syscall(__NR_gettid);
-  }
-}
-BIONIC_BENCHMARK(BM_unistd_gettid_syscall);
+BIONIC_TRIVIAL_BENCHMARK(BM_unistd_gettid_syscall, syscall(__NR_gettid));
diff --git a/benchmarks/util.h b/benchmarks/util.h
index 0813acc..ef4892d 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -41,6 +41,13 @@
 #define BIONIC_BENCHMARK_WITH_ARG(n, arg) \
   int _bionic_benchmark_##n __attribute__((unused)) = EmplaceBenchmark(std::string(#n), reinterpret_cast<benchmark_func_t>(n), arg)
 
+#define BIONIC_TRIVIAL_BENCHMARK(__name, __expression) \
+  static void __name(benchmark::State& state) { \
+    for (auto _ : state) { \
+      benchmark::DoNotOptimize(__expression); \
+    } \
+  } \
+  BIONIC_BENCHMARK(__name)
 
 constexpr auto KB = 1024;
 
diff --git a/benchmarks/wctype_benchmark.cpp b/benchmarks/wctype_benchmark.cpp
index f030ddc..cdf5568 100644
--- a/benchmarks/wctype_benchmark.cpp
+++ b/benchmarks/wctype_benchmark.cpp
@@ -19,58 +19,14 @@
 #include <benchmark/benchmark.h>
 #include "util.h"
 
-static void BM_wctype_towlower_ascii_y(benchmark::State& state) {
-  for (auto _ : state) {
-    towlower('X');
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towlower_ascii_y);
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towlower_ascii_y, towlower('X'));
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towlower_ascii_n, towlower('x'));
 
-static void BM_wctype_towlower_ascii_n(benchmark::State& state) {
-  for (auto _ : state) {
-    towlower('x');
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towlower_ascii_n);
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towlower_unicode_y, towlower(0x0391));
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towlower_unicode_n, towlower(0x03b1));
 
-static void BM_wctype_towlower_unicode_y(benchmark::State& state) {
-  for (auto _ : state) {
-    towlower(0x0391);
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towlower_unicode_y);
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towupper_ascii_y, towupper('x'));
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towupper_ascii_n, towupper('X'));
 
-static void BM_wctype_towlower_unicode_n(benchmark::State& state) {
-  for (auto _ : state) {
-    towlower(0x03b1);
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towlower_unicode_n);
-
-static void BM_wctype_towupper_ascii_y(benchmark::State& state) {
-  for (auto _ : state) {
-    towupper('x');
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towupper_ascii_y);
-
-static void BM_wctype_towupper_ascii_n(benchmark::State& state) {
-  for (auto _ : state) {
-    towupper('X');
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towupper_ascii_n);
-
-static void BM_wctype_towupper_unicode_y(benchmark::State& state) {
-  for (auto _ : state) {
-    towupper(0x03b1);
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towupper_unicode_y);
-
-static void BM_wctype_towupper_unicode_n(benchmark::State& state) {
-  for (auto _ : state) {
-    towupper(0x0391);
-  }
-}
-BIONIC_BENCHMARK(BM_wctype_towupper_unicode_n);
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towupper_unicode_y, towupper(0x03b1));
+BIONIC_TRIVIAL_BENCHMARK(BM_wctype_towupper_unicode_n, towupper(0x0391));
diff --git a/libc/Android.bp b/libc/Android.bp
index 4abb32f..9e2e691 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1891,6 +1891,9 @@
         "-Wall",
         "-Werror",
     ],
+    sanitize: {
+        never: true,
+    },
 }
 
 cc_defaults {
diff --git a/libc/bionic/wctype.cpp b/libc/bionic/wctype.cpp
index 6e33b6c..061f55a 100644
--- a/libc/bionic/wctype.cpp
+++ b/libc/bionic/wctype.cpp
@@ -117,12 +117,22 @@
 }
 
 wint_t towlower(wint_t wc) {
+  if (wc < 0x80) {
+    if (wc >= 'A' && wc <= 'Z') return wc | 0x20;
+    return wc;
+  }
+
   typedef UChar32 (*FnT)(UChar32);
   static auto u_tolower = reinterpret_cast<FnT>(__find_icu_symbol("u_tolower"));
   return u_tolower ? u_tolower(wc) : tolower(wc);
 }
 
 wint_t towupper(wint_t wc) {
+  if (wc < 0x80) {
+    if (wc >= 'a' && wc <= 'z') return wc & 0xdf;
+    return wc;
+  }
+
   typedef UChar32 (*FnT)(UChar32);
   static auto u_toupper = reinterpret_cast<FnT>(__find_icu_symbol("u_toupper"));
   return u_toupper ? u_toupper(wc) : toupper(wc);
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index d863e20..60fb698 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -8,7 +8,6 @@
 import commands
 import filecmp
 import glob
-import os.path
 import re
 import shutil
 import stat
@@ -19,8 +18,6 @@
 
 SupportedArchitectures = [ "arm", "arm64", "mips", "mips64", "x86", "x86_64" ]
 
-bionic_libc = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
-
 syscall_stub_header = \
 """
 ENTRY(%(func)s)
@@ -489,9 +486,9 @@
             self.parse_open_file(fp)
 
 
-def main(arch):
+def main(arch, syscall_file):
     parser = SysCallsTxtParser()
-    parser.parse_file(os.path.join(bionic_libc, "SYSCALLS.TXT"))
+    parser.parse_file(syscall_file)
 
     for syscall in parser.syscalls:
         syscall["__NR_name"] = make__NR_name(syscall["name"])
@@ -528,4 +525,10 @@
 
 
 if __name__ == "__main__":
-    main(sys.argv[1])
+    if len(sys.argv) < 2:
+      print "Usage: gensyscalls.py ARCH SOURCE_FILE"
+      sys.exit(1)
+
+    arch = sys.argv[1]
+    syscall_file = sys.argv[2]
+    main(arch, syscall_file)