Fix ClearEntryPointsInZygoteExecSpace.

Methods allocated in the shared region now don't have a profiling
info.

Also move test 689-zygote-jit-deopt to now use proper ZygoteHooks APIs
to fork from zygote, and have non-bionic build create a shared region.

Test: 689-zygote-jit-deopt
Bug: 119800099
Change-Id: I400618673a0b5b2ba7389e46d692ea6a58dbeea8
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 8f4d0d4..960018c 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -917,19 +917,11 @@
 
 void JitCodeCache::ClearEntryPointsInZygoteExecSpace() {
   MutexLock mu(Thread::Current(), *Locks::jit_lock_);
-  // Iterate over profiling infos to know which methods may have been JITted. Note that
-  // to be JITted, a method must have a profiling info.
-  for (ProfilingInfo* info : profiling_infos_) {
-    ArtMethod* method = info->GetMethod();
+  for (const auto& it : method_code_map_) {
+    ArtMethod* method = it.second;
     if (IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode())) {
       method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
     }
-    // If zygote does method tracing, or in some configuration where
-    // the JIT zygote does GC, we also need to clear the saved entry point
-    // in the profiling info.
-    if (IsInZygoteExecSpace(info->GetSavedEntryPoint())) {
-      info->SetSavedEntryPoint(nullptr);
-    }
   }
 }
 
@@ -1742,13 +1734,6 @@
     return;
   }
 
-  if (private_region_.IsValid()) {
-    // In case the zygote was running with its own private region (happens for
-    // unit tests), move the region to the shared one.
-    CHECK(!shared_region_.IsValid());
-    std::swap(shared_region_, private_region_);
-  }
-
   // Reset all statistics to be specific to this process.
   number_of_compilations_ = 0;
   number_of_osr_compilations_ = 0;
diff --git a/runtime/jit/jit_memory_region.cc b/runtime/jit/jit_memory_region.cc
index 9092695..d2d8f7c 100644
--- a/runtime/jit/jit_memory_region.cc
+++ b/runtime/jit/jit_memory_region.cc
@@ -546,10 +546,24 @@
 
 #else
 
-// When running on non-bionic configuration, this is not supported.
-int JitMemoryRegion::CreateZygoteMemory(size_t capacity ATTRIBUTE_UNUSED,
-                                        std::string* error_msg ATTRIBUTE_UNUSED) {
-  return -1;
+int JitMemoryRegion::CreateZygoteMemory(size_t capacity, std::string* error_msg) {
+  // To simplify host building, we don't rely on the latest memfd features.
+  LOG(WARNING) << "Returning un-sealable region on non-bionic";
+  static const char* kRegionName = "/jit-zygote-cache";
+  int fd = art::memfd_create(kRegionName, 0);
+  if (fd == -1) {
+    std::ostringstream oss;
+    oss << "Failed to create zygote mapping: " << strerror(errno);
+    *error_msg = oss.str();
+    return -1;
+  }
+  if (ftruncate(fd, capacity) != 0) {
+    std::ostringstream oss;
+    oss << "Failed to create zygote mapping: " << strerror(errno);
+    *error_msg = oss.str();
+    return -1;
+  }
+  return fd;
 }
 
 bool JitMemoryRegion::ProtectZygoteMemory(int fd ATTRIBUTE_UNUSED,
diff --git a/test/689-zygote-jit-deopt/run b/test/689-zygote-jit-deopt/run
new file mode 100644
index 0000000..7b4b7eb
--- /dev/null
+++ b/test/689-zygote-jit-deopt/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 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.
+
+./default-run "$@" --zygote
diff --git a/test/689-zygote-jit-deopt/src/Main.java b/test/689-zygote-jit-deopt/src/Main.java
index 330663e..fbdc728 100644
--- a/test/689-zygote-jit-deopt/src/Main.java
+++ b/test/689-zygote-jit-deopt/src/Main.java
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+import dalvik.system.ZygoteHooks;
+
 public class Main {
   public static void main(String[] args) {
     System.loadLibrary(args[0]);
@@ -21,7 +23,10 @@
       return;
     }
     ensureJitCompiled(Object.class, "toString");
-    transitionJitFromZygote();
+    ZygoteHooks.preFork();
+    ZygoteHooks.postForkChild(
+        /*flags=*/0, /*is_system_server=*/false, /*is_zygote=*/false, /*instruction_set=*/null);
+    ZygoteHooks.postForkCommon();
     deoptimizeBootImage();
     if (hasJitCompiledEntrypoint(Object.class, "toString")) {
       throw new Error("Expected Object.toString to be deoptimized");
@@ -32,5 +37,4 @@
   private static native void ensureJitCompiled(Class<?> cls, String name);
   private static native boolean hasJitCompiledEntrypoint(Class<?> cls, String name);
   private static native void deoptimizeBootImage();
-  private static native void transitionJitFromZygote();
 }
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index 7b023de..88d7a9f 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -241,7 +241,7 @@
       // Sleep to yield to the compiler thread.
       usleep(1000);
       ScopedObjectAccess soa(self);
-      if (!native) {
+      if (!native && jit->GetCodeCache()->CanAllocateProfilingInfo()) {
         // Make sure there is a profiling info, required by the compiler.
         ProfilingInfo::Create(self, method, /* retry_allocation */ true);
       }
@@ -365,17 +365,6 @@
   return (jit != nullptr) ? jit->HotMethodThreshold() : 0;
 }
 
-extern "C" JNIEXPORT void JNICALL Java_Main_transitionJitFromZygote(JNIEnv*, jclass) {
-  jit::Jit* jit = Runtime::Current()->GetJit();
-  if (jit == nullptr) {
-    return;
-  }
-  // Mimic the transition behavior a zygote fork would have.
-  jit->PreZygoteFork();
-  jit->GetCodeCache()->PostForkChildAction(/*is_system_server=*/ false, /*is_zygote=*/ false);
-  jit->PostForkChildAction(/*is_system_server=*/ false, /*is_zygote=*/ false);
-}
-
 extern "C" JNIEXPORT void JNICALL Java_Main_deoptimizeBootImage(JNIEnv*, jclass) {
   ScopedSuspendAll ssa(__FUNCTION__);
   Runtime::Current()->DeoptimizeBootImage();