blob: 8a5155f7a525c4715e25b6727b1836781134bfc2 [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);
Ian Rogersa8cd9f42011-08-19 16:43:41 -070088 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -070089 gJava_MyClass_foo_calls++;
90}
91
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070092TEST_F(JniCompilerTest, CompileAndRunNoArgMethod) {
93 SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
94
95 EXPECT_EQ(0, gJava_MyClass_foo_calls);
96 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
97 EXPECT_EQ(1, gJava_MyClass_foo_calls);
98 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
99 EXPECT_EQ(2, gJava_MyClass_foo_calls);
100}
101
Ian Rogersb033c752011-07-20 12:22:35 -0700102int gJava_MyClass_fooI_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700103jint Java_MyClass_fooI(JNIEnv* env, jobject thisObj, jint x) {
Ian Rogersb033c752011-07-20 12:22:35 -0700104 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
105 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700106 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
107 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700108 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700109 gJava_MyClass_fooI_calls++;
110 return x;
111}
112
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700113TEST_F(JniCompilerTest, CompileAndRunIntMethod) {
114 SetupForTest(false, "fooI", "(I)I",
115 reinterpret_cast<void*>(&Java_MyClass_fooI));
116
117 EXPECT_EQ(0, gJava_MyClass_fooI_calls);
118 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
119 EXPECT_EQ(42, result);
120 EXPECT_EQ(1, gJava_MyClass_fooI_calls);
121 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFED00D);
122 EXPECT_EQ(static_cast<jint>(0xCAFED00D), result);
123 EXPECT_EQ(2, gJava_MyClass_fooI_calls);
124}
125
Ian Rogersb033c752011-07-20 12:22:35 -0700126int gJava_MyClass_fooII_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700127jint Java_MyClass_fooII(JNIEnv* env, jobject thisObj, jint x, jint y) {
Ian Rogersb033c752011-07-20 12:22:35 -0700128 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
129 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700130 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
131 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700132 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700133 gJava_MyClass_fooII_calls++;
134 return x - y; // non-commutative operator
135}
136
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700137TEST_F(JniCompilerTest, CompileAndRunIntIntMethod) {
138 SetupForTest(false, "fooII", "(II)I",
139 reinterpret_cast<void*>(&Java_MyClass_fooII));
140
141 EXPECT_EQ(0, gJava_MyClass_fooII_calls);
142 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 99, 10);
143 EXPECT_EQ(99 - 10, result);
144 EXPECT_EQ(1, gJava_MyClass_fooII_calls);
145 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFEBABE,
146 0xCAFED00D);
147 EXPECT_EQ(static_cast<jint>(0xCAFEBABE - 0xCAFED00D), result);
148 EXPECT_EQ(2, gJava_MyClass_fooII_calls);
149}
150
Ian Rogersb033c752011-07-20 12:22:35 -0700151int gJava_MyClass_fooDD_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700152jdouble Java_MyClass_fooDD(JNIEnv* env, jobject thisObj, jdouble x, jdouble y) {
Ian Rogersb033c752011-07-20 12:22:35 -0700153 EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
154 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700155 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
156 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700157 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700158 gJava_MyClass_fooDD_calls++;
159 return x - y; // non-commutative operator
160}
161
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700162TEST_F(JniCompilerTest, CompileAndRunDoubleDoubleMethod) {
163 SetupForTest(false, "fooDD", "(DD)D",
164 reinterpret_cast<void*>(&Java_MyClass_fooDD));
165
166 EXPECT_EQ(0, gJava_MyClass_fooDD_calls);
167 jdouble result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_,
168 99.0, 10.0);
169 EXPECT_EQ(99.0 - 10.0, result);
170 EXPECT_EQ(1, gJava_MyClass_fooDD_calls);
171 jdouble a = 3.14159265358979323846;
172 jdouble b = 0.69314718055994530942;
173 result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_, a, b);
174 EXPECT_EQ(a - b, result);
175 EXPECT_EQ(2, gJava_MyClass_fooDD_calls);
176}
177
Ian Rogersb033c752011-07-20 12:22:35 -0700178int gJava_MyClass_fooIOO_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700179jobject Java_MyClass_fooIOO(JNIEnv* env, jobject thisObj, jint x, jobject y,
Ian Rogersb033c752011-07-20 12:22:35 -0700180 jobject z) {
181 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
182 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700183 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
184 EXPECT_TRUE(thisObj != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700185 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
Ian Rogersb033c752011-07-20 12:22:35 -0700186 gJava_MyClass_fooIOO_calls++;
187 switch (x) {
188 case 1:
189 return y;
190 case 2:
191 return z;
192 default:
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700193 return thisObj;
Ian Rogersb033c752011-07-20 12:22:35 -0700194 }
195}
196
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700197TEST_F(JniCompilerTest, CompileAndRunIntObjectObjectMethod) {
198 SetupForTest(false, "fooIOO",
199 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
200 reinterpret_cast<void*>(&Java_MyClass_fooIOO));
201
202 EXPECT_EQ(0, gJava_MyClass_fooIOO_calls);
203 jobject result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, NULL, NULL);
204 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
205 EXPECT_EQ(1, gJava_MyClass_fooIOO_calls);
206
207 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, NULL, jklass_);
208 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
209 EXPECT_EQ(2, gJava_MyClass_fooIOO_calls);
210 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, NULL, jklass_);
211 EXPECT_TRUE(env_->IsSameObject(NULL, result));
212 EXPECT_EQ(3, gJava_MyClass_fooIOO_calls);
213 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, NULL, jklass_);
214 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
215 EXPECT_EQ(4, gJava_MyClass_fooIOO_calls);
216
217 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, jklass_, NULL);
218 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
219 EXPECT_EQ(5, gJava_MyClass_fooIOO_calls);
220 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, jklass_, NULL);
221 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
222 EXPECT_EQ(6, gJava_MyClass_fooIOO_calls);
223 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, jklass_, NULL);
224 EXPECT_TRUE(env_->IsSameObject(NULL, result));
225 EXPECT_EQ(7, gJava_MyClass_fooIOO_calls);
226}
227
Ian Rogersb033c752011-07-20 12:22:35 -0700228int gJava_MyClass_fooSIOO_calls = 0;
Elliott Hughes330304d2011-08-12 14:28:05 -0700229jobject Java_MyClass_fooSIOO(JNIEnv* env, jclass klass, jint x, jobject y,
Ian Rogersb033c752011-07-20 12:22:35 -0700230 jobject z) {
231 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
232 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700233 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
234 EXPECT_TRUE(klass != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700235 EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
Ian Rogersb033c752011-07-20 12:22:35 -0700236 gJava_MyClass_fooSIOO_calls++;
237 switch (x) {
238 case 1:
239 return y;
240 case 2:
241 return z;
242 default:
243 return klass;
244 }
245}
246
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700247
248TEST_F(JniCompilerTest, CompileAndRunStaticIntObjectObjectMethod) {
249 SetupForTest(true, "fooSIOO",
250 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
251 reinterpret_cast<void*>(&Java_MyClass_fooSIOO));
252
253 EXPECT_EQ(0, gJava_MyClass_fooSIOO_calls);
254 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, NULL);
255 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
256 EXPECT_EQ(1, gJava_MyClass_fooSIOO_calls);
257
258 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, jobj_);
259 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
260 EXPECT_EQ(2, gJava_MyClass_fooSIOO_calls);
261 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, NULL, jobj_);
262 EXPECT_TRUE(env_->IsSameObject(NULL, result));
263 EXPECT_EQ(3, gJava_MyClass_fooSIOO_calls);
264 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, NULL, jobj_);
265 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
266 EXPECT_EQ(4, gJava_MyClass_fooSIOO_calls);
267
268 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, NULL);
269 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
270 EXPECT_EQ(5, gJava_MyClass_fooSIOO_calls);
271 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, NULL);
272 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
273 EXPECT_EQ(6, gJava_MyClass_fooSIOO_calls);
274 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, NULL);
275 EXPECT_TRUE(env_->IsSameObject(NULL, result));
276 EXPECT_EQ(7, gJava_MyClass_fooSIOO_calls);
277}
278
Ian Rogersdf20fe02011-07-20 20:34:16 -0700279int gJava_MyClass_fooSSIOO_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700280jobject Java_MyClass_fooSSIOO(JNIEnv* env, jclass klass, jint x, jobject y,
Ian Rogersdf20fe02011-07-20 20:34:16 -0700281 jobject z) {
282 EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
283 EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700284 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
285 EXPECT_TRUE(klass != NULL);
Ian Rogersa8cd9f42011-08-19 16:43:41 -0700286 EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700287 gJava_MyClass_fooSSIOO_calls++;
288 switch (x) {
289 case 1:
290 return y;
291 case 2:
292 return z;
293 default:
294 return klass;
295 }
296}
297
Ian Rogersdf20fe02011-07-20 20:34:16 -0700298TEST_F(JniCompilerTest, CompileAndRunStaticSynchronizedIntObjectObjectMethod) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700299 SetupForTest(true, "fooSSIOO",
300 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
301 reinterpret_cast<void*>(&Java_MyClass_fooSSIOO));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700302
Ian Rogersdf20fe02011-07-20 20:34:16 -0700303 EXPECT_EQ(0, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700304 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, NULL);
305 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700306 EXPECT_EQ(1, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700307
308 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, NULL, jobj_);
309 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700310 EXPECT_EQ(2, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700311 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, NULL, jobj_);
312 EXPECT_TRUE(env_->IsSameObject(NULL, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700313 EXPECT_EQ(3, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700314 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, NULL, jobj_);
315 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700316 EXPECT_EQ(4, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700317
318 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, NULL);
319 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700320 EXPECT_EQ(5, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700321 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, NULL);
322 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700323 EXPECT_EQ(6, gJava_MyClass_fooSSIOO_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700324 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, NULL);
325 EXPECT_TRUE(env_->IsSameObject(NULL, result));
Ian Rogersdf20fe02011-07-20 20:34:16 -0700326 EXPECT_EQ(7, gJava_MyClass_fooSSIOO_calls);
327}
328
Ian Rogers45a76cb2011-07-21 22:00:15 -0700329int gSuspendCounterHandler_calls;
330void SuspendCountHandler(Method** frame) {
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700331 EXPECT_TRUE((*frame)->GetName()->Equals("fooI"));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700332 gSuspendCounterHandler_calls++;
333 Thread::Current()->DecrementSuspendCount();
334}
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700335
Ian Rogers0d666d82011-08-14 16:03:46 -0700336TEST_F(JniCompilerTest, SuspendCountAcknowledgement) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700337 SetupForTest(false, "fooI", "(I)I",
338 reinterpret_cast<void*>(&Java_MyClass_fooI));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700339 Thread::Current()->RegisterSuspendCountEntryPoint(&SuspendCountHandler);
340
Ian Rogers45a76cb2011-07-21 22:00:15 -0700341 gJava_MyClass_fooI_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700342 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
343 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700344 EXPECT_EQ(1, gJava_MyClass_fooI_calls);
345 EXPECT_EQ(0, gSuspendCounterHandler_calls);
346 Thread::Current()->IncrementSuspendCount();
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700347 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
348 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700349 EXPECT_EQ(2, gJava_MyClass_fooI_calls);
350 EXPECT_EQ(1, gSuspendCounterHandler_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700351 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
352 EXPECT_EQ(42, result);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700353 EXPECT_EQ(3, gJava_MyClass_fooI_calls);
354 EXPECT_EQ(1, gSuspendCounterHandler_calls);
355}
356
357int gExceptionHandler_calls;
358void ExceptionHandler(Method** frame) {
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700359 EXPECT_TRUE((*frame)->GetName()->Equals("foo"));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700360 gExceptionHandler_calls++;
361 Thread::Current()->ClearException();
362}
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700363
Ian Rogers45a76cb2011-07-21 22:00:15 -0700364TEST_F(JniCompilerTest, ExceptionHandling) {
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700365 SetupForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClass_foo));
Ian Rogers45a76cb2011-07-21 22:00:15 -0700366 Thread::Current()->RegisterExceptionEntryPoint(&ExceptionHandler);
367
Ian Rogers45a76cb2011-07-21 22:00:15 -0700368 gJava_MyClass_foo_calls = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700369 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700370 EXPECT_EQ(1, gJava_MyClass_foo_calls);
371 EXPECT_EQ(0, gExceptionHandler_calls);
372 // TODO: create a real exception here
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700373 Thread::Current()->SetException(reinterpret_cast<Object*>(jobj_));
374 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700375 EXPECT_EQ(2, gJava_MyClass_foo_calls);
376 EXPECT_EQ(1, gExceptionHandler_calls);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700377 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700378 EXPECT_EQ(3, gJava_MyClass_foo_calls);
379 EXPECT_EQ(1, gExceptionHandler_calls);
380}
381
Ian Rogersb033c752011-07-20 12:22:35 -0700382} // namespace art