Merge "ART: Use timeout --foreground"
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index d8014bd..be1791b 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -133,6 +133,7 @@
     LOCAL_MODULE_PATH := $(3)
     LOCAL_DEX_PREOPT_IMAGE_LOCATION := $(TARGET_CORE_IMG_OUT)
     ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
+      LOCAL_MIN_SDK_VERSION := 19
       LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(LOCAL_PATH)/$(2)/main.list --minimal-main-dex
     endif
     include $(BUILD_JAVA_LIBRARY)
@@ -148,6 +149,7 @@
     LOCAL_JAVA_LIBRARIES := $(HOST_TEST_CORE_JARS)
     LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_LOCATION)
     ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
+      LOCAL_MIN_SDK_VERSION := 19
       LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(LOCAL_PATH)/$(2)/main.list --minimal-main-dex
     endif
     include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
diff --git a/cmdline/cmdline_parser.h b/cmdline/cmdline_parser.h
index 82c04e7..952be44 100644
--- a/cmdline/cmdline_parser.h
+++ b/cmdline/cmdline_parser.h
@@ -206,7 +206,7 @@
       };
       load_value_ = []() -> TArg& {
         assert(false && "Should not be appending values to ignored arguments");
-        return *reinterpret_cast<TArg*>(0);  // Blow up.
+        __builtin_trap();  // Blow up.
       };
 
       save_value_specified_ = true;
@@ -270,7 +270,7 @@
 
       load_value_ = []() -> TArg& {
         assert(false && "No load value function defined");
-        return *reinterpret_cast<TArg*>(0);  // Blow up.
+        __builtin_trap();  // Blow up.
       };
     }
 
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 872fab3..0b2c0b6 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -601,8 +601,7 @@
         Fatal(StringPrintf("dex2oat did not finish after %" PRId64 " seconds",
                            timeout_in_milliseconds_/1000));
       } else if (rc != 0) {
-        std::string message(StringPrintf("pthread_cond_timedwait failed: %s",
-                                         strerror(errno)));
+        std::string message(StringPrintf("pthread_cond_timedwait failed: %s", strerror(rc)));
         Fatal(message.c_str());
       }
     }
diff --git a/dexdump/Android.bp b/dexdump/Android.bp
index d15bbda..434cb35 100644
--- a/dexdump/Android.bp
+++ b/dexdump/Android.bp
@@ -49,6 +49,9 @@
         darwin: {
             enabled: false,
         },
+        windows: {
+            enabled: true,
+        },
     },
 }
 
diff --git a/libartbase/Android.bp b/libartbase/Android.bp
index c3fb5fd..0fcd6a5 100644
--- a/libartbase/Android.bp
+++ b/libartbase/Android.bp
@@ -35,7 +35,6 @@
         "base/memory_region.cc",
         "base/mem_map.cc",
         // "base/mem_map_fuchsia.cc", put in target when fuchsia supported by soong
-        "base/mem_map_unix.cc",
         "base/os_linux.cc",
         "base/runtime_debug.cc",
         "base/safe_copy.cc",
@@ -50,20 +49,38 @@
     ],
     target: {
         android: {
+            srcs: [
+                "base/mem_map_unix.cc",
+            ],
             static_libs: [
                 // ZipArchive support, the order matters here to get all symbols.
                 "libziparchive",
                 "libz",
             ],
+            shared_libs: [
+                "liblog",
+                // For ashmem.
+                "libcutils",
+                // For common macros.
+                "libbase",
+            ],
             // Exclude the version script from Darwin host since it's not
             // supported by the linker there. That means ASan checks on Darwin
             // might trigger ODR violations.
             version_script: "libartbase.map",
         },
-        host: {
+        not_windows: {
+            srcs: [
+                "base/mem_map_unix.cc",
+            ],
             shared_libs: [
                 "libziparchive",
                 "libz",
+                "liblog",
+                // For ashmem.
+                "libcutils",
+                // For common macros.
+                "libbase",
             ],
         },
         linux_glibc: {
@@ -71,17 +88,20 @@
         },
         windows: {
             version_script: "libartbase.map",
+            static_libs: [
+                "libziparchive",
+                "libz",
+                "liblog",
+                // For ashmem.
+                "libcutils",
+                // For common macros.
+                "libbase",
+            ],
+            cflags: ["-Wno-thread-safety"],
         },
     },
     generated_sources: ["art_libartbase_operator_srcs"],
     cflags: ["-DBUILDING_LIBART=1"],
-    shared_libs: [
-        "liblog",
-        // For ashmem.
-        "libcutils",
-        // For common macros.
-        "libbase",
-    ],
 
     // Utilities used by various ART libs and tools are linked in statically
     // here to avoid shared lib dependencies outside the ART APEX. No target
@@ -147,6 +167,14 @@
         "libziparchive",
     ],
     export_shared_lib_headers: ["libbase"],
+    target: {
+        windows: {
+            enabled: true,
+            shared: {
+                enabled: false,
+            },
+        },
+    },
 }
 
 art_cc_library {
@@ -160,6 +188,14 @@
         "libziparchive",
     ],
     export_shared_lib_headers: ["libbase"],
+    target: {
+        windows: {
+            enabled: true,
+            shared: {
+                enabled: false,
+            },
+        },
+    },
 }
 
 art_cc_library {
diff --git a/libartbase/base/arena_allocator.cc b/libartbase/base/arena_allocator.cc
index df3deba..0e7f6cc 100644
--- a/libartbase/base/arena_allocator.cc
+++ b/libartbase/base/arena_allocator.cc
@@ -16,7 +16,6 @@
 
 #include "arena_allocator-inl.h"
 
-#include <sys/mman.h>
 
 #include <algorithm>
 #include <cstddef>
@@ -25,6 +24,8 @@
 
 #include <android-base/logging.h>
 
+#include "mman.h"
+
 namespace art {
 
 constexpr size_t kMemoryToolRedZoneBytes = 8;
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc
index f8d6016..9490798 100644
--- a/libartbase/base/file_utils.cc
+++ b/libartbase/base/file_utils.cc
@@ -19,11 +19,13 @@
 #include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#ifndef _WIN32
 #include <sys/wait.h>
+#endif
 #include <unistd.h>
 
 // We need dladdr.
-#ifndef __APPLE__
+#if !defined(__APPLE__) && !defined(_WIN32)
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #define DEFINED_GNU_SOURCE
@@ -84,6 +86,10 @@
 }
 
 std::string GetAndroidRootSafe(std::string* error_msg) {
+#ifdef _WIN32
+  *error_msg = "GetAndroidRootSafe unsupported for Windows.";
+  return "";
+#else
   // Prefer ANDROID_ROOT if it's set.
   const char* android_dir = getenv("ANDROID_ROOT");
   if (android_dir != nullptr) {
@@ -118,6 +124,7 @@
     return "";
   }
   return "/system";
+#endif
 }
 
 std::string GetAndroidRoot() {
@@ -179,6 +186,15 @@
 
 void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache,
                     bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) {
+#ifdef _WIN32
+  UNUSED(subdir);
+  UNUSED(create_if_absent);
+  UNUSED(dalvik_cache);
+  UNUSED(have_android_data);
+  UNUSED(dalvik_cache_exists);
+  UNUSED(is_global_cache);
+  LOG(FATAL) << "GetDalvikCache unsupported on Windows.";
+#else
   CHECK(subdir != nullptr);
   std::string error_msg;
   const char* android_data = GetAndroidDataSafe(&error_msg);
@@ -199,6 +215,7 @@
     *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) &&
                             (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST));
   }
