1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <atomic>
18 #include <sstream>
19
20 #include "base/globals.h"
21 #include "jit/jit.h"
22 #include "jit/jit_code_cache.h"
23 #include "jni.h"
24 #include "runtime.h"
25 #include "thread_list.h"
26
27 namespace art {
28 namespace NativeWait {
29
30 std::atomic<bool> native_waiting = false;
31 std::atomic<bool> native_wait = false;
32
33 // Perform late debuggable switch in the same way the zygote would (clear-jit,
34 // unmark-zygote, set-debuggable, deopt boot, restart jit). NB This skips
35 // restarting the heap threads since that doesn't seem to be needed to trigger
36 // b/144947842.
Java_art_Test2031_simulateZygoteFork(JNIEnv *,jclass)37 extern "C" JNIEXPORT void JNICALL Java_art_Test2031_simulateZygoteFork(JNIEnv*, jclass) {
38 Runtime* runtime = Runtime::Current();
39 bool has_jit = runtime->GetJit() != nullptr;
40 if (has_jit) {
41 runtime->GetJit()->PreZygoteFork();
42 }
43 runtime->SetAsZygoteChild(/*is_system_server=*/false, /*is_zygote=*/false);
44 runtime->AddCompilerOption("--debuggable");
45 runtime->SetRuntimeDebugState(Runtime::RuntimeDebugState::kJavaDebuggableAtInit);
46 {
47 // Deoptimize the boot image as it may be non-debuggable.
48 ScopedSuspendAll ssa(__FUNCTION__);
49 runtime->DeoptimizeBootImage();
50 }
51
52 if (has_jit) {
53 runtime->GetJitCodeCache()->PostForkChildAction(false, false);
54 runtime->GetJit()->PostForkChildAction(false, false);
55 // We have "zygote" code that isn't really part of the BCP. just don't collect it.
56 runtime->GetJitCodeCache()->SetGarbageCollectCode(false);
57 }
58 }
59
Java_art_Test2031_setupJvmti(JNIEnv * env,jclass,jstring testdir)60 extern "C" JNIEXPORT void JNICALL Java_art_Test2031_setupJvmti(JNIEnv* env,
61 jclass,
62 [[maybe_unused]] jstring testdir) {
63 std::ostringstream oss;
64 oss << (kIsDebugBuild ? "libtiagentd.so" : "libtiagent.so")
65 << "=2031-zygote-compiled-frame-deopt,art";
66 LOG(INFO) << "agent " << oss.str();
67 Runtime::Current()->AttachAgent(env, oss.str(), nullptr);
68 }
Java_art_Test2031_waitForNativeSleep(JNIEnv *,jclass)69 extern "C" JNIEXPORT void JNICALL Java_art_Test2031_waitForNativeSleep(JNIEnv*, jclass) {
70 while (!native_waiting) {
71 }
72 }
Java_art_Test2031_wakeupNativeSleep(JNIEnv *,jclass)73 extern "C" JNIEXPORT void JNICALL Java_art_Test2031_wakeupNativeSleep(JNIEnv*, jclass) {
74 native_wait = false;
75 }
Java_art_Test2031_nativeSleep(JNIEnv *,jclass)76 extern "C" JNIEXPORT void JNICALL Java_art_Test2031_nativeSleep(JNIEnv*, jclass) {
77 native_wait = true;
78 do {
79 native_waiting = true;
80 } while (native_wait);
81 native_waiting = false;
82 }
83
84 } // namespace NativeWait
85 } // namespace art
86