/* * Copyright 2020 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 #include #include "base/globals.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" #include "jni.h" #include "runtime.h" #include "thread_list.h" namespace art { namespace NativeWait { std::atomic native_waiting = false; std::atomic native_wait = false; // Perform late debuggable switch in the same way the zygote would (clear-jit, // unmark-zygote, set-debuggable, deopt boot, restart jit). NB This skips // restarting the heap threads since that doesn't seem to be needed to trigger // b/144947842. extern "C" JNIEXPORT void JNICALL Java_art_Test2031_simulateZygoteFork(JNIEnv*, jclass) { Runtime* runtime = Runtime::Current(); bool has_jit = runtime->GetJit() != nullptr; if (has_jit) { runtime->GetJit()->PreZygoteFork(); } runtime->SetAsZygoteChild(/*is_system_server=*/false, /*is_zygote=*/false); runtime->AddCompilerOption("--debuggable"); runtime->SetJavaDebuggable(true); { // Deoptimize the boot image as it may be non-debuggable. ScopedSuspendAll ssa(__FUNCTION__); runtime->DeoptimizeBootImage(); } if (has_jit) { runtime->GetJitCodeCache()->PostForkChildAction(false, false); runtime->GetJit()->PostForkChildAction(false, false); // We have "zygote" code that isn't really part of the BCP. just don't collect it. runtime->GetJitCodeCache()->SetGarbageCollectCode(false); } } extern "C" JNIEXPORT void JNICALL Java_art_Test2031_setupJvmti(JNIEnv* env, jclass, jstring testdir) { const char* td = env->GetStringUTFChars(testdir, nullptr); std::string testdir_str; testdir_str.resize(env->GetStringUTFLength(testdir)); memcpy(testdir_str.data(), td, testdir_str.size()); env->ReleaseStringUTFChars(testdir, td); std::ostringstream oss; Runtime* runtime = Runtime::Current(); oss << testdir_str << (kIsDebugBuild ? "libtiagentd.so" : "libtiagent.so") << "=2031-zygote-compiled-frame-deopt,art"; LOG(INFO) << "agent " << oss.str(); runtime->AttachAgent(env, oss.str(), nullptr); } extern "C" JNIEXPORT void JNICALL Java_art_Test2031_waitForNativeSleep(JNIEnv*, jclass) { while (!native_waiting) { } } extern "C" JNIEXPORT void JNICALL Java_art_Test2031_wakeupNativeSleep(JNIEnv*, jclass) { native_wait = false; } extern "C" JNIEXPORT void JNICALL Java_art_Test2031_nativeSleep(JNIEnv*, jclass) { native_wait = true; do { native_waiting = true; } while (native_wait); native_waiting = false; } } // namespace NativeWait } // namespace art