+#endif
 }
 
 std::string GetDalvikCache(const char* subdir) {
@@ -262,9 +279,15 @@
 }
 
 bool LocationIsOnSystem(const char* path) {
+#ifdef _WIN32
+  UNUSED(path);
+  LOG(FATAL) << "LocationIsOnSystem is unsupported on Windows.";
+  return false;
+#else
   UniqueCPtr<const char[]> full_path(realpath(path, nullptr));
   return full_path != nullptr &&
       android::base::StartsWith(full_path.get(), GetAndroidRoot().c_str());
+#endif
 }
 
 bool LocationIsOnSystemFramework(const char* full_path) {
diff --git a/libartbase/base/malloc_arena_pool.cc b/libartbase/base/malloc_arena_pool.cc
index 02e29f1..4de34b5 100644
--- a/libartbase/base/malloc_arena_pool.cc
+++ b/libartbase/base/malloc_arena_pool.cc
@@ -16,7 +16,6 @@
 
 #include "malloc_arena_pool.h"
 
-#include <sys/mman.h>
 
 #include <algorithm>
 #include <cstddef>
@@ -25,6 +24,7 @@
 
 #include <android-base/logging.h>
 #include "arena_allocator-inl.h"
+#include "mman.h"
 
 namespace art {
 
diff --git a/libartbase/base/mem_map.cc b/libartbase/base/mem_map.cc
index 532ca28..2833750 100644
--- a/libartbase/base/mem_map.cc
+++ b/libartbase/base/mem_map.cc
@@ -18,8 +18,7 @@
 
 #include <inttypes.h>
 #include <stdlib.h>
-#include <sys/mman.h>  // For the PROT_* and MAP_* constants.
-#if !defined(ANDROID_OS) && !defined(__Fuchsia__)
+#if !defined(ANDROID_OS) && !defined(__Fuchsia__) && !defined(_WIN32)
 #include <sys/resource.h>
 #endif
 
@@ -39,6 +38,7 @@
 #include "globals.h"
 #include "logging.h"  // For VLOG_IS_ON.
 #include "memory_tool.h"
+#include "mman.h"  // For the PROT_* and MAP_* constants.
 #include "utils.h"
 
 #ifndef MAP_ANONYMOUS
@@ -811,19 +811,30 @@
     if (!kMadviseZeroes) {
       memset(base_begin_, 0, base_size_);
     }
+#ifdef _WIN32
+    // It is benign not to madvise away the pages here.
+    PLOG(WARNING) << "MemMap::MadviseDontNeedAndZero does not madvise on Windows.";
+#else
     int result = madvise(base_begin_, base_size_, MADV_DONTNEED);
     if (result == -1) {
       PLOG(WARNING) << "madvise failed";
     }
+#endif
   }
 }
 
 bool MemMap::Sync() {
+#ifdef _WIN32
+  // TODO: add FlushViewOfFile support.
+  PLOG(ERROR) << "MemMap::Sync unsupported on Windows.";
+  return false;
+#else
   // Historical note: To avoid Valgrind errors, we temporarily lifted the lower-end noaccess
   // protection before passing it to msync() when `redzone_size_` was non-null, as Valgrind
   // only accepts page-aligned base address, and excludes the higher-end noaccess protection
   // from the msync range. b/27552451.
   return msync(BaseBegin(), BaseSize(), MS_SYNC) == 0;
+#endif
 }
 
 bool MemMap::Protect(int prot) {
@@ -832,10 +843,12 @@
     return true;
   }
 
+#ifndef _WIN32
   if (mprotect(base_begin_, base_size_, prot) == 0) {
     prot_ = prot;
     return true;
   }
+#endif
 
   PLOG(ERROR) << "mprotect(" << reinterpret_cast<void*>(base_begin_) << ", " << base_size_ << ", "
               << prot << ") failed";
@@ -1206,7 +1219,11 @@
     DCHECK_LE(page_begin, page_end);
     DCHECK_LE(page_end, mem_end);
     std::fill(mem_begin, page_begin, 0);
+#ifdef _WIN32
+    LOG(WARNING) << "ZeroAndReleasePages does not madvise on Windows.";
+#else
     CHECK_NE(madvise(page_begin, page_end - page_begin, MADV_DONTNEED), -1) << "madvise failed";
+#endif
     std::fill(page_end, mem_end, 0);
   }
 }
diff --git a/libartbase/base/mem_map_fuchsia.cc b/libartbase/base/mem_map_fuchsia.cc
index d1c92ce..6b0e06c 100644
--- a/libartbase/base/mem_map_fuchsia.cc
+++ b/libartbase/base/mem_map_fuchsia.cc
@@ -15,8 +15,8 @@
  */
 
 #include "mem_map.h"
-#include <sys/mman.h>
 #include "logging.h"
+#include "mman.h"
 
 #include <zircon/process.h>
 #include <zircon/syscalls.h>
diff --git a/libartbase/base/mem_map_test.cc b/libartbase/base/mem_map_test.cc
index 074d4c2..bf39fd1 100644
--- a/libartbase/base/mem_map_test.cc
+++ b/libartbase/base/mem_map_test.cc
@@ -16,8 +16,6 @@
 
 #include "mem_map.h"
 
-#include <sys/mman.h>
-
 #include <memory>
 #include <random>
 
@@ -25,6 +23,7 @@
 #include "common_runtime_test.h"  // For TEST_DISABLED_FOR_MIPS
 #include "logging.h"
 #include "memory_tool.h"
