blob: f315d1f9adc430fa93dcd386bee9d968f96266a6 [file] [log] [blame]
Ian Rogersb033c752011-07-20 12:22:35 -07001// Copyright 2011 Google Inc. All Rights Reserved.
Ian Rogersb033c752011-07-20 12:22:35 -07002
3#include <sys/mman.h>
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07004
5#include "assembler.h"
6#include "class_linker.h"
7#include "common_test.h"
8#include "dex_file.h"
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07009#include "indirect_reference_table.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070010#include "jni_compiler.h"
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070011#include "jni_internal.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070012#include "mem_map.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070013#include "runtime.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070014#include "scoped_ptr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070015#include "thread.h"
Ian Rogersb033c752011-07-20 12:22:35 -070016#include "gtest/gtest.h"
17
18namespace art {
19
Brian Carlstromf734cf52011-08-17 16:28:14 -070020class JniCompilerTest : public CommonTest {
Ian Rogersb033c752011-07-20 12:22:35 -070021 protected:
22 virtual void SetUp() {
Brian Carlstromf734cf52011-08-17 16:28:14 -070023 CommonTest::SetUp();
Brian Carlstroma663ea52011-08-19 23:33:41 -070024 dex_.reset(OpenDexFileBase64(kMyClassNativesDex, "kMyClassNativesDex"));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070025 class_loader_ = AllocPathClassLoader(dex_.get());
buzbeec143c552011-08-20 17:38:58 -070026 Thread::Current()->SetClassLoaderOverride(class_loader_);
Ian Rogersb033c752011-07-20 12:22:35 -070027 }
28
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070029 void SetupForTest(bool direct, const char* method_name,
30 const char* method_sig, void* native_fnptr) {
buzbeec143c552011-08-20 17:38:58 -070031 env_ = Thread::Current()->GetJniEnv();
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070032
buzbeec143c552011-08-20 17:38:58 -070033 jklass_ = env_->FindClass("MyClass");
34 ASSERT_TRUE(jklass_ != NULL);
35
36 Class* c = class_linker_->FindClass("LMyClass;", class_loader_);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070037 Method* method;
38 if (direct) {
buzbeec143c552011-08-20 17:38:58 -070039 method = c->FindDirectMethod(method_name, method_sig);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070040 } else {
buzbeec143c552011-08-20 17:38:58 -070041 method = c->FindVirtualMethod(method_name, method_sig);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070042 }
43 ASSERT_TRUE(method != NULL);
44
45 // Compile the native method
46 jni_compiler.Compile(&jni_asm, method);
buzbeec143c552011-08-20 17:38:58 -070047 ASSERT_TRUE(method->HasCode());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070048
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070049 if (direct) {
50 jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
51 } else {
52 jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
53 }
54 ASSERT_TRUE(jmethod_ != NULL);
55
56 JNINativeMethod methods[] = {{method_name, method_sig, native_fnptr}};
57 ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1));
58
59 jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
60 jobj_ = env_->NewObject(jklass_, constructor);
61 ASSERT_TRUE(jobj_ != NULL);
Ian Rogersb033c752011-07-20 12:22:35 -070062 }
63
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070064 public:
65 static jclass jklass_;
66 static jobject jobj_;
67 protected:
68 scoped_ptr<DexFile> dex_;
69 PathClassLoader* class_loader_;
70 Assembler jni_asm;
71 JniCompiler jni_compiler;
72 JNIEnv* env_;
73 jmethodID jmethod_;
Ian Rogersb033c752011-07-20 12:22:35 -070074};
75
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070076jclass JniCompilerTest::jklass_;
77jobject JniCompilerTest::jobj_;
78
Ian Rogersb033c752011-07-20 12:22:35 -070079int gJava_MyClass_foo_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070080void Java_MyClass_foo(JNIEnv* env, jobject thisObj) {
Ian Rogersb033c752011-07-20 12:22:35 -070081 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
82 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070083 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
84 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -070085 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -070086 gJava_MyClass_foo_calls++;
87}
88
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070089TEST_F(JniCompilerTest, CompileAndRunNoArgMethod) {
90 SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
91
92 EXPECT_EQ(0, gJava_MyClass_foo_calls);
93 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
94 EXPECT_EQ(1, gJava_MyClass_foo_calls);
95 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
96 EXPECT_EQ(2, gJava_MyClass_foo_calls);
97}
98
Ian Rogersb033c752011-07-20 12:22:35 -070099int gJava_MyClass_fooI_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700100jint Java_MyClass_fooI(JNIEnv* env, jobject thisObj, jint x) {
Ian Rogersb033c752011-07-20 12:22:35 -0700101 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
102 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700103 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
104 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700105 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700106 gJava_MyClass_fooI_calls++;
107 return x;
108}
109
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700110TEST_F(JniCompilerTest, CompileAndRunIntMethod) {
111 SetupForTest(false, "fooI", "(I)I",
112 reinterpret_cast<void*>(&Java_MyClass_fooI));
113
114 EXPECT_EQ(0, gJava_MyClass_fooI_calls);
115 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
116 EXPECT_EQ(42, result);
117 EXPECT_EQ(1, gJava_MyClass_fooI_calls);
118 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFED00D);
119 EXPECT_EQ(static_cast<jint>(0xCAFED00D), result);
120 EXPECT_EQ(2, gJava_MyClass_fooI_calls);
121}
122
Ian Rogersb033c752011-07-20 12:22:35 -0700123int gJava_MyClass_fooII_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700124jint Java_MyClass_fooII(JNIEnv* env, jobject thisObj, jint x, jint y) {
Ian Rogersb033c752011-07-20 12:22:35 -0700125 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
126 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700127 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
128 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700129 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700130 gJava_MyClass_fooII_calls++;
131 return x - y; // non-commutative operator
132}
133
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700134TEST_F(JniCompilerTest, CompileAndRunIntIntMethod) {
135 SetupForTest(false, "fooII", "(II)I",
136 reinterpret_cast<void*>(&Java_MyClass_fooII));
137
138 EXPECT_EQ(0, gJava_MyClass_fooII_calls);
139 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 99, 10);
140 EXPECT_EQ(99 - 10, result);
141 EXPECT_EQ(1, gJava_MyClass_fooII_calls);
142 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFEBABE,
143 0xCAFED00D);
144 EXPECT_EQ(static_cast<jint>(0xCAFEBABE - 0xCAFED00D), result);
145 EXPECT_EQ(2, gJava_MyClass_fooII_calls);
146}
147
Ian Rogersb033c752011-07-20 12:22:35 -0700148int gJava_MyClass_fooDD_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700149jdouble Java_MyClass_fooDD(JNIEnv* env, jobject thisObj, jdouble x, jdouble y) {
Ian Rogersb033c752011-07-20 12:22:35 -0700150 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
151 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700152 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
153 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700154 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700155 gJava_MyClass_fooDD_calls++;
156 return x - y; // non-commutative operator
157}
158
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700159TEST_F(JniCompilerTest, CompileAndRunDoubleDoubleMethod) {
160 SetupForTest(false, "fooDD", "(DD)D",
161 reinterpret_cast<void*>(&Java_MyClass_fooDD));
162
163 EXPECT_EQ(0, gJava_MyClass_fooDD_calls);
164 jdouble result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_,
165 99.0, 10.0);
166 EXPECT_EQ(99.0 - 10.0, result);
167 EXPECT_EQ(1, gJava_MyClass_fooDD_calls);
168 jdouble a = 3.14159265358979323846;
169 jdouble b = 0.69314718055994530942;
170 result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_, a, b);
171 EXPECT_EQ(a - b, result);
172 EXPECT_EQ(2, gJava_MyClass_fooDD_calls);
173}
174
Ian Rogersb033c752011-07-20 12:22:35 -0700175int gJava_MyClass_fooIOO_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700176jobject Java_MyClass_fooIOO(JNIEnv* env, jobject thisObj, jint x, jobject y,
Ian Rogersb033c752011-07-20 12:22:35 -0700177 jobject z) {
178 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
179 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700180 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
181 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700182 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700183 gJava_MyClass_fooIOO_calls++;
184 switch (x) {
185 case 1:
186 return y;
187 case 2:
188 return z;
189 default:
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700190 return thisObj;
Ian Rogersb033c752011-07-20 12:22:35 -0700191 }
192}
193
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700194TEST_F(JniCompilerTest, CompileAndRunIntObjectObjectMethod) {
195 SetupForTest(false, "fooIOO",
196 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
197 reinterpret_cast<void*>(&Java_MyClass_fooIOO));
198
199 EXPECT_EQ(0, gJava_MyClass_fooIOO_calls);
200 jobject result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, NULL, NULL);
201 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
202 EXPECT_EQ(1, gJava_MyClass_fooIOO_calls);
203
204 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, NULL, jklass_);
205 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
206 EXPECT_EQ(2, gJava_MyClass_fooIOO_calls);
207 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, NULL, jklass_);
208 EXPECT_TRUE(env_->IsSameObject(NULL, result));
209 EXPECT_EQ(3, gJava_MyClass_fooIOO_calls);
210 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, NULL, jklass_);
211 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
212 EXPECT_EQ(4, gJava_MyClass_fooIOO_calls);
213
214 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, jklass_, NULL);
215 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
216 EXPECT_EQ(5, gJava_MyClass_fooIOO_calls);
217 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, jklass_, NULL);
218 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
219 EXPECT_EQ(6, gJava_MyClass_fooIOO_calls);
220 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, jklass_, NULL);
221 EXPECT_TRUE(env_->IsSameObject(NULL, result));
222 EXPECT_EQ(7, gJava_MyClass_fooIOO_calls);
223}
224
Ian Rogersb033c752011-07-20 12:22:35 -0700225int gJava_MyClass_fooSIOO_calls = 0;
Elliott Hughes330304d2011-08-12 14:28:05 -0700226jobject Java_MyClass_fooSIOO(JNIEnv* env, jclass klass, jint x, jobject y,
Ian Rogersb033c752011-07-20 12:22:35 -0700227 jobject z) {
228 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
229 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700230 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
231 EXPECT_TRUE(klass != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700232 EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
Ian Rogersb033c752011-07-20 12:22:35 -0700233 gJava_MyClass_fooSIOO_calls++;
234 switch (x) {
235 case 1:
236 return y;
237 case 2:
238 return z;
239 default:
240 return klass;
241 }
242}
243
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700244
245TEST_F(JniCompilerTest, CompileAndRunStaticIntObjectObjectMethod) {
246 SetupForTest(true, "fooSIOO",
247 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
248 reinterpret_cast<void*>(&Java_MyClass_fooSIOO));
249
250 EXPECT_EQ(0, gJava_MyClass_fooSIOO_calls);
251 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, NULL);
252 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
253 EXPECT_EQ(1, gJava_MyClass_fooSIOO_calls);
254
255 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, jobj_);
256 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
257 EXPECT_EQ(2, gJava_MyClass_fooSIOO_calls);
258 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, NULL, jobj_);
259 EXPECT_TRUE(env_->IsSameObject(NULL, result));
260 EXPECT_EQ(3, gJava_MyClass_fooSIOO_calls);
261 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, NULL, jobj_);
262 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
263 EXPECT_EQ(4, gJava_MyClass_fooSIOO_calls);
264
265 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, NULL);
266 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
267 EXPECT_EQ(5, gJava_MyClass_fooSIOO_calls);
268 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, NULL);
269 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
270 EXPECT_EQ(6, gJava_MyClass_fooSIOO_calls);
271 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, NULL);
272 EXPECT_TRUE(env_->IsSameObject(NULL, result));
273 EXPECT_EQ(7, gJava_MyClass_fooSIOO_calls);
274}
275
Ian Rogersdf20fe02011-07-20 20:34:16 -0700276int gJava_MyClass_fooSSIOO_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700277jobject Java_MyClass_fooSSIOO(JNIEnv* env, jclass klass, jint x, jobject y,
Ian Rogersdf20fe02011-07-20 20:34:16 -0700278 jobject z) {
279 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
280 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700281 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
282 EXPECT_TRUE(klass != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700283 EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700284 gJava_MyClass_fooSSIOO_calls++;
285 switch (x) {
286 case 1:
287 return y;
288 case 2:
289 return z;
290 default:
291 return klass;
292 }
293}
294
Ian Rogersdf20fe02011-07-20 20:34:16 -0700295TEST_F(JniCompilerTest, CompileAndRunStaticSynchronizedIntObjectObjectMethod) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700296 SetupForTest(true, "fooSSIOO",
297 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
298 reinterpret_cast<void*>(&Java_MyClass_fooSSIOO));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700299
Ian Rogersdf20fe02011-07-20 20:34:16 -0700300 EXPECT_EQ(0, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700301 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, NULL);
302 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700303 EXPECT_EQ(1, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700304
305 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, jobj_);
306 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700307 EXPECT_EQ(2, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700308 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, NULL, jobj_);
309 EXPECT_TRUE(env_->IsSameObject(NULL, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700310 EXPECT_EQ(3, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700311 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, NULL, jobj_);
312 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700313 EXPECT_EQ(4, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700314
315 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, NULL);
316 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700317 EXPECT_EQ(5, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700318 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, NULL);
319 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700320 EXPECT_EQ(6, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700321 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, NULL);
322 EXPECT_TRUE(env_->IsSameObject(NULL, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700323 EXPECT_EQ(7, gJava_MyClass_fooSSIOO_calls);
324}
325
Ian Rogers45a76cb2011-07-21 22:00:15 -0700326int gSuspendCounterHandler_calls;
327void SuspendCountHandler(Method** frame) {
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700328 EXPECT_TRUE((*frame)->GetName()->Equals("fooI"));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700329 gSuspendCounterHandler_calls++;
330 Thread::Current()->DecrementSuspendCount();
331}
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700332
Ian Rogers0d666d82011-08-14 16:03:46 -0700333TEST_F(JniCompilerTest, SuspendCountAcknowledgement) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700334 SetupForTest(false, "fooI", "(I)I",
335 reinterpret_cast<void*>(&Java_MyClass_fooI));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700336 Thread::Current()->RegisterSuspendCountEntryPoint(&SuspendCountHandler);
337
Ian Rogers45a76cb2011-07-21 22:00:15 -0700338 gJava_MyClass_fooI_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700339 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
340 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700341 EXPECT_EQ(1, gJava_MyClass_fooI_calls);
342 EXPECT_EQ(0, gSuspendCounterHandler_calls);
343 Thread::Current()->IncrementSuspendCount();
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700344 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
345 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700346 EXPECT_EQ(2, gJava_MyClass_fooI_calls);
347 EXPECT_EQ(1, gSuspendCounterHandler_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700348 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
349 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700350 EXPECT_EQ(3, gJava_MyClass_fooI_calls);
351 EXPECT_EQ(1, gSuspendCounterHandler_calls);
352}
353
354int gExceptionHandler_calls;
355void ExceptionHandler(Method** frame) {
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700356 EXPECT_TRUE((*frame)->GetName()->Equals("foo"));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700357 gExceptionHandler_calls++;
358 Thread::Current()->ClearException();
359}
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700360
Ian Rogers45a76cb2011-07-21 22:00:15 -0700361TEST_F(JniCompilerTest, ExceptionHandling) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700362 SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700363 Thread::Current()->RegisterExceptionEntryPoint(&ExceptionHandler);
364
Ian Rogers45a76cb2011-07-21 22:00:15 -0700365 gJava_MyClass_foo_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700366 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700367 EXPECT_EQ(1, gJava_MyClass_foo_calls);
368 EXPECT_EQ(0, gExceptionHandler_calls);
369 // TODO: create a real exception here
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700370 Thread::Current()->SetException(reinterpret_cast<Object*>(jobj_));
371 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700372 EXPECT_EQ(2, gJava_MyClass_foo_calls);
373 EXPECT_EQ(1, gExceptionHandler_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700374 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700375 EXPECT_EQ(3, gJava_MyClass_foo_calls);
376 EXPECT_EQ(1, gExceptionHandler_calls);
377}
378
Ian Rogersb033c752011-07-20 12:22:35 -0700379} // namespace art