blob: 39ba6ed3c3bf5fb38ffa809f32c4ad9c3c3c5724 [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();
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070024 dex_.reset(OpenDexFileBase64(kMyClassNativesDex));
25 class_loader_ = AllocPathClassLoader(dex_.get());
Ian Rogersb033c752011-07-20 12:22:35 -070026 }
27
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070028 void SetupForTest(bool direct, const char* method_name,
29 const char* method_sig, void* native_fnptr) {
30 const char* class_name = "LMyClass;";
31 Class* klass = class_linker_->FindClass(class_name, class_loader_);
32 ASSERT_TRUE(klass != NULL);
33
34 Method* method;
35 if (direct) {
36 method = klass->FindDirectMethod(method_name, method_sig);
37 } else {
38 method = klass->FindVirtualMethod(method_name, method_sig);
39 }
40 ASSERT_TRUE(method != NULL);
41
42 // Compile the native method
43 jni_compiler.Compile(&jni_asm, method);
44
45 env_ = Thread::Current()->GetJniEnv();
46
47 // TODO: when we support class loaders - env->FindClass(class_name);
48 IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env_)->locals;
49 uint32_t cookie = IRT_FIRST_SEGMENT; // TODO
50 IndirectRef klass_ref = locals.Add(cookie, klass);
51 jklass_ = reinterpret_cast<jclass>(klass_ref);
52 if (direct) {
53 jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
54 } else {
55 jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
56 }
57 ASSERT_TRUE(jmethod_ != NULL);
58
59 JNINativeMethod methods[] = {{method_name, method_sig, native_fnptr}};
60 ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1));
61
62 jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
63 jobj_ = env_->NewObject(jklass_, constructor);
64 ASSERT_TRUE(jobj_ != NULL);
Ian Rogersb033c752011-07-20 12:22:35 -070065 }
66
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070067 public:
68 static jclass jklass_;
69 static jobject jobj_;
70 protected:
71 scoped_ptr<DexFile> dex_;
72 PathClassLoader* class_loader_;
73 Assembler jni_asm;
74 JniCompiler jni_compiler;
75 JNIEnv* env_;
76 jmethodID jmethod_;
Ian Rogersb033c752011-07-20 12:22:35 -070077};
78
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070079jclass JniCompilerTest::jklass_;
80jobject JniCompilerTest::jobj_;
81
Ian Rogersb033c752011-07-20 12:22:35 -070082int gJava_MyClass_foo_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070083void Java_MyClass_foo(JNIEnv* env, jobject thisObj) {
Ian Rogersb033c752011-07-20 12:22:35 -070084 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
85 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070086 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
87 EXPECT_TRUE(thisObj != NULL);
88 // TODO: check JNIEnv and thisObj are sane
89 // EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -070090 gJava_MyClass_foo_calls++;
91}
92
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070093TEST_F(JniCompilerTest, CompileAndRunNoArgMethod) {
94 SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
95
96 EXPECT_EQ(0, gJava_MyClass_foo_calls);
97 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
98 EXPECT_EQ(1, gJava_MyClass_foo_calls);
99 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
100 EXPECT_EQ(2, gJava_MyClass_foo_calls);
101}
102
Ian Rogersb033c752011-07-20 12:22:35 -0700103int gJava_MyClass_fooI_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700104jint Java_MyClass_fooI(JNIEnv* env, jobject thisObj, jint x) {
Ian Rogersb033c752011-07-20 12:22:35 -0700105 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
106 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700107 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
108 EXPECT_TRUE(thisObj != NULL);
109 // TODO: check JNIEnv and thisObj are sane
110 // EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700111 gJava_MyClass_fooI_calls++;
112 return x;
113}
114
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700115TEST_F(JniCompilerTest, CompileAndRunIntMethod) {
116 SetupForTest(false, "fooI", "(I)I",
117 reinterpret_cast<void*>(&Java_MyClass_fooI));
118
119 EXPECT_EQ(0, gJava_MyClass_fooI_calls);
120 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
121 EXPECT_EQ(42, result);
122 EXPECT_EQ(1, gJava_MyClass_fooI_calls);
123 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFED00D);
124 EXPECT_EQ(static_cast<jint>(0xCAFED00D), result);
125 EXPECT_EQ(2, gJava_MyClass_fooI_calls);
126}
127
Ian Rogersb033c752011-07-20 12:22:35 -0700128int gJava_MyClass_fooII_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700129jint Java_MyClass_fooII(JNIEnv* env, jobject thisObj, jint x, jint y) {
Ian Rogersb033c752011-07-20 12:22:35 -0700130 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
131 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700132 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
133 EXPECT_TRUE(thisObj != NULL);
134 // TODO: check JNIEnv and thisObj are sane
135 // EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700136 gJava_MyClass_fooII_calls++;
137 return x - y; // non-commutative operator
138}
139
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700140TEST_F(JniCompilerTest, CompileAndRunIntIntMethod) {
141 SetupForTest(false, "fooII", "(II)I",
142 reinterpret_cast<void*>(&Java_MyClass_fooII));
143
144 EXPECT_EQ(0, gJava_MyClass_fooII_calls);
145 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 99, 10);
146 EXPECT_EQ(99 - 10, result);
147 EXPECT_EQ(1, gJava_MyClass_fooII_calls);
148 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFEBABE,
149 0xCAFED00D);
150 EXPECT_EQ(static_cast<jint>(0xCAFEBABE - 0xCAFED00D), result);
151 EXPECT_EQ(2, gJava_MyClass_fooII_calls);
152}
153
Ian Rogersb033c752011-07-20 12:22:35 -0700154int gJava_MyClass_fooDD_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700155jdouble Java_MyClass_fooDD(JNIEnv* env, jobject thisObj, jdouble x, jdouble y) {
Ian Rogersb033c752011-07-20 12:22:35 -0700156 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
157 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700158 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
159 EXPECT_TRUE(thisObj != NULL);
160 // TODO: check JNIEnv and thisObj are sane
161 // EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700162 gJava_MyClass_fooDD_calls++;
163 return x - y; // non-commutative operator
164}
165
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700166TEST_F(JniCompilerTest, CompileAndRunDoubleDoubleMethod) {
167 SetupForTest(false, "fooDD", "(DD)D",
168 reinterpret_cast<void*>(&Java_MyClass_fooDD));
169
170 EXPECT_EQ(0, gJava_MyClass_fooDD_calls);
171 jdouble result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_,
172 99.0, 10.0);
173 EXPECT_EQ(99.0 - 10.0, result);
174 EXPECT_EQ(1, gJava_MyClass_fooDD_calls);
175 jdouble a = 3.14159265358979323846;
176 jdouble b = 0.69314718055994530942;
177 result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_, a, b);
178 EXPECT_EQ(a - b, result);
179 EXPECT_EQ(2, gJava_MyClass_fooDD_calls);
180}
181
Ian Rogersb033c752011-07-20 12:22:35 -0700182int gJava_MyClass_fooIOO_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700183jobject Java_MyClass_fooIOO(JNIEnv* env, jobject thisObj, jint x, jobject y,
Ian Rogersb033c752011-07-20 12:22:35 -0700184 jobject z) {
185 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
186 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700187 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
188 EXPECT_TRUE(thisObj != NULL);
189 // TODO: check JNIEnv and thisObj are sane
190 // EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700191 gJava_MyClass_fooIOO_calls++;
192 switch (x) {
193 case 1:
194 return y;
195 case 2:
196 return z;
197 default:
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700198 return thisObj;
Ian Rogersb033c752011-07-20 12:22:35 -0700199 }
200}
201
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700202TEST_F(JniCompilerTest, CompileAndRunIntObjectObjectMethod) {
203 SetupForTest(false, "fooIOO",
204 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
205 reinterpret_cast<void*>(&Java_MyClass_fooIOO));
206
207 EXPECT_EQ(0, gJava_MyClass_fooIOO_calls);
208 jobject result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, NULL, NULL);
209 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
210 EXPECT_EQ(1, gJava_MyClass_fooIOO_calls);
211
212 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, NULL, jklass_);
213 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
214 EXPECT_EQ(2, gJava_MyClass_fooIOO_calls);
215 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, NULL, jklass_);
216 EXPECT_TRUE(env_->IsSameObject(NULL, result));
217 EXPECT_EQ(3, gJava_MyClass_fooIOO_calls);
218 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, NULL, jklass_);
219 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
220 EXPECT_EQ(4, gJava_MyClass_fooIOO_calls);
221
222 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, jklass_, NULL);
223 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
224 EXPECT_EQ(5, gJava_MyClass_fooIOO_calls);
225 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, jklass_, NULL);
226 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
227 EXPECT_EQ(6, gJava_MyClass_fooIOO_calls);
228 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, jklass_, NULL);
229 EXPECT_TRUE(env_->IsSameObject(NULL, result));
230 EXPECT_EQ(7, gJava_MyClass_fooIOO_calls);
231}
232
Ian Rogersb033c752011-07-20 12:22:35 -0700233int gJava_MyClass_fooSIOO_calls = 0;
Elliott Hughes330304d2011-08-12 14:28:05 -0700234jobject Java_MyClass_fooSIOO(JNIEnv* env, jclass klass, jint x, jobject y,
Ian Rogersb033c752011-07-20 12:22:35 -0700235 jobject z) {
236 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
237 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700238 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
239 EXPECT_TRUE(klass != NULL);
240 // TODO: check JNIEnv and klass are sane
241 // EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
Ian Rogersb033c752011-07-20 12:22:35 -0700242 gJava_MyClass_fooSIOO_calls++;
243 switch (x) {
244 case 1:
245 return y;
246 case 2:
247 return z;
248 default:
249 return klass;
250 }
251}
252
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700253
254TEST_F(JniCompilerTest, CompileAndRunStaticIntObjectObjectMethod) {
255 SetupForTest(true, "fooSIOO",
256 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
257 reinterpret_cast<void*>(&Java_MyClass_fooSIOO));
258
259 EXPECT_EQ(0, gJava_MyClass_fooSIOO_calls);
260 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, NULL);
261 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
262 EXPECT_EQ(1, gJava_MyClass_fooSIOO_calls);
263
264 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, jobj_);
265 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
266 EXPECT_EQ(2, gJava_MyClass_fooSIOO_calls);
267 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, NULL, jobj_);
268 EXPECT_TRUE(env_->IsSameObject(NULL, result));
269 EXPECT_EQ(3, gJava_MyClass_fooSIOO_calls);
270 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, NULL, jobj_);
271 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
272 EXPECT_EQ(4, gJava_MyClass_fooSIOO_calls);
273
274 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, NULL);
275 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
276 EXPECT_EQ(5, gJava_MyClass_fooSIOO_calls);
277 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, NULL);
278 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
279 EXPECT_EQ(6, gJava_MyClass_fooSIOO_calls);
280 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, NULL);
281 EXPECT_TRUE(env_->IsSameObject(NULL, result));
282 EXPECT_EQ(7, gJava_MyClass_fooSIOO_calls);
283}
284
Ian Rogersdf20fe02011-07-20 20:34:16 -0700285int gJava_MyClass_fooSSIOO_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700286jobject Java_MyClass_fooSSIOO(JNIEnv* env, jclass klass, jint x, jobject y,
Ian Rogersdf20fe02011-07-20 20:34:16 -0700287 jobject z) {
288 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
289 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700290 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
291 EXPECT_TRUE(klass != NULL);
292 // TODO: check JNIEnv and klass are sane
293 // EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700294 gJava_MyClass_fooSSIOO_calls++;
295 switch (x) {
296 case 1:
297 return y;
298 case 2:
299 return z;
300 default:
301 return klass;
302 }
303}
304
Ian Rogersdf20fe02011-07-20 20:34:16 -0700305TEST_F(JniCompilerTest, CompileAndRunStaticSynchronizedIntObjectObjectMethod) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700306 SetupForTest(true, "fooSSIOO",
307 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
308 reinterpret_cast<void*>(&Java_MyClass_fooSSIOO));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700309
Ian Rogersdf20fe02011-07-20 20:34:16 -0700310 EXPECT_EQ(0, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700311 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, NULL);
312 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700313 EXPECT_EQ(1, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700314
315 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, jobj_);
316 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700317 EXPECT_EQ(2, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700318 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, NULL, jobj_);
319 EXPECT_TRUE(env_->IsSameObject(NULL, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700320 EXPECT_EQ(3, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700321 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, NULL, jobj_);
322 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700323 EXPECT_EQ(4, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700324
325 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, NULL);
326 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700327 EXPECT_EQ(5, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700328 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, NULL);
329 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700330 EXPECT_EQ(6, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700331 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, NULL);
332 EXPECT_TRUE(env_->IsSameObject(NULL, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700333 EXPECT_EQ(7, gJava_MyClass_fooSSIOO_calls);
334}
335
Ian Rogers45a76cb2011-07-21 22:00:15 -0700336int gSuspendCounterHandler_calls;
337void SuspendCountHandler(Method** frame) {
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700338 EXPECT_TRUE((*frame)->GetName()->Equals("fooI"));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700339 gSuspendCounterHandler_calls++;
340 Thread::Current()->DecrementSuspendCount();
341}
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700342
Ian Rogers0d666d82011-08-14 16:03:46 -0700343TEST_F(JniCompilerTest, SuspendCountAcknowledgement) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700344 SetupForTest(false, "fooI", "(I)I",
345 reinterpret_cast<void*>(&Java_MyClass_fooI));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700346 Thread::Current()->RegisterSuspendCountEntryPoint(&SuspendCountHandler);
347
Ian Rogers45a76cb2011-07-21 22:00:15 -0700348 gJava_MyClass_fooI_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700349 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
350 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700351 EXPECT_EQ(1, gJava_MyClass_fooI_calls);
352 EXPECT_EQ(0, gSuspendCounterHandler_calls);
353 Thread::Current()->IncrementSuspendCount();
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700354 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
355 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700356 EXPECT_EQ(2, gJava_MyClass_fooI_calls);
357 EXPECT_EQ(1, gSuspendCounterHandler_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700358 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
359 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700360 EXPECT_EQ(3, gJava_MyClass_fooI_calls);
361 EXPECT_EQ(1, gSuspendCounterHandler_calls);
362}
363
364int gExceptionHandler_calls;
365void ExceptionHandler(Method** frame) {
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700366 EXPECT_TRUE((*frame)->GetName()->Equals("foo"));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700367 gExceptionHandler_calls++;
368 Thread::Current()->ClearException();
369}
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700370
Ian Rogers45a76cb2011-07-21 22:00:15 -0700371TEST_F(JniCompilerTest, ExceptionHandling) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700372 SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700373 Thread::Current()->RegisterExceptionEntryPoint(&ExceptionHandler);
374
Ian Rogers45a76cb2011-07-21 22:00:15 -0700375 gJava_MyClass_foo_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700376 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700377 EXPECT_EQ(1, gJava_MyClass_foo_calls);
378 EXPECT_EQ(0, gExceptionHandler_calls);
379 // TODO: create a real exception here
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700380 Thread::Current()->SetException(reinterpret_cast<Object*>(jobj_));
381 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700382 EXPECT_EQ(2, gJava_MyClass_foo_calls);
383 EXPECT_EQ(1, gExceptionHandler_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700384 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700385 EXPECT_EQ(3, gJava_MyClass_foo_calls);
386 EXPECT_EQ(1, gExceptionHandler_calls);
387}
388
Ian Rogersb033c752011-07-20 12:22:35 -0700389} // namespace art