+#include "mman.h"
 #include "unix_file/fd_file.h"
 
 namespace art {
diff --git a/libartbase/base/mem_map_unix.cc b/libartbase/base/mem_map_unix.cc
index 601b049..ac854df 100644
--- a/libartbase/base/mem_map_unix.cc
+++ b/libartbase/base/mem_map_unix.cc
@@ -16,7 +16,7 @@
 
 #include "mem_map.h"
 
-#include <sys/mman.h>
+#include "mman.h"
 
 namespace art {
 
diff --git a/libartbase/base/membarrier.cc b/libartbase/base/membarrier.cc
index 4c86b6b..abb36bc 100644
--- a/libartbase/base/membarrier.cc
+++ b/libartbase/base/membarrier.cc
@@ -18,8 +18,10 @@
 
 #include <errno.h>
 
+#if !defined(_WIN32)
 #include <sys/syscall.h>
 #include <unistd.h>
+#endif
 #include "macros.h"
 
 #if defined(__BIONIC__)
diff --git a/libartbase/base/memfd.cc b/libartbase/base/memfd.cc
index 7c20401..780be32 100644
--- a/libartbase/base/memfd.cc
+++ b/libartbase/base/memfd.cc
@@ -18,9 +18,11 @@
 
 #include <errno.h>
 #include <stdio.h>
+#if !defined(_WIN32)
 #include <sys/syscall.h>
 #include <sys/utsname.h>
 #include <unistd.h>
+#endif
 
 #include "macros.h"
 
diff --git a/libartbase/base/mman.h b/libartbase/base/mman.h
new file mode 100644
index 0000000..bd63f65
--- /dev/null
+++ b/libartbase/base/mman.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 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_MMAN_H_
+#define ART_LIBARTBASE_BASE_MMAN_H_
+
+#ifdef _WIN32
+
+// There is no sys/mman.h in mingw.
+// As these are just placeholders for the APIs, all values are stubbed out.
+
+#define PROT_READ      0        // 0x1
+#define PROT_WRITE     0        // 0x2
+#define PROT_EXEC      0        // 0x4
+#define PROT_NONE      0        // 0x0
+
+#define MAP_SHARED     0        // 0x01
+#define MAP_PRIVATE    0        // 0x02
+
+#define MAP_FAILED     nullptr  // ((void*) -1)
+#define MAP_FIXED      0        // 0x10
+#define MAP_ANONYMOUS  0        // 0x20
+
+#else
+
+#include <sys/mman.h>
+
+#endif
+
+
+#endif  // ART_LIBARTBASE_BASE_MMAN_H_
diff --git a/libartbase/base/os_linux.cc b/libartbase/base/os_linux.cc
index f8b31cf..a00779e 100644
--- a/libartbase/base/os_linux.cc
+++ b/libartbase/base/os_linux.cc
@@ -50,7 +50,12 @@
 }
 
 File* OS::CreateEmptyFileWriteOnly(const char* name) {
-  return art::CreateEmptyFile(name, O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC);
+#ifdef _WIN32
+  int flags = O_WRONLY | O_TRUNC;
+#else
+  int flags = O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC;
+#endif
+  return art::CreateEmptyFile(name, flags);
 }
 
 File* OS::OpenFileWithFlags(const char* name, int flags, bool auto_flush) {
diff --git a/libartbase/base/safe_copy.cc b/libartbase/base/safe_copy.cc
index b46b921..ad75aa7 100644
--- a/libartbase/base/safe_copy.cc
+++ b/libartbase/base/safe_copy.cc
@@ -16,8 +16,10 @@
 
 #include "safe_copy.h"
 
+#ifdef __linux__
 #include <sys/uio.h>
 #include <sys/user.h>
+#endif
 #include <unistd.h>
 
 #include <algorithm>
diff --git a/libartbase/base/safe_copy_test.cc b/libartbase/base/safe_copy_test.cc
index c23651f..9f7d409 100644
--- a/libartbase/base/safe_copy_test.cc
+++ b/libartbase/base/safe_copy_test.cc
@@ -18,12 +18,12 @@
 
 #include <errno.h>
 #include <string.h>
-#include <sys/mman.h>
 #include <sys/user.h>
 
 #include "android-base/logging.h"
 #include "globals.h"
 #include "gtest/gtest.h"
+#include "mman.h"
 
 
 namespace art {
diff --git a/libartbase/base/scoped_flock.cc b/libartbase/base/scoped_flock.cc
index 2f16fb2..b16a45a 100644
--- a/libartbase/base/scoped_flock.cc
+++ b/libartbase/base/scoped_flock.cc
@@ -35,6 +35,14 @@
 
 /* static */ ScopedFlock LockedFile::Open(const char* filename, int flags, bool block,
                                           std::string* error_msg) {
+#ifdef _WIN32
+  // TODO: implement file locking for Windows.
+  UNUSED(filename);
+  UNUSED(flags);
+  UNUSED(block);
+  *error_msg = "flock is unsupported on Windows";
+  return nullptr;
+#else
   while (true) {
     // NOTE: We don't check usage here because the ScopedFlock should *never* be
     // responsible for flushing its underlying FD. Its only purpose should be
@@ -89,10 +97,19 @@
 
     return ScopedFlock(new LockedFile(std::move((*file.get()))));
   }
+#endif
 }
 
 ScopedFlock LockedFile::DupOf(const int fd, const std::string& path,
                               const bool read_only_mode, std::string* error_msg) {
+#ifdef _WIN32
+  // TODO: implement file locking for Windows.
+  UNUSED(fd);
+  UNUSED(path);
+  UNUSED(read_only_mode);
+  *error_msg = "flock is unsupported on Windows.";
+  return nullptr;
+#else
   // NOTE: We don't check usage here because the ScopedFlock should *never* be
   // responsible for flushing its underlying FD. Its only purpose should be
   // to acquire a lock, and the unlock / close in the corresponding
@@ -112,9 +129,11 @@
   }
 
   return locked_file;
+#endif
 }
 
 void LockedFile::ReleaseLock() {
+#ifndef _WIN32
   if (this->Fd() != -1) {
     int flock_result = TEMP_FAILURE_RETRY(flock(this->Fd(), LOCK_UN));
     if (flock_result != 0) {
@@ -126,6 +145,7 @@
       PLOG(WARNING) << "Unable to unlock file " << this->GetPath();
     }
   }
+#endif
 }
 
 }  // namespace art
diff --git a/libartbase/base/socket_peer_is_trusted.cc b/libartbase/base/socket_peer_is_trusted.cc
index 440054e..3996d90 100644
--- a/libartbase/base/socket_peer_is_trusted.cc
+++ b/libartbase/base/socket_peer_is_trusted.cc
@@ -16,8 +16,10 @@
 
 #include "socket_peer_is_trusted.h"
 
+#if !defined(_WIN32)
 #include <pwd.h>
 #include <sys/socket.h>
+#endif
 
 #include <android-base/logging.h>
 
diff --git a/libartbase/base/time_utils.cc b/libartbase/base/time_utils.cc
index cb30246..aa6c987 100644
--- a/libartbase/base/time_utils.cc
+++ b/libartbase/base/time_utils.cc
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
+#include "time_utils.h"
+
 #include <inttypes.h>
+#include <stdio.h>
+
 #include <limits>
 #include <sstream>
 
-#include "time_utils.h"
-
 #include "android-base/stringprintf.h"
 
 #include "logging.h"
@@ -30,6 +32,20 @@
 
 namespace art {
 
+namespace {
+
+#if !defined(__linux__)
+int GetTimeOfDay(struct timeval* tv, struct timezone* tz) {
+#ifdef _WIN32
+  return mingw_gettimeofday(tv, tz);
+#else
+  return gettimeofday(tv, tz);
+#endif
+}
+#endif
+
+}  // namespace
+
 using android::base::StringPrintf;
 
 std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits) {
@@ -117,7 +133,12 @@
 std::string GetIsoDate() {
   time_t now = time(nullptr);
   tm tmbuf;
+#ifdef _WIN32
+  localtime_s(&tmbuf, &now);
+  tm* ptm = &tmbuf;
+#else
   tm* ptm = localtime_r(&now, &tmbuf);
+#endif
   return StringPrintf("%04d-%02d-%02d %02d:%02d:%02d",
       ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday,
       ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
@@ -130,7 +151,7 @@
   return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_nsec / UINT64_C(1000000);
 #else
   timeval now;
-  gettimeofday(&now, nullptr);
+  GetTimeOfDay(&now, nullptr);
   return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_usec / UINT64_C(1000);
 #endif
 }
@@ -142,7 +163,7 @@
   return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_nsec / UINT64_C(1000);
 #else
   timeval now;
-  gettimeofday(&now, nullptr);
+  GetTimeOfDay(&now, nullptr);
   return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_usec;
 #endif
 }
@@ -154,7 +175,7 @@
   return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
 #else
   timeval now;
-  gettimeofday(&now, nullptr);
+  GetTimeOfDay(&now, nullptr);
   return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_usec * UINT64_C(1000);
 #endif
 }
@@ -195,12 +216,12 @@
 
 void InitTimeSpec(bool absolute, int clock, int64_t ms, int32_t ns, timespec* ts) {
   if (absolute) {
-#if !defined(__APPLE__)
+#if defined(__linux__)
     clock_gettime(clock, ts);
 #else
     UNUSED(clock);
     timeval tv;
-    gettimeofday(&tv, nullptr);
+    GetTimeOfDay(&tv, nullptr);
     ts->tv_sec = tv.tv_sec;
     ts->tv_nsec = tv.tv_usec * 1000;
 #endif
diff --git a/libartbase/base/time_utils.h b/libartbase/base/time_utils.h
index 431d3e1..15805f3 100644
--- a/libartbase/base/time_utils.h
+++ b/libartbase/base/time_utils.h
@@ -18,6 +18,7 @@
 #define ART_LIBARTBASE_BASE_TIME_UTILS_H_
 
 #include <stdint.h>
+#include <stdio.h>  // Needed for correct _WIN32 build.
 #include <time.h>
 
 #include <string>
diff --git a/libartbase/base/unix_file/fd_file.cc b/libartbase/base/unix_file/fd_file.cc
index 76894c6..8831b9c 100644
--- a/libartbase/base/unix_file/fd_file.cc
+++ b/libartbase/base/unix_file/fd_file.cc
@@ -25,8 +25,13 @@
 #include <android/fdsan.h>
 #endif
 
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
 #include <limits>
 
+#include <android-base/file.h>
 #include <android-base/logging.h>
 
 // Includes needed for FdFile::Copy().
@@ -40,6 +45,96 @@
 
 namespace unix_file {
 
+#if defined(_WIN32)
+// RAII wrapper for an event object to allow asynchronous I/O to correctly signal completion.
+class ScopedEvent {
+ public:
+  ScopedEvent() {
+    handle_ = CreateEventA(/*lpEventAttributes*/ nullptr,
+                           /*bManualReset*/ true,
+                           /*bInitialState*/ false,
+                           /*lpName*/ nullptr);
+  }
+
+  ~ScopedEvent() { CloseHandle(handle_); }
+
+  HANDLE handle() { return handle_; }
+
+ private:
+  HANDLE handle_;
+  DISALLOW_COPY_AND_ASSIGN(ScopedEvent);
+};
+
+// Windows implementation of pread/pwrite. Note that these DO move the file descriptor's read/write
+// position, but do so atomically.
+static ssize_t pread(int fd, void* data, size_t byte_count, off64_t offset) {
+  ScopedEvent event;
+  if (event.handle() == INVALID_HANDLE_VALUE) {
+    PLOG(ERROR) << "Could not create event handle.";
+    errno = EIO;
+    return static_cast<ssize_t>(-1);
+  }
+
+  auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
+  DWORD bytes_read = 0;
+  OVERLAPPED overlapped = {};
+  overlapped.Offset = static_cast<DWORD>(offset);
+  overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
+  overlapped.hEvent = event.handle();
+  if (!ReadFile(handle, data, static_cast<DWORD>(byte_count), &bytes_read, &overlapped)) {
+    // If the read failed with other than ERROR_IO_PENDING, return an error.
+    // ERROR_IO_PENDING signals the write was begun asynchronously.
+    // Block until the asynchronous operation has finished or fails, and return
+    // result accordingly.
+    if (::GetLastError() != ERROR_IO_PENDING ||
+        !::GetOverlappedResult(handle, &overlapped, &bytes_read, TRUE)) {
+      // In case someone tries to read errno (since this is masquerading as a POSIX call).
+      errno = EIO;
+      return static_cast<ssize_t>(-1);
+    }
+  }
+  return static_cast<ssize_t>(bytes_read);
+}
+
+static ssize_t pwrite(int fd, const void* buf, size_t count, off64_t offset) {
+  ScopedEvent event;
+  if (event.handle() == INVALID_HANDLE_VALUE) {
+    PLOG(ERROR) << "Could not create event handle.";
+    errno = EIO;
+    return static_cast<ssize_t>(-1);
+  }
+
+  auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
+  DWORD bytes_written = 0;
+  OVERLAPPED overlapped = {};
+  overlapped.Offset = static_cast<DWORD>(offset);
+  overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
+  overlapped.hEvent = event.handle();
+  if (!::WriteFile(handle, buf, count, &bytes_written, &overlapped)) {
+    // If the write failed with other than ERROR_IO_PENDING, return an error.
+    // ERROR_IO_PENDING signals the write was begun asynchronously.
+    // Block until the asynchronous operation has finished or fails, and return
+    // result accordingly.
+    if (::GetLastError() != ERROR_IO_PENDING ||
+        !::GetOverlappedResult(handle, &overlapped, &bytes_written, TRUE)) {
+      // In case someone tries to read errno (since this is masquerading as a POSIX call).
+      errno = EIO;
+      return static_cast<ssize_t>(-1);
+    }
+  }
+  return static_cast<ssize_t>(bytes_written);
+}
+
+static int fsync(int fd) {
+  auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
+  if (handle != INVALID_HANDLE_VALUE && ::FlushFileBuffers(handle)) {
+    return 0;
+  }
+  errno = EINVAL;
+  return -1;
+}
+#endif
+
 #if defined(__BIONIC__)
 static uint64_t GetFdFileOwnerTag(FdFile* fd_file) {
   return android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_ART_FDFILE,
diff --git a/libartbase/base/utils.cc b/libartbase/base/utils.cc
index 0f172fd..58d8575 100644
--- a/libartbase/base/utils.cc
+++ b/libartbase/base/utils.cc
@@ -19,9 +19,7 @@
 #include <inttypes.h>
 #include <pthread.h>
 #include <sys/stat.h>
-#include <sys/syscall.h>
 #include <sys/types.h>
-#include <sys/wait.h>
 #include <unistd.h>
 
 #include <fstream>
@@ -47,6 +45,16 @@
 
 #if defined(__linux__)
 #include <linux/unistd.h>
+#include <sys/syscall.h>
+#endif
+
+#if defined(_WIN32)
+#include <windows.h>
+// This include needs to be here due to our coding conventions.  Unfortunately
+// it drags in the definition of the dread ERROR macro.
+#ifdef ERROR
+#undef ERROR
+#endif
 #endif
 
 namespace art {
@@ -61,6 +69,8 @@
   return owner;
 #elif defined(__BIONIC__)
   return gettid();
+#elif defined(_WIN32)
+  return static_cast<pid_t>(::GetCurrentThreadId());
 #else
   return syscall(__NR_gettid);
 #endif
@@ -68,12 +78,17 @@
 
 std::string GetThreadName(pid_t tid) {
   std::string result;
+#ifdef _WIN32
+  UNUSED(tid);
+  result = "<unknown>";
+#else
   // TODO: make this less Linux-specific.
   if (ReadFileToString(StringPrintf("/proc/self/task/%d/comm", tid), &result)) {
     result.resize(result.size() - 1);  // Lose the trailing '\n'.
   } else {
     result = "<unknown>";
   }
+#endif
   return result;
 }
 
@@ -137,7 +152,7 @@
   } else {
     s = thread_name + len - 15;
   }
-#if defined(__linux__)
+#if defined(__linux__) || defined(_WIN32)
   // pthread_setname_np fails rather than truncating long strings.
   char buf[16];       // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
   strncpy(buf, s, sizeof(buf)-1);
@@ -153,6 +168,11 @@
 
 void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) {
   *utime = *stime = *task_cpu = 0;
+#ifdef _WIN32
+  // TODO: implement this.
+  UNUSED(tid);
+  *state = 'S';
+#else
   std::string stats;
   // TODO: make this less Linux-specific.
   if (!ReadFileToString(StringPrintf("/proc/self/task/%d/stat", tid), &stats)) {
@@ -167,6 +187,7 @@
   *utime = strtoull(fields[11].c_str(), nullptr, 10);
   *stime = strtoull(fields[12].c_str(), nullptr, 10);
   *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
+#endif
 }
 
 static void ParseStringAfterChar(const std::string& s,
diff --git a/libartbase/base/zip_archive.cc b/libartbase/base/zip_archive.cc
index a7f4b28..5056edc 100644
--- a/libartbase/base/zip_archive.cc
+++ b/libartbase/base/zip_archive.cc
@@ -18,7 +18,6 @@
 
 #include <fcntl.h>
 #include <stdio.h>
-#include <sys/mman.h>  // For the PROT_* and MAP_* constants.
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -27,6 +26,7 @@
 #include "android-base/stringprintf.h"
 #include "ziparchive/zip_archive.h"
 
+#include "base/mman.h"
 #include "bit_utils.h"
 #include "unix_file/fd_file.h"
 
@@ -203,6 +203,11 @@
 }
 
 static void SetCloseOnExec(int fd) {
+#ifdef _WIN32
+  // Exec is not supported on Windows.
+  UNUSED(fd);
+  PLOG(ERROR) << "SetCloseOnExec is not supported on Windows.";
+#else
   // This dance is more portable than Linux's O_CLOEXEC open(2) flag.
   int flags = fcntl(fd, F_GETFD);
   if (flags == -1) {
@@ -214,6 +219,7 @@
     PLOG(WARNING) << "fcntl(" << fd << ", F_SETFD, " << flags << ") failed";
     return;
   }
+#endif
 }
 
 ZipArchive* ZipArchive::Open(const char* filename, std::string* error_msg) {
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index 4d6aa5c..a4f7e25 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -43,30 +43,58 @@
                 "libziparchive",
                 "libz",
             ],
+            shared_libs: [
+                 // For MemMap.
+                 "libartbase",
+                 "liblog",
+                 // For atrace.
+                 "libcutils",
+                 // For common macros.
+                 "libbase",
+            ],
+            export_shared_lib_headers: [
+                "libartbase",
+                "libbase",
+            ],
         },
-        host: {
+        not_windows: {
             shared_libs: [
                 "libziparchive",
                 "libz",
+                 // For MemMap.
+                 "libartbase",
+                 "liblog",
+                 // For atrace.
+                 "libcutils",
+                 // For common macros.
+                 "libbase",
             ],
+            export_shared_lib_headers: [
+                "libartbase",
+                "libbase",
+            ],
+        },
+        windows: {
+            static_libs: [
+                "libziparchive",
+                "libz",
+                 // For MemMap.
+                 "libartbase",
+                 "liblog",
+                 // For atrace.
+                 "libcutils",
+                 // For common macros.
+                 "libbase",
+            ],
+            export_static_lib_headers: [
+                "libartbase",
+                "libbase",
+            ],
+            cflags: ["-Wno-thread-safety"],
         },
     },
     generated_sources: ["dexfile_operator_srcs"],
-    shared_libs: [
-        // For MemMap.
-        "libartbase",
-        "liblog",
-        // For atrace.
-        "libcutils",
-        // For common macros.
-        "libbase",
-        "libz",
-    ],
     export_include_dirs: ["."],
-    export_shared_lib_headers: [
-        "libartbase",
-        "libbase",
-    ],
 }
 
 cc_defaults {
@@ -121,6 +149,14 @@
     strip: {
         keep_symbols: true,
     },
+    target: {
+        windows: {
+            enabled: true,
+            shared: {
+                enabled: false,
+            },
+        },
+    },
 }
 
 art_cc_library {
@@ -129,6 +165,14 @@
         "art_debug_defaults",
         "libdexfile_defaults",
     ],
+    target: {
+        windows: {
+            enabled: true,
+            shared: {
+                enabled: false,
+            },
+        },
+    },
 }
 
 cc_library_headers {
diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc
index ae1322d..57e838f 100644
--- a/libdexfile/dex/art_dex_file_loader.cc
+++ b/libdexfile/dex/art_dex_file_loader.cc
@@ -16,7 +16,6 @@
 
 #include "art_dex_file_loader.h"
 
-#include <sys/mman.h>  // For the PROT_* and MAP_* constants.
 #include <sys/stat.h>
 
 #include "android-base/stringprintf.h"
@@ -24,6 +23,7 @@
 #include "base/file_magic.h"
 #include "base/file_utils.h"
 #include "base/mem_map.h"
+#include "base/mman.h"  // For the PROT_* and MAP_* constants.
 #include "base/stl_util.h"
 #include "base/systrace.h"
 #include "base/unix_file/fd_file.h"
diff --git a/libdexfile/dex/dex_file_layout.cc b/libdexfile/dex/dex_file_layout.cc
index 75a3111..929025a 100644
--- a/libdexfile/dex/dex_file_layout.cc
+++ b/libdexfile/dex/dex_file_layout.cc
@@ -16,9 +16,9 @@
 
 #include "dex_file_layout.h"
 
-#include <sys/mman.h>
 
 #include "base/bit_utils.h"
+#include "base/mman.h"
 #include "dex_file.h"
 
 namespace art {
@@ -26,6 +26,12 @@
 int DexLayoutSection::MadviseLargestPageAlignedRegion(const uint8_t* begin,
                                                       const uint8_t* end,
                                                       int advice) {
+#ifdef _WIN32
+  UNUSED(begin);
+  UNUSED(end);
+  UNUSED(advice);
+  PLOG(WARNING) << "madvise is unsupported on Windows.";
+#else
   DCHECK_LE(begin, end);
   begin = AlignUp(begin, kPageSize);
   end = AlignDown(end, kPageSize);
@@ -37,6 +43,7 @@
     }
     return result;
   }
+#endif
   return 0;
 }
 
@@ -50,6 +57,11 @@
 }
 
 void DexLayoutSections::Madvise(const DexFile* dex_file, MadviseState state) const {
+#ifdef _WIN32
+  UNUSED(dex_file);
+  UNUSED(state);
+  PLOG(WARNING) << "madvise is unsupported on Windows.";
+#else
   // The dex file is already defaulted to random access everywhere.
   for (const DexLayoutSection& section : sections_) {
     switch (state) {
@@ -79,6 +91,7 @@
       }
     }
   }
+#endif
 }
 
 std::ostream& operator<<(std::ostream& os, const DexLayoutSection& section) {
diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc
index 1884bcf..a719d41 100644
--- a/libdexfile/dex/dex_file_loader.cc
+++ b/libdexfile/dex/dex_file_loader.cc
@@ -187,12 +187,18 @@
   std::string base_location = GetBaseLocation(dex_location);
   const char* suffix = dex_location + base_location.size();
   DCHECK(suffix[0] == 0 || suffix[0] == kMultiDexSeparator);
+#ifdef _WIN32
+  // Warning: No symbolic link processing here.
+  PLOG(WARNING) << "realpath is unsupported on Windows.";
+#else
   // Warning: Bionic implementation of realpath() allocates > 12KB on the stack.
   // Do not run this code on a small stack, e.g. in signal handler.
   UniqueCPtr<const char[]> path(realpath(base_location.c_str(), nullptr));
   if (path != nullptr && path.get() != base_location) {
     return std::string(path.get()) + suffix;
-  } else if (suffix[0] == 0) {
+  }
+#endif
+  if (suffix[0] == 0) {
     return base_location;
   } else {
     return dex_location;
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index f7f3a8d..3b57b07 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -95,7 +95,8 @@
       weak_ref_access_enabled_(true),
       copied_live_bytes_ratio_sum_(0.f),
       gc_count_(0),
-      inter_region_bitmap_(nullptr),
+      region_space_inter_region_bitmap_(nullptr),
+      non_moving_space_inter_region_bitmap_(nullptr),
       reclaimed_bytes_ratio_sum_(0.f),
       young_gen_(young_gen),
       skipped_blocks_lock_("concurrent copying bytes blocks lock", kMarkSweepMarkStackLock),
@@ -286,12 +287,32 @@
   gc_barrier_->Increment(self, barrier_count);
 }
 
+void ConcurrentCopying::CreateInterRegionRefBitmaps() {
+  DCHECK(kEnableGenerationalConcurrentCopyingCollection);
+  DCHECK(region_space_inter_region_bitmap_ == nullptr);
+  DCHECK(non_moving_space_inter_region_bitmap_ == nullptr);
+  DCHECK(region_space_ != nullptr);
+  DCHECK(heap_->non_moving_space_ != nullptr);
+  // Region-space
+  region_space_inter_region_bitmap_.reset(accounting::ContinuousSpaceBitmap::Create(
+      "region-space inter region ref bitmap",
+      reinterpret_cast<uint8_t*>(region_space_->Begin()),
+      region_space_->Limit() - region_space_->Begin()));
+  CHECK(region_space_inter_region_bitmap_ != nullptr)
+      << "Couldn't allocate region-space inter region ref bitmap";
+
+  // non-moving-space
+  non_moving_space_inter_region_bitmap_.reset(accounting::ContinuousSpaceBitmap::Create(
+      "non-moving-space inter region ref bitmap",
+      reinterpret_cast<uint8_t*>(heap_->non_moving_space_->Begin()),
+      heap_->non_moving_space_->Limit() - heap_->non_moving_space_->Begin()));
+  CHECK(non_moving_space_inter_region_bitmap_ != nullptr)
+      << "Couldn't allocate non-moving-space inter region ref bitmap";
+}
+
 void ConcurrentCopying::BindBitmaps() {
   Thread* self = Thread::Current();
   WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
-  uintptr_t continuous_spaces_begin = UINTPTR_MAX;
-  uintptr_t continuous_spaces_limit = 0;
-  DCHECK(inter_region_bitmap_ == nullptr);
   // Mark all of the spaces we never collect as immune.
   for (const auto& space : heap_->GetContinuousSpaces()) {
     if (space->GetGcRetentionPolicy() == space::kGcRetentionPolicyNeverCollect ||
@@ -301,6 +322,7 @@
     } else {
       CHECK(!space->IsZygoteSpace());
       CHECK(!space->IsImageSpace());
+      CHECK(space == region_space_ || space == heap_->non_moving_space_);
       if (kEnableGenerationalConcurrentCopyingCollection) {
         if (space == region_space_) {
           region_space_bitmap_ = region_space_->GetMarkBitmap();
@@ -323,11 +345,6 @@
           // be captured after the thread-flip of this GC cycle, as that is when
           // the young-gen for the next GC cycle starts getting populated.
           heap_->GetCardTable()->ClearCardRange(space->Begin(), space->Limit());
-
-          continuous_spaces_begin =
-              std::min(continuous_spaces_begin, reinterpret_cast<uintptr_t>(space->Begin()));
-          continuous_spaces_limit =
-              std::max(continuous_spaces_limit, reinterpret_cast<uintptr_t>(space->Limit()));
         }
       } else {
         if (space == region_space_) {
@@ -339,18 +356,10 @@
       }
     }
   }
-  if (kEnableGenerationalConcurrentCopyingCollection) {
-    if (young_gen_) {
-      for (const auto& space : GetHeap()->GetDiscontinuousSpaces()) {
-        CHECK(space->IsLargeObjectSpace());
-        space->AsLargeObjectSpace()->CopyLiveToMarked();
-      }
-    } else {
-      inter_region_bitmap_.reset(accounting::ContinuousSpaceBitmap::Create(
-          "inter region ref bitmap",
-          reinterpret_cast<uint8_t*>(continuous_spaces_begin),
-          continuous_spaces_limit - continuous_spaces_begin));
-      CHECK(inter_region_bitmap_ != nullptr) << "Couldn't allocate inter region ref bitmap";
+  if (kEnableGenerationalConcurrentCopyingCollection && young_gen_) {
+    for (const auto& space : GetHeap()->GetDiscontinuousSpaces()) {
+      CHECK(space->IsLargeObjectSpace());
+      space->AsLargeObjectSpace()->CopyLiveToMarked();
     }
   }
 }
@@ -1112,12 +1121,22 @@
   }
   ComputeLiveBytesAndMarkRefFieldsVisitor</*kHandleInterRegionRefs*/ true>
       visitor(this, obj_region_idx);
-  ref->VisitReferences</*kVisitNativeRoots=*/true, kDefaultVerifyFlags, kWithoutReadBarrier>(
+  ref->VisitReferences</*kVisitNativeRoots=*/ true, kDefaultVerifyFlags, kWithoutReadBarrier>(
       visitor, visitor);
   // Mark the corresponding card dirty if the object contains any
   // inter-region reference.
   if (visitor.ContainsInterRegionRefs()) {
-    inter_region_bitmap_->Set(ref);
+    if (obj_region_idx == static_cast<size_t>(-1)) {
+      // If an inter-region ref has been found in a non-region-space, then it
+      // must be non-moving-space. This is because this function cannot be
+      // called on a immune-space object, and a large-object-space object has
+      // only class object reference, which is either in some immune-space, or
+      // in non-moving-space.
+      DCHECK(heap_->non_moving_space_->HasAddress(ref));
+      non_moving_space_inter_region_bitmap_->Set(ref);
+    } else {
+      region_space_inter_region_bitmap_->Set(ref);
+    }
   }
 }
 
@@ -1427,11 +1446,15 @@
                 }
               }
               ScanDirtyObject</*kNoUnEvac*/ true>(obj);
-            } else if (space != region_space_ || region_space_->IsInUnevacFromSpace(obj)) {
+            } else if (space != region_space_) {
+              DCHECK(space == heap_->non_moving_space_);
               // We need to process un-evac references as they may be unprocessed,
               // if they skipped the marking phase due to heap mutation.
               ScanDirtyObject</*kNoUnEvac*/ false>(obj);
-              inter_region_bitmap_->Clear(obj);
+              non_moving_space_inter_region_bitmap_->Clear(obj);
+            } else if (region_space_->IsInUnevacFromSpace(obj)) {
+              ScanDirtyObject</*kNoUnEvac*/ false>(obj);
+              region_space_inter_region_bitmap_->Clear(obj);
             }
           },
           accounting::CardTable::kCardAged);
