1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "jni/jni_internal.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <pthread.h>
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
22*795d594fSAndroid Build Coastguard Worker #include "gc/heap.h"
23*795d594fSAndroid Build Coastguard Worker #include "java_vm_ext.h"
24*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
25*795d594fSAndroid Build Coastguard Worker
26*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
27*795d594fSAndroid Build Coastguard Worker
28*795d594fSAndroid Build Coastguard Worker class JavaVmExtTest : public CommonRuntimeTest {
29*795d594fSAndroid Build Coastguard Worker protected:
JavaVmExtTest()30*795d594fSAndroid Build Coastguard Worker JavaVmExtTest() {
31*795d594fSAndroid Build Coastguard Worker this->use_boot_image_ = true; // Make the Runtime creation cheaper.
32*795d594fSAndroid Build Coastguard Worker }
33*795d594fSAndroid Build Coastguard Worker
SetUp()34*795d594fSAndroid Build Coastguard Worker void SetUp() override {
35*795d594fSAndroid Build Coastguard Worker CommonRuntimeTest::SetUp();
36*795d594fSAndroid Build Coastguard Worker
37*795d594fSAndroid Build Coastguard Worker vm_ = Runtime::Current()->GetJavaVM();
38*795d594fSAndroid Build Coastguard Worker }
39*795d594fSAndroid Build Coastguard Worker
40*795d594fSAndroid Build Coastguard Worker
TearDown()41*795d594fSAndroid Build Coastguard Worker void TearDown() override {
42*795d594fSAndroid Build Coastguard Worker CommonRuntimeTest::TearDown();
43*795d594fSAndroid Build Coastguard Worker }
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker JavaVMExt* vm_;
46*795d594fSAndroid Build Coastguard Worker };
47*795d594fSAndroid Build Coastguard Worker
TEST_F(JavaVmExtTest,JNI_GetDefaultJavaVMInitArgs)48*795d594fSAndroid Build Coastguard Worker TEST_F(JavaVmExtTest, JNI_GetDefaultJavaVMInitArgs) {
49*795d594fSAndroid Build Coastguard Worker jint err = JNI_GetDefaultJavaVMInitArgs(nullptr);
50*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_ERR, err);
51*795d594fSAndroid Build Coastguard Worker }
52*795d594fSAndroid Build Coastguard Worker
TEST_F(JavaVmExtTest,JNI_GetCreatedJavaVMs)53*795d594fSAndroid Build Coastguard Worker TEST_F(JavaVmExtTest, JNI_GetCreatedJavaVMs) {
54*795d594fSAndroid Build Coastguard Worker JavaVM* vms_buf[1];
55*795d594fSAndroid Build Coastguard Worker jsize num_vms;
56*795d594fSAndroid Build Coastguard Worker jint ok = JNI_GetCreatedJavaVMs(vms_buf, arraysize(vms_buf), &num_vms);
57*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_OK, ok);
58*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(1, num_vms);
59*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(vms_buf[0], vm_);
60*795d594fSAndroid Build Coastguard Worker }
61*795d594fSAndroid Build Coastguard Worker
62*795d594fSAndroid Build Coastguard Worker static bool gSmallStack = false;
63*795d594fSAndroid Build Coastguard Worker static bool gAsDaemon = false;
64*795d594fSAndroid Build Coastguard Worker
attach_current_thread_callback(void * arg)65*795d594fSAndroid Build Coastguard Worker static void* attach_current_thread_callback([[maybe_unused]] void* arg) {
66*795d594fSAndroid Build Coastguard Worker JavaVM* vms_buf[1];
67*795d594fSAndroid Build Coastguard Worker jsize num_vms;
68*795d594fSAndroid Build Coastguard Worker JNIEnv* env;
69*795d594fSAndroid Build Coastguard Worker jint ok = JNI_GetCreatedJavaVMs(vms_buf, arraysize(vms_buf), &num_vms);
70*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_OK, ok);
71*795d594fSAndroid Build Coastguard Worker if (ok == JNI_OK) {
72*795d594fSAndroid Build Coastguard Worker if (!gAsDaemon) {
73*795d594fSAndroid Build Coastguard Worker ok = vms_buf[0]->AttachCurrentThread(&env, nullptr);
74*795d594fSAndroid Build Coastguard Worker } else {
75*795d594fSAndroid Build Coastguard Worker ok = vms_buf[0]->AttachCurrentThreadAsDaemon(&env, nullptr);
76*795d594fSAndroid Build Coastguard Worker }
77*795d594fSAndroid Build Coastguard Worker // TODO: Find a way to test with exact SMALL_STACK value, for which we would bail. The pthreads
78*795d594fSAndroid Build Coastguard Worker // spec says that the stack size argument is a lower bound, and bionic currently gives us
79*795d594fSAndroid Build Coastguard Worker // a chunk more on arm64.
80*795d594fSAndroid Build Coastguard Worker if (!gSmallStack) {
81*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_OK, ok);
82*795d594fSAndroid Build Coastguard Worker }
83*795d594fSAndroid Build Coastguard Worker if (ok == JNI_OK) {
84*795d594fSAndroid Build Coastguard Worker ok = vms_buf[0]->DetachCurrentThread();
85*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_OK, ok);
86*795d594fSAndroid Build Coastguard Worker }
87*795d594fSAndroid Build Coastguard Worker }
88*795d594fSAndroid Build Coastguard Worker return nullptr;
89*795d594fSAndroid Build Coastguard Worker }
90*795d594fSAndroid Build Coastguard Worker
TEST_F(JavaVmExtTest,AttachCurrentThread)91*795d594fSAndroid Build Coastguard Worker TEST_F(JavaVmExtTest, AttachCurrentThread) {
92*795d594fSAndroid Build Coastguard Worker pthread_t pthread;
93*795d594fSAndroid Build Coastguard Worker const char* reason = __PRETTY_FUNCTION__;
94*795d594fSAndroid Build Coastguard Worker gSmallStack = false;
95*795d594fSAndroid Build Coastguard Worker gAsDaemon = false;
96*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_create, (&pthread, nullptr, attach_current_thread_callback,
97*795d594fSAndroid Build Coastguard Worker nullptr), reason);
98*795d594fSAndroid Build Coastguard Worker void* ret_val;
99*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_join, (pthread, &ret_val), reason);
100*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(ret_val, nullptr);
101*795d594fSAndroid Build Coastguard Worker }
102*795d594fSAndroid Build Coastguard Worker
TEST_F(JavaVmExtTest,AttachCurrentThreadAsDaemon)103*795d594fSAndroid Build Coastguard Worker TEST_F(JavaVmExtTest, AttachCurrentThreadAsDaemon) {
104*795d594fSAndroid Build Coastguard Worker pthread_t pthread;
105*795d594fSAndroid Build Coastguard Worker const char* reason = __PRETTY_FUNCTION__;
106*795d594fSAndroid Build Coastguard Worker gSmallStack = false;
107*795d594fSAndroid Build Coastguard Worker gAsDaemon = true;
108*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_create, (&pthread, nullptr, attach_current_thread_callback,
109*795d594fSAndroid Build Coastguard Worker nullptr), reason);
110*795d594fSAndroid Build Coastguard Worker void* ret_val;
111*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_join, (pthread, &ret_val), reason);
112*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(ret_val, nullptr);
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker
TEST_F(JavaVmExtTest,AttachCurrentThread_SmallStack)115*795d594fSAndroid Build Coastguard Worker TEST_F(JavaVmExtTest, AttachCurrentThread_SmallStack) {
116*795d594fSAndroid Build Coastguard Worker TEST_DISABLED_FOR_MEMORY_TOOL(); // b/123500163
117*795d594fSAndroid Build Coastguard Worker pthread_t pthread;
118*795d594fSAndroid Build Coastguard Worker pthread_attr_t attr;
119*795d594fSAndroid Build Coastguard Worker const char* reason = __PRETTY_FUNCTION__;
120*795d594fSAndroid Build Coastguard Worker gSmallStack = true;
121*795d594fSAndroid Build Coastguard Worker gAsDaemon = false;
122*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), reason);
123*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, PTHREAD_STACK_MIN), reason);
124*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_create, (&pthread, &attr, attach_current_thread_callback,
125*795d594fSAndroid Build Coastguard Worker nullptr), reason);
126*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), reason);
127*795d594fSAndroid Build Coastguard Worker void* ret_val;
128*795d594fSAndroid Build Coastguard Worker CHECK_PTHREAD_CALL(pthread_join, (pthread, &ret_val), reason);
129*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(ret_val, nullptr);
130*795d594fSAndroid Build Coastguard Worker }
131*795d594fSAndroid Build Coastguard Worker
TEST_F(JavaVmExtTest,DetachCurrentThread)132*795d594fSAndroid Build Coastguard Worker TEST_F(JavaVmExtTest, DetachCurrentThread) {
133*795d594fSAndroid Build Coastguard Worker JNIEnv* env;
134*795d594fSAndroid Build Coastguard Worker jint ok = vm_->AttachCurrentThread(&env, nullptr);
135*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(JNI_OK, ok);
136*795d594fSAndroid Build Coastguard Worker ok = vm_->DetachCurrentThread();
137*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_OK, ok);
138*795d594fSAndroid Build Coastguard Worker
139*795d594fSAndroid Build Coastguard Worker jint err = vm_->DetachCurrentThread();
140*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_ERR, err);
141*795d594fSAndroid Build Coastguard Worker }
142*795d594fSAndroid Build Coastguard Worker
143*795d594fSAndroid Build Coastguard Worker class JavaVmExtStackTraceTest : public JavaVmExtTest {
144*795d594fSAndroid Build Coastguard Worker protected:
SetUpRuntimeOptions(RuntimeOptions * options)145*795d594fSAndroid Build Coastguard Worker void SetUpRuntimeOptions(RuntimeOptions* options) override {
146*795d594fSAndroid Build Coastguard Worker options->emplace_back("-XX:GlobalRefAllocStackTraceLimit=50000", nullptr);
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker };
149*795d594fSAndroid Build Coastguard Worker
TEST_F(JavaVmExtStackTraceTest,TestEnableDisable)150*795d594fSAndroid Build Coastguard Worker TEST_F(JavaVmExtStackTraceTest, TestEnableDisable) {
151*795d594fSAndroid Build Coastguard Worker ASSERT_FALSE(Runtime::Current()->GetHeap()->IsAllocTrackingEnabled());
152*795d594fSAndroid Build Coastguard Worker
153*795d594fSAndroid Build Coastguard Worker JNIEnv* env;
154*795d594fSAndroid Build Coastguard Worker jint ok = vm_->AttachCurrentThread(&env, nullptr);
155*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(JNI_OK, ok);
156*795d594fSAndroid Build Coastguard Worker
157*795d594fSAndroid Build Coastguard Worker std::vector<jobject> global_refs_;
158*795d594fSAndroid Build Coastguard Worker jobject local_ref = env->NewStringUTF("Hello");
159*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < 2000; ++i) {
160*795d594fSAndroid Build Coastguard Worker global_refs_.push_back(env->NewGlobalRef(local_ref));
161*795d594fSAndroid Build Coastguard Worker }
162*795d594fSAndroid Build Coastguard Worker
163*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(Runtime::Current()->GetHeap()->IsAllocTrackingEnabled());
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard Worker for (jobject global_ref : global_refs_) {
166*795d594fSAndroid Build Coastguard Worker env->DeleteGlobalRef(global_ref);
167*795d594fSAndroid Build Coastguard Worker }
168*795d594fSAndroid Build Coastguard Worker
169*795d594fSAndroid Build Coastguard Worker EXPECT_FALSE(Runtime::Current()->GetHeap()->IsAllocTrackingEnabled());
170*795d594fSAndroid Build Coastguard Worker
171*795d594fSAndroid Build Coastguard Worker global_refs_.clear();
172*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < 2000; ++i) {
173*795d594fSAndroid Build Coastguard Worker global_refs_.push_back(env->NewGlobalRef(local_ref));
174*795d594fSAndroid Build Coastguard Worker }
175*795d594fSAndroid Build Coastguard Worker
176*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(Runtime::Current()->GetHeap()->IsAllocTrackingEnabled());
177*795d594fSAndroid Build Coastguard Worker
178*795d594fSAndroid Build Coastguard Worker for (jobject global_ref : global_refs_) {
179*795d594fSAndroid Build Coastguard Worker env->DeleteGlobalRef(global_ref);
180*795d594fSAndroid Build Coastguard Worker }
181*795d594fSAndroid Build Coastguard Worker
182*795d594fSAndroid Build Coastguard Worker EXPECT_FALSE(Runtime::Current()->GetHeap()->IsAllocTrackingEnabled());
183*795d594fSAndroid Build Coastguard Worker
184*795d594fSAndroid Build Coastguard Worker ok = vm_->DetachCurrentThread();
185*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(JNI_OK, ok);
186*795d594fSAndroid Build Coastguard Worker }
187*795d594fSAndroid Build Coastguard Worker
188*795d594fSAndroid Build Coastguard Worker } // namespace art
189