@@ -1443,16 +1466,20 @@
                          ScanDirtyObject</*kNoUnEvac*/ true>(obj);
                        };
         if (space == region_space_) {
-          region_space_->ScanUnevacFromSpace(inter_region_bitmap_.get(), visitor);
+          region_space_->ScanUnevacFromSpace(region_space_inter_region_bitmap_.get(), visitor);
         } else {
-          inter_region_bitmap_->VisitMarkedRange(reinterpret_cast<uintptr_t>(space->Begin()),
-                                                 reinterpret_cast<uintptr_t>(space->End()),
-                                                 visitor);
+          DCHECK(space == heap_->non_moving_space_);
+          non_moving_space_inter_region_bitmap_->VisitMarkedRange(
+              reinterpret_cast<uintptr_t>(space->Begin()),
+              reinterpret_cast<uintptr_t>(space->End()),
+              visitor);
         }
       }
     }
     // Done scanning unevac space.
     done_scanning_.store(true, std::memory_order_release);
+    // NOTE: inter-region-ref bitmaps can be cleared here to release memory, if needed.
+    // Currently we do it in ReclaimPhase().
     if (kVerboseMode) {
       LOG(INFO) << "GC end of ScanCardsForSpace";
     }
@@ -3527,7 +3554,8 @@
     // We do not currently use the region space cards at all, madvise them away to save ram.
     heap_->GetCardTable()->ClearCardRange(region_space_->Begin(), region_space_->Limit());
   } else if (kEnableGenerationalConcurrentCopyingCollection && !young_gen_) {
-    inter_region_bitmap_.reset();
+    region_space_inter_region_bitmap_->Clear();
+    non_moving_space_inter_region_bitmap_->Clear();
   }
   {
     MutexLock mu(self, skipped_blocks_lock_);
diff --git a/runtime/gc/collector/concurrent_copying.h b/runtime/gc/collector/concurrent_copying.h
index aabfc8e..a2d4837 100644
--- a/runtime/gc/collector/concurrent_copying.h
+++ b/runtime/gc/collector/concurrent_copying.h
@@ -98,6 +98,9 @@
     return kCollectorTypeCC;
   }
   void RevokeAllThreadLocalBuffers() override;
+  // Creates inter-region ref bitmaps for region-space and non-moving-space.
+  // Gets called in Heap construction after the two spaces are created.
+  void CreateInterRegionRefBitmaps();
   void SetRegionSpace(space::RegionSpace* region_space) {
     DCHECK(region_space != nullptr);
     region_space_ = region_space;
@@ -391,7 +394,8 @@
   size_t gc_count_;
   // Bit is set if the corresponding object has inter-region references that
   // were found during the marking phase of two-phase full-heap GC cycle.
-  std::unique_ptr<accounting::ContinuousSpaceBitmap> inter_region_bitmap_;
+  std::unique_ptr<accounting::ContinuousSpaceBitmap> region_space_inter_region_bitmap_;
+  std::unique_ptr<accounting::ContinuousSpaceBitmap> non_moving_space_inter_region_bitmap_;
 
   // reclaimed_bytes_ratio = reclaimed_bytes/num_allocated_bytes per GC cycle
   float reclaimed_bytes_ratio_sum_;
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index d868aba..bf8aaae 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -666,6 +666,9 @@
       concurrent_copying_collector_->SetRegionSpace(region_space_);
       if (kEnableGenerationalConcurrentCopyingCollection) {
         young_concurrent_copying_collector_->SetRegionSpace(region_space_);
+        // At this point, non-moving space should be created.
+        DCHECK(non_moving_space_ != nullptr);
+        concurrent_copying_collector_->CreateInterRegionRefBitmaps();
       }
       garbage_collectors_.push_back(concurrent_copying_collector_);
       if (kEnableGenerationalConcurrentCopyingCollection) {
@@ -2736,7 +2739,7 @@
           // active_concurrent_copying_collector_. So we should not concurrency here.
           active_concurrent_copying_collector_ = (gc_type == collector::kGcTypeSticky) ?
               young_concurrent_copying_collector_ : concurrent_copying_collector_;
-          active_concurrent_copying_collector_->SetRegionSpace(region_space_);
+          DCHECK(active_concurrent_copying_collector_->RegionSpace() == region_space_);
         }
         collector = active_concurrent_copying_collector_;
         break;
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index b7ac1e8..9ce4749 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -240,11 +240,6 @@
 
   runtime->PreZygoteFork();
 
-  if (Trace::GetMethodTracingMode() != TracingMode::kTracingInactive) {
-    // Tracing active, pause it.
-    Trace::Pause();
-  }
-
   // Grab thread before fork potentially makes Thread::pthread_key_self_ unusable.
   return reinterpret_cast<jlong>(ThreadForEnv(env));
 }
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 8bec2d9..f459f9c 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -160,6 +160,7 @@
 }
 
 void Thread::InitTlsEntryPoints() {
+  ScopedTrace trace("InitTlsEntryPoints");
   // Insert a placeholder so we can easily tell if we call an unimplemented entry point.
   uintptr_t* begin = reinterpret_cast<uintptr_t*>(&tlsPtr_.jni_entrypoints);
   uintptr_t* end = reinterpret_cast<uintptr_t*>(
@@ -903,6 +904,8 @@
   tlsPtr_.pthread_self = pthread_self();
   CHECK(is_started_);
 
+  ScopedTrace trace("Thread::Init");
+
   SetUpAlternateSignalStack();
   if (!InitStackHwm()) {
     return false;
@@ -912,7 +915,10 @@
   RemoveSuspendTrigger();
   InitCardTable();
   InitTid();
-  interpreter::InitInterpreterTls(this);
+  {
+    ScopedTrace trace2("InitInterpreterTls");
+    interpreter::InitInterpreterTls(this);
+  }
 
 #ifdef ART_TARGET_ANDROID
   __get_tls()[TLS_SLOT_ART_THREAD_SELF] = this;
@@ -936,6 +942,7 @@
     }
   }
 
+  ScopedTrace trace3("ThreadList::Register");
   thread_list->Register(this);
   return true;
 }
@@ -943,6 +950,7 @@
 template <typename PeerAction>
 Thread* Thread::Attach(const char* thread_name, bool as_daemon, PeerAction peer_action) {
   Runtime* runtime = Runtime::Current();
+  ScopedTrace trace("Thread::Attach");
   if (runtime == nullptr) {
     LOG(ERROR) << "Thread attaching to non-existent runtime: " <<
         ((thread_name != nullptr) ? thread_name : "(Unnamed)");
@@ -950,6 +958,7 @@
   }
   Thread* self;
   {
+    ScopedTrace trace2("Thread birth");
     MutexLock mu(nullptr, *Locks::runtime_shutdown_lock_);
     if (runtime->IsShuttingDownLocked()) {
       LOG(WARNING) << "Thread attaching while runtime is shutting down: " <<
@@ -1251,6 +1260,7 @@
 }
 
 bool Thread::InitStackHwm() {
+  ScopedTrace trace("InitStackHwm");
   void* read_stack_base;
   size_t read_stack_size;
   size_t read_guard_size;
diff --git a/runtime/trace.cc b/runtime/trace.cc
index f6c36cf..ce955d8 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -517,106 +517,6 @@
   }
 }
 
-void Trace::Pause() {
-  bool stop_alloc_counting = false;
-  Runtime* runtime = Runtime::Current();
-  Trace* the_trace = nullptr;
-
-  Thread* const self = Thread::Current();
-  pthread_t sampling_pthread = 0U;
-  {
-    MutexLock mu(self, *Locks::trace_lock_);
-    if (the_trace_ == nullptr) {
-      LOG(ERROR) << "Trace pause requested, but no trace currently running";
-      return;
-    } else {
-      the_trace = the_trace_;
-      sampling_pthread = sampling_pthread_;
-    }
-  }
-
-  if (sampling_pthread != 0U) {
-    {
-      MutexLock mu(self, *Locks::trace_lock_);
-      the_trace_ = nullptr;
-    }
-    CHECK_PTHREAD_CALL(pthread_join, (sampling_pthread, nullptr), "sampling thread shutdown");
-    sampling_pthread_ = 0U;
-    {
-      MutexLock mu(self, *Locks::trace_lock_);
-      the_trace_ = the_trace;
-    }
-  }
-
-  if (the_trace != nullptr) {
-    gc::ScopedGCCriticalSection gcs(self,
-                                    gc::kGcCauseInstrumentation,
-                                    gc::kCollectorTypeInstrumentation);
-    ScopedSuspendAll ssa(__FUNCTION__);
-    stop_alloc_counting = (the_trace->flags_ & Trace::kTraceCountAllocs) != 0;
-
-    if (the_trace->trace_mode_ == TraceMode::kSampling) {
-      MutexLock mu(self, *Locks::thread_list_lock_);
-      runtime->GetThreadList()->ForEach(ClearThreadStackTraceAndClockBase, nullptr);
-    } else {
-      runtime->GetInstrumentation()->DisableMethodTracing(kTracerInstrumentationKey);
-      runtime->GetInstrumentation()->RemoveListener(
-          the_trace,
-          instrumentation::Instrumentation::kMethodEntered |
-          instrumentation::Instrumentation::kMethodExited |
-          instrumentation::Instrumentation::kMethodUnwind);
-    }
-  }
-
-  if (stop_alloc_counting) {
-    // Can be racy since SetStatsEnabled is not guarded by any locks.
-    Runtime::Current()->SetStatsEnabled(false);
-  }
-}
-
-void Trace::Resume() {
-  Thread* self = Thread::Current();
-  Trace* the_trace;
-  {
-    MutexLock mu(self, *Locks::trace_lock_);
-    if (the_trace_ == nullptr) {
-      LOG(ERROR) << "No trace to resume (or sampling mode), ignoring this request";
-      return;
-    }
-    the_trace = the_trace_;
-  }
-
-  Runtime* runtime = Runtime::Current();
-
-  // Enable count of allocs if specified in the flags.
-  bool enable_stats = (the_trace->flags_ & kTraceCountAllocs) != 0;
-
-  {
-    gc::ScopedGCCriticalSection gcs(self,
-                                    gc::kGcCauseInstrumentation,
-                                    gc::kCollectorTypeInstrumentation);
-    ScopedSuspendAll ssa(__FUNCTION__);
-
-    // Reenable.
-    if (the_trace->trace_mode_ == TraceMode::kSampling) {
-      CHECK_PTHREAD_CALL(pthread_create, (&sampling_pthread_, nullptr, &RunSamplingThread,
-          reinterpret_cast<void*>(the_trace->interval_us_)), "Sampling profiler thread");
-    } else {
-      runtime->GetInstrumentation()->AddListener(the_trace,
-                                                 instrumentation::Instrumentation::kMethodEntered |
-                                                 instrumentation::Instrumentation::kMethodExited |
-                                                 instrumentation::Instrumentation::kMethodUnwind);
-      // TODO: In full-PIC mode, we don't need to fully deopt.
-      runtime->GetInstrumentation()->EnableMethodTracing(kTracerInstrumentationKey);
-    }
-  }
-
-  // Can't call this when holding the mutator lock.
-  if (enable_stats) {
-    runtime->SetStatsEnabled(true);
-  }
-}
-
 TracingMode Trace::GetMethodTracingMode() {
   MutexLock mu(Thread::Current(), *Locks::trace_lock_);
   if (the_trace_ == nullptr) {
diff --git a/runtime/trace.h b/runtime/trace.h
index 1089962..582f756 100644
--- a/runtime/trace.h
+++ b/runtime/trace.h
@@ -156,9 +156,6 @@
       REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_,
                !Locks::trace_lock_);
 
-  static void Pause() REQUIRES(!Locks::trace_lock_, !Locks::thread_list_lock_);
-  static void Resume() REQUIRES(!Locks::trace_lock_);
-
   // Stop tracing. This will finish the trace and write it to file/send it via DDMS.
   static void Stop()
       REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_);
diff --git a/tools/libcore_failures.txt b/tools/libcore_failures.txt
index c66f71d..3c65b01 100644
--- a/tools/libcore_failures.txt
+++ b/tools/libcore_failures.txt
@@ -198,5 +198,30 @@
   modes: [device],
   bug: 116446372,
   names: ["libcore.libcore.io.FdsanTest#testSocket"]
+},
+{
+  description: "Host implementation of android_getaddrinfo differs from device implementation",
+  result: EXEC_FAILED,
+  modes: [host],
+  bug: 121230364,
+  names: [
+    "libcore.libcore.net.InetAddressUtilsTest#parseNumericAddress[8]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[10]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[11]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[12]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[5]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[6]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[7]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[8]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_isNotNumericAddress[9]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[10]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[11]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[12]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[5]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[6]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[7]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[8]",
+    "libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[9]"
+  ]
 }
 ]